Regarding transparency, are you using an item with both fill and stroke? This would require the item to be rendered to a separate canvas first and then blended over with transparency, which would explain why it's slow.
We haven't looked into optimizations too heavily yet, I'm sure there's plenty of room for things to improve still.
There's obviously a little overhead of the library, but when things run slow, usually the biggest part of the code is spent in the native canvas drawing methods.
Perhaps you could use a profiler to find out what's slowing it down?
Jürg
Profiling on WebKit showed other results, I'm not sure you're reading the profiler correctly?
Regards,
Jürg
We wanted opacity set to something below 1.0 not to make the fill appear behind the stroke (mimicking the way it's handled in Illustrator and thus Scriptographer), so the solution was to draw everything without opacity into a separate canvas and then render the image with opacity into the main canvas. This is a bottleneck indeed.
Alternatives could be to convert stroke to non-overlapping fill once we implement a path stroker / outliner and see how that performs.
We're open to other suggestions.
Jürg
The observation about isZero() is a good one. For Segments we override Point with SegmentPoint, so we can intercept changes to its coordinates (x & y) through getters / setters. The price we pay is slightly slower performance in property access, which is why in most SegmentPoint specific code we use its internal properties _x & _y directly. The internal isZero() calls are one place where we forgot to do so, and it does indeed show. I shall fix that. There might be other places too.
BTW, the inlining of _x & _y will not work for instances of Point, only for SegmentPoint. In the base class Point, x & y are real properties, not accessors, and _x & _y are not there.
The other observation about DOM creation being 'slow' is not a surprise. It was never intended to be used that way, and we haven't optimised the Path.* constructors or even the DOM hierarchy methods for speed yet. If you're creating and destroying the DOM on each frame, why not just use Canvas drawing operations directly? The performance improvements should be rather big.
Instead of destroying and recreating the rects, you might want to try scaling them in place? You can either modify their segments, or just set their bounds to the new dimensions.
To clarify: The motivation for creating Paper.js was to provide a well abstracted vector graphics toolset that facilitates the creation and manipulation of vector shapes very much in a way that for example a drawing application like InkScape or Illustrator would require. We provide the complicated math to calculate path lengths, bounding boxes including stroke styles, dashing, etc. It wasn't the plan to be a high performance drawing toolkit for shapes that are created and destroyed on each frame.
Even the fact that it seemed so well suited for animations came as quite a surprise to us. We only realised this once we ported the foundations of Scriptographer over.
Jürg
From my tests it seemed that 25% of the time are spent in some underscore.js code. Did you look into that?
On 12 Aug 2011, at 14:29, Peter Rietzler wrote:
For Canvas, one solution could be to tolerate the mixing of fills and strokes. This could be a flag per project perhaps? I don't think there will be another solution on the short term.
As for the Quad trees, how easy is it to keep them up to date with moving items? And what do they reference? The bounds of the item, or just the center? I'm very interested in this work, and we're happy to integrate code if it makes sense.
Jürg
Jürg
I doubt that this is the solution, since it requires the creation of a full tree from scratch on each frame. This would be extreme overkill if for example all we executed was one hit-test.
What we would need is a structure that could be updated for the changed items only without rebuilding the whole thing. This could then be kept up-to-date for us behind the scenes, without the user even needing to know it's there.
If anybody has suggestions?
Transparency:
If there's only a fill, the drawing should already happen at the optimal speed. Perhaps you could put an example up online for me to test?