Open shashi-drishya opened 6 months ago
@asturur, can we have this
I am currently working on this feature for a private project and it is major when the canvas has 5000+ objects. Not only does rendering improves significantly (50ms dropped to 9ms for each render). The same amount of time is saved if the app tracks the result of isOnScreen (instead of running it from Object#render) and reused by findTarget that won't need to interate through all the objects but only the objects that are visible on screen.
Also I turned the renderer to be an infinite loop, bailing out the current tick if nothing has changed That seems to be a good design decision inspired by pixi.js
This is part of the roadmap since long and was never started. It will be done after v6 is out and the first fires of documentation and issues are settled.
I think this was in planning since 2018 at least.
The issue with approaching this as a rendering library and not as an app is that tracking is up to you. So when you change the color of an object you know you don't need to call canvas.renderAll but maybe something like canvas.renderObject(object).
When dragging an object that is one of the basic feature of fabric, is already harder because you have to track previous and next position for update, and if there are animations running on the canvas maybe you have to settle with renderAll at the end.
Is a balance between spending time deciding what to re-render and what intersect with it or just rendering everything.
You can expect this to go out as a method for the canvas and then slowly integrate supported actions.
Just popping in to say something like canvas.renderObject(object) is exactly what I was searching for and would def be useful.
i think it will be something like canvas.renderObjects([objects]), and i will start to work on it as soon as i m done with fabricjs.github.io enough to swap fabricjs.com
@ShaMan123 Can you write more about how you implemented this in your project?
You need to track the changing objects depending on your business logic and compute the bounding box that contains them. Then you render the rect which is the union of the previous and current dirty rects onto a separate canvas by filtering the objects that overlap it. Finally, you clear the rect from the main canvas and draw the new rect over it. Be sure to round the rect values when you do that to integer values to avoid canvas anti aliasing.
CheckList
Description
The selective rendering feature should enhance canvas performance by only updating the modified object. When an object is altered or manipulated, the canvas should efficiently re-render just that specific object rather than the entire canvas. This selective rendering should be smart enough to update only the necessary portions of the canvas that are impacted by the change.
The feature should accommodate scenarios like moving, scaling, rotating, or modifying object properties. The solution should intelligently track changes, optimize redrawing, and minimize unnecessary updates to improve performance, particularly with complex or crowded canvases.
Additionally, this feature should be intuitive and straightforward to integrate, allowing developers to enhance their applications' performance without extensive refactoring. By focusing on updating only the changed object, the canvas should operate more efficiently, providing smoother user interactions and enhanced application responsiveness.
Current State
In Fabric.js, the default behavior when an object is modified is to re-render the entire canvas. This approach ensures that the canvas's visual state remains consistent, especially when multiple overlapping objects are involved.
However, this can be inefficient in cases where only a single object is updated, as redrawing the whole canvas may involve unnecessary computation, particularly for large or complex canvases. The lack of selective rendering is a key reason why developers sometimes request more optimized rendering features for scenarios where frequent or incremental updates are necessary.