Description
V6
Hi everyone,
fabric is moving forward!
We have 2 main goals for v6:
- js/ts migration which is covered here IMPORTANT: Migrating to modern javascript/typescript #7596
- Group rewrite 🎉
You can see #8316
Group Rewrite
This is a tracking issue for the group rewrite, read below for more detail including the current state of things and gist.
We aim to fix and support long desired features including:
- Nested selection - DONE
- Resizing and customized layout - DONE
- Transform and coordinate system (which is relative to the parent group) - DONE
Motivating Issues/Discussions
#7473 #7316 #6776 #7136 #7299 #7130 #7142 #7449 and anything with a group
tag
How do you fit in?
- You can become an alpha tester (we aim to publish an alpha tag to npm regularly).
IMPORTANT NOTICE: all changes made to the v6 branch are experimental and can be removed or changed without notice and without proper support (including supported features from v5). fabric might change drastically between commits. Meaning if you want in - it's on you.
You can join the effort by contributing
This description is updated continuously with relevant information
You don't need to scroll and read endless comments (unless you are a maintainer :))
Current State
Fixed logic across fabric for nested objects to be selectable.
Group has been completely rewritten and Layer has been introduced. As part of the rewrite group is now a layout engine, you can use it to customize layout of objects.
In general the rewrite allows any object to be selectable and interactive if it is referenced in the _objects
array of it's parent and it references it's parent via the group
property. If you build custom objects with nesting this is what you are looking for.
Usage
It is advised to use set
on group/objects from now on (until #7596 is done, then it might change due to setters)
Changing subTargetCheck
or interactive
enables/disables crucial functionality so for these props it is not an advice but a MUST.
new fabric.Group(objects, {
subTargetCheck: true,
interactive: true // enables selecting subtargets
});
Progress
- feat(Group): First Patch of New Group! 🥳 #7858
- feat(Group): 2nd Patch of New Group! 🎉 #7859
- fix(Group): patch2 minors #7916
- fix(Group): patch #7916 #8000
- feat(Layer): 3rd Patch of Group Rewrite ♦️ #7860 needs porting to v6
- fix(v6): 4th PR of Group Rewrite 🎛️ nested controls 😜 #7861
- fix(Group): 🛠️ layout, angle and origin ⚡ #8004
- fix(Group): remove added object from canvas #8034 needs porting to v6
- BREAKING(Object Stacking): 🔙 refactor logic to support Group 🔝 #8461
-
fix(ActiveSelection): 🔃preserveObjectStacking
📌 #7878 -
fix(ActiveSelection): 🚀 multiple nested selection 🗂️ #7882 - fix(): selection logic to support nested multiselection #8665
- fix(V6): nested selection 🔧 fix canvas exporting 🧩 #7893 needs porting to v6
- feat(Object):
fill-parent
layout #7901 needs porting to v6 - chore(): cleanup type assertions, expose
Object#parent
=> rmisActiveSelection
#8951
Experimental
Triggering Layout
#9148 extracts layout management to a standalone class
triggerLayout
forces a group to recalculate its bounding box and reposition its objects.
You can define a layout strategy and assign it to the layout manager.
Read the code, it has comments explaining stuff and types that make it clear what you need to return from the method.
Look at the modified trigger, it is possible adding more triggers.
However I will promote an overall solution.
#7882 is a POC, follow the progress trigger
BREAKING
- all awkward methods such as
addWithUpdate
are removed includingtoGroup
/toActiveSelection
- renamed object stacking methods on canvas (e.g.
moveTo
->moveObjectTo
) - strict object tree - EXTREMELY BREAKING because it steals under the radar
- an object can have only one parent
- no need to call
remove
before adding to another group, fabric handles it internally - no need (and discouraged) to use awkward active selection code for removing an object
- canvas methods still need to enforce a strict check
- if you hacked group prior to the rewrite you will probably need to rewrite your logic
Pitfalls
All object origin methods (e.g. translateToOriginPoint
) are relative methods.
You should use them ONLY in the correct plane and with points that belong to the relative plane.
IMO it makes them worthless.
#8767 changes that.
BUGS
If you encounter bugs related to group or if you have a feature request please submit a relevant ticket.
Notice that bug reports of versions below v6 will be completely disregarded and closed. This was hard work, put effort into your repro so it is in v6.
Working Examples
Using v6!
stale branch
- CodeSandbox or JSFiddle
- Layer or in JSFiddle
To Do
- refactor selection logic
- use
dblClick
to select nested objects? create mechanism for dev to customize selection? for now overridesearchPossibleTargets
- refactor to enable n levels of nesting (logic is adequate for 2)
Line 422 in 109efe5
- look into active selection - creating from nested objects (deprecate/refactor
_chooseObjectsToRender
) - z-index of relatives when deselecting an object and selecting another - https://codesandbox.io/s/yiliv
- alt-selection for selecting objects under top object with another click - POC
- use
- @asturur rethink
preserveObjectStacking
in favor of a drag image/ghost - can wait/stale due to fix(ActiveSelection): 🔃preserveObjectStacking
📌 #7878 - text selection in scaled and rotated group is wrong (
getLocalPointer
8bf7f92) - bounding box and controls of object under transformed group (fix(v6!): nested controls #7758 )
-
phase out coords (can be delayed, now that bbox and controls are fixed)Redo coords #8767 - update tests
- refactor object caching - Group/Canvas Caching #7874
- object caching in some cases leaves traces (probably caused by wrong size when clearing cache)
- caching edge case - nested absolute clip path (see fiddle, try moving group, image should be clipped). Possible fix is to handle a registry of children with abs clip paths OR modify the
shouldCache
method - fix group's caching behavior + shadow logic - Group With ClipPath and Text with Shadow Renders Incorrectly #7454
- rethink
_renderObjects
- nested active object will fail withperPixelTargetFind
because it will not get rendered by group (add logic tocanvas.isTargetTransparent
) feat(Group): render selected objects #7863 - rethink
ActiveSelection
caching - why not?
- support layers under groups feat(Layer): 3rd Patch of Group Rewrite ♦️ #7860
- ActiveSelection.toGroup use
removeAll
instead -
getObjectsBoundingBox
- needs work to exactly fit when group is rotated - initial layout inconsistent with old group
- initial layout - supporting
originX/Y
407023c andangle
fix(Group): 6th Patch of New Group 🛠️ layout, angle and origin ⚡ #7867 - initial layout ( compare against the working examples of v6!) (Layer/Group)
- Layer - respect originX/originY?
- Group
centerObject
methods:object.setRelativeCenterPoint(new Point())
object.setRelativeCenterPoint(new Point(object.getRelativeCenterPoint().x, 0))
- should
clipPath
become evented/interactive? feat(V6): interactive clip path #7879 -
groupSVGElements
-
support fill, strokewill not be supported by fabric, see feat(Group): 2nd Patch of New Group! 🎉 #7859 (comment)backgroundColor
- might be replaced withfill-parent
layout for object - remove object selection monitors in favor of a simple check
canvas.getActiveObjects().includes(obj)
- canvas/group
removed
event dereferencing inconsistency feat(Group): 2nd Patch of New Group! 🎉 #7859 (comment)_ - fixed by fix(Group): patch #7916 #8000 -
Redo coords #8767flipX/Y
on group and/or nested objects is a complete mess
Look
Video is running in original speed
Cutting Edge
The blue circles are rendered by a textbox and because of the rewrite with a few lines of code I got this working
Pay no attention to caching of course
This is EXTREMELY exciting because it means that anyone could create custom objects subclassing whatever object they need and have nested selection work out of the box!