fabric 4.6.0-browser → 5.1.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 +54 -0
- package/HEADER.js +1 -1
- package/README.md +1 -6
- package/SECURITY.md +5 -0
- package/dist/fabric.js +692 -400
- package/dist/fabric.min.js +1 -1
- package/lib/event.js +7 -3
- package/package.json +5 -3
- package/src/brushes/base_brush.class.js +2 -2
- package/src/brushes/pattern_brush.class.js +7 -5
- package/src/brushes/pencil_brush.class.js +33 -4
- package/src/canvas.class.js +9 -17
- package/src/filters/blendcolor_filter.class.js +6 -0
- package/src/filters/blendimage_filter.class.js +3 -2
- package/src/filters/blur_filter.class.js +2 -0
- package/src/filters/colormatrix_filter.class.js +3 -1
- package/src/mixins/animation.mixin.js +16 -21
- package/src/mixins/canvas_events.mixin.js +27 -56
- package/src/mixins/eraser_brush.mixin.js +354 -420
- package/src/mixins/itext_behavior.mixin.js +7 -1
- package/src/mixins/object_geometry.mixin.js +3 -34
- package/src/mixins/object_straightening.mixin.js +4 -9
- package/src/parser.js +13 -9
- package/src/shapes/circle.class.js +20 -17
- package/src/shapes/group.class.js +13 -25
- package/src/shapes/image.class.js +3 -3
- package/src/shapes/object.class.js +46 -19
- package/src/shapes/path.class.js +13 -9
- package/src/shapes/polygon.class.js +9 -1
- package/src/shapes/polyline.class.js +33 -9
- package/src/shapes/text.class.js +38 -21
- package/src/static_canvas.class.js +11 -7
- package/src/util/animate.js +175 -26
- package/src/util/misc.js +193 -45
- package/src/util/path.js +2 -56
package/src/util/misc.js
CHANGED
|
@@ -139,6 +139,135 @@
|
|
|
139
139
|
};
|
|
140
140
|
},
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Creates a vetor from points represented as a point
|
|
144
|
+
* @static
|
|
145
|
+
* @memberOf fabric.util
|
|
146
|
+
*
|
|
147
|
+
* @typedef {Object} Point
|
|
148
|
+
* @property {number} x
|
|
149
|
+
* @property {number} y
|
|
150
|
+
*
|
|
151
|
+
* @param {Point} from
|
|
152
|
+
* @param {Point} to
|
|
153
|
+
* @returns {Point} vector
|
|
154
|
+
*/
|
|
155
|
+
createVector: function (from, to) {
|
|
156
|
+
return new fabric.Point(to.x - from.x, to.y - from.y);
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Calculates angle between 2 vectors using dot product
|
|
161
|
+
* @static
|
|
162
|
+
* @memberOf fabric.util
|
|
163
|
+
* @param {Point} a
|
|
164
|
+
* @param {Point} b
|
|
165
|
+
* @returns the angle in radian between the vectors
|
|
166
|
+
*/
|
|
167
|
+
calcAngleBetweenVectors: function (a, b) {
|
|
168
|
+
return Math.acos((a.x * b.x + a.y * b.y) / (Math.hypot(a.x, a.y) * Math.hypot(b.x, b.y)));
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @static
|
|
173
|
+
* @memberOf fabric.util
|
|
174
|
+
* @param {Point} v
|
|
175
|
+
* @returns {Point} vector representing the unit vector of pointing to the direction of `v`
|
|
176
|
+
*/
|
|
177
|
+
getHatVector: function (v) {
|
|
178
|
+
return new fabric.Point(v.x, v.y).multiply(1 / Math.hypot(v.x, v.y));
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @static
|
|
183
|
+
* @memberOf fabric.util
|
|
184
|
+
* @param {Point} A
|
|
185
|
+
* @param {Point} B
|
|
186
|
+
* @param {Point} C
|
|
187
|
+
* @returns {{ vector: Point, angle: number }} vector representing the bisector of A and A's angle
|
|
188
|
+
*/
|
|
189
|
+
getBisector: function (A, B, C) {
|
|
190
|
+
var AB = fabric.util.createVector(A, B), AC = fabric.util.createVector(A, C);
|
|
191
|
+
var alpha = fabric.util.calcAngleBetweenVectors(AB, AC);
|
|
192
|
+
// check if alpha is relative to AB->BC
|
|
193
|
+
var ro = fabric.util.calcAngleBetweenVectors(fabric.util.rotateVector(AB, alpha), AC);
|
|
194
|
+
var phi = alpha * (ro === 0 ? 1 : -1) / 2;
|
|
195
|
+
return {
|
|
196
|
+
vector: fabric.util.getHatVector(fabric.util.rotateVector(AB, phi)),
|
|
197
|
+
angle: alpha
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Project stroke width on points returning 2 projections for each point as follows:
|
|
203
|
+
* - `miter`: 2 points corresponding to the outer boundary and the inner boundary of stroke.
|
|
204
|
+
* - `bevel`: 2 points corresponding to the bevel boundaries, tangent to the bisector.
|
|
205
|
+
* - `round`: same as `bevel`
|
|
206
|
+
* Used to calculate object's bounding box
|
|
207
|
+
* @static
|
|
208
|
+
* @memberOf fabric.util
|
|
209
|
+
* @param {Point[]} points
|
|
210
|
+
* @param {Object} options
|
|
211
|
+
* @param {number} options.strokeWidth
|
|
212
|
+
* @param {'miter'|'bevel'|'round'} options.strokeLineJoin
|
|
213
|
+
* @param {number} options.strokeMiterLimit https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit
|
|
214
|
+
* @param {boolean} options.strokeUniform
|
|
215
|
+
* @param {number} options.scaleX
|
|
216
|
+
* @param {number} options.scaleY
|
|
217
|
+
* @param {boolean} [openPath] whether the shape is open or not, affects the calculations of the first and last points
|
|
218
|
+
* @returns {fabric.Point[]} array of size 2n/4n of all suspected points
|
|
219
|
+
*/
|
|
220
|
+
projectStrokeOnPoints: function (points, options, openPath) {
|
|
221
|
+
var coords = [], s = options.strokeWidth / 2,
|
|
222
|
+
strokeUniformScalar = options.strokeUniform ?
|
|
223
|
+
new fabric.Point(1 / options.scaleX, 1 / options.scaleY) : new fabric.Point(1, 1),
|
|
224
|
+
getStrokeHatVector = function (v) {
|
|
225
|
+
var scalar = s / (Math.hypot(v.x, v.y));
|
|
226
|
+
return new fabric.Point(v.x * scalar * strokeUniformScalar.x, v.y * scalar * strokeUniformScalar.y);
|
|
227
|
+
};
|
|
228
|
+
if (points.length <= 1) {return coords;}
|
|
229
|
+
points.forEach(function (p, index) {
|
|
230
|
+
var A = new fabric.Point(p.x, p.y), B, C;
|
|
231
|
+
if (index === 0) {
|
|
232
|
+
C = points[index + 1];
|
|
233
|
+
B = openPath ? getStrokeHatVector(fabric.util.createVector(C, A)).addEquals(A) : points[points.length - 1];
|
|
234
|
+
}
|
|
235
|
+
else if (index === points.length - 1) {
|
|
236
|
+
B = points[index - 1];
|
|
237
|
+
C = openPath ? getStrokeHatVector(fabric.util.createVector(B, A)).addEquals(A) : points[0];
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
B = points[index - 1];
|
|
241
|
+
C = points[index + 1];
|
|
242
|
+
}
|
|
243
|
+
var bisector = fabric.util.getBisector(A, B, C),
|
|
244
|
+
bisectorVector = bisector.vector,
|
|
245
|
+
alpha = bisector.angle,
|
|
246
|
+
scalar,
|
|
247
|
+
miterVector;
|
|
248
|
+
if (options.strokeLineJoin === 'miter') {
|
|
249
|
+
scalar = -s / Math.sin(alpha / 2);
|
|
250
|
+
miterVector = new fabric.Point(
|
|
251
|
+
bisectorVector.x * scalar * strokeUniformScalar.x,
|
|
252
|
+
bisectorVector.y * scalar * strokeUniformScalar.y
|
|
253
|
+
);
|
|
254
|
+
if (Math.hypot(miterVector.x, miterVector.y) / s <= options.strokeMiterLimit) {
|
|
255
|
+
coords.push(A.add(miterVector));
|
|
256
|
+
coords.push(A.subtract(miterVector));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
scalar = -s * Math.SQRT2;
|
|
261
|
+
miterVector = new fabric.Point(
|
|
262
|
+
bisectorVector.x * scalar * strokeUniformScalar.x,
|
|
263
|
+
bisectorVector.y * scalar * strokeUniformScalar.y
|
|
264
|
+
);
|
|
265
|
+
coords.push(A.add(miterVector));
|
|
266
|
+
coords.push(A.subtract(miterVector));
|
|
267
|
+
});
|
|
268
|
+
return coords;
|
|
269
|
+
},
|
|
270
|
+
|
|
142
271
|
/**
|
|
143
272
|
* Apply transform t to point p
|
|
144
273
|
* @static
|
|
@@ -451,6 +580,25 @@
|
|
|
451
580
|
});
|
|
452
581
|
},
|
|
453
582
|
|
|
583
|
+
/**
|
|
584
|
+
* Creates corresponding fabric instances residing in an object, e.g. `clipPath`
|
|
585
|
+
* @see {@link fabric.Object.ENLIVEN_PROPS}
|
|
586
|
+
* @param {Object} object
|
|
587
|
+
* @param {Object} [context] assign enlived props to this object (pass null to skip this)
|
|
588
|
+
* @param {(objects:fabric.Object[]) => void} callback
|
|
589
|
+
*/
|
|
590
|
+
enlivenObjectEnlivables: function (object, context, callback) {
|
|
591
|
+
var enlivenProps = fabric.Object.ENLIVEN_PROPS.filter(function (key) { return !!object[key]; });
|
|
592
|
+
fabric.util.enlivenObjects(enlivenProps.map(function (key) { return object[key]; }), function (enlivedProps) {
|
|
593
|
+
var objects = {};
|
|
594
|
+
enlivenProps.forEach(function (key, index) {
|
|
595
|
+
objects[key] = enlivedProps[index];
|
|
596
|
+
context && (context[key] = enlivedProps[index]);
|
|
597
|
+
});
|
|
598
|
+
callback && callback(objects);
|
|
599
|
+
});
|
|
600
|
+
},
|
|
601
|
+
|
|
454
602
|
/**
|
|
455
603
|
* Create and wait for loading of patterns
|
|
456
604
|
* @static
|
|
@@ -542,49 +690,6 @@
|
|
|
542
690
|
}
|
|
543
691
|
},
|
|
544
692
|
|
|
545
|
-
/**
|
|
546
|
-
* WARNING: THIS WAS TO SUPPORT OLD BROWSERS. deprecated.
|
|
547
|
-
* WILL BE REMOVED IN FABRIC 5.0
|
|
548
|
-
* Draws a dashed line between two points
|
|
549
|
-
*
|
|
550
|
-
* This method is used to draw dashed line around selection area.
|
|
551
|
-
* See <a href="http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas">dotted stroke in canvas</a>
|
|
552
|
-
*
|
|
553
|
-
* @param {CanvasRenderingContext2D} ctx context
|
|
554
|
-
* @param {Number} x start x coordinate
|
|
555
|
-
* @param {Number} y start y coordinate
|
|
556
|
-
* @param {Number} x2 end x coordinate
|
|
557
|
-
* @param {Number} y2 end y coordinate
|
|
558
|
-
* @param {Array} da dash array pattern
|
|
559
|
-
* @deprecated
|
|
560
|
-
*/
|
|
561
|
-
drawDashedLine: function(ctx, x, y, x2, y2, da) {
|
|
562
|
-
var dx = x2 - x,
|
|
563
|
-
dy = y2 - y,
|
|
564
|
-
len = sqrt(dx * dx + dy * dy),
|
|
565
|
-
rot = atan2(dy, dx),
|
|
566
|
-
dc = da.length,
|
|
567
|
-
di = 0,
|
|
568
|
-
draw = true;
|
|
569
|
-
|
|
570
|
-
ctx.save();
|
|
571
|
-
ctx.translate(x, y);
|
|
572
|
-
ctx.moveTo(0, 0);
|
|
573
|
-
ctx.rotate(rot);
|
|
574
|
-
|
|
575
|
-
x = 0;
|
|
576
|
-
while (len > x) {
|
|
577
|
-
x += da[di++ % dc];
|
|
578
|
-
if (x > len) {
|
|
579
|
-
x = len;
|
|
580
|
-
}
|
|
581
|
-
ctx[draw ? 'lineTo' : 'moveTo'](x, 0);
|
|
582
|
-
draw = !draw;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
ctx.restore();
|
|
586
|
-
},
|
|
587
|
-
|
|
588
693
|
/**
|
|
589
694
|
* Creates canvas element
|
|
590
695
|
* @static
|
|
@@ -712,7 +817,7 @@
|
|
|
712
817
|
* @param {Boolean} [options.flipX]
|
|
713
818
|
* @param {Boolean} [options.flipY]
|
|
714
819
|
* @param {Number} [options.skewX]
|
|
715
|
-
* @param {Number} [options.
|
|
820
|
+
* @param {Number} [options.skewY]
|
|
716
821
|
* @return {Number[]} transform matrix
|
|
717
822
|
*/
|
|
718
823
|
calcDimensionsMatrix: function(options) {
|
|
@@ -1066,6 +1171,49 @@
|
|
|
1066
1171
|
x: bbox.width,
|
|
1067
1172
|
y: bbox.height,
|
|
1068
1173
|
};
|
|
1069
|
-
}
|
|
1174
|
+
},
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* Merges 2 clip paths into one visually equal clip path
|
|
1178
|
+
*
|
|
1179
|
+
* **IMPORTANT**:\
|
|
1180
|
+
* Does **NOT** clone the arguments, clone them proir if necessary.
|
|
1181
|
+
*
|
|
1182
|
+
* Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap.
|
|
1183
|
+
* Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible.
|
|
1184
|
+
*
|
|
1185
|
+
* In order to handle the `inverted` property we follow logic described in the following cases:\
|
|
1186
|
+
* **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\
|
|
1187
|
+
* **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\
|
|
1188
|
+
* **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged.
|
|
1189
|
+
*
|
|
1190
|
+
* @memberOf fabric.util
|
|
1191
|
+
* @param {fabric.Object} c1
|
|
1192
|
+
* @param {fabric.Object} c2
|
|
1193
|
+
* @returns {fabric.Object} merged clip path
|
|
1194
|
+
*/
|
|
1195
|
+
mergeClipPaths: function (c1, c2) {
|
|
1196
|
+
var a = c1, b = c2;
|
|
1197
|
+
if (a.inverted && !b.inverted) {
|
|
1198
|
+
// case (2)
|
|
1199
|
+
a = c2;
|
|
1200
|
+
b = c1;
|
|
1201
|
+
}
|
|
1202
|
+
// `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane
|
|
1203
|
+
fabric.util.applyTransformToObject(
|
|
1204
|
+
b,
|
|
1205
|
+
fabric.util.multiplyTransformMatrices(
|
|
1206
|
+
fabric.util.invertTransform(a.calcTransformMatrix()),
|
|
1207
|
+
b.calcTransformMatrix()
|
|
1208
|
+
)
|
|
1209
|
+
);
|
|
1210
|
+
// assign the `inverted` prop to the wrapping group
|
|
1211
|
+
var inverted = a.inverted && b.inverted;
|
|
1212
|
+
if (inverted) {
|
|
1213
|
+
// case (1)
|
|
1214
|
+
a.inverted = b.inverted = false;
|
|
1215
|
+
}
|
|
1216
|
+
return new fabric.Group([a], { clipPath: b, inverted: inverted });
|
|
1217
|
+
},
|
|
1070
1218
|
};
|
|
1071
1219
|
})(typeof exports !== 'undefined' ? exports : this);
|
package/src/util/path.js
CHANGED
|
@@ -507,15 +507,15 @@
|
|
|
507
507
|
p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc;
|
|
508
508
|
// nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100
|
|
509
509
|
// the path
|
|
510
|
-
while (tmpLen < distance &&
|
|
510
|
+
while (tmpLen < distance && nextStep > 0.0001) {
|
|
511
511
|
p = iterator(perc);
|
|
512
512
|
lastPerc = perc;
|
|
513
513
|
nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);
|
|
514
514
|
// compare tmpLen each cycle with distance, decide next perc to test.
|
|
515
515
|
if ((nextLen + tmpLen) > distance) {
|
|
516
516
|
// we discard this step and we make smaller steps.
|
|
517
|
-
nextStep /= 2;
|
|
518
517
|
perc -= nextStep;
|
|
518
|
+
nextStep /= 2;
|
|
519
519
|
}
|
|
520
520
|
else {
|
|
521
521
|
tempP = p;
|
|
@@ -811,50 +811,6 @@
|
|
|
811
811
|
});
|
|
812
812
|
}
|
|
813
813
|
|
|
814
|
-
/**
|
|
815
|
-
* Calculate bounding box of a elliptic-arc
|
|
816
|
-
* @deprecated
|
|
817
|
-
* @param {Number} fx start point of arc
|
|
818
|
-
* @param {Number} fy
|
|
819
|
-
* @param {Number} rx horizontal radius
|
|
820
|
-
* @param {Number} ry vertical radius
|
|
821
|
-
* @param {Number} rot angle of horizontal axis
|
|
822
|
-
* @param {Number} large 1 or 0, whatever the arc is the big or the small on the 2 points
|
|
823
|
-
* @param {Number} sweep 1 or 0, 1 clockwise or counterclockwise direction
|
|
824
|
-
* @param {Number} tx end point of arc
|
|
825
|
-
* @param {Number} ty
|
|
826
|
-
*/
|
|
827
|
-
function getBoundsOfArc(fx, fy, rx, ry, rot, large, sweep, tx, ty) {
|
|
828
|
-
|
|
829
|
-
var fromX = 0, fromY = 0, bound, bounds = [],
|
|
830
|
-
segs = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
|
|
831
|
-
|
|
832
|
-
for (var i = 0, len = segs.length; i < len; i++) {
|
|
833
|
-
bound = getBoundsOfCurve(fromX, fromY, segs[i][1], segs[i][2], segs[i][3], segs[i][4], segs[i][5], segs[i][6]);
|
|
834
|
-
bounds.push({ x: bound[0].x + fx, y: bound[0].y + fy });
|
|
835
|
-
bounds.push({ x: bound[1].x + fx, y: bound[1].y + fy });
|
|
836
|
-
fromX = segs[i][5];
|
|
837
|
-
fromY = segs[i][6];
|
|
838
|
-
}
|
|
839
|
-
return bounds;
|
|
840
|
-
};
|
|
841
|
-
|
|
842
|
-
/**
|
|
843
|
-
* Draws arc
|
|
844
|
-
* @deprecated
|
|
845
|
-
* @param {CanvasRenderingContext2D} ctx
|
|
846
|
-
* @param {Number} fx
|
|
847
|
-
* @param {Number} fy
|
|
848
|
-
* @param {Array} coords coords of the arc, without the front 'A/a'
|
|
849
|
-
*/
|
|
850
|
-
function drawArc(ctx, fx, fy, coords) {
|
|
851
|
-
coords = coords.slice(0).unshift('X'); // command A or a does not matter
|
|
852
|
-
var beziers = fromArcToBeziers(fx, fy, coords);
|
|
853
|
-
beziers.forEach(function(bezier) {
|
|
854
|
-
ctx.bezierCurveTo.apply(ctx, bezier.slice(1));
|
|
855
|
-
});
|
|
856
|
-
};
|
|
857
|
-
|
|
858
814
|
/**
|
|
859
815
|
* Join path commands to go back to svg format
|
|
860
816
|
* @param {Array} pathData fabricJS parsed path commands
|
|
@@ -870,14 +826,4 @@
|
|
|
870
826
|
fabric.util.getBoundsOfCurve = getBoundsOfCurve;
|
|
871
827
|
fabric.util.getPointOnPath = getPointOnPath;
|
|
872
828
|
fabric.util.transformPath = transformPath;
|
|
873
|
-
/**
|
|
874
|
-
* Typo of `fromArcToBeziers` kept for not breaking the api once corrected.
|
|
875
|
-
* Will be removed in fabric 5.0
|
|
876
|
-
* @deprecated
|
|
877
|
-
*/
|
|
878
|
-
fabric.util.fromArcToBeizers = fromArcToBeziers;
|
|
879
|
-
// kept because we do not want to make breaking changes.
|
|
880
|
-
// but useless and deprecated.
|
|
881
|
-
fabric.util.getBoundsOfArc = getBoundsOfArc;
|
|
882
|
-
fabric.util.drawArc = drawArc;
|
|
883
829
|
})();
|