Search code examples
javascriptsvgsvg-path

JS svg painting. How to lower Lines drawing frequency(mousemove event)?


I'm writing a simple SVG drawing app, now i'm trying to optimize line drawing. The raw variant is draw every 'lineTo' on every mousemove event. It creates bad looking sharpness.

Im using global variable testInt to simulate delay between lineTo's actions, it gives really nice smooth line, but seems like bad practise. Could anyone suggest a better solution?

Here's my drawLine function code (as i said it basically modifies existing < path > element):

drawLine: function(id, X, Y){
    var path = document.getElementById(id);
    if(path.getAttribute('d'))
    {
        testInt++;
        if(testInt>=6)
        {
            PathHelper.addLineTo(path, X, Y);
            testInt = 0;
        }
    }
    else
    {
        PathHelper.moveTo(path, X, Y);
    }
}

PathHelper is only generates the right string and inserts it in already created path.


Solution

  • Here's a solution which will introduce a delay between the drawing of each line. Notice that the canDrawLine flag exists in a closure, so no global variables are used. I'm using setTimeout to toggle the flag to true after a delay each time a line is drawn.

    drawLine: drawLineFactory();
    
    function drawLineFactory() {
    
      var canDrawLine = true;
    
      //Decrease to draw lines more often; increase to draw lines less often
      var TIME_BETWEEN_LINES_MS = 100;
    
      function drawLine(id, X, Y) {
    
        //If a line was recently drawn, we won't do anything
        if (canDrawLine) {
          var path = document.getElementById(id);
          if (path.getAttribute('d')) {
            PathHelper.addLineTo(path, X, Y);
    
            //We won't be able to draw another line until the delay has passed
            canDrawLine = false;
            setTimeout(function() {
              canDrawLine = true;
            }, TIME_BETWEEN_LINES_MS);
    
          } else {
            PathHelper.moveTo(path, X, Y);
          }
        }
      }
    
      return drawLine;
    }