Reputation: 111
I need to draw a line between where the mouse used to be and where the mouse is now. In my search for an answer I found https://www.w3schools.com/graphics/svg_line.asp which explains making a single static line in HTML but nothing to do with dynamically creating them in JS.
Here is the code I am working with so far. I can draw circles with every mouse movement but not draw a line between those two mouse movements.
<script src="https://d3js.org/d3.v4.min.js">
</script>
<svg id="svg" style="width:100%; height:800px" />
<script>
const svg = d3.select('#svg');
let drawing = false;
let previous_coords = null;
function draw_point(previous_coords) {
if (!drawing)
return;
const coords = d3.mouse(this);
svg.append('circle')
.attr('cx', coords[0])
.attr('cy', coords[1])
.attr('r', 5)
.style('fill', 'black');
// this block doesn't work
svg.append('line')
.attr('x1', previous_coords[0])
.attr('y1', previous_coords[1])
.attr('x2', coords[0])
.attr('y2', coords[1])
.style('stroke', rgb(255, 0, 0))
.style('stroke-width', 10);
previous_coords = d3.mouse(this);
};
svg.on('mousedown', () => {
drawing = true;
});
svg.on('mouseup', () => {
drawing = false;
});
svg.on('mousemove', draw_point);
</script>
Upvotes: 3
Views: 2937
Reputation: 20140
I'm not sure d3
is the best possible choice of library for what you are trying to do, but your immediate issue is the variable previous_coords
. You have declared it both as a global, and as an argument to your draw_point
function. Since draw_point is called as an event handler for the mousemove
event I don't think it will ever be passed a point as an argument. If you eliminate the extraneous argument declaration, then you still have the problem of not initializing previous_coords
before you use it, but this can be solved by initializing previous_coords
in the mouse down event. Here is an updated snippet that hopefully works as you intended:
<script src="https://d3js.org/d3.v4.min.js">
</script>
<svg id="svg" style="width:100%; height:800px" />
<script>
const svg = d3.select('#svg');
let drawing = false;
let previous_coords = null;
function draw_point() {
if (!drawing)
return;
const coords = d3.mouse(this);
svg.append('circle')
.attr('cx', previous_coords[0])
.attr('cy', previous_coords[1])
.attr('r', 5)
.style('fill', 'black');
svg.append('circle')
.attr('cx', coords[0])
.attr('cy', coords[1])
.attr('r', 5)
.style('fill', 'black');
// this block doesn't work
svg.append('line')
.attr('x1', previous_coords[0])
.attr('y1', previous_coords[1])
.attr('x2', coords[0])
.attr('y2', coords[1])
.style('stroke', 'rgb(255, 0, 0)')
.style('stroke-width', 2);
previous_coords = coords;
};
svg.on('mousedown', function() {
previous_coords = d3.mouse(this)
drawing = true;
});
svg.on('mouseup', () => {
drawing = false;
});
svg.on('mousemove', draw_point);
</script>
Upvotes: 2