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

feat(V6): Group Rewrite + Nested Selection #7669

Closed
wants to merge 173 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
6d04a73
fix(): group selection
ShaMan123 Feb 10, 2022
c197e9d
Update itext_click_behavior.mixin.js
ShaMan123 Feb 10, 2022
77caa46
ci: build
ShaMan123 Feb 10, 2022
1259773
fix(tests): `toLocalPoint`, `group.subTargetCheck`
ShaMan123 Feb 11, 2022
8bf7f92
fix(): `getLocalPointer`
ShaMan123 Feb 11, 2022
db8ba4d
Update object_origin.mixin.js
ShaMan123 Feb 11, 2022
b247039
Revert "ci: build"
ShaMan123 Feb 11, 2022
502226e
ci: build
ShaMan123 Feb 11, 2022
1c03905
fix(): select nested object
ShaMan123 Feb 11, 2022
15c0074
fix(): select nested object - even better
ShaMan123 Feb 11, 2022
8166f30
fix(): select nested object - much better
ShaMan123 Feb 11, 2022
fb4d1f0
create `object_ancestry`
ShaMan123 Feb 11, 2022
8afba50
feat(object_stacking): `isInFrontOf`
ShaMan123 Feb 11, 2022
f0dce78
test(): ancestry + `isInFrontOf`
ShaMan123 Feb 11, 2022
bb34ecf
Update object_ancestry.mixin.js
ShaMan123 Feb 11, 2022
8d89a56
Update object_ancestry.mixin.js
ShaMan123 Feb 11, 2022
138b592
try fixing selection logic
ShaMan123 Feb 11, 2022
69c4fcf
Update object_geometry.mixin.js
ShaMan123 Feb 12, 2022
b1e4c76
fix 138b5924
ShaMan123 Feb 12, 2022
e8049b7
ci(): 🤢 lint
ShaMan123 Feb 12, 2022
ce7447d
Update canvas_grouping.mixin.js
ShaMan123 Feb 12, 2022
d82e303
Update canvas_grouping.mixin.js
ShaMan123 Feb 12, 2022
250507d
Update canvas_grouping.mixin.js
ShaMan123 Feb 12, 2022
23707cf
Revert "ci: build"
ShaMan123 Feb 12, 2022
4346e24
ci: build
ShaMan123 Feb 12, 2022
c20b7ce
fix: _createGroup wrong order
ShaMan123 Feb 12, 2022
9286cee
Revert "ci: build"
ShaMan123 Feb 12, 2022
4432f45
ci: build
ShaMan123 Feb 12, 2022
6ce776c
rewrite group!
ShaMan123 Feb 12, 2022
c320247
lint
ShaMan123 Feb 12, 2022
6111270
cleanup
ShaMan123 Feb 12, 2022
7887a6d
Update group.class.js
ShaMan123 Feb 12, 2022
a16745a
Update active_selection.class.js
ShaMan123 Feb 12, 2022
b421cec
svg
ShaMan123 Feb 12, 2022
b0b8f6b
typo
ShaMan123 Feb 12, 2022
f7615a4
Update group.class.js
ShaMan123 Feb 12, 2022
cb21cb3
fix(): clip path positioning
ShaMan123 Feb 12, 2022
77ea1bf
better cb21cb30
ShaMan123 Feb 12, 2022
bc9c2ee
feat(layout): support `clip-path` layout directive
ShaMan123 Feb 12, 2022
c8550ab
JSDOC
ShaMan123 Feb 12, 2022
f884c54
fix: fromObject
ShaMan123 Feb 12, 2022
4864a6b
cleanup
ShaMan123 Feb 12, 2022
bb05a71
Update group.class.js
ShaMan123 Feb 12, 2022
b67843a
Revert "ci: build"
ShaMan123 Feb 12, 2022
2948e21
ci: build
ShaMan123 Feb 12, 2022
e3d9476
fix(): call setCoords from constructor
ShaMan123 Feb 12, 2022
eca7546
Update group.class.js
ShaMan123 Feb 12, 2022
69178c4
Revert "ci: build"
ShaMan123 Feb 12, 2022
ec82ad1
feat(Layer): 🤪
ShaMan123 Feb 12, 2022
4119a28
Update layer.class.js
ShaMan123 Feb 12, 2022
7d85831
imperative layout
ShaMan123 Feb 12, 2022
c8cf5d8
Update layer.class.js
ShaMan123 Feb 12, 2022
ecfb024
layout event
ShaMan123 Feb 13, 2022
c316eac
Update group.class.js
ShaMan123 Feb 13, 2022
ef22993
Update group.class.js
ShaMan123 Feb 13, 2022
e78ddcf
Update group.class.js
ShaMan123 Feb 13, 2022
841917e
Update spray_brush.class.js
ShaMan123 Feb 13, 2022
31d3a63
Update collection.mixin.js
ShaMan123 Feb 13, 2022
fc603e6
collection methods
ShaMan123 Feb 13, 2022
7782c3d
safeguard
ShaMan123 Feb 13, 2022
23f4582
dump `isCacheDirty`
ShaMan123 Feb 13, 2022
4d510be
Update group.class.js
ShaMan123 Feb 13, 2022
43fc3f7
perf(): reduce iterations
ShaMan123 Feb 13, 2022
5b2cdd3
ci(): lint
ShaMan123 Feb 13, 2022
53ade6b
feat(getAncestors): strict opt
ShaMan123 Feb 13, 2022
ccebec3
fix(Canvas._chooseObjectsToRender): render selected nested object's t…
ShaMan123 Feb 13, 2022
0a855e5
Update canvas.class.js
ShaMan123 Feb 13, 2022
921873b
Update group.class.js
ShaMan123 Feb 13, 2022
aad22d5
Revert "feat(getAncestors): strict opt"
ShaMan123 Feb 13, 2022
57a4e83
feat(getAncestors): strict opt
ShaMan123 Feb 13, 2022
874e9e5
remove `setOnGroup`
ShaMan123 Feb 13, 2022
50c69b8
Update group.js
ShaMan123 Feb 14, 2022
23835e0
Update group.class.js
ShaMan123 Feb 14, 2022
6d969f8
fix 50c69b8d
ShaMan123 Feb 14, 2022
2bbd5f9
Update group.class.js
ShaMan123 Feb 14, 2022
537f40b
tests
ShaMan123 Feb 14, 2022
4641ca8
Update object.class.js
ShaMan123 Feb 14, 2022
5803598
fix: insertAt
ShaMan123 Feb 14, 2022
5b80ec5
Update group.js
ShaMan123 Feb 14, 2022
f4ea61e
fix(Collection): `insertAt`
ShaMan123 Feb 14, 2022
d6cafc2
tests(): level
ShaMan123 Feb 14, 2022
4d1d9a0
fix(): insertAt, duplicate objects
ShaMan123 Feb 14, 2022
18e6576
Update package.json
ShaMan123 Feb 14, 2022
0cd421c
fix(): dumping objects to console
ShaMan123 Feb 14, 2022
2452448
Update package-lock.json
ShaMan123 Feb 14, 2022
2b49ae2
tests(): remove `_shouldGroup`
ShaMan123 Feb 14, 2022
5c53087
fix(): exitGroup
ShaMan123 Feb 14, 2022
b875ad6
Update object.js
ShaMan123 Feb 14, 2022
b3a1709
remove `toGroup`
ShaMan123 Feb 14, 2022
675cb1b
Update fabric.js
ShaMan123 Feb 14, 2022
2a535cb
Update object_clipPath.js
ShaMan123 Feb 14, 2022
e9549f5
perf(Canvas): `_chooseObjectsToRender`
ShaMan123 Feb 14, 2022
817b185
**MAJOR** fix(Canvas): **MEMORY LEAK** remove canvas ref for nested o…
ShaMan123 Feb 14, 2022
ce4a603
fix: layout calc
ShaMan123 Feb 15, 2022
dca221d
ci: lint
ShaMan123 Feb 15, 2022
2aea478
Revert "Update fabric.js"
ShaMan123 Feb 15, 2022
7a968a3
move to new group
ShaMan123 Feb 15, 2022
654b6ef
Merge remote-tracking branch 'upstream/master' into v6!
ShaMan123 Feb 16, 2022
dd2ed30
Layer.fromObject promise
ShaMan123 Feb 16, 2022
6b53d3c
revert test suite
ShaMan123 Feb 16, 2022
81e4027
revert
ShaMan123 Feb 16, 2022
08cfff7
Update misc.js
ShaMan123 Feb 20, 2022
a6ec1c6
backward compatible
ShaMan123 Feb 20, 2022
a674309
Merge branch 'master' into v6!
ShaMan123 Feb 20, 2022
73e5c77
Update group.class.js
ShaMan123 Feb 20, 2022
27a1506
Merge branch 'master' into v6!
ShaMan123 Feb 21, 2022
7643132
fix(Object): getCenterPoint relative to parent/canvas
ShaMan123 Feb 21, 2022
eb817e6
c
ShaMan123 Feb 21, 2022
5b7cd86
fix(Collection): callback
ShaMan123 Feb 21, 2022
3c23301
layout progress
ShaMan123 Feb 21, 2022
4ae4796
Update group.class.js
ShaMan123 Feb 21, 2022
71ed13f
Update group.class.js
ShaMan123 Feb 21, 2022
9579f35
Update group.class.js
ShaMan123 Feb 21, 2022
4820cb0
fix clip path layout
ShaMan123 Feb 21, 2022
ba319de
Merge branch 'master' into v6!
ShaMan123 Feb 21, 2022
d9062cc
Merge branch 'master' into v6!
asturur Feb 21, 2022
9ffb232
cleanup
ShaMan123 Feb 21, 2022
ac86103
perf(): getTotalAngle
ShaMan123 Feb 21, 2022
10abf42
collection removed
ShaMan123 Feb 21, 2022
35e0ade
finalize collection
ShaMan123 Feb 21, 2022
22b6855
Update group.class.js
ShaMan123 Feb 21, 2022
c787aa6
tests
ShaMan123 Feb 21, 2022
0cb706d
svg fill/stroke
ShaMan123 Feb 22, 2022
8fd8866
layout + origin
ShaMan123 Feb 22, 2022
1d82162
Update group.class.js
ShaMan123 Feb 22, 2022
5b85d8b
svg tests
ShaMan123 Feb 22, 2022
f24a75d
Merge branch 'master' into v6!
ShaMan123 Feb 23, 2022
0754aaf
resolveOrigin
ShaMan123 Feb 23, 2022
b55beed
Update object_origin.mixin.js
ShaMan123 Feb 23, 2022
e4a8c03
Merge branch 'object-origin-patch' into v6!
ShaMan123 Feb 23, 2022
602633a
fix(): animation is relative to canvas
ShaMan123 Feb 23, 2022
2464adf
lint
ShaMan123 Feb 23, 2022
cc1f4da
Update group.class.js
ShaMan123 Feb 23, 2022
fd3c399
Update group.class.js
ShaMan123 Feb 23, 2022
28f2d2c
fix(layout): account for object transform
ShaMan123 Feb 23, 2022
15ae594
safety
ShaMan123 Feb 23, 2022
dcaae09
fix(): active selection creation origin
ShaMan123 Feb 24, 2022
1d9fb0b
fix(): first layout + origin
ShaMan123 Feb 24, 2022
06d4d78
Update group.js
ShaMan123 Feb 24, 2022
d690f06
Merge branch 'master' into v6!
ShaMan123 Feb 24, 2022
9387fe6
JSDOC
ShaMan123 Feb 24, 2022
147903c
Update canvas.js
ShaMan123 Feb 24, 2022
11ce7f1
Update canvas.js
ShaMan123 Feb 24, 2022
4763be4
lint
ShaMan123 Feb 24, 2022
273e0c7
lint whitespace
ShaMan123 Feb 24, 2022
4ddbf30
fix(): objects bbox + rotation
ShaMan123 Feb 26, 2022
b4c9729
Revert "fix(): objects bbox + rotation"
ShaMan123 Feb 26, 2022
407023c
fix most of initial layout cases
ShaMan123 Feb 27, 2022
5bd111f
lint
ShaMan123 Feb 27, 2022
4335d4f
fix(): clip path layout
ShaMan123 Feb 27, 2022
2b9eb2a
fix(): clip path layout size/transform
ShaMan123 Feb 27, 2022
582e50b
Revert "fix(): active selection creation origin"
ShaMan123 Feb 27, 2022
c0794eb
chore(): revert `searchPossibleTargets`
ShaMan123 Feb 27, 2022
cf87dbe
lint
ShaMan123 Feb 27, 2022
b6a52a2
Update controls12.png
ShaMan123 Feb 27, 2022
060cdd2
Update misc.js
ShaMan123 Feb 27, 2022
4d1bfdd
Update group.class.js
ShaMan123 Feb 27, 2022
23fb6cd
Update group.class.js
ShaMan123 Feb 27, 2022
7eacaca
fix(test): remove default fill for group
ShaMan123 Feb 27, 2022
ae80ebe
Update object.class.js
ShaMan123 Feb 27, 2022
e7f0816
fill + clipping
ShaMan123 Feb 27, 2022
a5791df
Revert "Update object.class.js"
ShaMan123 Feb 27, 2022
7c23299
svg layout
ShaMan123 Feb 27, 2022
f70019b
safety
ShaMan123 Feb 27, 2022
48b59b8
Merge branch 'master' into v6!
ShaMan123 Mar 9, 2022
f8587f6
fix(): object center in initilization
ShaMan123 Mar 27, 2022
45f93a8
Update canvas.class.js (#7811)
ShaMan123 Mar 29, 2022
b814f94
fix(v6!): force initial layout (#7761)
ShaMan123 Mar 29, 2022
98c6748
Merge branch 'master' into v6!
ShaMan123 Mar 30, 2022
92f9c02
Merge branch 'master' into v6!
ShaMan123 Apr 4, 2022
73aae99
deprecate dead methods
ShaMan123 Apr 4, 2022
d602f2e
lint
ShaMan123 Apr 4, 2022
bf603cb
fix(v6!): nested controls (#7758)
ShaMan123 Apr 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ var filesToInclude = [
'src/shapes/polygon.class.js',
'src/shapes/path.class.js',
'src/shapes/group.class.js',
'src/shapes/layer.class.js',
ifSpecifiedInclude('interaction', 'src/shapes/active_selection.class.js'),
'src/shapes/image.class.js',

Expand Down
2 changes: 1 addition & 1 deletion src/brushes/spray_brush.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric
rects = this._getOptimizedRects(rects);
}

var group = new fabric.Group(rects);
var group = new fabric.Group(rects, { objectCaching: true, layout: 'fixed', subTargetCheck: false });
this.shadow && group.set('shadow', new fabric.Shadow(this.shadow));
this.canvas.fire('before:path:created', { path: group });
this.canvas.add(group);
Expand Down
4 changes: 2 additions & 2 deletions src/canvas.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -873,7 +873,7 @@
this._normalizePointer(objToCheck.group, pointer) : pointer;
if (this._checkTarget(pointerToUse, objToCheck, pointer)) {
target = objects[i];
if (target.subTargetCheck && target instanceof fabric.Group) {
if (target.subTargetCheck && Array.isArray(target._objects)) {
subTarget = this._searchPossibleTargets(target._objects, pointer);
subTarget && this.targets.push(subTarget);
}
Expand All @@ -892,7 +892,7 @@
*/
searchPossibleTargets: function (objects, pointer) {
var target = this._searchPossibleTargets(objects, pointer);
return target;
return /*this.targets[0] ||*/ target;
},

/**
Expand Down
8 changes: 4 additions & 4 deletions src/mixins/animation.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati

return fabric.util.animate({
target: this,
startValue: object.left,
startValue: object.getX(),
endValue: this.getCenterPoint().x,
duration: this.FX_DURATION,
onChange: function(value) {
object.set('left', value);
object.setX(value);
_this.requestRenderAll();
onChange();
},
Expand Down Expand Up @@ -58,11 +58,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati

return fabric.util.animate({
target: this,
startValue: object.top,
startValue: object.getY(),
endValue: this.getCenterPoint().y,
duration: this.FX_DURATION,
onChange: function(value) {
object.set('top', value);
object.setY(value);
_this.requestRenderAll();
onChange();
},
Expand Down
23 changes: 15 additions & 8 deletions src/mixins/canvas_events.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,9 @@
/**
* @private
*/
_onResize: function () {
_onResize: function (e) {
this.calcOffset();
this.fire('resize', { e: e });
},

/**
Expand Down Expand Up @@ -673,13 +674,13 @@
// save pointer for check in __onMouseUp event
this._previousPointer = pointer;
var shouldRender = this._shouldRender(target),
shouldGroup = this._shouldGroup(e, target);
didGroup = false;
if (this._shouldClearSelection(e, target)) {
this.discardActiveObject(e);
}
else if (shouldGroup) {
this._handleGrouping(e, target);
else if (this._handleGrouping(e, target)) {
target = this._activeObject;
didGroup = true;
}

if (this.selection && (!target ||
Expand All @@ -702,7 +703,7 @@
fabric.util.isTouchEvent(e)
);
target.__corner = corner;
if (target === this._activeObject && (corner || !shouldGroup)) {
if (target === this._activeObject && (corner || !didGroup)) {
this._setupCurrentTransform(e, target, alreadySelected);
var control = target.controls[corner],
pointer = this.getPointer(e),
Expand All @@ -712,9 +713,10 @@
}
}
}
this._objectsToRender = this._chooseObjectsToRender();
this._handleEvent(e, 'down');
// we must renderAll so that we update the visuals
(shouldRender || shouldGroup) && this.requestRenderAll();
(shouldRender || didGroup) && this.requestRenderAll();
},

/**
Expand Down Expand Up @@ -900,8 +902,13 @@
*/
_transformObject: function(e) {
var pointer = this.getPointer(e),
transform = this._currentTransform;

transform = this._currentTransform,
target = transform.target;
if (target.group) {
// transform pointer to target's containing coordinate plane
// both agree on every point
pointer = fabric.util.transformPoint(pointer, fabric.util.invertTransform(target.group.calcTransformMatrix()));
}
transform.reset = false;
transform.shiftKey = e.shiftKey;
transform.altKey = e[this.centeredKey];
Expand Down
115 changes: 60 additions & 55 deletions src/mixins/canvas_grouping.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,114 +9,98 @@
* @private
* @param {Event} e Event object
* @param {fabric.Object} target
* @return {Boolean}
*/
_shouldGroup: function(e, target) {
var activeObject = this._activeObject;
return activeObject && this._isSelectionKeyPressed(e) && target && target.selectable && this.selection &&
(activeObject !== target || activeObject.type === 'activeSelection') && !target.onSelect({ e: e });
},

/**
* @private
* @param {Event} e Event object
* @param {fabric.Object} target
* @returns {boolean} true if grouping occured
*/
_handleGrouping: function (e, target) {
var activeObject = this._activeObject;
if (!(activeObject && this._isSelectionKeyPressed(e)
&& this.selection && target && target.selectable && !target.onSelect({ e: e }))) {
return false;
}
// avoid multi select when shift click on a corner
if (activeObject.__corner) {
return;
return false;
}
if (target === activeObject) {
// if it's a group, find target again, using activeGroup objects
target = this.findTarget(e, true);
// if even object is not found or we are on activeObjectCorner, bail out
target = this.targets.pop();
if (!target || !target.selectable) {
return;
return false;
}
}
if (activeObject && activeObject.type === 'activeSelection') {
this._updateActiveSelection(target, e);
}
else {
return activeObject && activeObject.type === 'activeSelection' ?
this._updateActiveSelection(target, e) :
this._createActiveSelection(target, e);
}
},

/**
* @private
* @returns {boolean} true if target was added to active selection
*/
_updateActiveSelection: function(target, e) {
var activeSelection = this._activeObject,
currentActiveObjects = activeSelection._objects.slice(0);
if (activeSelection.contains(target)) {
currentActiveObjects = activeSelection._objects.slice(0),
modified = false;
// target is about to be removed from active selection
// we make sure it is a direct child of active selection
if (target.group === activeSelection) {
activeSelection.removeWithUpdate(target);
modified = true;
this._hoveredTarget = target;
this._hoveredTargets = this.targets.concat();
if (activeSelection.size() === 1) {
// activate last remaining object
this._setActiveObject(activeSelection.item(0), e);
}
}
else {
// target is about to be added to active selection
// we make sure it is not already a descendant of active selection
else if (!target.isDescendantOf(activeSelection)) {
activeSelection.addWithUpdate(target);
modified = true;
this._hoveredTarget = activeSelection;
this._hoveredTargets = this.targets.concat();
}
this._fireSelectionEvents(currentActiveObjects, e);
modified && this._fireSelectionEvents(currentActiveObjects, e);
return modified;
},

/**
* @private
* @returns {boolean} true if active selection was created
*/
_createActiveSelection: function(target, e) {
_createActiveSelection: function (target, e) {
var activeObject = this._activeObject;
// target is about be added to a new active selection
// we make sure `activeObject` and `target` aren't ancestors of each other in order to avoid recursive selection
if (target === activeObject || target.isDescendantOf(activeObject) || activeObject.isDescendantOf(target)) {
return false;
}
var currentActives = this.getActiveObjects(), group = this._createGroup(target);
this._hoveredTarget = group;
// ISSUE 4115: should we consider subTargets here?
// this._hoveredTargets = [];
// this._hoveredTargets = this.targets.concat();
this._setActiveObject(group, e);
this._fireSelectionEvents(currentActives, e);
return true;
},

/**
* @private
* @param {Object} target
*/
_createGroup: function(target) {
var objects = this._objects,
isActiveLower = objects.indexOf(this._activeObject) < objects.indexOf(target),
groupObjects = isActiveLower
? [this._activeObject, target]
: [target, this._activeObject];
this._activeObject.isEditing && this._activeObject.exitEditing();
_createGroup: function (target) {
var activeObject = this._activeObject;
var groupObjects = target.isInFrontOf(activeObject) ?
[activeObject, target] :
[target, activeObject];
activeObject.isEditing && activeObject.exitEditing();
// handle case: target is nested
return new fabric.ActiveSelection(groupObjects, {
canvas: this
});
},

/**
* @private
* @param {Event} e mouse event
*/
_groupSelectedObjects: function (e) {

var group = this._collectObjects(e),
aGroup;

// do not create group for 1 element only
if (group.length === 1) {
this.setActiveObject(group[0], e);
}
else if (group.length > 1) {
aGroup = new fabric.ActiveSelection(group.reverse(), {
canvas: this
});
this.setActiveObject(aGroup, e);
}
},

/**
* @private
*/
Expand Down Expand Up @@ -161,6 +145,27 @@
return group;
},

/**
* @private
* @param {Event} e mouse event
*/
_groupSelectedObjects: function (e) {

var objects = this._collectObjects(e),
aGroup;

// do not create group for 1 element only
if (objects.length === 1) {
this.setActiveObject(objects[0], e);
}
else if (objects.length > 1) {
aGroup = new fabric.ActiveSelection(objects.reverse(), {
canvas: this
});
this.setActiveObject(aGroup, e);
}
},

/**
* @private
*/
Expand Down
Loading