Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using Javascript SVG to draw a line, multiple <SVG>'s are made as the mouse moves. How do I ensure only the last <SVG> remains?

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:

multiple svg tags as mouse moves

multiple svg tags as mouse moves2

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>
like image 730
Marcooz2007 Avatar asked Oct 28 '25 13:10

Marcooz2007


1 Answers

The main idea is this:

  1. you create the svg element only once so you don't put it in a function that you call many times on mouse move

  2. 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.

  3. on mouse move you reset the values for x2 and y2 only if drawing = true

  4. 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>
like image 87
enxaneta Avatar answered Oct 31 '25 04:10

enxaneta



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!