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
|
@@ -676,7 +676,10 @@
|
|
|
676
676
|
* @chainable true
|
|
677
677
|
*/
|
|
678
678
|
setViewportTransform: function (vpt) {
|
|
679
|
-
var activeObject = this._activeObject,
|
|
679
|
+
var activeObject = this._activeObject,
|
|
680
|
+
backgroundObject = this.backgroundImage,
|
|
681
|
+
overlayObject = this.overlayImage,
|
|
682
|
+
object, i, len;
|
|
680
683
|
this.viewportTransform = vpt;
|
|
681
684
|
for (i = 0, len = this._objects.length; i < len; i++) {
|
|
682
685
|
object = this._objects[i];
|
|
@@ -685,6 +688,12 @@
|
|
|
685
688
|
if (activeObject) {
|
|
686
689
|
activeObject.setCoords();
|
|
687
690
|
}
|
|
691
|
+
if (backgroundObject) {
|
|
692
|
+
backgroundObject.setCoords(true);
|
|
693
|
+
}
|
|
694
|
+
if (overlayObject) {
|
|
695
|
+
overlayObject.setCoords(true);
|
|
696
|
+
}
|
|
688
697
|
this.calcViewportBoundaries();
|
|
689
698
|
this.renderOnAddRemove && this.requestRenderAll();
|
|
690
699
|
return this;
|
package/src/util/misc.js
CHANGED
|
@@ -969,6 +969,59 @@
|
|
|
969
969
|
}).join(' ') + ')';
|
|
970
970
|
},
|
|
971
971
|
|
|
972
|
+
/**
|
|
973
|
+
* given an object and a transform, apply the inverse transform to the object,
|
|
974
|
+
* this is equivalent to remove from that object that transformation, so that
|
|
975
|
+
* added in a space with the removed transform, the object will be the same as before.
|
|
976
|
+
* Removing from an object a transform that scale by 2 is like scaling it by 1/2.
|
|
977
|
+
* Removing from an object a transfrom that rotate by 30deg is like rotating by 30deg
|
|
978
|
+
* in the opposite direction.
|
|
979
|
+
* This util is used to add objects inside transformed groups or nested groups.
|
|
980
|
+
* @memberOf fabric.util
|
|
981
|
+
* @param {fabric.Object} object the object you want to transform
|
|
982
|
+
* @param {Array} transform the destination transform
|
|
983
|
+
*/
|
|
984
|
+
removeTransformFromObject: function(object, transform) {
|
|
985
|
+
var inverted = fabric.util.invertTransform(transform),
|
|
986
|
+
finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix());
|
|
987
|
+
fabric.util.applyTransformToObject(object, finalTransform);
|
|
988
|
+
},
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* given an object and a transform, apply the transform to the object.
|
|
992
|
+
* this is equivalent to change the space where the object is drawn.
|
|
993
|
+
* Adding to an object a transform that scale by 2 is like scaling it by 2.
|
|
994
|
+
* This is used when removing an object from an active selection for example.
|
|
995
|
+
* @memberOf fabric.util
|
|
996
|
+
* @param {fabric.Object} object the object you want to transform
|
|
997
|
+
* @param {Array} transform the destination transform
|
|
998
|
+
*/
|
|
999
|
+
addTransformToObject: function(object, transform) {
|
|
1000
|
+
fabric.util.applyTransformToObject(
|
|
1001
|
+
object,
|
|
1002
|
+
fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix())
|
|
1003
|
+
);
|
|
1004
|
+
},
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* discard an object transform state and apply the one from the matrix.
|
|
1008
|
+
* @memberOf fabric.util
|
|
1009
|
+
* @param {fabric.Object} object the object you want to transform
|
|
1010
|
+
* @param {Array} transform the destination transform
|
|
1011
|
+
*/
|
|
1012
|
+
applyTransformToObject: function(object, transform) {
|
|
1013
|
+
var options = fabric.util.qrDecompose(transform),
|
|
1014
|
+
center = new fabric.Point(options.translateX, options.translateY);
|
|
1015
|
+
object.flipX = false;
|
|
1016
|
+
object.flipY = false;
|
|
1017
|
+
object.set('scaleX', options.scaleX);
|
|
1018
|
+
object.set('scaleY', options.scaleY);
|
|
1019
|
+
object.skewX = options.skewX;
|
|
1020
|
+
object.skewY = options.skewY;
|
|
1021
|
+
object.angle = options.angle;
|
|
1022
|
+
object.setPositionByOrigin(center, 'center', 'center');
|
|
1023
|
+
},
|
|
1024
|
+
|
|
972
1025
|
/**
|
|
973
1026
|
* given a width and height, return the size of the bounding box
|
|
974
1027
|
* that can contains the box with width/height with applied transform
|
package/src/util/path.js
CHANGED
|
@@ -439,6 +439,17 @@
|
|
|
439
439
|
};
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
+
function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) {
|
|
443
|
+
return function (pct) {
|
|
444
|
+
var invT = 1 - pct,
|
|
445
|
+
tangentX = (3 * invT * invT * (p2x - p1x)) + (6 * invT * pct * (p3x - p2x)) +
|
|
446
|
+
(3 * pct * pct * (p4x - p3x)),
|
|
447
|
+
tangentY = (3 * invT * invT * (p2y - p1y)) + (6 * invT * pct * (p3y - p2y)) +
|
|
448
|
+
(3 * pct * pct * (p4y - p3y));
|
|
449
|
+
return Math.atan2(tangentY, tangentX);
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
|
|
442
453
|
function QB1(t) {
|
|
443
454
|
return t * t;
|
|
444
455
|
}
|
|
@@ -461,6 +472,16 @@
|
|
|
461
472
|
};
|
|
462
473
|
}
|
|
463
474
|
|
|
475
|
+
function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
476
|
+
return function (pct) {
|
|
477
|
+
var invT = 1 - pct,
|
|
478
|
+
tangentX = (2 * invT * (p2x - p1x)) + (2 * pct * (p3x - p2x)),
|
|
479
|
+
tangentY = (2 * invT * (p2y - p1y)) + (2 * pct * (p3y - p2y));
|
|
480
|
+
return Math.atan2(tangentY, tangentX);
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
|
|
464
485
|
// this will run over a path segment ( a cubic or quadratic segment) and approximate it
|
|
465
486
|
// with 100 segemnts. This will good enough to calculate the length of the curve
|
|
466
487
|
function pathIterator(iterator, x1, y1) {
|
|
@@ -479,15 +500,16 @@
|
|
|
479
500
|
* The percentage will be then used to find the correct point on the canvas for the path.
|
|
480
501
|
* @param {Array} segInfo fabricJS collection of information on a parsed path
|
|
481
502
|
* @param {Number} distance from starting point, in pixels.
|
|
482
|
-
* @return {
|
|
503
|
+
* @return {Object} info object with x and y ( the point on canvas ) and angle, the tangent on that point;
|
|
483
504
|
*/
|
|
484
505
|
function findPercentageForDistance(segInfo, distance) {
|
|
485
506
|
var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y },
|
|
486
|
-
p, nextLen, nextStep = 0.01;
|
|
507
|
+
p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc;
|
|
487
508
|
// nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100
|
|
488
509
|
// the path
|
|
489
510
|
while (tmpLen < distance && perc <= 1 && nextStep > 0.0001) {
|
|
490
511
|
p = iterator(perc);
|
|
512
|
+
lastPerc = perc;
|
|
491
513
|
nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);
|
|
492
514
|
// compare tmpLen each cycle with distance, decide next perc to test.
|
|
493
515
|
if ((nextLen + tmpLen) > distance) {
|
|
@@ -501,6 +523,7 @@
|
|
|
501
523
|
tmpLen += nextLen;
|
|
502
524
|
}
|
|
503
525
|
}
|
|
526
|
+
p.angle = angleFinder(lastPerc);
|
|
504
527
|
return p;
|
|
505
528
|
}
|
|
506
529
|
|
|
@@ -514,7 +537,7 @@
|
|
|
514
537
|
var totalLength = 0, len = path.length, current,
|
|
515
538
|
//x2 and y2 are the coords of segment start
|
|
516
539
|
//x1 and y1 are the coords of the current point
|
|
517
|
-
x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo;
|
|
540
|
+
x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder;
|
|
518
541
|
for (var i = 0; i < len; i++) {
|
|
519
542
|
current = path[i];
|
|
520
543
|
tempInfo = {
|
|
@@ -544,7 +567,18 @@
|
|
|
544
567
|
current[5],
|
|
545
568
|
current[6]
|
|
546
569
|
);
|
|
570
|
+
angleFinder = getTangentCubicIterator(
|
|
571
|
+
x1,
|
|
572
|
+
y1,
|
|
573
|
+
current[1],
|
|
574
|
+
current[2],
|
|
575
|
+
current[3],
|
|
576
|
+
current[4],
|
|
577
|
+
current[5],
|
|
578
|
+
current[6]
|
|
579
|
+
);
|
|
547
580
|
tempInfo.iterator = iterator;
|
|
581
|
+
tempInfo.angleFinder = angleFinder;
|
|
548
582
|
tempInfo.length = pathIterator(iterator, x1, y1);
|
|
549
583
|
x1 = current[5];
|
|
550
584
|
y1 = current[6];
|
|
@@ -558,7 +592,16 @@
|
|
|
558
592
|
current[3],
|
|
559
593
|
current[4]
|
|
560
594
|
);
|
|
595
|
+
angleFinder = getTangentQuadraticIterator(
|
|
596
|
+
x1,
|
|
597
|
+
y1,
|
|
598
|
+
current[1],
|
|
599
|
+
current[2],
|
|
600
|
+
current[3],
|
|
601
|
+
current[4]
|
|
602
|
+
);
|
|
561
603
|
tempInfo.iterator = iterator;
|
|
604
|
+
tempInfo.angleFinder = angleFinder;
|
|
562
605
|
tempInfo.length = pathIterator(iterator, x1, y1);
|
|
563
606
|
x1 = current[3];
|
|
564
607
|
y1 = current[4];
|
|
@@ -584,29 +627,33 @@
|
|
|
584
627
|
if (!infos) {
|
|
585
628
|
infos = getPathSegmentsInfo(path);
|
|
586
629
|
}
|
|
587
|
-
// var distance = infos[infos.length - 1] * perc;
|
|
588
630
|
var i = 0;
|
|
589
631
|
while ((distance - infos[i].length > 0) && i < (infos.length - 2)) {
|
|
590
632
|
distance -= infos[i].length;
|
|
591
633
|
i++;
|
|
592
634
|
}
|
|
635
|
+
// var distance = infos[infos.length - 1] * perc;
|
|
593
636
|
var segInfo = infos[i], segPercent = distance / segInfo.length,
|
|
594
|
-
command = segInfo.command, segment = path[i];
|
|
637
|
+
command = segInfo.command, segment = path[i], info;
|
|
595
638
|
|
|
596
639
|
switch (command) {
|
|
597
640
|
case 'M':
|
|
598
|
-
return { x: segInfo.x, y: segInfo.y };
|
|
641
|
+
return { x: segInfo.x, y: segInfo.y, angle: 0 };
|
|
599
642
|
case 'Z':
|
|
600
643
|
case 'z':
|
|
601
|
-
|
|
644
|
+
info = new fabric.Point(segInfo.x, segInfo.y).lerp(
|
|
602
645
|
new fabric.Point(segInfo.destX, segInfo.destY),
|
|
603
646
|
segPercent
|
|
604
647
|
);
|
|
648
|
+
info.angle = Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x);
|
|
649
|
+
return info;
|
|
605
650
|
case 'L':
|
|
606
|
-
|
|
651
|
+
info = new fabric.Point(segInfo.x, segInfo.y).lerp(
|
|
607
652
|
new fabric.Point(segment[1], segment[2]),
|
|
608
653
|
segPercent
|
|
609
654
|
);
|
|
655
|
+
info.angle = Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x);
|
|
656
|
+
return info;
|
|
610
657
|
case 'C':
|
|
611
658
|
return findPercentageForDistance(segInfo, distance);
|
|
612
659
|
case 'Q':
|