1

So I want to make a drawing tool using SVG, I'm using a rather naive approach to change the d attribute of my Path:

$("div#drawarea").bind("mousemove", function(ev) {

  ev.preventDefault();

  ev.stopPropagation();

  var pX= (ev.pageX - this.offsetLeft);

  var pY= (ev.pageY - this.offsetTop);

  $path.attr("d", $path.attr("d") + " L" +pX+ "," + pY); //using jquery-svg here to change the d attribute

});

As you can see I do this on the mousemove function. The code works but it becomes unresponsive when the mouse is moving fast creating numerous straight lines when I actually want it to be smooth lines. I think this is happening because the numerous string concatenations I'm doing on the mousemove event (the d attribute on the path can become quite big when the click has been held for long, thousands of characters long in fact).

I'm wondering if there is any native way to add new values at the end of a path instead of manipulating the d attribute directly. I checked the jquery-svg sourcecode and it seems that the library also uses the naive string concatenation mode internally so using its methods would not wield any benefit.

Also I'm wondering if this is the case or if the browser just limits the amount of mousemove events (once every X milliseconds?) that can be triggered and so no performance optimizations would improve this.

Hoffmann
  • 14,369
  • 16
  • 76
  • 91
  • 2
    What you could do is have the "mousemove" handler simply add the point to an array. Then, have another routine periodically update the SVG, like maybe once every quarter-second or so, rebuilding the "d" attribute from the array of points. – Pointy Aug 20 '12 at 19:11
  • @Pointy that would improve performance, but is a rather ugly way to do it (I follow the philosophy that if you need a timer to do something in Javascript you should rethink the way you are doing it). I will wait to see if I get any other answer, if not I will try it your way. Thanks. – Hoffmann Aug 20 '12 at 19:36
  • Well the problem is that browsers fire a *lot* of those events, and making a DOM update on each one is going to get slow. If you don't want to use a polling timer, you could have the event check to see if an update has been scheduled, and schedule one it not. Then, the SVG update code can clear the flag once it's run. – Pointy Aug 20 '12 at 19:39

2 Answers2

2

Use the SVG pathseg DOM methods. You have to write more complicated code but the browser doesn't have to reparse the whole path attribute. Firefox for instance does take advantage of this and it's quite likely other broswers also.

Community
  • 1
  • 1
Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • I just want to drop by and say that although this approach worked a little better but I ended up using a canvas tag. – Hoffmann Aug 30 '13 at 20:32
1

In case someone else stumbeld upon the quesion of what is the fastes way to update an SVG-Path data attribute (for realtime applications), I run a small test on that:

http://jsperf.com/svg-path-test

Yes, setting it as string means that it needs to be parsed, which isn't the case for the DOM SVG interface but the first method is still much faster. Maybee the interface updates the DOM with each point added, slowing down the whole process.

stfn
  • 647
  • 5
  • 9