{
const width = 500;
const height = 500;
let pointer;
let pointerLine;
const root = d3.create('div')
const distanceDiv = root.append('div')
.style('height', '25px')
.text('Distance: ---');
const performanceDiv = root.append('div')
.style('height', '25px')
.text('Performance: ---');
const svg = root.append('svg')
.style('width', `${width}px`)
.style('height', `${height}px`)
.style('border', '2px dotted DimGrey')
.on('mouseout', () => {
pointer.attr('opacity', 0);
pointerLine.attr('opacity', 0);
})
.on('mousemove', () => {
const mousePos = d3.mouse(d3.event.target);
const point = new Vector2(mousePos[0] - 1, mousePos[1])
const t0 = performance.now();
const pointOnLine = ClosestPointOnLine(point, line.start, line.end);
const t1 = performance.now();
distanceDiv.text(`Distance: ${Vector2.dist(point, pointOnLine).toFixed(2)}`);
performanceDiv.text(`Performance: ${(t1 - t0).toFixed(3)}`);
pointer.attr('opacity', 1)
.attr('cx', point.x)
.attr('cy', point.y)
pointerLine.attr('opacity', 1)
.attr('x1', point.x)
.attr('y1', point.y)
.attr('x2', pointOnLine.x)
.attr('y2', pointOnLine.y);
})
svg.append('line')
.attr('x1', line.start.x)
.attr('y1', line.start.y)
.attr('x2', line.end.x)
.attr('y2', line.end.y)
.attr('stroke', 'SteelBlue')
.attr('stroke-width', 1.3)
.attr('pointer-events', 'none');
pointer = svg.append('circle')
.attr('cx', 100)
.attr('cy', 100)
.attr('r', 3)
.attr('fill', 'OrangeRed')
.attr('opacity', 0)
.attr('pointer-events', 'none');
pointerLine = svg.append('line')
.attr('stroke', 'OrangeRed')
.attr('stroke-width', 1.3)
.attr('pointer-events', 'none')
.attr('opacity', 0);
return root.node();
}