@nasser-sw/fabric 7.0.1-beta3 → 7.0.1-beta5
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/0 +0 -0
- package/dist/index.js +345 -162
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/index.min.mjs +1 -1
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +345 -162
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +345 -162
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +345 -162
- package/dist/index.node.mjs.map +1 -1
- package/dist/package.json.min.mjs +1 -1
- package/dist/package.json.mjs +1 -1
- package/dist/src/shapes/Line.d.ts +32 -86
- package/dist/src/shapes/Line.d.ts.map +1 -1
- package/dist/src/shapes/Line.min.mjs +1 -1
- package/dist/src/shapes/Line.min.mjs.map +1 -1
- package/dist/src/shapes/Line.mjs +345 -161
- package/dist/src/shapes/Line.mjs.map +1 -1
- package/dist-extensions/src/shapes/CustomLine.d.ts +10 -0
- package/dist-extensions/src/shapes/CustomLine.d.ts.map +1 -0
- package/dist-extensions/src/shapes/Line.d.ts +32 -86
- package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
- package/fabric-test-editor.html +157 -8
- package/fabric-test2.html +513 -0
- package/fabric.ts +182 -182
- package/package.json +1 -1
- package/src/shapes/Line.ts +397 -164
- package/debug/konva/CHANGELOG.md +0 -1474
- package/debug/konva/LICENSE +0 -22
- package/debug/konva/README.md +0 -205
- package/debug/konva/gulpfile.mjs +0 -110
- package/debug/konva/package.json +0 -139
- package/debug/konva/release.sh +0 -65
- package/debug/konva/resources/doc-includes/ContainerParams.txt +0 -6
- package/debug/konva/resources/doc-includes/NodeParams.txt +0 -20
- package/debug/konva/resources/doc-includes/ShapeParams.txt +0 -53
- package/debug/konva/resources/jsdoc.conf.json +0 -28
- package/debug/konva/rollup.config.mjs +0 -32
- package/debug/konva/src/Animation.ts +0 -237
- package/debug/konva/src/BezierFunctions.ts +0 -826
- package/debug/konva/src/Canvas.ts +0 -193
- package/debug/konva/src/Container.ts +0 -649
- package/debug/konva/src/Context.ts +0 -1017
- package/debug/konva/src/Core.ts +0 -5
- package/debug/konva/src/DragAndDrop.ts +0 -173
- package/debug/konva/src/Factory.ts +0 -246
- package/debug/konva/src/FastLayer.ts +0 -29
- package/debug/konva/src/Global.ts +0 -210
- package/debug/konva/src/Group.ts +0 -31
- package/debug/konva/src/Layer.ts +0 -546
- package/debug/konva/src/Node.ts +0 -3477
- package/debug/konva/src/PointerEvents.ts +0 -67
- package/debug/konva/src/Shape.ts +0 -2081
- package/debug/konva/src/Stage.ts +0 -1000
- package/debug/konva/src/Tween.ts +0 -811
- package/debug/konva/src/Util.ts +0 -1123
- package/debug/konva/src/Validators.ts +0 -210
- package/debug/konva/src/_CoreInternals.ts +0 -85
- package/debug/konva/src/_FullInternals.ts +0 -171
- package/debug/konva/src/canvas-backend.ts +0 -36
- package/debug/konva/src/filters/Blur.ts +0 -388
- package/debug/konva/src/filters/Brighten.ts +0 -48
- package/debug/konva/src/filters/Brightness.ts +0 -30
- package/debug/konva/src/filters/Contrast.ts +0 -75
- package/debug/konva/src/filters/Emboss.ts +0 -207
- package/debug/konva/src/filters/Enhance.ts +0 -154
- package/debug/konva/src/filters/Grayscale.ts +0 -25
- package/debug/konva/src/filters/HSL.ts +0 -108
- package/debug/konva/src/filters/HSV.ts +0 -106
- package/debug/konva/src/filters/Invert.ts +0 -23
- package/debug/konva/src/filters/Kaleidoscope.ts +0 -274
- package/debug/konva/src/filters/Mask.ts +0 -220
- package/debug/konva/src/filters/Noise.ts +0 -44
- package/debug/konva/src/filters/Pixelate.ts +0 -107
- package/debug/konva/src/filters/Posterize.ts +0 -46
- package/debug/konva/src/filters/RGB.ts +0 -82
- package/debug/konva/src/filters/RGBA.ts +0 -103
- package/debug/konva/src/filters/Sepia.ts +0 -27
- package/debug/konva/src/filters/Solarize.ts +0 -29
- package/debug/konva/src/filters/Threshold.ts +0 -44
- package/debug/konva/src/index.ts +0 -3
- package/debug/konva/src/shapes/Arc.ts +0 -176
- package/debug/konva/src/shapes/Arrow.ts +0 -231
- package/debug/konva/src/shapes/Circle.ts +0 -76
- package/debug/konva/src/shapes/Ellipse.ts +0 -121
- package/debug/konva/src/shapes/Image.ts +0 -319
- package/debug/konva/src/shapes/Label.ts +0 -386
- package/debug/konva/src/shapes/Line.ts +0 -364
- package/debug/konva/src/shapes/Path.ts +0 -1013
- package/debug/konva/src/shapes/Rect.ts +0 -79
- package/debug/konva/src/shapes/RegularPolygon.ts +0 -167
- package/debug/konva/src/shapes/Ring.ts +0 -94
- package/debug/konva/src/shapes/Sprite.ts +0 -370
- package/debug/konva/src/shapes/Star.ts +0 -125
- package/debug/konva/src/shapes/Text.ts +0 -1065
- package/debug/konva/src/shapes/TextPath.ts +0 -583
- package/debug/konva/src/shapes/Transformer.ts +0 -1889
- package/debug/konva/src/shapes/Wedge.ts +0 -129
- package/debug/konva/src/skia-backend.ts +0 -35
- package/debug/konva/src/types.ts +0 -84
- package/debug/konva/tsconfig.json +0 -31
- package/debug/konva/tsconfig.test.json +0 -7
package/dist/index.node.cjs
CHANGED
|
@@ -412,7 +412,7 @@ class Cache {
|
|
|
412
412
|
}
|
|
413
413
|
const cache = new Cache();
|
|
414
414
|
|
|
415
|
-
var version = "7.0.1-
|
|
415
|
+
var version = "7.0.1-beta5";
|
|
416
416
|
|
|
417
417
|
// use this syntax so babel plugin see this import here
|
|
418
418
|
const VERSION = version;
|
|
@@ -17629,33 +17629,29 @@ class PatternBrush extends PencilBrush {
|
|
|
17629
17629
|
}
|
|
17630
17630
|
}
|
|
17631
17631
|
|
|
17632
|
-
// @TODO this code is terrible and Line should be a special case of polyline.
|
|
17633
|
-
|
|
17634
17632
|
const coordProps = ['x1', 'x2', 'y1', 'y2'];
|
|
17635
|
-
/**
|
|
17636
|
-
* A Class to draw a line
|
|
17637
|
-
* A bunch of methods will be added to Polyline to handle the line case
|
|
17638
|
-
* The line class is very strange to work with, is all special, it hardly aligns
|
|
17639
|
-
* to what a developer want everytime there is an angle
|
|
17640
|
-
* @deprecated
|
|
17641
|
-
*/
|
|
17642
17633
|
class Line extends FabricObject {
|
|
17643
|
-
/**
|
|
17644
|
-
* Constructor
|
|
17645
|
-
* @param {Array} [points] Array of points
|
|
17646
|
-
* @param {Object} [options] Options object
|
|
17647
|
-
* @return {Line} thisArg
|
|
17648
|
-
*/
|
|
17649
17634
|
constructor() {
|
|
17650
|
-
let [x1, y1, x2, y2] = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0,
|
|
17635
|
+
let [x1, y1, x2, y2] = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0, 100, 0];
|
|
17651
17636
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17652
17637
|
super();
|
|
17653
|
-
|
|
17638
|
+
_defineProperty(this, "hitStrokeWidth", 'auto');
|
|
17639
|
+
_defineProperty(this, "_updatingEndpoints", false);
|
|
17640
|
+
_defineProperty(this, "_useEndpointCoords", true);
|
|
17654
17641
|
this.setOptions(options);
|
|
17655
17642
|
this.x1 = x1;
|
|
17656
17643
|
this.x2 = x2;
|
|
17657
17644
|
this.y1 = y1;
|
|
17658
17645
|
this.y2 = y2;
|
|
17646
|
+
if (options.hitStrokeWidth !== undefined) {
|
|
17647
|
+
this.hitStrokeWidth = options.hitStrokeWidth;
|
|
17648
|
+
}
|
|
17649
|
+
this.hasBorders = false;
|
|
17650
|
+
this.hasControls = true;
|
|
17651
|
+
this.selectable = true;
|
|
17652
|
+
this.hoverCursor = 'move';
|
|
17653
|
+
this.perPixelTargetFind = false;
|
|
17654
|
+
this.strokeLineCap = 'butt';
|
|
17659
17655
|
this._setWidthHeight();
|
|
17660
17656
|
const {
|
|
17661
17657
|
left,
|
|
@@ -17663,96 +17659,323 @@ class Line extends FabricObject {
|
|
|
17663
17659
|
} = options;
|
|
17664
17660
|
typeof left === 'number' && this.set(LEFT, left);
|
|
17665
17661
|
typeof top === 'number' && this.set(TOP, top);
|
|
17662
|
+
this._setupLineControls();
|
|
17663
|
+
}
|
|
17664
|
+
_setupLineControls() {
|
|
17665
|
+
this.controls = {
|
|
17666
|
+
p1: new Control({
|
|
17667
|
+
x: 0,
|
|
17668
|
+
y: 0,
|
|
17669
|
+
cursorStyle: 'move',
|
|
17670
|
+
actionHandler: this._endpointActionHandler.bind(this),
|
|
17671
|
+
positionHandler: this._p1PositionHandler.bind(this),
|
|
17672
|
+
render: this._renderEndpointControl.bind(this),
|
|
17673
|
+
sizeX: 12,
|
|
17674
|
+
sizeY: 12
|
|
17675
|
+
}),
|
|
17676
|
+
p2: new Control({
|
|
17677
|
+
x: 0,
|
|
17678
|
+
y: 0,
|
|
17679
|
+
cursorStyle: 'move',
|
|
17680
|
+
actionHandler: this._endpointActionHandler.bind(this),
|
|
17681
|
+
positionHandler: this._p2PositionHandler.bind(this),
|
|
17682
|
+
render: this._renderEndpointControl.bind(this),
|
|
17683
|
+
sizeX: 12,
|
|
17684
|
+
sizeY: 12
|
|
17685
|
+
})
|
|
17686
|
+
};
|
|
17687
|
+
}
|
|
17688
|
+
_p1PositionHandler() {
|
|
17689
|
+
var _this$canvas;
|
|
17690
|
+
const vpt = ((_this$canvas = this.canvas) === null || _this$canvas === void 0 ? void 0 : _this$canvas.viewportTransform) || [1, 0, 0, 1, 0, 0];
|
|
17691
|
+
return new Point(this.x1, this.y1).transform(vpt);
|
|
17692
|
+
}
|
|
17693
|
+
_p2PositionHandler() {
|
|
17694
|
+
var _this$canvas2;
|
|
17695
|
+
const vpt = ((_this$canvas2 = this.canvas) === null || _this$canvas2 === void 0 ? void 0 : _this$canvas2.viewportTransform) || [1, 0, 0, 1, 0, 0];
|
|
17696
|
+
return new Point(this.x2, this.y2).transform(vpt);
|
|
17697
|
+
}
|
|
17698
|
+
_renderEndpointControl(ctx, left, top) {
|
|
17699
|
+
const size = 12;
|
|
17700
|
+
ctx.save();
|
|
17701
|
+
ctx.fillStyle = '#007bff';
|
|
17702
|
+
ctx.strokeStyle = '#ffffff';
|
|
17703
|
+
ctx.lineWidth = 2;
|
|
17704
|
+
ctx.beginPath();
|
|
17705
|
+
ctx.arc(left, top, size / 2, 0, 2 * Math.PI);
|
|
17706
|
+
ctx.fill();
|
|
17707
|
+
ctx.stroke();
|
|
17708
|
+
ctx.restore();
|
|
17709
|
+
}
|
|
17710
|
+
drawBorders(ctx) {
|
|
17711
|
+
let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17712
|
+
if (this._useEndpointCoords) {
|
|
17713
|
+
this._drawLineBorders(ctx, styleOverride);
|
|
17714
|
+
return this;
|
|
17715
|
+
}
|
|
17716
|
+
return super.drawBorders(ctx, styleOverride, {});
|
|
17717
|
+
}
|
|
17718
|
+
_drawLineBorders(ctx) {
|
|
17719
|
+
var _this$canvas3;
|
|
17720
|
+
let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17721
|
+
const vpt = ((_this$canvas3 = this.canvas) === null || _this$canvas3 === void 0 ? void 0 : _this$canvas3.viewportTransform) || [1, 0, 0, 1, 0, 0];
|
|
17722
|
+
ctx.save();
|
|
17723
|
+
ctx.setTransform(vpt[0], vpt[1], vpt[2], vpt[3], vpt[4], vpt[5]);
|
|
17724
|
+
ctx.strokeStyle = styleOverride.borderColor || this.borderColor || 'rgba(100, 200, 200, 0.5)';
|
|
17725
|
+
ctx.lineWidth = (this.strokeWidth || 1) + 5;
|
|
17726
|
+
ctx.lineCap = this.strokeLineCap || 'butt';
|
|
17727
|
+
ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
|
|
17728
|
+
ctx.beginPath();
|
|
17729
|
+
ctx.moveTo(this.x1, this.y1);
|
|
17730
|
+
ctx.lineTo(this.x2, this.y2);
|
|
17731
|
+
ctx.stroke();
|
|
17732
|
+
ctx.restore();
|
|
17733
|
+
}
|
|
17734
|
+
_renderControls(ctx) {
|
|
17735
|
+
let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17736
|
+
ctx.save();
|
|
17737
|
+
ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;
|
|
17738
|
+
this.drawControls(ctx, styleOverride);
|
|
17739
|
+
ctx.restore();
|
|
17740
|
+
}
|
|
17741
|
+
getBoundingRect() {
|
|
17742
|
+
if (this._useEndpointCoords) {
|
|
17743
|
+
const {
|
|
17744
|
+
x1,
|
|
17745
|
+
y1,
|
|
17746
|
+
x2,
|
|
17747
|
+
y2
|
|
17748
|
+
} = this;
|
|
17749
|
+
const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;
|
|
17750
|
+
const padding = Math.max(effectiveStrokeWidth / 2 + 5, 10);
|
|
17751
|
+
return {
|
|
17752
|
+
left: Math.min(x1, x2) - padding,
|
|
17753
|
+
top: Math.min(y1, y2) - padding,
|
|
17754
|
+
width: Math.abs(x2 - x1) + padding * 2 || padding * 2,
|
|
17755
|
+
height: Math.abs(y2 - y1) + padding * 2 || padding * 2
|
|
17756
|
+
};
|
|
17757
|
+
}
|
|
17758
|
+
return super.getBoundingRect();
|
|
17666
17759
|
}
|
|
17760
|
+
setCoords() {
|
|
17761
|
+
if (this._useEndpointCoords) {
|
|
17762
|
+
// Set the object's center to the geometric center of the line
|
|
17763
|
+
const center = this._findCenterFromElement();
|
|
17764
|
+
this.left = center.x;
|
|
17765
|
+
this.top = center.y;
|
|
17766
|
+
|
|
17767
|
+
// Set width and height for hit detection and bounding box
|
|
17768
|
+
const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;
|
|
17769
|
+
const hitPadding = Math.max(effectiveStrokeWidth / 2 + 5, 10);
|
|
17770
|
+
this.width = Math.abs(this.x2 - this.x1) + hitPadding * 2;
|
|
17771
|
+
this.height = Math.abs(this.y2 - this.y1) + hitPadding * 2;
|
|
17772
|
+
}
|
|
17773
|
+
super.setCoords();
|
|
17774
|
+
}
|
|
17775
|
+
getCoords() {
|
|
17776
|
+
if (this._useEndpointCoords) {
|
|
17777
|
+
const deltaX = this.x2 - this.x1;
|
|
17778
|
+
const deltaY = this.y2 - this.y1;
|
|
17779
|
+
const length = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
17780
|
+
if (length === 0) {
|
|
17781
|
+
return super.getCoords();
|
|
17782
|
+
}
|
|
17783
|
+
const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth;
|
|
17784
|
+
const halfWidth = Math.max(effectiveStrokeWidth / 2 + 2, 5);
|
|
17667
17785
|
|
|
17668
|
-
|
|
17669
|
-
|
|
17670
|
-
|
|
17671
|
-
|
|
17672
|
-
|
|
17673
|
-
|
|
17674
|
-
|
|
17675
|
-
|
|
17676
|
-
x2,
|
|
17677
|
-
y2
|
|
17678
|
-
} = this;
|
|
17679
|
-
this.width = Math.abs(x2 - x1);
|
|
17680
|
-
this.height = Math.abs(y2 - y1);
|
|
17681
|
-
const {
|
|
17682
|
-
left,
|
|
17683
|
-
top,
|
|
17684
|
-
width,
|
|
17685
|
-
height
|
|
17686
|
-
} = makeBoundingBoxFromPoints([{
|
|
17687
|
-
x: x1,
|
|
17688
|
-
y: y1
|
|
17689
|
-
}, {
|
|
17690
|
-
x: x2,
|
|
17691
|
-
y: y2
|
|
17692
|
-
}]);
|
|
17693
|
-
const position = new Point(left + width / 2, top + height / 2);
|
|
17694
|
-
this.setPositionByOrigin(position, CENTER, CENTER);
|
|
17786
|
+
// Unit vector perpendicular to line
|
|
17787
|
+
const perpX = -deltaY / length;
|
|
17788
|
+
const perpY = deltaX / length;
|
|
17789
|
+
|
|
17790
|
+
// Four corners of oriented rectangle
|
|
17791
|
+
return [new Point(this.x1 + perpX * halfWidth, this.y1 + perpY * halfWidth), new Point(this.x2 + perpX * halfWidth, this.y2 + perpY * halfWidth), new Point(this.x2 - perpX * halfWidth, this.y2 - perpY * halfWidth), new Point(this.x1 - perpX * halfWidth, this.y1 - perpY * halfWidth)];
|
|
17792
|
+
}
|
|
17793
|
+
return super.getCoords();
|
|
17695
17794
|
}
|
|
17795
|
+
containsPoint(point) {
|
|
17796
|
+
if (this._useEndpointCoords) {
|
|
17797
|
+
var _this$canvas4;
|
|
17798
|
+
if (((_this$canvas4 = this.canvas) === null || _this$canvas4 === void 0 ? void 0 : _this$canvas4.getActiveObject()) === this) {
|
|
17799
|
+
return super.containsPoint(point);
|
|
17800
|
+
}
|
|
17801
|
+
const distance = this._distanceToLineSegment(point.x, point.y);
|
|
17802
|
+
const effectiveStrokeWidth = this.hitStrokeWidth === 'auto' ? this.strokeWidth : this.hitStrokeWidth || 1;
|
|
17803
|
+
const tolerance = Math.max(effectiveStrokeWidth / 2 + 2, 5);
|
|
17804
|
+
return distance <= tolerance;
|
|
17805
|
+
}
|
|
17806
|
+
return super.containsPoint(point);
|
|
17807
|
+
}
|
|
17808
|
+
_distanceToLineSegment(px, py) {
|
|
17809
|
+
const x1 = this.x1,
|
|
17810
|
+
y1 = this.y1,
|
|
17811
|
+
x2 = this.x2,
|
|
17812
|
+
y2 = this.y2;
|
|
17813
|
+
const pd2 = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
|
|
17814
|
+
if (pd2 === 0) {
|
|
17815
|
+
return Math.sqrt((px - x1) * (px - x1) + (py - y1) * (py - y1));
|
|
17816
|
+
}
|
|
17817
|
+
const u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / pd2;
|
|
17818
|
+
let closestX, closestY;
|
|
17819
|
+
if (u < 0) {
|
|
17820
|
+
closestX = x1;
|
|
17821
|
+
closestY = y1;
|
|
17822
|
+
} else if (u > 1) {
|
|
17823
|
+
closestX = x2;
|
|
17824
|
+
closestY = y2;
|
|
17825
|
+
} else {
|
|
17826
|
+
closestX = x1 + u * (x2 - x1);
|
|
17827
|
+
closestY = y1 + u * (y2 - y1);
|
|
17828
|
+
}
|
|
17829
|
+
return Math.sqrt((px - closestX) * (px - closestX) + (py - closestY) * (py - closestY));
|
|
17830
|
+
}
|
|
17831
|
+
_endpointActionHandler(eventData, transformData, x, y) {
|
|
17832
|
+
var _this$canvas6;
|
|
17833
|
+
const controlKey = transformData.corner;
|
|
17834
|
+
const pointer = new Point(x, y);
|
|
17835
|
+
let newX = pointer.x;
|
|
17836
|
+
let newY = pointer.y;
|
|
17837
|
+
if (eventData.shiftKey) {
|
|
17838
|
+
const otherControl = controlKey === 'p1' ? 'p2' : 'p1';
|
|
17839
|
+
const otherX = this[otherControl === 'p1' ? 'x1' : 'x2'];
|
|
17840
|
+
const otherY = this[otherControl === 'p1' ? 'y1' : 'y2'];
|
|
17841
|
+
const snapped = this._snapToAngle(otherX, otherY, newX, newY);
|
|
17842
|
+
newX = snapped.x;
|
|
17843
|
+
newY = snapped.y;
|
|
17844
|
+
}
|
|
17845
|
+
if (this._useEndpointCoords) {
|
|
17846
|
+
var _this$canvas5;
|
|
17847
|
+
if (controlKey === 'p1') {
|
|
17848
|
+
this.x1 = newX;
|
|
17849
|
+
this.y1 = newY;
|
|
17850
|
+
} else if (controlKey === 'p2') {
|
|
17851
|
+
this.x2 = newX;
|
|
17852
|
+
this.y2 = newY;
|
|
17853
|
+
}
|
|
17854
|
+
this.dirty = true;
|
|
17855
|
+
this.setCoords();
|
|
17856
|
+
(_this$canvas5 = this.canvas) === null || _this$canvas5 === void 0 || _this$canvas5.requestRenderAll();
|
|
17857
|
+
return true;
|
|
17858
|
+
}
|
|
17696
17859
|
|
|
17697
|
-
|
|
17698
|
-
|
|
17699
|
-
|
|
17700
|
-
|
|
17701
|
-
|
|
17860
|
+
// Fallback for old system
|
|
17861
|
+
this._updatingEndpoints = true;
|
|
17862
|
+
if (controlKey === 'p1') {
|
|
17863
|
+
this.x1 = newX;
|
|
17864
|
+
this.y1 = newY;
|
|
17865
|
+
} else if (controlKey === 'p2') {
|
|
17866
|
+
this.x2 = newX;
|
|
17867
|
+
this.y2 = newY;
|
|
17868
|
+
}
|
|
17869
|
+
this._setWidthHeight();
|
|
17870
|
+
this.dirty = true;
|
|
17871
|
+
this._updatingEndpoints = false;
|
|
17872
|
+
(_this$canvas6 = this.canvas) === null || _this$canvas6 === void 0 || _this$canvas6.requestRenderAll();
|
|
17873
|
+
this.fire('modified', {
|
|
17874
|
+
transform: transformData,
|
|
17875
|
+
target: this,
|
|
17876
|
+
e: eventData
|
|
17877
|
+
});
|
|
17878
|
+
return true;
|
|
17879
|
+
}
|
|
17880
|
+
_snapToAngle(fromX, fromY, toX, toY) {
|
|
17881
|
+
const deltaX = toX - fromX;
|
|
17882
|
+
const deltaY = toY - fromY;
|
|
17883
|
+
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
17884
|
+
if (distance === 0) return {
|
|
17885
|
+
x: toX,
|
|
17886
|
+
y: toY
|
|
17887
|
+
};
|
|
17888
|
+
let angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
|
|
17889
|
+
const snapIncrement = 15;
|
|
17890
|
+
const snappedAngle = Math.round(angle / snapIncrement) * snapIncrement;
|
|
17891
|
+
const snappedRadians = snappedAngle * (Math.PI / 180);
|
|
17892
|
+
return {
|
|
17893
|
+
x: fromX + Math.cos(snappedRadians) * distance,
|
|
17894
|
+
y: fromY + Math.sin(snappedRadians) * distance
|
|
17895
|
+
};
|
|
17896
|
+
}
|
|
17897
|
+
_setWidthHeight() {
|
|
17898
|
+
let skipReposition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
17899
|
+
this.width = Math.abs(this.x2 - this.x1) || 1;
|
|
17900
|
+
this.height = Math.abs(this.y2 - this.y1) || 1;
|
|
17901
|
+
if (!skipReposition && !this._updatingEndpoints) {
|
|
17902
|
+
const {
|
|
17903
|
+
left,
|
|
17904
|
+
top,
|
|
17905
|
+
width,
|
|
17906
|
+
height
|
|
17907
|
+
} = makeBoundingBoxFromPoints([{
|
|
17908
|
+
x: this.x1,
|
|
17909
|
+
y: this.y1
|
|
17910
|
+
}, {
|
|
17911
|
+
x: this.x2,
|
|
17912
|
+
y: this.y2
|
|
17913
|
+
}]);
|
|
17914
|
+
this.setPositionByOrigin(new Point(left + width / 2, top + height / 2), CENTER, CENTER);
|
|
17915
|
+
}
|
|
17916
|
+
}
|
|
17702
17917
|
_set(key, value) {
|
|
17918
|
+
const oldLeft = this.left;
|
|
17919
|
+
const oldTop = this.top;
|
|
17703
17920
|
super._set(key, value);
|
|
17704
17921
|
if (coordProps.includes(key)) {
|
|
17705
|
-
// this doesn't make sense very much, since setting x1 when top or left
|
|
17706
|
-
// are already set, is just going to show a strange result since the
|
|
17707
|
-
// line will move way more than the developer expect.
|
|
17708
|
-
// in fabric5 it worked only when the line didn't have extra transformations,
|
|
17709
|
-
// in fabric6 too. With extra transform they behave bad in different ways.
|
|
17710
|
-
// This needs probably a good rework or a tutorial if you have to create a dynamic line
|
|
17711
17922
|
this._setWidthHeight();
|
|
17923
|
+
this.dirty = true;
|
|
17924
|
+
}
|
|
17925
|
+
if ((key === 'left' || key === 'top') && this.canvas && !this._updatingEndpoints) {
|
|
17926
|
+
const deltaX = this.left - oldLeft;
|
|
17927
|
+
const deltaY = this.top - oldTop;
|
|
17928
|
+
if (deltaX !== 0 || deltaY !== 0) {
|
|
17929
|
+
this._updatingEndpoints = true;
|
|
17930
|
+
this.x1 += deltaX;
|
|
17931
|
+
this.y1 += deltaY;
|
|
17932
|
+
this.x2 += deltaX;
|
|
17933
|
+
this.y2 += deltaY;
|
|
17934
|
+
this._updatingEndpoints = false;
|
|
17935
|
+
}
|
|
17712
17936
|
}
|
|
17713
17937
|
return this;
|
|
17714
17938
|
}
|
|
17715
|
-
|
|
17716
|
-
|
|
17717
|
-
|
|
17718
|
-
|
|
17719
|
-
|
|
17939
|
+
render(ctx) {
|
|
17940
|
+
if (this._useEndpointCoords) {
|
|
17941
|
+
this._renderDirectly(ctx);
|
|
17942
|
+
return;
|
|
17943
|
+
}
|
|
17944
|
+
super.render(ctx);
|
|
17945
|
+
}
|
|
17946
|
+
_renderDirectly(ctx) {
|
|
17947
|
+
var _this$canvas7, _this$stroke;
|
|
17948
|
+
if (!this.visible) return;
|
|
17949
|
+
ctx.save();
|
|
17950
|
+
const vpt = ((_this$canvas7 = this.canvas) === null || _this$canvas7 === void 0 ? void 0 : _this$canvas7.viewportTransform) || [1, 0, 0, 1, 0, 0];
|
|
17951
|
+
ctx.transform(vpt[0], vpt[1], vpt[2], vpt[3], vpt[4], vpt[5]);
|
|
17952
|
+
ctx.globalAlpha = this.opacity;
|
|
17953
|
+
ctx.strokeStyle = ((_this$stroke = this.stroke) === null || _this$stroke === void 0 ? void 0 : _this$stroke.toString()) || '#000';
|
|
17954
|
+
ctx.lineWidth = this.strokeWidth;
|
|
17955
|
+
ctx.lineCap = this.strokeLineCap || 'butt';
|
|
17956
|
+
ctx.beginPath();
|
|
17957
|
+
ctx.moveTo(this.x1, this.y1);
|
|
17958
|
+
ctx.lineTo(this.x2, this.y2);
|
|
17959
|
+
ctx.stroke();
|
|
17960
|
+
ctx.restore();
|
|
17961
|
+
}
|
|
17720
17962
|
_render(ctx) {
|
|
17963
|
+
if (this._useEndpointCoords) return;
|
|
17721
17964
|
ctx.beginPath();
|
|
17722
17965
|
const p = this.calcLinePoints();
|
|
17723
17966
|
ctx.moveTo(p.x1, p.y1);
|
|
17724
17967
|
ctx.lineTo(p.x2, p.y2);
|
|
17725
17968
|
ctx.lineWidth = this.strokeWidth;
|
|
17726
|
-
|
|
17727
|
-
// TODO: test this
|
|
17728
|
-
// make sure setting "fill" changes color of a line
|
|
17729
|
-
// (by copying fillStyle to strokeStyle, since line is stroked, not filled)
|
|
17730
17969
|
const origStrokeStyle = ctx.strokeStyle;
|
|
17731
17970
|
if (isFiller(this.stroke)) {
|
|
17732
17971
|
ctx.strokeStyle = this.stroke.toLive(ctx);
|
|
17733
|
-
} else {
|
|
17734
|
-
var _this$stroke;
|
|
17735
|
-
ctx.strokeStyle = (_this$stroke = this.stroke) !== null && _this$stroke !== void 0 ? _this$stroke : ctx.fillStyle;
|
|
17736
17972
|
}
|
|
17737
17973
|
this.stroke && this._renderStroke(ctx);
|
|
17738
17974
|
ctx.strokeStyle = origStrokeStyle;
|
|
17739
17975
|
}
|
|
17740
|
-
|
|
17741
|
-
/**
|
|
17742
|
-
* This function is an helper for svg import. it returns the center of the object in the svg
|
|
17743
|
-
* untransformed coordinates
|
|
17744
|
-
* @private
|
|
17745
|
-
* @return {Point} center point from element coordinates
|
|
17746
|
-
*/
|
|
17747
17976
|
_findCenterFromElement() {
|
|
17748
17977
|
return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);
|
|
17749
17978
|
}
|
|
17750
|
-
|
|
17751
|
-
/**
|
|
17752
|
-
* Returns object representation of an instance
|
|
17753
|
-
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
|
17754
|
-
* @return {Object} object representation of an instance
|
|
17755
|
-
*/
|
|
17756
17979
|
toObject() {
|
|
17757
17980
|
let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
17758
17981
|
return {
|
|
@@ -17760,32 +17983,25 @@ class Line extends FabricObject {
|
|
|
17760
17983
|
...this.calcLinePoints()
|
|
17761
17984
|
};
|
|
17762
17985
|
}
|
|
17763
|
-
|
|
17764
|
-
/*
|
|
17765
|
-
* Calculate object dimensions from its properties
|
|
17766
|
-
* @private
|
|
17767
|
-
*/
|
|
17768
17986
|
_getNonTransformedDimensions() {
|
|
17769
17987
|
const dim = super._getNonTransformedDimensions();
|
|
17770
|
-
if (this.strokeLineCap === '
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
}
|
|
17774
|
-
if (this.height === 0) {
|
|
17775
|
-
dim.x -= this.strokeWidth;
|
|
17776
|
-
}
|
|
17988
|
+
if (this.strokeLineCap === 'round') {
|
|
17989
|
+
dim.x += this.strokeWidth;
|
|
17990
|
+
dim.y += this.strokeWidth;
|
|
17777
17991
|
}
|
|
17778
17992
|
return dim;
|
|
17779
17993
|
}
|
|
17780
|
-
|
|
17781
|
-
/**
|
|
17782
|
-
* Recalculates line points given width and height
|
|
17783
|
-
* Those points are simply placed around the center,
|
|
17784
|
-
* This is not useful outside internal render functions and svg output
|
|
17785
|
-
* Is not meant to be for the developer.
|
|
17786
|
-
* @private
|
|
17787
|
-
*/
|
|
17788
17994
|
calcLinePoints() {
|
|
17995
|
+
if (this._updatingEndpoints) {
|
|
17996
|
+
const centerX = (this.x1 + this.x2) / 2;
|
|
17997
|
+
const centerY = (this.y1 + this.y2) / 2;
|
|
17998
|
+
return {
|
|
17999
|
+
x1: this.x1 - centerX,
|
|
18000
|
+
y1: this.y1 - centerY,
|
|
18001
|
+
x2: this.x2 - centerX,
|
|
18002
|
+
y2: this.y2 - centerY
|
|
18003
|
+
};
|
|
18004
|
+
}
|
|
17789
18005
|
const {
|
|
17790
18006
|
x1: _x1,
|
|
17791
18007
|
x2: _x2,
|
|
@@ -17794,48 +18010,39 @@ class Line extends FabricObject {
|
|
|
17794
18010
|
width,
|
|
17795
18011
|
height
|
|
17796
18012
|
} = this;
|
|
17797
|
-
const xMult = _x1 <= _x2 ? -1 : 1
|
|
17798
|
-
|
|
17799
|
-
x1 = xMult * width / 2,
|
|
17800
|
-
y1 = yMult * height / 2,
|
|
17801
|
-
x2 = xMult * -width / 2,
|
|
17802
|
-
y2 = yMult * -height / 2;
|
|
18013
|
+
const xMult = _x1 <= _x2 ? -1 : 1;
|
|
18014
|
+
const yMult = _y1 <= _y2 ? -1 : 1;
|
|
17803
18015
|
return {
|
|
17804
|
-
x1,
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
y2
|
|
18016
|
+
x1: xMult * width / 2,
|
|
18017
|
+
y1: yMult * height / 2,
|
|
18018
|
+
x2: xMult * -width / 2,
|
|
18019
|
+
y2: yMult * -height / 2
|
|
17808
18020
|
};
|
|
17809
18021
|
}
|
|
17810
|
-
|
|
17811
|
-
/* _FROM_SVG_START_ */
|
|
17812
|
-
|
|
17813
|
-
/**
|
|
17814
|
-
* Returns svg representation of an instance
|
|
17815
|
-
* @return {Array} an array of strings with the specific svg representation
|
|
17816
|
-
* of the instance
|
|
17817
|
-
*/
|
|
17818
18022
|
_toSVG() {
|
|
17819
|
-
|
|
17820
|
-
|
|
17821
|
-
x2
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
|
|
17825
|
-
|
|
18023
|
+
if (this._useEndpointCoords) {
|
|
18024
|
+
// Use absolute coordinates to bypass all Fabric.js transforms
|
|
18025
|
+
return [`<line stroke="${this.stroke}" stroke-width="${this.strokeWidth}" stroke-linecap="${this.strokeLineCap}" `, `x1="${this.x1}" y1="${this.y1}" x2="${this.x2}" y2="${this.y2}" />\n`];
|
|
18026
|
+
} else {
|
|
18027
|
+
// Use standard calcLinePoints for legacy mode
|
|
18028
|
+
const {
|
|
18029
|
+
x1,
|
|
18030
|
+
x2,
|
|
18031
|
+
y1,
|
|
18032
|
+
y2
|
|
18033
|
+
} = this.calcLinePoints();
|
|
18034
|
+
return ['<line ', 'COMMON_PARTS', `x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" />\n`];
|
|
18035
|
+
}
|
|
18036
|
+
}
|
|
18037
|
+
toSVG(reviver) {
|
|
18038
|
+
if (this._useEndpointCoords) {
|
|
18039
|
+
// Override toSVG to prevent Fabric.js from adding transform wrapper
|
|
18040
|
+
const markup = this._toSVG().join('');
|
|
18041
|
+
return reviver ? reviver(markup) : markup;
|
|
18042
|
+
}
|
|
18043
|
+
// Use default behavior for legacy mode
|
|
18044
|
+
return super.toSVG(reviver);
|
|
17826
18045
|
}
|
|
17827
|
-
|
|
17828
|
-
/**
|
|
17829
|
-
* List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})
|
|
17830
|
-
* @see http://www.w3.org/TR/SVG/shapes.html#LineElement
|
|
17831
|
-
*/
|
|
17832
|
-
|
|
17833
|
-
/**
|
|
17834
|
-
* Returns Line instance from an SVG element
|
|
17835
|
-
* @param {HTMLElement} element Element to parse
|
|
17836
|
-
* @param {Object} [options] Options object
|
|
17837
|
-
* @param {Function} [callback] callback function invoked after parsing
|
|
17838
|
-
*/
|
|
17839
18046
|
static async fromElement(element, options, cssRules) {
|
|
17840
18047
|
const {
|
|
17841
18048
|
x1 = 0,
|
|
@@ -17846,14 +18053,6 @@ class Line extends FabricObject {
|
|
|
17846
18053
|
} = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);
|
|
17847
18054
|
return new this([x1, y1, x2, y2], parsedAttributes);
|
|
17848
18055
|
}
|
|
17849
|
-
|
|
17850
|
-
/* _FROM_SVG_END_ */
|
|
17851
|
-
|
|
17852
|
-
/**
|
|
17853
|
-
* Returns Line instance from an object representation
|
|
17854
|
-
* @param {Object} object Object to create an instance from
|
|
17855
|
-
* @returns {Promise<Line>}
|
|
17856
|
-
*/
|
|
17857
18056
|
static fromObject(_ref) {
|
|
17858
18057
|
let {
|
|
17859
18058
|
x1,
|
|
@@ -17870,22 +18069,6 @@ class Line extends FabricObject {
|
|
|
17870
18069
|
});
|
|
17871
18070
|
}
|
|
17872
18071
|
}
|
|
17873
|
-
/**
|
|
17874
|
-
* x value or first line edge
|
|
17875
|
-
* @type number
|
|
17876
|
-
*/
|
|
17877
|
-
/**
|
|
17878
|
-
* y value or first line edge
|
|
17879
|
-
* @type number
|
|
17880
|
-
*/
|
|
17881
|
-
/**
|
|
17882
|
-
* x value or second line edge
|
|
17883
|
-
* @type number
|
|
17884
|
-
*/
|
|
17885
|
-
/**
|
|
17886
|
-
* y value or second line edge
|
|
17887
|
-
* @type number
|
|
17888
|
-
*/
|
|
17889
18072
|
_defineProperty(Line, "type", 'Line');
|
|
17890
18073
|
_defineProperty(Line, "cacheProperties", [...cacheProperties, ...coordProps]);
|
|
17891
18074
|
_defineProperty(Line, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat(coordProps));
|