fabric 4.5.1-browser → 5.0.0-browser
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/CONTRIBUTING.md +14 -0
- package/HEADER.js +1 -1
- package/README.md +3 -6
- package/SECURITY.md +5 -0
- package/build.js +1 -0
- package/dist/fabric.js +1160 -668
- package/dist/fabric.min.js +1 -1
- package/lib/event.js +7 -3
- package/package.json +9 -3
- package/publish-next.js +15 -0
- package/publish.js +3 -0
- package/src/brushes/base_brush.class.js +3 -5
- package/src/brushes/pattern_brush.class.js +7 -5
- package/src/brushes/pencil_brush.class.js +49 -37
- package/src/canvas.class.js +27 -57
- package/src/filters/saturate_filter.class.js +9 -1
- package/src/filters/vibrance_filter.class.js +122 -0
- package/src/mixins/animation.mixin.js +20 -25
- package/src/mixins/canvas_events.mixin.js +30 -59
- package/src/mixins/canvas_grouping.mixin.js +4 -4
- package/src/mixins/collection.mixin.js +11 -2
- package/src/mixins/eraser_brush.mixin.js +495 -452
- package/src/mixins/itext_behavior.mixin.js +7 -1
- package/src/mixins/itext_key_behavior.mixin.js +7 -1
- package/src/mixins/object_geometry.mixin.js +5 -35
- package/src/mixins/object_interactivity.mixin.js +18 -7
- package/src/mixins/object_straightening.mixin.js +4 -9
- package/src/mixins/observable.mixin.js +22 -0
- package/src/parser.js +13 -9
- package/src/shapes/circle.class.js +22 -19
- package/src/shapes/ellipse.class.js +2 -2
- package/src/shapes/group.class.js +24 -32
- package/src/shapes/image.class.js +3 -25
- package/src/shapes/itext.class.js +10 -0
- package/src/shapes/line.class.js +5 -21
- package/src/shapes/object.class.js +67 -32
- package/src/shapes/path.class.js +17 -18
- package/src/shapes/polygon.class.js +11 -10
- package/src/shapes/polyline.class.js +33 -24
- package/src/shapes/rect.class.js +0 -18
- package/src/shapes/text.class.js +120 -58
- package/src/shapes/triangle.class.js +0 -15
- package/src/static_canvas.class.js +43 -20
- package/src/util/animate.js +149 -16
- package/src/util/animate_color.js +2 -1
- package/src/util/lang_object.js +5 -1
- package/src/util/misc.js +193 -42
- package/src/util/path.js +89 -52
|
@@ -13,8 +13,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
13
13
|
* @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
|
|
14
14
|
* @param {Function} [callbacks.onComplete] Invoked on completion
|
|
15
15
|
* @param {Function} [callbacks.onChange] Invoked on every step of animation
|
|
16
|
-
* @return {fabric.
|
|
17
|
-
* @chainable
|
|
16
|
+
* @return {fabric.AnimationContext} context
|
|
18
17
|
*/
|
|
19
18
|
fxCenterObjectH: function (object, callbacks) {
|
|
20
19
|
callbacks = callbacks || { };
|
|
@@ -24,7 +23,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
24
23
|
onChange = callbacks.onChange || empty,
|
|
25
24
|
_this = this;
|
|
26
25
|
|
|
27
|
-
fabric.util.animate({
|
|
26
|
+
return fabric.util.animate({
|
|
27
|
+
target: this,
|
|
28
28
|
startValue: object.left,
|
|
29
29
|
endValue: this.getCenter().left,
|
|
30
30
|
duration: this.FX_DURATION,
|
|
@@ -38,8 +38,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
38
38
|
onComplete();
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
|
-
|
|
42
|
-
return this;
|
|
43
41
|
},
|
|
44
42
|
|
|
45
43
|
/**
|
|
@@ -48,8 +46,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
48
46
|
* @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
|
|
49
47
|
* @param {Function} [callbacks.onComplete] Invoked on completion
|
|
50
48
|
* @param {Function} [callbacks.onChange] Invoked on every step of animation
|
|
51
|
-
* @return {fabric.
|
|
52
|
-
* @chainable
|
|
49
|
+
* @return {fabric.AnimationContext} context
|
|
53
50
|
*/
|
|
54
51
|
fxCenterObjectV: function (object, callbacks) {
|
|
55
52
|
callbacks = callbacks || { };
|
|
@@ -59,7 +56,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
59
56
|
onChange = callbacks.onChange || empty,
|
|
60
57
|
_this = this;
|
|
61
58
|
|
|
62
|
-
fabric.util.animate({
|
|
59
|
+
return fabric.util.animate({
|
|
60
|
+
target: this,
|
|
63
61
|
startValue: object.top,
|
|
64
62
|
endValue: this.getCenter().top,
|
|
65
63
|
duration: this.FX_DURATION,
|
|
@@ -73,8 +71,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
73
71
|
onComplete();
|
|
74
72
|
}
|
|
75
73
|
});
|
|
76
|
-
|
|
77
|
-
return this;
|
|
78
74
|
},
|
|
79
75
|
|
|
80
76
|
/**
|
|
@@ -83,8 +79,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
83
79
|
* @param {Object} [callbacks] Callbacks object with optional "onComplete" and/or "onChange" properties
|
|
84
80
|
* @param {Function} [callbacks.onComplete] Invoked on completion
|
|
85
81
|
* @param {Function} [callbacks.onChange] Invoked on every step of animation
|
|
86
|
-
* @return {fabric.
|
|
87
|
-
* @chainable
|
|
82
|
+
* @return {fabric.AnimationContext} context
|
|
88
83
|
*/
|
|
89
84
|
fxRemove: function (object, callbacks) {
|
|
90
85
|
callbacks = callbacks || { };
|
|
@@ -94,7 +89,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
94
89
|
onChange = callbacks.onChange || empty,
|
|
95
90
|
_this = this;
|
|
96
91
|
|
|
97
|
-
fabric.util.animate({
|
|
92
|
+
return fabric.util.animate({
|
|
93
|
+
target: this,
|
|
98
94
|
startValue: object.opacity,
|
|
99
95
|
endValue: 0,
|
|
100
96
|
duration: this.FX_DURATION,
|
|
@@ -108,8 +104,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
108
104
|
onComplete();
|
|
109
105
|
}
|
|
110
106
|
});
|
|
111
|
-
|
|
112
|
-
return this;
|
|
113
107
|
}
|
|
114
108
|
});
|
|
115
109
|
|
|
@@ -120,7 +114,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
120
114
|
* @param {Number|Object} value Value to animate property to (if string was given first) or options object
|
|
121
115
|
* @return {fabric.Object} thisArg
|
|
122
116
|
* @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}
|
|
123
|
-
* @
|
|
117
|
+
* @return {fabric.AnimationContext | fabric.AnimationContext[]} animation context (or an array if passed multiple properties)
|
|
124
118
|
*
|
|
125
119
|
* As object — multiple properties
|
|
126
120
|
*
|
|
@@ -133,22 +127,22 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
133
127
|
* object.animate('left', { duration: ... });
|
|
134
128
|
*
|
|
135
129
|
*/
|
|
136
|
-
animate: function() {
|
|
130
|
+
animate: function () {
|
|
137
131
|
if (arguments[0] && typeof arguments[0] === 'object') {
|
|
138
|
-
var propsToAnimate = [], prop, skipCallbacks;
|
|
132
|
+
var propsToAnimate = [], prop, skipCallbacks, out = [];
|
|
139
133
|
for (prop in arguments[0]) {
|
|
140
134
|
propsToAnimate.push(prop);
|
|
141
135
|
}
|
|
142
136
|
for (var i = 0, len = propsToAnimate.length; i < len; i++) {
|
|
143
137
|
prop = propsToAnimate[i];
|
|
144
138
|
skipCallbacks = i !== len - 1;
|
|
145
|
-
this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks);
|
|
139
|
+
out.push(this._animate(prop, arguments[0][prop], arguments[1], skipCallbacks));
|
|
146
140
|
}
|
|
141
|
+
return out;
|
|
147
142
|
}
|
|
148
143
|
else {
|
|
149
|
-
this._animate.apply(this, arguments);
|
|
144
|
+
return this._animate.apply(this, arguments);
|
|
150
145
|
}
|
|
151
|
-
return this;
|
|
152
146
|
},
|
|
153
147
|
|
|
154
148
|
/**
|
|
@@ -196,13 +190,14 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
196
190
|
}
|
|
197
191
|
|
|
198
192
|
var _options = {
|
|
193
|
+
target: this,
|
|
199
194
|
startValue: options.from,
|
|
200
195
|
endValue: to,
|
|
201
196
|
byValue: options.by,
|
|
202
197
|
easing: options.easing,
|
|
203
198
|
duration: options.duration,
|
|
204
|
-
abort: options.abort && function
|
|
205
|
-
return options.abort.call(_this);
|
|
199
|
+
abort: options.abort && function(value, valueProgress, timeProgress) {
|
|
200
|
+
return options.abort.call(_this, value, valueProgress, timeProgress);
|
|
206
201
|
},
|
|
207
202
|
onChange: function (value, valueProgress, timeProgress) {
|
|
208
203
|
if (propPair) {
|
|
@@ -227,10 +222,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
227
222
|
};
|
|
228
223
|
|
|
229
224
|
if (propIsColor) {
|
|
230
|
-
fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);
|
|
225
|
+
return fabric.util.animateColor(_options.startValue, _options.endValue, _options.duration, _options);
|
|
231
226
|
}
|
|
232
227
|
else {
|
|
233
|
-
fabric.util.animate(_options);
|
|
228
|
+
return fabric.util.animate(_options);
|
|
234
229
|
}
|
|
235
230
|
}
|
|
236
231
|
});
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
this._onDragOver = this._onDragOver.bind(this);
|
|
107
107
|
this._onDragEnter = this._simpleEventHandler.bind(this, 'dragenter');
|
|
108
108
|
this._onDragLeave = this._simpleEventHandler.bind(this, 'dragleave');
|
|
109
|
-
this._onDrop = this.
|
|
109
|
+
this._onDrop = this._onDrop.bind(this);
|
|
110
110
|
this.eventsBound = true;
|
|
111
111
|
},
|
|
112
112
|
|
|
@@ -218,6 +218,18 @@
|
|
|
218
218
|
this._fireEnterLeaveEvents(target, e);
|
|
219
219
|
},
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* `drop:before` is a an event that allow you to schedule logic
|
|
223
|
+
* before the `drop` event. Prefer `drop` event always, but if you need
|
|
224
|
+
* to run some drop-disabling logic on an event, since there is no way
|
|
225
|
+
* to handle event handlers ordering, use `drop:before`
|
|
226
|
+
* @param {Event} e
|
|
227
|
+
*/
|
|
228
|
+
_onDrop: function (e) {
|
|
229
|
+
this._simpleEventHandler('drop:before', e);
|
|
230
|
+
return this._simpleEventHandler('drop', e);
|
|
231
|
+
},
|
|
232
|
+
|
|
221
233
|
/**
|
|
222
234
|
* @private
|
|
223
235
|
* @param {Event} e Event object fired on mousedown
|
|
@@ -450,25 +462,34 @@
|
|
|
450
462
|
);
|
|
451
463
|
}
|
|
452
464
|
}
|
|
465
|
+
var corner, pointer;
|
|
453
466
|
if (target) {
|
|
467
|
+
corner = target._findTargetCorner(
|
|
468
|
+
this.getPointer(e, true),
|
|
469
|
+
fabric.util.isTouchEvent(e)
|
|
470
|
+
);
|
|
454
471
|
if (target.selectable && target !== this._activeObject && target.activeOn === 'up') {
|
|
455
472
|
this.setActiveObject(target, e);
|
|
456
473
|
shouldRender = true;
|
|
457
474
|
}
|
|
458
475
|
else {
|
|
459
|
-
var corner = target._findTargetCorner(
|
|
460
|
-
this.getPointer(e, true),
|
|
461
|
-
fabric.util.isTouchEvent(e)
|
|
462
|
-
);
|
|
463
476
|
var control = target.controls[corner],
|
|
464
477
|
mouseUpHandler = control && control.getMouseUpHandler(e, target, control);
|
|
465
478
|
if (mouseUpHandler) {
|
|
466
|
-
|
|
479
|
+
pointer = this.getPointer(e);
|
|
467
480
|
mouseUpHandler(e, transform, pointer.x, pointer.y);
|
|
468
481
|
}
|
|
469
482
|
}
|
|
470
483
|
target.isMoving = false;
|
|
471
484
|
}
|
|
485
|
+
// if we are ending up a transform on a different control or a new object
|
|
486
|
+
// fire the original mouse up from the corner that started the transform
|
|
487
|
+
if (transform && (transform.target !== target || transform.corner !== corner)) {
|
|
488
|
+
var originalControl = transform.target && transform.target.controls[transform.corner],
|
|
489
|
+
originalMouseUpHandler = originalControl && originalControl.getMouseUpHandler(e, target, control);
|
|
490
|
+
pointer = pointer || this.getPointer(e);
|
|
491
|
+
originalMouseUpHandler && originalMouseUpHandler(e, transform, pointer.x, pointer.y);
|
|
492
|
+
}
|
|
472
493
|
this._setCursorFromEvent(e, target);
|
|
473
494
|
this._handleEvent(e, 'up', LEFT_CLICK, isClick);
|
|
474
495
|
this._groupSelector = null;
|
|
@@ -550,7 +571,6 @@
|
|
|
550
571
|
|
|
551
572
|
var transform = this._currentTransform,
|
|
552
573
|
target = transform.target,
|
|
553
|
-
eventName,
|
|
554
574
|
options = {
|
|
555
575
|
e: e,
|
|
556
576
|
target: target,
|
|
@@ -565,59 +585,10 @@
|
|
|
565
585
|
target.setCoords();
|
|
566
586
|
|
|
567
587
|
if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {
|
|
568
|
-
if (transform.actionPerformed) {
|
|
569
|
-
// this is not friendly to the new control api.
|
|
570
|
-
// is deprecated.
|
|
571
|
-
eventName = this._addEventOptions(options, transform);
|
|
572
|
-
this._fire(eventName, options);
|
|
573
|
-
}
|
|
574
588
|
this._fire('modified', options);
|
|
575
589
|
}
|
|
576
590
|
},
|
|
577
591
|
|
|
578
|
-
/**
|
|
579
|
-
* Mutate option object in order to add by property and give back the event name.
|
|
580
|
-
* @private
|
|
581
|
-
* @deprecated since 4.2.0
|
|
582
|
-
* @param {Object} options to mutate
|
|
583
|
-
* @param {Object} transform to inspect action from
|
|
584
|
-
*/
|
|
585
|
-
_addEventOptions: function(options, transform) {
|
|
586
|
-
// we can probably add more details at low cost
|
|
587
|
-
// scale change, rotation changes, translation changes
|
|
588
|
-
var eventName, by;
|
|
589
|
-
switch (transform.action) {
|
|
590
|
-
case 'scaleX':
|
|
591
|
-
eventName = 'scaled';
|
|
592
|
-
by = 'x';
|
|
593
|
-
break;
|
|
594
|
-
case 'scaleY':
|
|
595
|
-
eventName = 'scaled';
|
|
596
|
-
by = 'y';
|
|
597
|
-
break;
|
|
598
|
-
case 'skewX':
|
|
599
|
-
eventName = 'skewed';
|
|
600
|
-
by = 'x';
|
|
601
|
-
break;
|
|
602
|
-
case 'skewY':
|
|
603
|
-
eventName = 'skewed';
|
|
604
|
-
by = 'y';
|
|
605
|
-
break;
|
|
606
|
-
case 'scale':
|
|
607
|
-
eventName = 'scaled';
|
|
608
|
-
by = 'equally';
|
|
609
|
-
break;
|
|
610
|
-
case 'rotate':
|
|
611
|
-
eventName = 'rotated';
|
|
612
|
-
break;
|
|
613
|
-
case 'drag':
|
|
614
|
-
eventName = 'moved';
|
|
615
|
-
break;
|
|
616
|
-
}
|
|
617
|
-
options.by = by;
|
|
618
|
-
return eventName;
|
|
619
|
-
},
|
|
620
|
-
|
|
621
592
|
/**
|
|
622
593
|
* @private
|
|
623
594
|
* @param {Event} e Event object fired on mousedown
|
|
@@ -712,8 +683,8 @@
|
|
|
712
683
|
if (this.selection && (!target ||
|
|
713
684
|
(!target.selectable && !target.isEditing && target !== this._activeObject))) {
|
|
714
685
|
this._groupSelector = {
|
|
715
|
-
ex:
|
|
716
|
-
ey:
|
|
686
|
+
ex: this._absolutePointer.x,
|
|
687
|
+
ey: this._absolutePointer.y,
|
|
717
688
|
top: 0,
|
|
718
689
|
left: 0
|
|
719
690
|
};
|
|
@@ -806,7 +777,7 @@
|
|
|
806
777
|
|
|
807
778
|
// We initially clicked in an empty area, so we draw a box for multiple selection
|
|
808
779
|
if (groupSelector) {
|
|
809
|
-
pointer = this.
|
|
780
|
+
pointer = this._absolutePointer;
|
|
810
781
|
|
|
811
782
|
groupSelector.left = pointer.x - groupSelector.ex;
|
|
812
783
|
groupSelector.top = pointer.y - groupSelector.ey;
|
|
@@ -139,10 +139,10 @@
|
|
|
139
139
|
continue;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||
|
|
143
|
-
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||
|
|
144
|
-
(allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||
|
|
145
|
-
(allowIntersect && currentObject.containsPoint(selectionX2Y2))
|
|
142
|
+
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2, true)) ||
|
|
143
|
+
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2, true) ||
|
|
144
|
+
(allowIntersect && currentObject.containsPoint(selectionX1Y1, null, true)) ||
|
|
145
|
+
(allowIntersect && currentObject.containsPoint(selectionX2Y2, null, true))
|
|
146
146
|
) {
|
|
147
147
|
group.push(currentObject);
|
|
148
148
|
// only add one object if it's a click
|
|
@@ -142,10 +142,19 @@ fabric.Collection = {
|
|
|
142
142
|
/**
|
|
143
143
|
* Returns true if collection contains an object
|
|
144
144
|
* @param {Object} object Object to check against
|
|
145
|
+
* @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`
|
|
145
146
|
* @return {Boolean} `true` if collection contains an object
|
|
146
147
|
*/
|
|
147
|
-
contains: function(object) {
|
|
148
|
-
|
|
148
|
+
contains: function (object, deep) {
|
|
149
|
+
if (this._objects.indexOf(object) > -1) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
else if (deep) {
|
|
153
|
+
return this._objects.some(function (obj) {
|
|
154
|
+
return typeof obj.contains === 'function' && obj.contains(object, true);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
149
158
|
},
|
|
150
159
|
|
|
151
160
|
/**
|