fabricjs / fabric.js

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

Upvote: Layers #3000

Open awehring opened 8 years ago

awehring commented 8 years ago

At the Wiki there is "Support for multiple layers (for performance)" on the Roadmap.

I would like to upvote this feature.

It is not only helpfull for performance reasons, but can be very useful for any kind of drawing application. Basically it offers a powerull way to organize the drawings, steers which objects are currently visible/selectable/changeable.

For those, who are not familiar with the concept of layers, here is a short introduction: https://www.youtube.com/watch?v=CuKNa4KBC8s This video shows some powerful examples how layers can be used: https://www.youtube.com/watch?v=tEzBAVPQUF0 (Edit: I updated the video-links to better ones. This was the original link: https://www.youtube.com/watch?v=mE82knjW7IA)

I thought a bit about the functionality of a layer feature in fabrics. If you are interested, we can discuss it here.

PS: I appreciate the faster release policy very much.

asturur commented 8 years ago

I bet that multiple layers "for performance" was referred to keep a copy of the canvas in a single big image, to redraw under the active object. Yes we may end up implementi layers, but it will be a long term issue. I update the list of planned feature to reflect the next features that are coming.

awehring commented 8 years ago

Thank you for clarifying this!

I would like to share my thoughts about layer features anyway (layers in my sense) . They are surely not complete, but might be useful somehow.

Every object (rectangle, circle, ...) belongs to a layer. The layers are stacked above each other.

A layer-object has these main properties:

The boolean properties are ANDed with the respective object properties, e. g. the visibility of an object is given by: object.visible && layer.visible. So by setting a layer to invisible, all objects belonging to it are hidden.

Methods for a layer:

By default, there always exists one layer per canvas. If no layers are added, all the current functionality works like now. So compatibility withr current applications is preserved.

To me, the necessary work does not look excessive; but the devil is surely in the details, as always.
Layers could help to structure the application and enhance the performance. Let me give you two use cases: In a game there might be 4 layers: background, scene background, foreground and character. The background contains the landscape that never changes. It does not need to be regularly rendered. The scene background changes from time to time, when a new scene starts. It is rendered rarely. The foreground and character layers are dynamic and require the most computing and rendering time. The often necessary loops in the application across the objects are shorter, because they do not need to walk over all elements, but only over the fewer objects at the active layers. This does not only save processing time, but it also helps to focus the programmers attention to the important parts.

In a drawing application it is often difficult to manipulate an object, if it is hidden behind lots of other objects. If the objects are grouped on layers, it is easy to access them, when the layers above are switched off (made invisible and/or unselectable).

Comments are welcome.

samuelhorwitz commented 8 years ago

Besides the rendering aspect, what you are describing sounds like improved group support. This is actually just being discussed now #3012

EDIT: I see now that you are discussing something else. I thought you were referring to nested layers

awehring commented 8 years ago

Thank you for the reference.

Layers can be seen as an improved group support (nested or otherwise), but they are more like groups on steroids.

Every respected drawing application has good support of layers (Photoshop, Illustrator, Corel Draw, Sketch, CAD programs, even Gimp and Photoshop Elements).

Watch these videos to become impressed ;-) Basic concept: https://www.youtube.com/watch?v=CuKNa4KBC8s Some powerful examples: https://www.youtube.com/watch?v=tEzBAVPQUF0 (I referenced theses videos in the opening post too now.)
It's more or less impossible to make complex drawings without layers. As fabric.js becomes more and more a complete drawing library and is used for sophisticated applications, layers are a real need. Much of the functionality will better exist in the application, but fabric.js should offer some support, as outlined in the 3rd post. At least I think so.

DennisSmolek commented 8 years ago

So I also like the concept of layers if it ever gets built in, but it's fairly easy to modify the element stack order and not too hard to implement on the application layer.

What I might suggest is simply a demo where you have a layers panel.

FWIW: My method is to add a layer prop to my items, then have a layer array. I sort my items by their layer order(from the layer array) then their own order

butch2k commented 8 years ago

I choose to override the remove and add methods and rather than using them directly i use addtoLayer and a removeFromLayer functions which deal with positioning the objects correctly in the _objects array as well as managing the Layers at the application level through a layer property attached to the objects.

Moving the objects is just a matter of splicing in/out based on layers size.

zoomclub commented 8 years ago

Hi, just dropping by after hearing about the new version release. I had reviewed Fabric a while back and am quite surprised to learn that there is still a lack of layer support after all this time. I think this issue makes a strong case for layers, which I very much agree with.

Overall, such a foundational abstraction from the usual graphic world should have been considered from the get go. Anyhow, something along the lines of what @DennisSmolek proposes above works as well.

Happy layering :)

mbriggs commented 8 years ago

while its easy to override the object stack, there are still certain behaviors that will call methods like "bringToFront". it would be awesome to have "bringToFront" mean "bringToFront within my layer group" rather then "bringToFrontOfEverything". Note that we already have the base concept here, there is a background and overlay objects that are treated differently wrt object stack. This would be expanding on that idea. Instead of a single stack with fixed exceptions, allow for multiple stacks with a specified order. Solving the issue in a more general way also means that background and overlay are not special cases.

asturur commented 8 years ago

bring to front should work inside groups.

On Aug 4, 2016 12:48 PM, "Matt Briggs" notifications@github.com wrote:

while its easy to override the object stack, there are still certain behaviors that will call methods like "bringToFront". it would be awesome to have "bringToFront" mean "bringToFront within my layer group" rather then "bringToFrontOfEverything". Note that we already have the base concept here, there is a background and overlay objects that are treated differently wrt object stack. This would be expanding on that idea. Instead of a single stack with fixed exceptions, allow for multiple stacks with a specified order. Solving the issue in a more general way also means that background and overlay are not special cases.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kangax/fabric.js/issues/3000#issuecomment-237612815, or mute the thread https://github.com/notifications/unsubscribe-auth/ABI4QOD2ioObiWy0ZFKuq2Qbn285eB0iks5qchfXgaJpZM4Ij_YU .

eugene-ilyin commented 6 years ago

Hello

bring to front should work inside groups.

I found that it doesn't work. As I understand, when you try to call functions bringToFront or sendToBack from the object inside of the group, they are calling for the instance of fabric.Object. And they cannot change the order of objects in the group.

I made an example https://jsfiddle.net/Eugene_Ilyin/ckjdd1og/ There is my custom function moveObjectOnTheTop(), which is, of course, cannot be a final solution but can be a basis for the further patch.

@asturur what do you think about my approach? If you think it's correct, I can try to prepare a well-formatted patch.

P.S. I'm using fabric v2.

ShaMan123 commented 2 years ago

Layer is here

7669

DennisSmolek commented 2 years ago

Layer is here #7669

I'm not sure what that PR does but as it isn't merged yet I'm not sure it's correct yet to close this related issue, Mark it as fixed or pending, but if that PR in part or in whole get's rejected this issue will become an orphan...