I am trying to write a program which lets users draw a line (using SVG) between two points. Upon selecting position one (by clicking) the user then moves the mouse which draws the line, eventually they will click again and the new line should set. However, during the mouse-moving function, many lines are drawn causing the below issue:


Instead of this happening, I am needing only the last SVG tag to exist - does anyone know of a way that I can delete the old ones in real time? Or, if not, any other method of doing this?
const userPointsStartEnd = [{x: undefined, y: undefined},
{x: undefined, y: undefined}];
let userPath = [];
function onMouseDown(event) {
//Add code here
// alert("clientX: " + event.clientX +" - clientY: " + event.clientY);
if (userPointsStartEnd[0].x === undefined) {
userPointsStartEnd[0].x = (event.clientX);
userPointsStartEnd[0].y = (event.clientY);
// alert(userPointsStartEnd[0].x);
} else {
userPointsStartEnd[1].x.push(event.clientX);
userPointsStartEnd[1].y.push(event.clientY);
}
}
function onMouseMove(event) {
//Add code here
let lineExist = false;
if (userPointsStartEnd[0].x !== undefined) {
const userLine = document.getElementById('content');
// userPath = 'M' + userPointsStartEnd[0].x + ' ' + userPointsStartEnd[0].y + ' ' + 'L' + event.clientX + ' ' + event.clientY;
//userPath += ' Z';
// alert(event.clientX);
//alert(userPath);
let startX = '' + userPointsStartEnd[0].x;
let startY = '' + userPointsStartEnd[0].y;
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
var newLine = document.createElementNS('http://www.w3.org/2000/svg', 'line');
svgElement.setAttribute('style', 'position: absolute;');
//svgElement.setAttribute('fill-opacity', "0.2");
svgElement.setAttribute('height', "1000");
svgElement.setAttribute('width', "1000");
newLine.setAttribute('id', 'line2');
newLine.setAttribute('x1', startX);
newLine.setAttribute('y1', startY);
// newLine.setAttribute('x2', event.clientX);
// newLine.setAttribute('y2', event.clientY);
while(!lineExist) {
newLine.setAttribute('x2', event.clientX);
newLine.setAttribute('y2', event.clientY);
lineExist=true;
}
newLine.setAttribute("stroke", "black")
userLine.append(newLine);
svgElement.appendChild(newLine);
userLine.appendChild(svgElement);
}
}
function onMouseUp(event) {
}
function setup() {
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mousedown', onMouseDown);
document.addEventListener('mouseup', onMouseUp);
}
window.onload = () => setup()
<html>
<script src="question.js"></script>
<body>
<div id="content" style="display:block; overflow:visible; position:absolute">
<div id="userLine"style="display:block; overflow:visible">
</div>
</div>
</body>
</html>
The main idea is this:
you create the svg element only once so you don't put it in a function that you call many times on mouse move
you create the line on mouse down. The line will have length 0 in this moment since x2=x1 and y2=y1. If you create the line on mouse move you'll have many lines since the mousemove event is fired many times while you move the mouse over the document.
Also on mouse down I set the variable drawing as true: yes I am drawing.
on mouse move you reset the values for x2 and y2 only if drawing = true
on mouse up drawing=false
let svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElement.setAttribute("style", "position: absolute;");
svgElement.setAttribute("height", "1000");
svgElement.setAttribute("width", "1000");
const userLine = document.getElementById("userLine");
userLine.appendChild(svgElement);
let newLine;
let drawing = false;
function onMouseDown(event) {
drawing = true;
newLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
//newLine.setAttribute('id', 'line2');
newLine.setAttribute("stroke", "black");
newLine.setAttribute("x1", event.clientX);
newLine.setAttribute("y1", event.clientY);
newLine.setAttribute("x2", event.clientX);
newLine.setAttribute("y2", event.clientY);
svgElement.appendChild(newLine);
}
function onMouseMove(event) {
//Add code here
if (drawing) {
newLine.setAttribute("x2", event.clientX);
newLine.setAttribute("y2", event.clientY);
}
}
function onMouseUp(event) {
drawing = false;
}
function setup() {
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mousedown", onMouseDown);
document.addEventListener("mouseup", onMouseUp);
}
window.onload = () => setup();
svg{background:#ccc}
body{margin:0;padding:0;}
<div id="content" style="display:block; overflow:visible; position:absolute">
<div id="userLine" style="display:block; overflow:visible">
</div>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With