{
let regl = stack.layers.regl;
let ctx = stack.layers.canvas;
let svg = d3.select(stack.layers.svg);
let xScale = d3.scaleLinear()
.domain([-3, 3])
.range([viewport.margin.l, viewport.width - viewport.margin.r])
.clamp(true);
let yScale = constrainLinearScaleAspectRatio(
d3.scaleLinear()
.domain([-1.5, 1.5])
.range([viewport.height - viewport.margin.b, viewport.margin.t])
.clamp(true),
xScale, 1);
let update;
let points = [[1, -1], [1, 1], [-1, -1], [-1, 1]];
let pointsBuffer = regl.buffer(points);
svg.selectAll('g.axes').remove();
let axes = svg.append('g')
.attr('class', 'axes')
.call(viewportAxes(viewport, xScale, yScale))
let g = svg.selectAll('g.handles').remove();
g = svg.selectAll('g.handles')
.data([points])
.enter().append('g')
.attr('class', 'handles');
let handles = g.selectAll('circle')
.data(d => d).enter().append('circle')
.attr('cursor', 'move')
.attr('r', 5)
.attr('stroke-width', 30)
.attr('stroke', 'transparent')
.attr('fill', 'blue')
.call(d3.drag()
.on("drag", (d) => {
d[0] = xScale.invert(d3.event.x);
d[1] = yScale.invert(d3.event.y);
update();
}));
update = function update () {
handles
.attr('cx', data => xScale(data[0]))
.attr('cy', data => yScale(data[1]));
pointsBuffer.subdata(points)
regl.poll();
regl.clear({color: [1, 1, 1, 1]})
configureViewport(viewport, ({viewport3}) => {
configureLinearScales(xScale, yScale, ({view3}) => {
drawStrip({points: pointsBuffer, count: points.length});
})
})
let ctxTransform = mat3multiply(mat3create(),
mat3ViewportFromLinearScales(mat3create(), xScale, yScale),
mat3fromLinearScales(mat3create(), xScale, yScale));
ctx.clearRect(0, 0, stack.width, stack.height);
ctx.beginPath();
ctx.lineWidth = 4;
ctx.strokeStyle = '#3a3';
ctx.moveTo.apply(ctx, vec2transformMat3([], points[1], ctxTransform));
ctx.lineTo.apply(ctx, vec2transformMat3([], points[2], ctxTransform));
ctx.moveTo.apply(ctx, vec2transformMat3([], points[3], ctxTransform));
ctx.lineTo.apply(ctx, vec2transformMat3([], points[0], ctxTransform));
ctx.stroke();
}
update();
yield stack.container
}