Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upvote: Layers #3000

Open
awehring opened this issue May 22, 2016 · 12 comments
Open

Upvote: Layers #3000

awehring opened this issue May 22, 2016 · 12 comments

Comments

@awehring
Copy link

awehring commented May 22, 2016

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
Copy link
Member

asturur commented May 23, 2016

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
Copy link
Author

awehring commented May 24, 2016

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:

  • visible: when false, all objects belonging to this layer are not visible.
  • selectable: when false, the objects belonging to this layer cannot be selected.
  • evented: when false, the objects belonging to this layer cannot be a target of events
  • opacity: the visible opacity of an object is the product of object.opacity * layer.opacity. (This property can be considered as a first step. Later on, filters could be applied to layers accordingly.)

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:

  • add(), remove() creates and destroys a layer.
  • bringForward(), bringToFront(), moveTo(), etc., moves a layer in a stack of layers (The current object.bringForward(), etc., works within a layer).
  • render() renders the layer
  • deactivate() deactivates all objects on a layer.
  • canvas.add() could get an additional parameter that references the layer to which the new object shall belong.

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
Copy link

samuelhorwitz commented May 26, 2016

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
Copy link
Author

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
Copy link

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
Copy link

butch2k commented Jun 10, 2016

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
Copy link

zoomclub commented Jul 10, 2016

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
Copy link

mbriggs commented Aug 4, 2016

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
Copy link
Member

asturur commented Aug 4, 2016

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
#3000 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABI4QOD2ioObiWy0ZFKuq2Qbn285eB0iks5qchfXgaJpZM4Ij_YU
.

@eugene-ilyin
Copy link

eugene-ilyin commented Jan 12, 2018

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
Copy link
Contributor

ShaMan123 commented Feb 12, 2022

Layer is here
#7669

@DennisSmolek
Copy link

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
9 participants