fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser
http://fabricjs.com
Other
29.05k stars 3.51k forks source link

Possible Feature - Object/Background caching #1102

Closed GordoRank closed 10 years ago

GordoRank commented 10 years ago

Within my app I have the need to have lots of Fabric objects on canvas at any given time. To make matters worse most of them have to have shadows and/or other expensive effects added to them.

Due to this need, using Fabric as is was an impossibility.

For that reason I added a caching/rasteration rendering pipeline to Fabric.

The caching mode is initialized by setting the property turbo to true when initializing a Fabric canvas.

There are however two caveats, which is why I haven't created a pull request yet for it as I want to gauge feedback from @kangax and anyone else as to whether this is in keeping with Fabrics intentions.

The Caveats :

  1. When developing an app changing an objects properties with dot notation will not update the object. (I believe this is deprecated anyway) Instead the properties must be changed using the object.set() method. This only applies to properties internal to an object like text or fontSize. Any transform properties such as top or left can still be set with dot notation.
  2. While transforming or moving an object it's z-index is ignored and the object is brought to the top of the stack for the duration of the transformation. As soon as you let go of the mouse, it returns to it's correct place in the stack.

Upon doing some testing I realised that using turbo mode also has the huge benefit of making the initial loading of complex scenes with lots of objects infinitely faster. In my example below we are talking 5 seconds versus 3 minutes!

I have uploaded two videos to YouTube to show you before and after. (Please switch the videos to HD as I recorded in 1920x1080)

NO TURBO :

http://www.youtube.com/watch?v=Hv_UI-YhCTk

WITH TURBO :

http://www.youtube.com/watch?v=-Ic9Pgrkbvk

In these two videos I am loading 1000 fabric objects into a canvas. 500 images and 500 I-Text objects. (For this reason the hidden textarea fix in my recent pull request #1111 is paramount as having 500 textareas added to the DOM causes a huge amount of strain)

In the first video you will see that the objects load quickly at first and then slow down to a complete crawl. You will see me waiting for the objects to load as they pop up slowly on by one. Eventually I gave up waiting and attempted to move an object. The result was way less than 1 fps.

In the second video you will see that all objects are drawn to the screen pretty quickly within a few seconds and then all object manipulation happens at a fluid an constant 60fps.

Let me know what you think. If its something that people want included in Fabric despite the two (in my opinion minor) caveats, then I will make a pull request tomorrow.

ryan-digbil commented 10 years ago

I would love to have this also.

+1

schainks commented 10 years ago

+1 !

This is a great request, kindly consider it. I could really use this too.

GordoRank commented 10 years ago

@kangax Would be great to get your thoughts on this. I have a PR ready to go.

GordoRank commented 10 years ago

I've just added my first experimental version of this into my fork.

It is fully tested with most major object types:

I still have work to do on animating/paths/brushes.

It may be I simply end up turning turbo mode off for these things.

kangax commented 10 years ago

Swamped with work at the moment; will try to get to all PR's soon-ish.

kangax

On Wed, Jan 22, 2014 at 9:54 AM, GordoRank notifications@github.com wrote:

I've just added my first experimental version of this into my fork.

It is fully tested with most major object types:

  • Rect
  • Circle
  • Ellipse
  • Triangle
  • Image
  • Text
  • I-Text
  • SVG

I still have work to do on animating/paths/brushes.

It may be I simply end up turning turbo mode off for these things.

— Reply to this email directly or view it on GitHubhttps://github.com/kangax/fabric.js/issues/1102#issuecomment-33029736 .

GordoRank commented 10 years ago

@kangax No worries! I'm lucky that right now my work heavily involves Fabric :-)

fmahannah commented 10 years ago

We absolutely need this feature for a project we are working on. Once we get a number of objects on canvas the drag performance is really slow and jumpy! Is there any place I can get this fork to implement in our project? Thanks!

skrichten commented 10 years ago

This sounds great. The "caveats" are not bad at all. Any update on this topic?

ryan-digbil commented 10 years ago

Have you gotten to this pull request yet? We really need this feature. When we have a lot of objects, or a large canvas everything is slow and stuttery.

kangax commented 10 years ago

@ryan-digbil if @GordoRank makes PR for this, I can take a look. I read description and everything sounds awesome except transformation bringing object to top; this would be somewhat of a back-incompatible (albeit purely visual) change that might not be all that great in some applications.

jwmao commented 8 years ago

@kangax , any updates for this feature? We really need this feature in my project.

asturur commented 8 years ago

We could make this caching different. Make a sandwich with: all objects under the transforming one cached as a single image, the transforming object all objects over the transforming one cached as a single image.

The performance problem with large canvas would stay anyway.

jwmao commented 8 years ago

@asturur Any possible solution that you can suggest?

neerajrathod05 commented 6 years ago

@kangax, We are facing the same problem when objects get increased the drag performance get lagging. We want to manage around 10k objects. Please respond, Is this issue has been fixed, if no then suggest any workaround for it, so we can proceed further.

asturur commented 6 years ago

10k objects is MUCH work. Some speed improvement can be made with a new render logic i have in mind, but i m far from starting it.