fabric 4.3.0 → 4.4.0
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 +22 -0
- package/HEADER.js +1 -1
- package/README.md +3 -1
- package/dist/fabric.js +312 -101
- package/dist/fabric.min.js +1 -1
- package/{.travis.yml → old-travis-reference.yml} +0 -5
- package/package.json +6 -4
- package/src/brushes/base_brush.class.js +18 -0
- package/src/brushes/circle_brush.class.js +3 -0
- package/src/brushes/pencil_brush.class.js +3 -0
- package/src/brushes/spray_brush.class.js +3 -0
- package/src/canvas.class.js +45 -28
- package/src/controls.actions.js +1 -1
- package/src/controls.render.js +1 -1
- package/src/mixins/canvas_events.mixin.js +17 -11
- package/src/shapes/group.class.js +34 -31
- package/src/shapes/image.class.js +15 -2
- package/src/shapes/itext.class.js +3 -2
- package/src/shapes/object.class.js +12 -2
- package/src/shapes/text.class.js +38 -13
- package/src/static_canvas.class.js +10 -1
- package/src/util/misc.js +53 -0
- package/src/util/path.js +55 -8
package/dist/fabric.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* build: `node build.js modules=ALL exclude=gestures,accessors requirejs minifier=uglifyjs` */
|
|
2
2
|
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
|
|
3
3
|
|
|
4
|
-
var fabric = fabric || { version: '4.
|
|
4
|
+
var fabric = fabric || { version: '4.4.0' };
|
|
5
5
|
if (typeof exports !== 'undefined') {
|
|
6
6
|
exports.fabric = fabric;
|
|
7
7
|
}
|
|
@@ -1561,6 +1561,59 @@ fabric.CommonMethods = {
|
|
|
1561
1561
|
}).join(' ') + ')';
|
|
1562
1562
|
},
|
|
1563
1563
|
|
|
1564
|
+
/**
|
|
1565
|
+
* given an object and a transform, apply the inverse transform to the object,
|
|
1566
|
+
* this is equivalent to remove from that object that transformation, so that
|
|
1567
|
+
* added in a space with the removed transform, the object will be the same as before.
|
|
1568
|
+
* Removing from an object a transform that scale by 2 is like scaling it by 1/2.
|
|
1569
|
+
* Removing from an object a transfrom that rotate by 30deg is like rotating by 30deg
|
|
1570
|
+
* in the opposite direction.
|
|
1571
|
+
* This util is used to add objects inside transformed groups or nested groups.
|
|
1572
|
+
* @memberOf fabric.util
|
|
1573
|
+
* @param {fabric.Object} object the object you want to transform
|
|
1574
|
+
* @param {Array} transform the destination transform
|
|
1575
|
+
*/
|
|
1576
|
+
removeTransformFromObject: function(object, transform) {
|
|
1577
|
+
var inverted = fabric.util.invertTransform(transform),
|
|
1578
|
+
finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix());
|
|
1579
|
+
fabric.util.applyTransformToObject(object, finalTransform);
|
|
1580
|
+
},
|
|
1581
|
+
|
|
1582
|
+
/**
|
|
1583
|
+
* given an object and a transform, apply the transform to the object.
|
|
1584
|
+
* this is equivalent to change the space where the object is drawn.
|
|
1585
|
+
* Adding to an object a transform that scale by 2 is like scaling it by 2.
|
|
1586
|
+
* This is used when removing an object from an active selection for example.
|
|
1587
|
+
* @memberOf fabric.util
|
|
1588
|
+
* @param {fabric.Object} object the object you want to transform
|
|
1589
|
+
* @param {Array} transform the destination transform
|
|
1590
|
+
*/
|
|
1591
|
+
addTransformToObject: function(object, transform) {
|
|
1592
|
+
fabric.util.applyTransformToObject(
|
|
1593
|
+
object,
|
|
1594
|
+
fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix())
|
|
1595
|
+
);
|
|
1596
|
+
},
|
|
1597
|
+
|
|
1598
|
+
/**
|
|
1599
|
+
* discard an object transform state and apply the one from the matrix.
|
|
1600
|
+
* @memberOf fabric.util
|
|
1601
|
+
* @param {fabric.Object} object the object you want to transform
|
|
1602
|
+
* @param {Array} transform the destination transform
|
|
1603
|
+
*/
|
|
1604
|
+
applyTransformToObject: function(object, transform) {
|
|
1605
|
+
var options = fabric.util.qrDecompose(transform),
|
|
1606
|
+
center = new fabric.Point(options.translateX, options.translateY);
|
|
1607
|
+
object.flipX = false;
|
|
1608
|
+
object.flipY = false;
|
|
1609
|
+
object.set('scaleX', options.scaleX);
|
|
1610
|
+
object.set('scaleY', options.scaleY);
|
|
1611
|
+
object.skewX = options.skewX;
|
|
1612
|
+
object.skewY = options.skewY;
|
|
1613
|
+
object.angle = options.angle;
|
|
1614
|
+
object.setPositionByOrigin(center, 'center', 'center');
|
|
1615
|
+
},
|
|
1616
|
+
|
|
1564
1617
|
/**
|
|
1565
1618
|
* given a width and height, return the size of the bounding box
|
|
1566
1619
|
* that can contains the box with width/height with applied transform
|
|
@@ -2048,6 +2101,17 @@ fabric.CommonMethods = {
|
|
|
2048
2101
|
};
|
|
2049
2102
|
}
|
|
2050
2103
|
|
|
2104
|
+
function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {
|
|
2105
|
+
return function (pct) {
|
|
2106
|
+
var invT = 1 - pct,
|
|
2107
|
+
tangentX = (3 * invT * invT * (p2x - p1x)) + (6 * invT * pct * (p3x - p2x)) +
|
|
2108
|
+
(3 * pct * pct * (p4x - p3x)),
|
|
2109
|
+
tangentY = (3 * invT * invT * (p2y - p1y)) + (6 * invT * pct * (p3y - p2y)) +
|
|
2110
|
+
(3 * pct * pct * (p4y - p3y));
|
|
2111
|
+
return Math.atan2(tangentY, tangentX);
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2051
2115
|
function QB1(t) {
|
|
2052
2116
|
return t * t;
|
|
2053
2117
|
}
|
|
@@ -2070,6 +2134,16 @@ fabric.CommonMethods = {
|
|
|
2070
2134
|
};
|
|
2071
2135
|
}
|
|
2072
2136
|
|
|
2137
|
+
function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
2138
|
+
return function (pct) {
|
|
2139
|
+
var invT = 1 - pct,
|
|
2140
|
+
tangentX = (2 * invT * (p2x - p1x)) + (2 * pct * (p3x - p2x)),
|
|
2141
|
+
tangentY = (2 * invT * (p2y - p1y)) + (2 * pct * (p3y - p2y));
|
|
2142
|
+
return Math.atan2(tangentY, tangentX);
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
|
|
2073
2147
|
// this will run over a path segment ( a cubic or quadratic segment) and approximate it
|
|
2074
2148
|
// with 100 segemnts. This will good enough to calculate the length of the curve
|
|
2075
2149
|
function pathIterator(iterator, x1, y1) {
|
|
@@ -2088,15 +2162,16 @@ fabric.CommonMethods = {
|
|
|
2088
2162
|
* The percentage will be then used to find the correct point on the canvas for the path.
|
|
2089
2163
|
* @param {Array} segInfo fabricJS collection of information on a parsed path
|
|
2090
2164
|
* @param {Number} distance from starting point, in pixels.
|
|
2091
|
-
* @return {
|
|
2165
|
+
* @return {Object} info object with x and y ( the point on canvas ) and angle, the tangent on that point;
|
|
2092
2166
|
*/
|
|
2093
2167
|
function findPercentageForDistance(segInfo, distance) {
|
|
2094
2168
|
var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y },
|
|
2095
|
-
p, nextLen, nextStep = 0.01;
|
|
2169
|
+
p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc;
|
|
2096
2170
|
// nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100
|
|
2097
2171
|
// the path
|
|
2098
2172
|
while (tmpLen < distance && perc <= 1 && nextStep > 0.0001) {
|
|
2099
2173
|
p = iterator(perc);
|
|
2174
|
+
lastPerc = perc;
|
|
2100
2175
|
nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);
|
|
2101
2176
|
// compare tmpLen each cycle with distance, decide next perc to test.
|
|
2102
2177
|
if ((nextLen + tmpLen) > distance) {
|
|
@@ -2110,6 +2185,7 @@ fabric.CommonMethods = {
|
|
|
2110
2185
|
tmpLen += nextLen;
|
|
2111
2186
|
}
|
|
2112
2187
|
}
|
|
2188
|
+
p.angle = angleFinder(lastPerc);
|
|
2113
2189
|
return p;
|
|
2114
2190
|
}
|
|
2115
2191
|
|
|
@@ -2123,7 +2199,7 @@ fabric.CommonMethods = {
|
|
|
2123
2199
|
var totalLength = 0, len = path.length, current,
|
|
2124
2200
|
//x2 and y2 are the coords of segment start
|
|
2125
2201
|
//x1 and y1 are the coords of the current point
|
|
2126
|
-
x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo;
|
|
2202
|
+
x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder;
|
|
2127
2203
|
for (var i = 0; i < len; i++) {
|
|
2128
2204
|
current = path[i];
|
|
2129
2205
|
tempInfo = {
|
|
@@ -2153,7 +2229,18 @@ fabric.CommonMethods = {
|
|
|
2153
2229
|
current[5],
|
|
2154
2230
|
current[6]
|
|
2155
2231
|
);
|
|
2232
|
+
angleFinder = getTangentCubicIterator(
|
|
2233
|
+
x1,
|
|
2234
|
+
y1,
|
|
2235
|
+
current[1],
|
|
2236
|
+
current[2],
|
|
2237
|
+
current[3],
|
|
2238
|
+
current[4],
|
|
2239
|
+
current[5],
|
|
2240
|
+
current[6]
|
|
2241
|
+
);
|
|
2156
2242
|
tempInfo.iterator = iterator;
|
|
2243
|
+
tempInfo.angleFinder = angleFinder;
|
|
2157
2244
|
tempInfo.length = pathIterator(iterator, x1, y1);
|
|
2158
2245
|
x1 = current[5];
|
|
2159
2246
|
y1 = current[6];
|
|
@@ -2167,7 +2254,16 @@ fabric.CommonMethods = {
|
|
|
2167
2254
|
current[3],
|
|
2168
2255
|
current[4]
|
|
2169
2256
|
);
|
|
2257
|
+
angleFinder = getTangentQuadraticIterator(
|
|
2258
|
+
x1,
|
|
2259
|
+
y1,
|
|
2260
|
+
current[1],
|
|
2261
|
+
current[2],
|
|
2262
|
+
current[3],
|
|
2263
|
+
current[4]
|
|
2264
|
+
);
|
|
2170
2265
|
tempInfo.iterator = iterator;
|
|
2266
|
+
tempInfo.angleFinder = angleFinder;
|
|
2171
2267
|
tempInfo.length = pathIterator(iterator, x1, y1);
|
|
2172
2268
|
x1 = current[3];
|
|
2173
2269
|
y1 = current[4];
|
|
@@ -2193,29 +2289,33 @@ fabric.CommonMethods = {
|
|
|
2193
2289
|
if (!infos) {
|
|
2194
2290
|
infos = getPathSegmentsInfo(path);
|
|
2195
2291
|
}
|
|
2196
|
-
// var distance = infos[infos.length - 1] * perc;
|
|
2197
2292
|
var i = 0;
|
|
2198
2293
|
while ((distance - infos[i].length > 0) && i < (infos.length - 2)) {
|
|
2199
2294
|
distance -= infos[i].length;
|
|
2200
2295
|
i++;
|
|
2201
2296
|
}
|
|
2297
|
+
// var distance = infos[infos.length - 1] * perc;
|
|
2202
2298
|
var segInfo = infos[i], segPercent = distance / segInfo.length,
|
|
2203
|
-
command = segInfo.command, segment = path[i];
|
|
2299
|
+
command = segInfo.command, segment = path[i], info;
|
|
2204
2300
|
|
|
2205
2301
|
switch (command) {
|
|
2206
2302
|
case 'M':
|
|
2207
|
-
return { x: segInfo.x, y: segInfo.y };
|
|
2303
|
+
return { x: segInfo.x, y: segInfo.y, angle: 0 };
|
|
2208
2304
|
case 'Z':
|
|
2209
2305
|
case 'z':
|
|
2210
|
-
|
|
2306
|
+
info = new fabric.Point(segInfo.x, segInfo.y).lerp(
|
|
2211
2307
|
new fabric.Point(segInfo.destX, segInfo.destY),
|
|
2212
2308
|
segPercent
|
|
2213
2309
|
);
|
|
2310
|
+
info.angle = Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x);
|
|
2311
|
+
return info;
|
|
2214
2312
|
case 'L':
|
|
2215
|
-
|
|
2313
|
+
info = new fabric.Point(segInfo.x, segInfo.y).lerp(
|
|
2216
2314
|
new fabric.Point(segment[1], segment[2]),
|
|
2217
2315
|
segPercent
|
|
2218
2316
|
);
|
|
2317
|
+
info.angle = Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x);
|
|
2318
|
+
return info;
|
|
2219
2319
|
case 'C':
|
|
2220
2320
|
return findPercentageForDistance(segInfo, distance);
|
|
2221
2321
|
case 'Q':
|
|
@@ -6445,7 +6545,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|
|
6445
6545
|
* @return {Boolean} true if one flip, but not two.
|
|
6446
6546
|
*/
|
|
6447
6547
|
function targetHasOneFlip(target) {
|
|
6448
|
-
return
|
|
6548
|
+
return target.flipX !== target.flipY;
|
|
6449
6549
|
}
|
|
6450
6550
|
|
|
6451
6551
|
/**
|
|
@@ -7022,7 +7122,7 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|
|
7022
7122
|
), xSizeBy2 = xSize / 2, ySizeBy2 = ySize / 2;
|
|
7023
7123
|
ctx.save();
|
|
7024
7124
|
ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor;
|
|
7025
|
-
ctx.strokeStyle = styleOverride.
|
|
7125
|
+
ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor;
|
|
7026
7126
|
// this is still wrong
|
|
7027
7127
|
ctx.lineWidth = 1;
|
|
7028
7128
|
ctx.translate(left, top);
|
|
@@ -8942,7 +9042,10 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|
|
8942
9042
|
* @chainable true
|
|
8943
9043
|
*/
|
|
8944
9044
|
setViewportTransform: function (vpt) {
|
|
8945
|
-
var activeObject = this._activeObject,
|
|
9045
|
+
var activeObject = this._activeObject,
|
|
9046
|
+
backgroundObject = this.backgroundImage,
|
|
9047
|
+
overlayObject = this.overlayImage,
|
|
9048
|
+
object, i, len;
|
|
8946
9049
|
this.viewportTransform = vpt;
|
|
8947
9050
|
for (i = 0, len = this._objects.length; i < len; i++) {
|
|
8948
9051
|
object = this._objects[i];
|
|
@@ -8951,6 +9054,12 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
|
|
|
8951
9054
|
if (activeObject) {
|
|
8952
9055
|
activeObject.setCoords();
|
|
8953
9056
|
}
|
|
9057
|
+
if (backgroundObject) {
|
|
9058
|
+
backgroundObject.setCoords(true);
|
|
9059
|
+
}
|
|
9060
|
+
if (overlayObject) {
|
|
9061
|
+
overlayObject.setCoords(true);
|
|
9062
|
+
}
|
|
8954
9063
|
this.calcViewportBoundaries();
|
|
8955
9064
|
this.renderOnAddRemove && this.requestRenderAll();
|
|
8956
9065
|
return this;
|
|
@@ -10170,6 +10279,15 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype
|
|
|
10170
10279
|
*/
|
|
10171
10280
|
strokeDashArray: null,
|
|
10172
10281
|
|
|
10282
|
+
/**
|
|
10283
|
+
* When `true`, the free drawing is limited to the whiteboard size. Default to false.
|
|
10284
|
+
* @type Boolean
|
|
10285
|
+
* @default false
|
|
10286
|
+
*/
|
|
10287
|
+
|
|
10288
|
+
limitedToCanvasSize: false,
|
|
10289
|
+
|
|
10290
|
+
|
|
10173
10291
|
/**
|
|
10174
10292
|
* Sets brush styles
|
|
10175
10293
|
* @private
|
|
@@ -10234,6 +10352,15 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype
|
|
|
10234
10352
|
|
|
10235
10353
|
ctx.shadowColor = '';
|
|
10236
10354
|
ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;
|
|
10355
|
+
},
|
|
10356
|
+
|
|
10357
|
+
/**
|
|
10358
|
+
* Check is pointer is outside canvas boundaries
|
|
10359
|
+
* @param {Object} pointer
|
|
10360
|
+
* @private
|
|
10361
|
+
*/
|
|
10362
|
+
_isOutSideCanvas: function(pointer) {
|
|
10363
|
+
return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight();
|
|
10237
10364
|
}
|
|
10238
10365
|
});
|
|
10239
10366
|
|
|
@@ -10296,6 +10423,9 @@ fabric.BaseBrush = fabric.util.createClass(/** @lends fabric.BaseBrush.prototype
|
|
|
10296
10423
|
if (!this.canvas._isMainEvent(options.e)) {
|
|
10297
10424
|
return;
|
|
10298
10425
|
}
|
|
10426
|
+
if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
|
|
10427
|
+
return;
|
|
10428
|
+
}
|
|
10299
10429
|
if (this._captureDrawingPath(pointer) && this._points.length > 1) {
|
|
10300
10430
|
if (this.needsFullRender()) {
|
|
10301
10431
|
// redraw curve
|
|
@@ -10605,6 +10735,9 @@ fabric.CircleBrush = fabric.util.createClass(fabric.BaseBrush, /** @lends fabric
|
|
|
10605
10735
|
* @param {Object} pointer
|
|
10606
10736
|
*/
|
|
10607
10737
|
onMouseMove: function(pointer) {
|
|
10738
|
+
if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
|
|
10739
|
+
return;
|
|
10740
|
+
}
|
|
10608
10741
|
if (this.needsFullRender()) {
|
|
10609
10742
|
this.canvas.clearContext(this.canvas.contextTop);
|
|
10610
10743
|
this.addPoint(pointer);
|
|
@@ -10752,6 +10885,9 @@ fabric.SprayBrush = fabric.util.createClass( fabric.BaseBrush, /** @lends fabric
|
|
|
10752
10885
|
* @param {Object} pointer
|
|
10753
10886
|
*/
|
|
10754
10887
|
onMouseMove: function(pointer) {
|
|
10888
|
+
if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {
|
|
10889
|
+
return;
|
|
10890
|
+
}
|
|
10755
10891
|
this.addSprayChunk(pointer);
|
|
10756
10892
|
this.render(this.sprayChunkPoints);
|
|
10757
10893
|
},
|
|
@@ -11454,13 +11590,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
11454
11590
|
target.render(ctx);
|
|
11455
11591
|
ctx.restore();
|
|
11456
11592
|
|
|
11457
|
-
target === this._activeObject && target._renderControls(ctx, {
|
|
11458
|
-
hasBorders: false,
|
|
11459
|
-
transparentCorners: false
|
|
11460
|
-
}, {
|
|
11461
|
-
hasBorders: false,
|
|
11462
|
-
});
|
|
11463
|
-
|
|
11464
11593
|
target.selectionBackgroundColor = originalColor;
|
|
11465
11594
|
|
|
11466
11595
|
var isTransparent = fabric.util.isTransparent(
|
|
@@ -11722,18 +11851,19 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
11722
11851
|
activeObject = this._activeObject,
|
|
11723
11852
|
aObjects = this.getActiveObjects(),
|
|
11724
11853
|
activeTarget, activeTargetSubs,
|
|
11725
|
-
isTouch = isTouchEvent(e)
|
|
11854
|
+
isTouch = isTouchEvent(e),
|
|
11855
|
+
shouldLookForActive = (aObjects.length > 1 && !skipGroup) || aObjects.length === 1;
|
|
11726
11856
|
|
|
11727
11857
|
// first check current group (if one exists)
|
|
11728
11858
|
// active group does not check sub targets like normal groups.
|
|
11729
11859
|
// if active group just exits.
|
|
11730
11860
|
this.targets = [];
|
|
11731
11861
|
|
|
11732
|
-
if
|
|
11862
|
+
// if we hit the corner of an activeObject, let's return that.
|
|
11863
|
+
if (shouldLookForActive && activeObject._findTargetCorner(pointer, isTouch)) {
|
|
11733
11864
|
return activeObject;
|
|
11734
11865
|
}
|
|
11735
|
-
|
|
11736
|
-
if (aObjects.length === 1 && activeObject._findTargetCorner(pointer, isTouch)) {
|
|
11866
|
+
if (aObjects.length > 1 && !skipGroup && activeObject === this._searchPossibleTargets([activeObject], pointer)) {
|
|
11737
11867
|
return activeObject;
|
|
11738
11868
|
}
|
|
11739
11869
|
if (aObjects.length === 1 &&
|
|
@@ -11769,7 +11899,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
11769
11899
|
obj.evented &&
|
|
11770
11900
|
// http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html
|
|
11771
11901
|
// http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html
|
|
11772
|
-
|
|
11902
|
+
obj.containsPoint(pointer)
|
|
11773
11903
|
) {
|
|
11774
11904
|
if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {
|
|
11775
11905
|
var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);
|
|
@@ -12045,38 +12175,50 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12045
12175
|
*/
|
|
12046
12176
|
_fireSelectionEvents: function(oldObjects, e) {
|
|
12047
12177
|
var somethingChanged = false, objects = this.getActiveObjects(),
|
|
12048
|
-
added = [], removed = []
|
|
12178
|
+
added = [], removed = [];
|
|
12049
12179
|
oldObjects.forEach(function(oldObject) {
|
|
12050
12180
|
if (objects.indexOf(oldObject) === -1) {
|
|
12051
12181
|
somethingChanged = true;
|
|
12052
|
-
oldObject.fire('deselected',
|
|
12182
|
+
oldObject.fire('deselected', {
|
|
12183
|
+
e: e,
|
|
12184
|
+
target: oldObject
|
|
12185
|
+
});
|
|
12053
12186
|
removed.push(oldObject);
|
|
12054
12187
|
}
|
|
12055
12188
|
});
|
|
12056
12189
|
objects.forEach(function(object) {
|
|
12057
12190
|
if (oldObjects.indexOf(object) === -1) {
|
|
12058
12191
|
somethingChanged = true;
|
|
12059
|
-
object.fire('selected',
|
|
12192
|
+
object.fire('selected', {
|
|
12193
|
+
e: e,
|
|
12194
|
+
target: object
|
|
12195
|
+
});
|
|
12060
12196
|
added.push(object);
|
|
12061
12197
|
}
|
|
12062
12198
|
});
|
|
12063
12199
|
if (oldObjects.length > 0 && objects.length > 0) {
|
|
12064
|
-
|
|
12065
|
-
|
|
12066
|
-
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12200
|
+
somethingChanged && this.fire('selection:updated', {
|
|
12201
|
+
e: e,
|
|
12202
|
+
selected: added,
|
|
12203
|
+
deselected: removed,
|
|
12204
|
+
// added for backward compatibility
|
|
12205
|
+
// deprecated
|
|
12206
|
+
updated: added[0] || removed[0],
|
|
12207
|
+
target: this._activeObject,
|
|
12208
|
+
});
|
|
12070
12209
|
}
|
|
12071
12210
|
else if (objects.length > 0) {
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12211
|
+
this.fire('selection:created', {
|
|
12212
|
+
e: e,
|
|
12213
|
+
selected: added,
|
|
12214
|
+
target: this._activeObject,
|
|
12215
|
+
});
|
|
12076
12216
|
}
|
|
12077
12217
|
else if (oldObjects.length > 0) {
|
|
12078
|
-
|
|
12079
|
-
|
|
12218
|
+
this.fire('selection:cleared', {
|
|
12219
|
+
e: e,
|
|
12220
|
+
deselected: removed,
|
|
12221
|
+
});
|
|
12080
12222
|
}
|
|
12081
12223
|
},
|
|
12082
12224
|
|
|
@@ -12095,6 +12237,10 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12095
12237
|
},
|
|
12096
12238
|
|
|
12097
12239
|
/**
|
|
12240
|
+
* This is a private method for now.
|
|
12241
|
+
* This is supposed to be equivalent to setActiveObject but without firing
|
|
12242
|
+
* any event. There is commitment to have this stay this way.
|
|
12243
|
+
* This is the functional part of setActiveObject.
|
|
12098
12244
|
* @private
|
|
12099
12245
|
* @param {Object} object to set as active
|
|
12100
12246
|
* @param {Event} [e] Event (passed along when firing "object:selected")
|
|
@@ -12115,6 +12261,13 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12115
12261
|
},
|
|
12116
12262
|
|
|
12117
12263
|
/**
|
|
12264
|
+
* This is a private method for now.
|
|
12265
|
+
* This is supposed to be equivalent to discardActiveObject but without firing
|
|
12266
|
+
* any events. There is commitment to have this stay this way.
|
|
12267
|
+
* This is the functional part of discardActiveObject.
|
|
12268
|
+
* @param {Event} [e] Event (passed along when firing "object:deselected")
|
|
12269
|
+
* @param {Object} object to set as active
|
|
12270
|
+
* @return {Boolean} true if the selection happened
|
|
12118
12271
|
* @private
|
|
12119
12272
|
*/
|
|
12120
12273
|
_discardActiveObject: function(e, object) {
|
|
@@ -12225,7 +12378,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12225
12378
|
layoutProps.forEach(function(prop) {
|
|
12226
12379
|
originalValues[prop] = instance[prop];
|
|
12227
12380
|
});
|
|
12228
|
-
this._activeObject.
|
|
12381
|
+
fabric.util.addTransformToObject(instance, this._activeObject.calcOwnMatrix());
|
|
12229
12382
|
return originalValues;
|
|
12230
12383
|
}
|
|
12231
12384
|
else {
|
|
@@ -12727,15 +12880,21 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12727
12880
|
}
|
|
12728
12881
|
}
|
|
12729
12882
|
if (target) {
|
|
12730
|
-
|
|
12731
|
-
this.
|
|
12732
|
-
|
|
12733
|
-
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
|
|
12738
|
-
|
|
12883
|
+
if (target.selectable && target !== this._activeObject && target.activeOn === 'up') {
|
|
12884
|
+
this.setActiveObject(target, e);
|
|
12885
|
+
shouldRender = true;
|
|
12886
|
+
}
|
|
12887
|
+
else {
|
|
12888
|
+
var corner = target._findTargetCorner(
|
|
12889
|
+
this.getPointer(e, true),
|
|
12890
|
+
fabric.util.isTouchEvent(e)
|
|
12891
|
+
);
|
|
12892
|
+
var control = target.controls[corner],
|
|
12893
|
+
mouseUpHandler = control && control.getMouseUpHandler(e, target, control);
|
|
12894
|
+
if (mouseUpHandler) {
|
|
12895
|
+
var pointer = this.getPointer(e);
|
|
12896
|
+
mouseUpHandler(e, transform, pointer.x, pointer.y);
|
|
12897
|
+
}
|
|
12739
12898
|
}
|
|
12740
12899
|
target.isMoving = false;
|
|
12741
12900
|
}
|
|
@@ -12991,7 +13150,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
12991
13150
|
|
|
12992
13151
|
if (target) {
|
|
12993
13152
|
var alreadySelected = target === this._activeObject;
|
|
12994
|
-
if (target.selectable) {
|
|
13153
|
+
if (target.selectable && target.activeOn === 'down') {
|
|
12995
13154
|
this.setActiveObject(target, e);
|
|
12996
13155
|
}
|
|
12997
13156
|
var corner = target._findTargetCorner(
|
|
@@ -13200,7 +13359,6 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
13200
13359
|
transform = this._currentTransform;
|
|
13201
13360
|
|
|
13202
13361
|
transform.reset = false;
|
|
13203
|
-
transform.target.isMoving = true;
|
|
13204
13362
|
transform.shiftKey = e.shiftKey;
|
|
13205
13363
|
transform.altKey = e[this.centeredKey];
|
|
13206
13364
|
|
|
@@ -13224,6 +13382,7 @@ fabric.PatternBrush = fabric.util.createClass(fabric.PencilBrush, /** @lends fab
|
|
|
13224
13382
|
actionPerformed = actionHandler(e, transform, x, y);
|
|
13225
13383
|
}
|
|
13226
13384
|
if (action === 'drag' && actionPerformed) {
|
|
13385
|
+
transform.target.isMoving = true;
|
|
13227
13386
|
this.setCursor(transform.target.moveCursor || this.moveCursor);
|
|
13228
13387
|
}
|
|
13229
13388
|
transform.actionPerformed = transform.actionPerformed || actionPerformed;
|
|
@@ -14362,6 +14521,17 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
14362
14521
|
*/
|
|
14363
14522
|
paintFirst: 'fill',
|
|
14364
14523
|
|
|
14524
|
+
/**
|
|
14525
|
+
* When 'down', object is set to active on mousedown/touchstart
|
|
14526
|
+
* When 'up', object is set to active on mouseup/touchend
|
|
14527
|
+
* Experimental. Let's see if this breaks anything before supporting officially
|
|
14528
|
+
* @private
|
|
14529
|
+
* since 4.4.0
|
|
14530
|
+
* @type String
|
|
14531
|
+
* @default 'down'
|
|
14532
|
+
*/
|
|
14533
|
+
activeOn: 'down',
|
|
14534
|
+
|
|
14365
14535
|
/**
|
|
14366
14536
|
* List of properties to consider when checking if state
|
|
14367
14537
|
* of an object is changed (fabric.Object#hasStateChanged)
|
|
@@ -14630,7 +14800,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
14630
14800
|
strokeLineCap: this.strokeLineCap,
|
|
14631
14801
|
strokeDashOffset: this.strokeDashOffset,
|
|
14632
14802
|
strokeLineJoin: this.strokeLineJoin,
|
|
14633
|
-
|
|
14803
|
+
strokeUniform: this.strokeUniform,
|
|
14634
14804
|
strokeMiterLimit: toFixed(this.strokeMiterLimit, NUM_FRACTION_DIGITS),
|
|
14635
14805
|
scaleX: toFixed(this.scaleX, NUM_FRACTION_DIGITS),
|
|
14636
14806
|
scaleY: toFixed(this.scaleY, NUM_FRACTION_DIGITS),
|
|
@@ -14782,7 +14952,6 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|
|
14782
14952
|
this.group.set('dirty', true);
|
|
14783
14953
|
}
|
|
14784
14954
|
}
|
|
14785
|
-
|
|
14786
14955
|
return this;
|
|
14787
14956
|
},
|
|
14788
14957
|
|
|
@@ -19654,17 +19823,27 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
19654
19823
|
* @chainable
|
|
19655
19824
|
*/
|
|
19656
19825
|
addWithUpdate: function(object) {
|
|
19826
|
+
var nested = !!this.group;
|
|
19657
19827
|
this._restoreObjectsState();
|
|
19658
19828
|
fabric.util.resetObjectTransform(this);
|
|
19659
19829
|
if (object) {
|
|
19830
|
+
if (nested) {
|
|
19831
|
+
// if this group is inside another group, we need to pre transform the object
|
|
19832
|
+
fabric.util.removeTransformFromObject(object, this.group.calcTransformMatrix());
|
|
19833
|
+
}
|
|
19660
19834
|
this._objects.push(object);
|
|
19661
19835
|
object.group = this;
|
|
19662
19836
|
object._set('canvas', this.canvas);
|
|
19663
19837
|
}
|
|
19664
19838
|
this._calcBounds();
|
|
19665
19839
|
this._updateObjectsCoords();
|
|
19666
|
-
this.setCoords();
|
|
19667
19840
|
this.dirty = true;
|
|
19841
|
+
if (nested) {
|
|
19842
|
+
this.group.addWithUpdate();
|
|
19843
|
+
}
|
|
19844
|
+
else {
|
|
19845
|
+
this.setCoords();
|
|
19846
|
+
}
|
|
19668
19847
|
return this;
|
|
19669
19848
|
},
|
|
19670
19849
|
|
|
@@ -19855,12 +20034,21 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
19855
20034
|
|
|
19856
20035
|
/**
|
|
19857
20036
|
* Restores original state of each of group objects (original state is that which was before group was created).
|
|
20037
|
+
* if the nested boolean is true, the original state will be restored just for the
|
|
20038
|
+
* first group and not for all the group chain
|
|
19858
20039
|
* @private
|
|
20040
|
+
* @param {Boolean} nested tell the function to restore object state up to the parent group and not more
|
|
19859
20041
|
* @return {fabric.Group} thisArg
|
|
19860
20042
|
* @chainable
|
|
19861
20043
|
*/
|
|
19862
20044
|
_restoreObjectsState: function() {
|
|
19863
|
-
this.
|
|
20045
|
+
var groupMatrix = this.calcOwnMatrix();
|
|
20046
|
+
this._objects.forEach(function(object) {
|
|
20047
|
+
// instead of using _this = this;
|
|
20048
|
+
fabric.util.addTransformToObject(object, groupMatrix);
|
|
20049
|
+
delete object.group;
|
|
20050
|
+
object.setCoords();
|
|
20051
|
+
});
|
|
19864
20052
|
return this;
|
|
19865
20053
|
},
|
|
19866
20054
|
|
|
@@ -19869,37 +20057,20 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
19869
20057
|
* i.e. it tells you what would happen if the supplied object was in
|
|
19870
20058
|
* the group, and then the group was destroyed. It mutates the supplied
|
|
19871
20059
|
* object.
|
|
20060
|
+
* Warning: this method is not useful anymore, it has been kept to no break the api.
|
|
20061
|
+
* is not used in the fabricJS codebase
|
|
20062
|
+
* this method will be reduced to using the utility.
|
|
20063
|
+
* @private
|
|
20064
|
+
* @deprecated
|
|
19872
20065
|
* @param {fabric.Object} object
|
|
20066
|
+
* @param {Array} parentMatrix parent transformation
|
|
19873
20067
|
* @return {fabric.Object} transformedObject
|
|
19874
20068
|
*/
|
|
19875
|
-
realizeTransform: function(object) {
|
|
19876
|
-
|
|
19877
|
-
options = fabric.util.qrDecompose(matrix),
|
|
19878
|
-
center = new fabric.Point(options.translateX, options.translateY);
|
|
19879
|
-
object.flipX = false;
|
|
19880
|
-
object.flipY = false;
|
|
19881
|
-
object.set('scaleX', options.scaleX);
|
|
19882
|
-
object.set('scaleY', options.scaleY);
|
|
19883
|
-
object.skewX = options.skewX;
|
|
19884
|
-
object.skewY = options.skewY;
|
|
19885
|
-
object.angle = options.angle;
|
|
19886
|
-
object.setPositionByOrigin(center, 'center', 'center');
|
|
20069
|
+
realizeTransform: function(object, parentMatrix) {
|
|
20070
|
+
fabric.util.addTransformToObject(object, parentMatrix);
|
|
19887
20071
|
return object;
|
|
19888
20072
|
},
|
|
19889
20073
|
|
|
19890
|
-
/**
|
|
19891
|
-
* Restores original state of a specified object in group
|
|
19892
|
-
* @private
|
|
19893
|
-
* @param {fabric.Object} object
|
|
19894
|
-
* @return {fabric.Group} thisArg
|
|
19895
|
-
*/
|
|
19896
|
-
_restoreObjectState: function(object) {
|
|
19897
|
-
this.realizeTransform(object);
|
|
19898
|
-
delete object.group;
|
|
19899
|
-
object.setCoords();
|
|
19900
|
-
return this;
|
|
19901
|
-
},
|
|
19902
|
-
|
|
19903
20074
|
/**
|
|
19904
20075
|
* Destroys a group (restoring state of its objects)
|
|
19905
20076
|
* @return {fabric.Group} thisArg
|
|
@@ -19972,19 +20143,20 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
19972
20143
|
_calcBounds: function(onlyWidthHeight) {
|
|
19973
20144
|
var aX = [],
|
|
19974
20145
|
aY = [],
|
|
19975
|
-
o, prop,
|
|
20146
|
+
o, prop, coords,
|
|
19976
20147
|
props = ['tr', 'br', 'bl', 'tl'],
|
|
19977
20148
|
i = 0, iLen = this._objects.length,
|
|
19978
20149
|
j, jLen = props.length;
|
|
19979
20150
|
|
|
19980
20151
|
for ( ; i < iLen; ++i) {
|
|
19981
20152
|
o = this._objects[i];
|
|
19982
|
-
|
|
20153
|
+
coords = o.calcACoords();
|
|
19983
20154
|
for (j = 0; j < jLen; j++) {
|
|
19984
20155
|
prop = props[j];
|
|
19985
|
-
aX.push(
|
|
19986
|
-
aY.push(
|
|
20156
|
+
aX.push(coords[prop].x);
|
|
20157
|
+
aY.push(coords[prop].y);
|
|
19987
20158
|
}
|
|
20159
|
+
o.aCoords = coords;
|
|
19988
20160
|
}
|
|
19989
20161
|
|
|
19990
20162
|
this._getBounds(aX, aY, onlyWidthHeight);
|
|
@@ -20340,6 +20512,15 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
20340
20512
|
*/
|
|
20341
20513
|
stateProperties: fabric.Object.prototype.stateProperties.concat('cropX', 'cropY'),
|
|
20342
20514
|
|
|
20515
|
+
/**
|
|
20516
|
+
* List of properties to consider when checking if cache needs refresh
|
|
20517
|
+
* Those properties are checked by statefullCache ON ( or lazy mode if we want ) or from single
|
|
20518
|
+
* calls to Object.set(key, value). If the key is in this list, the object is marked as dirty
|
|
20519
|
+
* and refreshed at the next render
|
|
20520
|
+
* @type Array
|
|
20521
|
+
*/
|
|
20522
|
+
cacheProperties: fabric.Object.prototype.cacheProperties.concat('cropX', 'cropY'),
|
|
20523
|
+
|
|
20343
20524
|
/**
|
|
20344
20525
|
* key used to retrieve the texture representing this image
|
|
20345
20526
|
* @since 2.0.0
|
|
@@ -20375,7 +20556,11 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
20375
20556
|
|
|
20376
20557
|
/**
|
|
20377
20558
|
* Constructor
|
|
20378
|
-
*
|
|
20559
|
+
* Image can be initialized with any canvas drawable or a string.
|
|
20560
|
+
* The string should be a url and will be loaded as an image.
|
|
20561
|
+
* Canvas and Image element work out of the box, while videos require extra code to work.
|
|
20562
|
+
* Please check video element events for seeking.
|
|
20563
|
+
* @param {HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | String} element Image element
|
|
20379
20564
|
* @param {Object} [options] Options object
|
|
20380
20565
|
* @param {function} [callback] callback function to call after eventual filters applied.
|
|
20381
20566
|
* @return {fabric.Image} thisArg
|
|
@@ -20800,7 +20985,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
|
|
|
20800
20985
|
sH = min(h * scaleY, elHeight - sY),
|
|
20801
20986
|
x = -w / 2, y = -h / 2,
|
|
20802
20987
|
maxDestW = min(w, elWidth / scaleX - cropX),
|
|
20803
|
-
maxDestH = min(h, elHeight /
|
|
20988
|
+
maxDestH = min(h, elHeight / scaleY - cropY);
|
|
20804
20989
|
|
|
20805
20990
|
elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);
|
|
20806
20991
|
},
|
|
@@ -25135,9 +25320,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
25135
25320
|
return;
|
|
25136
25321
|
}
|
|
25137
25322
|
|
|
25138
|
-
var
|
|
25139
|
-
'fontFamily fontWeight fontSize text underline overline linethrough' +
|
|
25140
|
-
' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles path'.split(' ');
|
|
25323
|
+
var additionalProps =
|
|
25324
|
+
('fontFamily fontWeight fontSize text underline overline linethrough' +
|
|
25325
|
+
' textAlign fontStyle lineHeight textBackgroundColor charSpacing styles path').split(' ');
|
|
25141
25326
|
|
|
25142
25327
|
/**
|
|
25143
25328
|
* Text class
|
|
@@ -25297,13 +25482,13 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
25297
25482
|
* as well as for history (undo/redo) purposes
|
|
25298
25483
|
* @type Array
|
|
25299
25484
|
*/
|
|
25300
|
-
stateProperties: fabric.Object.prototype.stateProperties.concat(
|
|
25485
|
+
stateProperties: fabric.Object.prototype.stateProperties.concat(additionalProps),
|
|
25301
25486
|
|
|
25302
25487
|
/**
|
|
25303
25488
|
* List of properties to consider when checking if cache needs refresh
|
|
25304
25489
|
* @type Array
|
|
25305
25490
|
*/
|
|
25306
|
-
cacheProperties: fabric.Object.prototype.cacheProperties.concat(
|
|
25491
|
+
cacheProperties: fabric.Object.prototype.cacheProperties.concat(additionalProps),
|
|
25307
25492
|
|
|
25308
25493
|
/**
|
|
25309
25494
|
* When defined, an object is rendered via stroke and this property specifies its color.
|
|
@@ -25321,6 +25506,14 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
25321
25506
|
*/
|
|
25322
25507
|
shadow: null,
|
|
25323
25508
|
|
|
25509
|
+
/**
|
|
25510
|
+
* fabric.Path that the text can follow.
|
|
25511
|
+
* This feature is in BETA.
|
|
25512
|
+
* @type fabric.Path
|
|
25513
|
+
* @default
|
|
25514
|
+
*/
|
|
25515
|
+
path: null,
|
|
25516
|
+
|
|
25324
25517
|
/**
|
|
25325
25518
|
* @private
|
|
25326
25519
|
*/
|
|
@@ -25852,6 +26045,8 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
25852
26045
|
if (positionInPath > totalPathLength) {
|
|
25853
26046
|
positionInPath %= totalPathLength;
|
|
25854
26047
|
}
|
|
26048
|
+
// it would probably much fater to send all the grapheme position for a line
|
|
26049
|
+
// and calculate path position/angle at once.
|
|
25855
26050
|
this._setGraphemeOnPath(positionInPath, graphemeInfo, startingPoint);
|
|
25856
26051
|
}
|
|
25857
26052
|
lineBounds[i] = graphemeInfo;
|
|
@@ -25883,11 +26078,10 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
25883
26078
|
path = this.path;
|
|
25884
26079
|
|
|
25885
26080
|
// we are at currentPositionOnPath. we want to know what point on the path is.
|
|
25886
|
-
var
|
|
25887
|
-
|
|
25888
|
-
graphemeInfo.
|
|
25889
|
-
graphemeInfo.
|
|
25890
|
-
graphemeInfo.angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
|
|
26081
|
+
var info = fabric.util.getPointOnPath(path.path, centerPosition, path.segmentsInfo);
|
|
26082
|
+
graphemeInfo.renderLeft = info.x - startingPoint.x;
|
|
26083
|
+
graphemeInfo.renderTop = info.y - startingPoint.y;
|
|
26084
|
+
graphemeInfo.angle = info.angle;
|
|
25891
26085
|
},
|
|
25892
26086
|
|
|
25893
26087
|
/**
|
|
@@ -26427,13 +26621,15 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
26427
26621
|
(currentDecoration !== lastDecoration || currentFill !== lastFill || _size !== size || _dy !== dy)
|
|
26428
26622
|
&& boxWidth > 0
|
|
26429
26623
|
) {
|
|
26430
|
-
lastDecoration && lastFill
|
|
26624
|
+
if (lastDecoration && lastFill) {
|
|
26625
|
+
ctx.fillStyle = lastFill;
|
|
26431
26626
|
ctx.fillRect(
|
|
26432
26627
|
leftOffset + lineLeftOffset + boxStart,
|
|
26433
26628
|
top + this.offsets[type] * size + dy,
|
|
26434
26629
|
boxWidth,
|
|
26435
26630
|
this.fontSize / 15
|
|
26436
26631
|
);
|
|
26632
|
+
}
|
|
26437
26633
|
boxStart = charBox.left;
|
|
26438
26634
|
boxWidth = charBox.width;
|
|
26439
26635
|
lastDecoration = currentDecoration;
|
|
@@ -26536,9 +26732,11 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
26536
26732
|
'textAlign',
|
|
26537
26733
|
'textBackgroundColor',
|
|
26538
26734
|
'charSpacing',
|
|
26735
|
+
'path'
|
|
26539
26736
|
].concat(propertiesToInclude);
|
|
26540
26737
|
var obj = this.callSuper('toObject', additionalProperties);
|
|
26541
26738
|
obj.styles = clone(this.styles, true);
|
|
26739
|
+
obj.path = this.path && this.path.toObject();
|
|
26542
26740
|
return obj;
|
|
26543
26741
|
},
|
|
26544
26742
|
|
|
@@ -26694,11 +26892,23 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
26694
26892
|
* Returns fabric.Text instance from an object representation
|
|
26695
26893
|
* @static
|
|
26696
26894
|
* @memberOf fabric.Text
|
|
26697
|
-
* @param {Object} object Object to create an instance from
|
|
26895
|
+
* @param {Object} object plain js Object to create an instance from
|
|
26698
26896
|
* @param {Function} [callback] Callback to invoke when an fabric.Text instance is created
|
|
26699
26897
|
*/
|
|
26700
26898
|
fabric.Text.fromObject = function(object, callback) {
|
|
26701
|
-
|
|
26899
|
+
var objectCopy = clone(object), path = object.path;
|
|
26900
|
+
delete objectCopy.path;
|
|
26901
|
+
return fabric.Object._fromObject('Text', objectCopy, function(textInstance) {
|
|
26902
|
+
if (path) {
|
|
26903
|
+
fabric.Object._fromObject('Path', path, function(pathInstance) {
|
|
26904
|
+
textInstance.set('path', pathInstance);
|
|
26905
|
+
callback(textInstance);
|
|
26906
|
+
}, 'path');
|
|
26907
|
+
}
|
|
26908
|
+
else {
|
|
26909
|
+
callback(textInstance);
|
|
26910
|
+
}
|
|
26911
|
+
}, 'text');
|
|
26702
26912
|
};
|
|
26703
26913
|
|
|
26704
26914
|
fabric.Text.genericFonts = ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace'];
|
|
@@ -27507,8 +27717,9 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
|
|
|
27507
27717
|
* High level function to know the color of the cursor.
|
|
27508
27718
|
* the currentChar is the one that precedes the cursor
|
|
27509
27719
|
* Returns color (fill) of char at the current cursor
|
|
27510
|
-
*
|
|
27511
|
-
*
|
|
27720
|
+
* if the text object has a pattern or gradient for filler, it will return that.
|
|
27721
|
+
* Unused by the library, is for the end user
|
|
27722
|
+
* @return {String | fabric.Gradient | fabric.Pattern} Character color (fill)
|
|
27512
27723
|
*/
|
|
27513
27724
|
getCurrentCharColor: function() {
|
|
27514
27725
|
var cp = this._getCurrentCharIndex();
|