fabric 6.0.0-beta7 → 6.0.0-beta8
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 +11 -0
- package/dist/fabric.d.ts +3 -0
- package/dist/index.js +405 -399
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.mjs +404 -400
- package/dist/index.mjs.map +1 -1
- package/dist/index.node.cjs +407 -413
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.d.ts +0 -2
- package/dist/index.node.mjs +406 -414
- package/dist/index.node.mjs.map +1 -1
- package/dist/src/canvas/DOMManagers/CanvasDOMManager.d.ts +29 -0
- package/dist/src/canvas/DOMManagers/StaticCanvasDOMManager.d.ts +29 -0
- package/dist/src/canvas/DOMManagers/util.d.ts +24 -0
- package/dist/src/canvas/DOMManagers/util.spec.d.ts +1 -0
- package/dist/src/canvas/SelectableCanvas.d.ts +9 -33
- package/dist/src/canvas/StaticCanvas.d.ts +12 -38
- package/dist/src/constants.d.ts +1 -0
- package/dist/src/shapes/IText/ITextClickBehavior.d.ts +0 -7
- package/dist/src/util/dom_misc.d.ts +0 -29
- package/dist/src/util/index.d.ts +0 -2
- package/fabric.ts +6 -0
- package/index.node.ts +3 -15
- package/package.json +1 -1
- package/rollup.config.mjs +6 -7
- package/src/canvas/DOMManagers/CanvasDOMManager.ts +124 -0
- package/src/canvas/DOMManagers/StaticCanvasDOMManager.ts +80 -0
- package/src/canvas/DOMManagers/util.spec.ts +23 -0
- package/src/canvas/DOMManagers/util.ts +98 -0
- package/src/canvas/SelectableCanvas.ts +23 -127
- package/src/canvas/StaticCanvas.ts +37 -119
- package/src/canvas/TextEditingManager.ts +7 -1
- package/src/constants.ts +2 -0
- package/src/shapes/IText/ITextClickBehavior.ts +4 -21
- package/src/shapes/Text/constants.ts +2 -2
- package/src/util/dom_misc.ts +0 -83
- package/src/util/index.ts +0 -7
- package/src/util/misc/textStyles.ts +2 -1
package/dist/index.js
CHANGED
|
@@ -416,7 +416,7 @@
|
|
|
416
416
|
}
|
|
417
417
|
const cache = new Cache();
|
|
418
418
|
|
|
419
|
-
var version = "6.0.0-
|
|
419
|
+
var version = "6.0.0-beta8";
|
|
420
420
|
|
|
421
421
|
// use this syntax so babel plugin see this import here
|
|
422
422
|
const VERSION = version;
|
|
@@ -440,6 +440,7 @@
|
|
|
440
440
|
const BOTTOM = 'bottom';
|
|
441
441
|
const RIGHT = 'right';
|
|
442
442
|
const NONE = 'none';
|
|
443
|
+
const reNewline = /\r?\n/;
|
|
443
444
|
|
|
444
445
|
/*
|
|
445
446
|
* This Map connects the objects type value with their
|
|
@@ -1521,133 +1522,6 @@
|
|
|
1521
1522
|
return getFabricWindow().cancelAnimationFrame(handle);
|
|
1522
1523
|
}
|
|
1523
1524
|
|
|
1524
|
-
/**
|
|
1525
|
-
* Wraps element with another element
|
|
1526
|
-
* @param {HTMLElement} element Element to wrap
|
|
1527
|
-
* @param {HTMLElement|String} wrapper Element to wrap with
|
|
1528
|
-
* @param {Object} [attributes] Attributes to set on a wrapper
|
|
1529
|
-
* @return {HTMLElement} wrapper
|
|
1530
|
-
*/
|
|
1531
|
-
function wrapElement(element, wrapper) {
|
|
1532
|
-
if (element.parentNode) {
|
|
1533
|
-
element.parentNode.replaceChild(wrapper, element);
|
|
1534
|
-
}
|
|
1535
|
-
wrapper.appendChild(element);
|
|
1536
|
-
return wrapper;
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
/**
|
|
1540
|
-
* Returns element scroll offsets
|
|
1541
|
-
* @param {HTMLElement} element Element to operate on
|
|
1542
|
-
* @return {Object} Object with left/top values
|
|
1543
|
-
*/
|
|
1544
|
-
function getScrollLeftTop(element) {
|
|
1545
|
-
let left = 0,
|
|
1546
|
-
top = 0;
|
|
1547
|
-
const doc = getDocumentFromElement(element);
|
|
1548
|
-
const docElement = doc.documentElement,
|
|
1549
|
-
body = doc.body || {
|
|
1550
|
-
scrollLeft: 0,
|
|
1551
|
-
scrollTop: 0
|
|
1552
|
-
};
|
|
1553
|
-
// While loop checks (and then sets element to) .parentNode OR .host
|
|
1554
|
-
// to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
|
|
1555
|
-
// but the .parentNode of a root ShadowDOM node will always be null, instead
|
|
1556
|
-
// it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
|
|
1557
|
-
// @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
|
|
1558
|
-
while (element && (element.parentNode || element.host)) {
|
|
1559
|
-
// @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
|
|
1560
|
-
element = element.parentNode || element.host;
|
|
1561
|
-
// @ts-expect-error because element is typed as HTMLElement but it can go up to document
|
|
1562
|
-
if (element === doc) {
|
|
1563
|
-
left = body.scrollLeft || docElement.scrollLeft || 0;
|
|
1564
|
-
top = body.scrollTop || docElement.scrollTop || 0;
|
|
1565
|
-
} else {
|
|
1566
|
-
left += element.scrollLeft || 0;
|
|
1567
|
-
top += element.scrollTop || 0;
|
|
1568
|
-
}
|
|
1569
|
-
if (element.nodeType === 1 && element.style.position === 'fixed') {
|
|
1570
|
-
break;
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
return {
|
|
1574
|
-
left,
|
|
1575
|
-
top
|
|
1576
|
-
};
|
|
1577
|
-
}
|
|
1578
|
-
|
|
1579
|
-
/**
|
|
1580
|
-
* Returns offset for a given element
|
|
1581
|
-
* @param {HTMLElement} element Element to get offset for
|
|
1582
|
-
* @return {Object} Object with "left" and "top" properties
|
|
1583
|
-
*/
|
|
1584
|
-
function getElementOffset(element) {
|
|
1585
|
-
var _getWindowFromElement;
|
|
1586
|
-
let box = {
|
|
1587
|
-
left: 0,
|
|
1588
|
-
top: 0
|
|
1589
|
-
};
|
|
1590
|
-
const doc = element && getDocumentFromElement(element),
|
|
1591
|
-
offset = {
|
|
1592
|
-
left: 0,
|
|
1593
|
-
top: 0
|
|
1594
|
-
},
|
|
1595
|
-
offsetAttributes = {
|
|
1596
|
-
borderLeftWidth: LEFT,
|
|
1597
|
-
borderTopWidth: TOP,
|
|
1598
|
-
paddingLeft: LEFT,
|
|
1599
|
-
paddingTop: TOP
|
|
1600
|
-
};
|
|
1601
|
-
if (!doc) {
|
|
1602
|
-
return offset;
|
|
1603
|
-
}
|
|
1604
|
-
const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {};
|
|
1605
|
-
for (const attr in offsetAttributes) {
|
|
1606
|
-
// @ts-expect-error TS learn to iterate!
|
|
1607
|
-
offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0;
|
|
1608
|
-
}
|
|
1609
|
-
const docElem = doc.documentElement;
|
|
1610
|
-
if (typeof element.getBoundingClientRect !== 'undefined') {
|
|
1611
|
-
box = element.getBoundingClientRect();
|
|
1612
|
-
}
|
|
1613
|
-
const scrollLeftTop = getScrollLeftTop(element);
|
|
1614
|
-
return {
|
|
1615
|
-
left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,
|
|
1616
|
-
top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
/**
|
|
1621
|
-
* Makes element unselectable
|
|
1622
|
-
* @param {HTMLElement} element Element to make unselectable
|
|
1623
|
-
* @return {HTMLElement} Element that was passed in
|
|
1624
|
-
*/
|
|
1625
|
-
function makeElementUnselectable(element) {
|
|
1626
|
-
if (typeof element.onselectstart !== 'undefined') {
|
|
1627
|
-
element.onselectstart = () => false;
|
|
1628
|
-
}
|
|
1629
|
-
element.style.userSelect = NONE;
|
|
1630
|
-
return element;
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
/**
|
|
1634
|
-
* Makes element selectable
|
|
1635
|
-
* @param {HTMLElement} element Element to make selectable
|
|
1636
|
-
* @return {HTMLElement} Element that was passed in
|
|
1637
|
-
*/
|
|
1638
|
-
function makeElementSelectable(element) {
|
|
1639
|
-
if (typeof element.onselectstart !== 'undefined') {
|
|
1640
|
-
element.onselectstart = null;
|
|
1641
|
-
}
|
|
1642
|
-
element.style.userSelect = '';
|
|
1643
|
-
return element;
|
|
1644
|
-
}
|
|
1645
|
-
const getDocumentFromElement = el => el.ownerDocument || null;
|
|
1646
|
-
const getWindowFromElement = el => {
|
|
1647
|
-
var _el$ownerDocument;
|
|
1648
|
-
return ((_el$ownerDocument = el.ownerDocument) === null || _el$ownerDocument === void 0 ? void 0 : _el$ownerDocument.defaultView) || null;
|
|
1649
|
-
};
|
|
1650
|
-
|
|
1651
1525
|
let id = 0;
|
|
1652
1526
|
const uid = () => id++;
|
|
1653
1527
|
|
|
@@ -2890,6 +2764,228 @@
|
|
|
2890
2764
|
return !!fabricObject && typeof fabricObject.onDragStart === 'function' && typeof fabricObject.shouldStartDragging === 'function';
|
|
2891
2765
|
};
|
|
2892
2766
|
|
|
2767
|
+
/**
|
|
2768
|
+
* Returns element scroll offsets
|
|
2769
|
+
* @param {HTMLElement} element Element to operate on
|
|
2770
|
+
* @return {Object} Object with left/top values
|
|
2771
|
+
*/
|
|
2772
|
+
function getScrollLeftTop(element) {
|
|
2773
|
+
let left = 0,
|
|
2774
|
+
top = 0;
|
|
2775
|
+
const doc = getDocumentFromElement(element);
|
|
2776
|
+
const docElement = doc.documentElement,
|
|
2777
|
+
body = doc.body || {
|
|
2778
|
+
scrollLeft: 0,
|
|
2779
|
+
scrollTop: 0
|
|
2780
|
+
};
|
|
2781
|
+
// While loop checks (and then sets element to) .parentNode OR .host
|
|
2782
|
+
// to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
|
|
2783
|
+
// but the .parentNode of a root ShadowDOM node will always be null, instead
|
|
2784
|
+
// it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
|
|
2785
|
+
// @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
|
|
2786
|
+
while (element && (element.parentNode || element.host)) {
|
|
2787
|
+
// @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
|
|
2788
|
+
element = element.parentNode || element.host;
|
|
2789
|
+
// @ts-expect-error because element is typed as HTMLElement but it can go up to document
|
|
2790
|
+
if (element === doc) {
|
|
2791
|
+
left = body.scrollLeft || docElement.scrollLeft || 0;
|
|
2792
|
+
top = body.scrollTop || docElement.scrollTop || 0;
|
|
2793
|
+
} else {
|
|
2794
|
+
left += element.scrollLeft || 0;
|
|
2795
|
+
top += element.scrollTop || 0;
|
|
2796
|
+
}
|
|
2797
|
+
if (element.nodeType === 1 && element.style.position === 'fixed') {
|
|
2798
|
+
break;
|
|
2799
|
+
}
|
|
2800
|
+
}
|
|
2801
|
+
return {
|
|
2802
|
+
left,
|
|
2803
|
+
top
|
|
2804
|
+
};
|
|
2805
|
+
}
|
|
2806
|
+
const getDocumentFromElement = el => el.ownerDocument || null;
|
|
2807
|
+
const getWindowFromElement = el => {
|
|
2808
|
+
var _el$ownerDocument;
|
|
2809
|
+
return ((_el$ownerDocument = el.ownerDocument) === null || _el$ownerDocument === void 0 ? void 0 : _el$ownerDocument.defaultView) || null;
|
|
2810
|
+
};
|
|
2811
|
+
|
|
2812
|
+
//@ts-nocheck
|
|
2813
|
+
// TODO this file needs to go away, cross browser style support is not fabricjs domain.
|
|
2814
|
+
|
|
2815
|
+
/**
|
|
2816
|
+
* wrapper for setting element's style
|
|
2817
|
+
* @param {HTMLElement} element
|
|
2818
|
+
* @param {Object | string} styles
|
|
2819
|
+
*/
|
|
2820
|
+
function setStyle(element, styles) {
|
|
2821
|
+
const elementStyle = element.style;
|
|
2822
|
+
if (!elementStyle) {
|
|
2823
|
+
return;
|
|
2824
|
+
} else if (typeof styles === 'string') {
|
|
2825
|
+
element.style.cssText += ';' + styles;
|
|
2826
|
+
} else {
|
|
2827
|
+
Object.entries(styles).forEach(_ref => {
|
|
2828
|
+
let [property, value] = _ref;
|
|
2829
|
+
return elementStyle.setProperty(property, value);
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
const setCanvasDimensions = function (el, ctx, _ref) {
|
|
2835
|
+
let {
|
|
2836
|
+
width,
|
|
2837
|
+
height
|
|
2838
|
+
} = _ref;
|
|
2839
|
+
let retinaScaling = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
|
|
2840
|
+
el.width = width;
|
|
2841
|
+
el.height = height;
|
|
2842
|
+
if (retinaScaling > 1) {
|
|
2843
|
+
el.setAttribute('width', (width * retinaScaling).toString());
|
|
2844
|
+
el.setAttribute('height', (height * retinaScaling).toString());
|
|
2845
|
+
ctx.scale(retinaScaling, retinaScaling);
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
function allowTouchScrolling(element, allow) {
|
|
2849
|
+
const touchAction = allow ? 'manipulation' : NONE;
|
|
2850
|
+
setStyle(element, {
|
|
2851
|
+
'touch-action': touchAction,
|
|
2852
|
+
'-ms-touch-action': touchAction
|
|
2853
|
+
});
|
|
2854
|
+
}
|
|
2855
|
+
const setCSSDimensions = (el, _ref2) => {
|
|
2856
|
+
let {
|
|
2857
|
+
width,
|
|
2858
|
+
height
|
|
2859
|
+
} = _ref2;
|
|
2860
|
+
width && (el.style.width = typeof width === 'number' ? "".concat(width, "px") : width);
|
|
2861
|
+
height && (el.style.height = typeof height === 'number' ? "".concat(height, "px") : height);
|
|
2862
|
+
};
|
|
2863
|
+
|
|
2864
|
+
/**
|
|
2865
|
+
* Returns offset for a given element
|
|
2866
|
+
* @param {HTMLElement} element Element to get offset for
|
|
2867
|
+
* @return {Object} Object with "left" and "top" properties
|
|
2868
|
+
*/
|
|
2869
|
+
function getElementOffset(element) {
|
|
2870
|
+
var _getWindowFromElement;
|
|
2871
|
+
let box = {
|
|
2872
|
+
left: 0,
|
|
2873
|
+
top: 0
|
|
2874
|
+
};
|
|
2875
|
+
const doc = element && getDocumentFromElement(element),
|
|
2876
|
+
offset = {
|
|
2877
|
+
left: 0,
|
|
2878
|
+
top: 0
|
|
2879
|
+
},
|
|
2880
|
+
offsetAttributes = {
|
|
2881
|
+
borderLeftWidth: LEFT,
|
|
2882
|
+
borderTopWidth: TOP,
|
|
2883
|
+
paddingLeft: LEFT,
|
|
2884
|
+
paddingTop: TOP
|
|
2885
|
+
};
|
|
2886
|
+
if (!doc) {
|
|
2887
|
+
return offset;
|
|
2888
|
+
}
|
|
2889
|
+
const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {};
|
|
2890
|
+
for (const attr in offsetAttributes) {
|
|
2891
|
+
// @ts-expect-error TS learn to iterate!
|
|
2892
|
+
offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0;
|
|
2893
|
+
}
|
|
2894
|
+
const docElem = doc.documentElement;
|
|
2895
|
+
if (typeof element.getBoundingClientRect !== 'undefined') {
|
|
2896
|
+
box = element.getBoundingClientRect();
|
|
2897
|
+
}
|
|
2898
|
+
const scrollLeftTop = getScrollLeftTop(element);
|
|
2899
|
+
return {
|
|
2900
|
+
left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,
|
|
2901
|
+
top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top
|
|
2902
|
+
};
|
|
2903
|
+
}
|
|
2904
|
+
|
|
2905
|
+
/**
|
|
2906
|
+
* Makes element unselectable
|
|
2907
|
+
* @param {HTMLElement} element Element to make unselectable
|
|
2908
|
+
* @return {HTMLElement} Element that was passed in
|
|
2909
|
+
*/
|
|
2910
|
+
function makeElementUnselectable(element) {
|
|
2911
|
+
if (typeof element.onselectstart !== 'undefined') {
|
|
2912
|
+
element.onselectstart = () => false;
|
|
2913
|
+
}
|
|
2914
|
+
element.style.userSelect = NONE;
|
|
2915
|
+
return element;
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2918
|
+
class StaticCanvasDOMManager {
|
|
2919
|
+
/**
|
|
2920
|
+
* Keeps a copy of the canvas style before setting retina scaling and other potions
|
|
2921
|
+
* in order to return it to original state on dispose
|
|
2922
|
+
* @type string
|
|
2923
|
+
*/
|
|
2924
|
+
|
|
2925
|
+
constructor(arg0) {
|
|
2926
|
+
_defineProperty(this, "_originalCanvasStyle", void 0);
|
|
2927
|
+
_defineProperty(this, "lower", void 0);
|
|
2928
|
+
const el = this.createLowerCanvas(arg0);
|
|
2929
|
+
this.lower = {
|
|
2930
|
+
el,
|
|
2931
|
+
ctx: el.getContext('2d')
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
createLowerCanvas(arg0) {
|
|
2935
|
+
// canvasEl === 'HTMLCanvasElement' does not work on jsdom/node
|
|
2936
|
+
const el = isHTMLCanvas(arg0) ? arg0 : getFabricDocument().getElementById(arg0) || createCanvasElement();
|
|
2937
|
+
if (el.hasAttribute('data-fabric')) {
|
|
2938
|
+
/* _DEV_MODE_START_ */
|
|
2939
|
+
throw new Error('fabric.js: trying to initialize a canvas that has already been initialized');
|
|
2940
|
+
/* _DEV_MODE_END_ */
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
this._originalCanvasStyle = el.style.cssText;
|
|
2944
|
+
el.setAttribute('data-fabric', 'main');
|
|
2945
|
+
el.classList.add('lower-canvas');
|
|
2946
|
+
return el;
|
|
2947
|
+
}
|
|
2948
|
+
cleanupDOM(_ref) {
|
|
2949
|
+
let {
|
|
2950
|
+
width,
|
|
2951
|
+
height
|
|
2952
|
+
} = _ref;
|
|
2953
|
+
const {
|
|
2954
|
+
el
|
|
2955
|
+
} = this.lower;
|
|
2956
|
+
// restore canvas style and attributes
|
|
2957
|
+
el.classList.remove('lower-canvas');
|
|
2958
|
+
el.removeAttribute('data-fabric');
|
|
2959
|
+
// restore canvas size to original size in case retina scaling was applied
|
|
2960
|
+
el.setAttribute('width', "".concat(width));
|
|
2961
|
+
el.setAttribute('height', "".concat(height));
|
|
2962
|
+
el.style.cssText = this._originalCanvasStyle || '';
|
|
2963
|
+
this._originalCanvasStyle = undefined;
|
|
2964
|
+
}
|
|
2965
|
+
setDimensions(size, retinaScaling) {
|
|
2966
|
+
const {
|
|
2967
|
+
el,
|
|
2968
|
+
ctx
|
|
2969
|
+
} = this.lower;
|
|
2970
|
+
setCanvasDimensions(el, ctx, size, retinaScaling);
|
|
2971
|
+
}
|
|
2972
|
+
setCSSDimensions(size) {
|
|
2973
|
+
setCSSDimensions(this.lower.el, size);
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
/**
|
|
2977
|
+
* Calculates canvas element offset relative to the document
|
|
2978
|
+
*/
|
|
2979
|
+
calcOffset() {
|
|
2980
|
+
return getElementOffset(this.lower.el);
|
|
2981
|
+
}
|
|
2982
|
+
dispose() {
|
|
2983
|
+
getEnv().dispose(this.lower.el);
|
|
2984
|
+
// @ts-expect-error disposing
|
|
2985
|
+
delete this.lower;
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
|
|
2893
2989
|
const StaticCanvasDefaults = {
|
|
2894
2990
|
backgroundColor: '',
|
|
2895
2991
|
backgroundImage: null,
|
|
@@ -3051,6 +3147,14 @@
|
|
|
3051
3147
|
* Can be use to read the raw pixels, but never write or manipulate
|
|
3052
3148
|
* @type HTMLCanvasElement
|
|
3053
3149
|
*/
|
|
3150
|
+
get lowerCanvasEl() {
|
|
3151
|
+
var _this$elements$lower;
|
|
3152
|
+
return (_this$elements$lower = this.elements.lower) === null || _this$elements$lower === void 0 ? void 0 : _this$elements$lower.el;
|
|
3153
|
+
}
|
|
3154
|
+
get contextContainer() {
|
|
3155
|
+
var _this$elements$lower2;
|
|
3156
|
+
return (_this$elements$lower2 = this.elements.lower) === null || _this$elements$lower2 === void 0 ? void 0 : _this$elements$lower2.ctx;
|
|
3157
|
+
}
|
|
3054
3158
|
|
|
3055
3159
|
/**
|
|
3056
3160
|
* Width in virtual/logical pixels of the canvas.
|
|
@@ -3076,12 +3180,6 @@
|
|
|
3076
3180
|
* @type boolean
|
|
3077
3181
|
*/
|
|
3078
3182
|
|
|
3079
|
-
/**
|
|
3080
|
-
* Keeps a copy of the canvas style before setting retina scaling and other potions
|
|
3081
|
-
* in order to return it to original state on dispose
|
|
3082
|
-
* @type string
|
|
3083
|
-
*/
|
|
3084
|
-
|
|
3085
3183
|
// reference to
|
|
3086
3184
|
|
|
3087
3185
|
static getDefaults() {
|
|
@@ -3094,15 +3192,14 @@
|
|
|
3094
3192
|
this.set(options);
|
|
3095
3193
|
this.initElements(el);
|
|
3096
3194
|
this._setDimensionsImpl({
|
|
3097
|
-
width: this.width || this.
|
|
3098
|
-
height: this.height || this.
|
|
3195
|
+
width: this.width || this.elements.lower.el.width || 0,
|
|
3196
|
+
height: this.height || this.elements.lower.el.height || 0
|
|
3099
3197
|
});
|
|
3100
3198
|
this.viewportTransform = [...this.viewportTransform];
|
|
3101
3199
|
this.calcViewportBoundaries();
|
|
3102
3200
|
}
|
|
3103
3201
|
initElements(el) {
|
|
3104
|
-
this.
|
|
3105
|
-
this._originalCanvasStyle = this.lowerCanvasEl.style.cssText;
|
|
3202
|
+
this.elements = new StaticCanvasDOMManager(el);
|
|
3106
3203
|
}
|
|
3107
3204
|
add() {
|
|
3108
3205
|
const size = super.add(...arguments);
|
|
@@ -3165,45 +3262,13 @@
|
|
|
3165
3262
|
getRetinaScaling() {
|
|
3166
3263
|
return this._isRetinaScaling() ? Math.max(1, config.devicePixelRatio) : 1;
|
|
3167
3264
|
}
|
|
3168
|
-
_initRetinaScaling() {
|
|
3169
|
-
this.__initRetinaScaling(this.lowerCanvasEl, this.contextContainer);
|
|
3170
|
-
}
|
|
3171
|
-
__initRetinaScaling(canvas, context) {
|
|
3172
|
-
const scaleRatio = config.devicePixelRatio;
|
|
3173
|
-
canvas.setAttribute('width', (this.width * scaleRatio).toString());
|
|
3174
|
-
canvas.setAttribute('height', (this.height * scaleRatio).toString());
|
|
3175
|
-
context.scale(scaleRatio, scaleRatio);
|
|
3176
|
-
}
|
|
3177
3265
|
|
|
3178
3266
|
/**
|
|
3179
3267
|
* Calculates canvas element offset relative to the document
|
|
3180
3268
|
* This method is also attached as "resize" event handler of window
|
|
3181
3269
|
*/
|
|
3182
3270
|
calcOffset() {
|
|
3183
|
-
return this._offset =
|
|
3184
|
-
}
|
|
3185
|
-
|
|
3186
|
-
/**
|
|
3187
|
-
* Creates a bottom canvas
|
|
3188
|
-
* @private
|
|
3189
|
-
* @param {HTMLElement} [canvasEl]
|
|
3190
|
-
*/
|
|
3191
|
-
_createLowerCanvas(canvasEl) {
|
|
3192
|
-
// canvasEl === 'HTMLCanvasElement' does not work on jsdom/node
|
|
3193
|
-
if (isHTMLCanvas(canvasEl)) {
|
|
3194
|
-
this.lowerCanvasEl = canvasEl;
|
|
3195
|
-
} else {
|
|
3196
|
-
this.lowerCanvasEl = getFabricDocument().getElementById(canvasEl) || createCanvasElement();
|
|
3197
|
-
}
|
|
3198
|
-
if (this.lowerCanvasEl.hasAttribute('data-fabric')) {
|
|
3199
|
-
/* _DEV_MODE_START_ */
|
|
3200
|
-
throw new Error('fabric.js: trying to initialize a canvas that has already been initialized');
|
|
3201
|
-
/* _DEV_MODE_END_ */
|
|
3202
|
-
}
|
|
3203
|
-
|
|
3204
|
-
this.lowerCanvasEl.classList.add('lower-canvas');
|
|
3205
|
-
this.lowerCanvasEl.setAttribute('data-fabric', 'main');
|
|
3206
|
-
this.contextContainer = this.lowerCanvasEl.getContext('2d');
|
|
3271
|
+
return this._offset = this.elements.calcOffset();
|
|
3207
3272
|
}
|
|
3208
3273
|
|
|
3209
3274
|
/**
|
|
@@ -3259,19 +3324,19 @@
|
|
|
3259
3324
|
cssOnly = false,
|
|
3260
3325
|
backstoreOnly = false
|
|
3261
3326
|
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3327
|
+
if (!cssOnly) {
|
|
3328
|
+
const size = _objectSpread2({
|
|
3329
|
+
width: this.width,
|
|
3330
|
+
height: this.height
|
|
3331
|
+
}, dimensions);
|
|
3332
|
+
this.elements.setDimensions(size, this.getRetinaScaling());
|
|
3333
|
+
this.hasLostContext = true;
|
|
3334
|
+
this.width = size.width;
|
|
3335
|
+
this.height = size.height;
|
|
3336
|
+
}
|
|
3337
|
+
if (!backstoreOnly) {
|
|
3338
|
+
this.elements.setCSSDimensions(dimensions);
|
|
3339
|
+
}
|
|
3275
3340
|
this.calcOffset();
|
|
3276
3341
|
}
|
|
3277
3342
|
|
|
@@ -3298,29 +3363,6 @@
|
|
|
3298
3363
|
}
|
|
3299
3364
|
}
|
|
3300
3365
|
|
|
3301
|
-
/**
|
|
3302
|
-
* Helper for setting width/height
|
|
3303
|
-
* @private
|
|
3304
|
-
* @param {String} prop property (width|height)
|
|
3305
|
-
* @param {Number} value value to set property to
|
|
3306
|
-
* @todo subclass in canvas and handle upperCanvasEl there.
|
|
3307
|
-
*/
|
|
3308
|
-
_setBackstoreDimension(prop, value) {
|
|
3309
|
-
this.lowerCanvasEl[prop] = value;
|
|
3310
|
-
this[prop] = value;
|
|
3311
|
-
}
|
|
3312
|
-
|
|
3313
|
-
/**
|
|
3314
|
-
* Helper for setting css width/height
|
|
3315
|
-
* @private
|
|
3316
|
-
* @param {String} prop property (width|height)
|
|
3317
|
-
* @param {String} value value to set property to
|
|
3318
|
-
* @todo subclass in canvas and handle upperCanvasEl there.
|
|
3319
|
-
*/
|
|
3320
|
-
_setCssDimension(prop, value) {
|
|
3321
|
-
this.lowerCanvasEl.style[prop] = value;
|
|
3322
|
-
}
|
|
3323
|
-
|
|
3324
3366
|
/**
|
|
3325
3367
|
* Returns canvas zoom level
|
|
3326
3368
|
* @return {Number}
|
|
@@ -3405,7 +3447,7 @@
|
|
|
3405
3447
|
* @return {HTMLCanvasElement}
|
|
3406
3448
|
*/
|
|
3407
3449
|
getElement() {
|
|
3408
|
-
return this.
|
|
3450
|
+
return this.elements.lower.el;
|
|
3409
3451
|
}
|
|
3410
3452
|
|
|
3411
3453
|
/**
|
|
@@ -3421,7 +3463,7 @@
|
|
|
3421
3463
|
* @return {CanvasRenderingContext2D}
|
|
3422
3464
|
*/
|
|
3423
3465
|
getContext() {
|
|
3424
|
-
return this.
|
|
3466
|
+
return this.elements.lower.ctx;
|
|
3425
3467
|
}
|
|
3426
3468
|
|
|
3427
3469
|
/**
|
|
@@ -3433,7 +3475,7 @@
|
|
|
3433
3475
|
this.overlayImage = null;
|
|
3434
3476
|
this.backgroundColor = '';
|
|
3435
3477
|
this.overlayColor = '';
|
|
3436
|
-
this.clearContext(this.
|
|
3478
|
+
this.clearContext(this.getContext());
|
|
3437
3479
|
this.fire('canvas:cleared');
|
|
3438
3480
|
this.renderOnAddRemove && this.requestRenderAll();
|
|
3439
3481
|
}
|
|
@@ -3446,7 +3488,7 @@
|
|
|
3446
3488
|
if (this.destroyed) {
|
|
3447
3489
|
return;
|
|
3448
3490
|
}
|
|
3449
|
-
this.renderCanvas(this.
|
|
3491
|
+
this.renderCanvas(this.getContext(), this._objects);
|
|
3450
3492
|
}
|
|
3451
3493
|
|
|
3452
3494
|
/**
|
|
@@ -4013,10 +4055,10 @@
|
|
|
4013
4055
|
return;
|
|
4014
4056
|
}
|
|
4015
4057
|
Object.values(styles).forEach(styleRow => {
|
|
4016
|
-
Object.values(styleRow).forEach(
|
|
4058
|
+
Object.values(styleRow).forEach(_ref => {
|
|
4017
4059
|
let {
|
|
4018
4060
|
fontFamily = ''
|
|
4019
|
-
} =
|
|
4061
|
+
} = _ref;
|
|
4020
4062
|
if (!fontList[fontFamily] && fontPaths[fontFamily]) {
|
|
4021
4063
|
fontList[fontFamily] = true;
|
|
4022
4064
|
}
|
|
@@ -4138,8 +4180,8 @@
|
|
|
4138
4180
|
clipPath
|
|
4139
4181
|
}, {
|
|
4140
4182
|
signal
|
|
4141
|
-
})]).then(
|
|
4142
|
-
let [enlived, enlivedMap] =
|
|
4183
|
+
})]).then(_ref2 => {
|
|
4184
|
+
let [enlived, enlivedMap] = _ref2;
|
|
4143
4185
|
this.clear();
|
|
4144
4186
|
this.add(...enlived);
|
|
4145
4187
|
this.set(serialized);
|
|
@@ -4278,7 +4320,10 @@
|
|
|
4278
4320
|
* @throws if aborted by a consequent call
|
|
4279
4321
|
*/
|
|
4280
4322
|
dispose() {
|
|
4281
|
-
!this.disposed && this.cleanupDOM(
|
|
4323
|
+
!this.disposed && this.elements.cleanupDOM({
|
|
4324
|
+
width: this.width,
|
|
4325
|
+
height: this.height
|
|
4326
|
+
});
|
|
4282
4327
|
this.disposed = true;
|
|
4283
4328
|
return new Promise((resolve, reject) => {
|
|
4284
4329
|
const task = () => {
|
|
@@ -4299,21 +4344,6 @@
|
|
|
4299
4344
|
});
|
|
4300
4345
|
}
|
|
4301
4346
|
|
|
4302
|
-
/**
|
|
4303
|
-
* Invoked as part of the **sync** operation of {@link dispose}.
|
|
4304
|
-
*/
|
|
4305
|
-
cleanupDOM() {
|
|
4306
|
-
const canvasElement = this.lowerCanvasEl;
|
|
4307
|
-
// restore canvas style and attributes
|
|
4308
|
-
canvasElement.classList.remove('lower-canvas');
|
|
4309
|
-
canvasElement.removeAttribute('data-fabric');
|
|
4310
|
-
// restore canvas size to original size in case retina scaling was applied
|
|
4311
|
-
canvasElement.setAttribute('width', "".concat(this.width));
|
|
4312
|
-
canvasElement.setAttribute('height', "".concat(this.height));
|
|
4313
|
-
canvasElement.style.cssText = this._originalCanvasStyle || '';
|
|
4314
|
-
this._originalCanvasStyle = undefined;
|
|
4315
|
-
}
|
|
4316
|
-
|
|
4317
4347
|
/**
|
|
4318
4348
|
* Clears the canvas element, disposes objects and frees resources.
|
|
4319
4349
|
*
|
|
@@ -4341,10 +4371,7 @@
|
|
|
4341
4371
|
this.overlayImage.dispose();
|
|
4342
4372
|
}
|
|
4343
4373
|
this.overlayImage = null;
|
|
4344
|
-
|
|
4345
|
-
this.contextContainer = null;
|
|
4346
|
-
// @ts-expect-error disposing
|
|
4347
|
-
this.lowerCanvasEl = undefined;
|
|
4374
|
+
this.elements.dispose();
|
|
4348
4375
|
}
|
|
4349
4376
|
|
|
4350
4377
|
/**
|
|
@@ -10084,28 +10111,6 @@
|
|
|
10084
10111
|
return true;
|
|
10085
10112
|
};
|
|
10086
10113
|
|
|
10087
|
-
//@ts-nocheck
|
|
10088
|
-
// TODO this file needs to go away, cross browser style support is not fabricjs domain.
|
|
10089
|
-
|
|
10090
|
-
/**
|
|
10091
|
-
* wrapper for setting element's style
|
|
10092
|
-
* @param {HTMLElement} element
|
|
10093
|
-
* @param {Object | string} styles
|
|
10094
|
-
*/
|
|
10095
|
-
function setStyle(element, styles) {
|
|
10096
|
-
const elementStyle = element.style;
|
|
10097
|
-
if (!elementStyle) {
|
|
10098
|
-
return;
|
|
10099
|
-
} else if (typeof styles === 'string') {
|
|
10100
|
-
element.style.cssText += ';' + styles;
|
|
10101
|
-
} else {
|
|
10102
|
-
Object.entries(styles).forEach(_ref => {
|
|
10103
|
-
let [property, value] = _ref;
|
|
10104
|
-
return elementStyle.setProperty(property, value);
|
|
10105
|
-
});
|
|
10106
|
-
}
|
|
10107
|
-
}
|
|
10108
|
-
|
|
10109
10114
|
/**
|
|
10110
10115
|
* Attributes parsed from all SVG elements
|
|
10111
10116
|
* @type array
|
|
@@ -12168,7 +12173,7 @@
|
|
|
12168
12173
|
// clone to prevent mutation
|
|
12169
12174
|
return cloneDeep(styles);
|
|
12170
12175
|
}
|
|
12171
|
-
const textLines = text.split(
|
|
12176
|
+
const textLines = text.split(reNewline),
|
|
12172
12177
|
stylesObject = {};
|
|
12173
12178
|
let charIndex = -1,
|
|
12174
12179
|
styleIndex = 0;
|
|
@@ -13314,7 +13319,6 @@
|
|
|
13314
13319
|
findScaleToFit: findScaleToFit,
|
|
13315
13320
|
getBisector: getBisector,
|
|
13316
13321
|
getBoundsOfCurve: getBoundsOfCurve,
|
|
13317
|
-
getElementOffset: getElementOffset,
|
|
13318
13322
|
getPathSegmentsInfo: getPathSegmentsInfo,
|
|
13319
13323
|
getPointOnPath: getPointOnPath,
|
|
13320
13324
|
getPointer: getPointer,
|
|
@@ -13332,8 +13336,6 @@
|
|
|
13332
13336
|
joinPath: joinPath,
|
|
13333
13337
|
loadImage: loadImage,
|
|
13334
13338
|
makeBoundingBoxFromPoints: makeBoundingBoxFromPoints,
|
|
13335
|
-
makeElementSelectable: makeElementSelectable,
|
|
13336
|
-
makeElementUnselectable: makeElementUnselectable,
|
|
13337
13339
|
makePathSimpler: makePathSimpler,
|
|
13338
13340
|
matrixToSVG: matrixToSVG,
|
|
13339
13341
|
mergeClipPaths: mergeClipPaths,
|
|
@@ -13367,10 +13369,120 @@
|
|
|
13367
13369
|
toFixed: toFixed,
|
|
13368
13370
|
transformPath: transformPath,
|
|
13369
13371
|
transformPoint: transformPoint,
|
|
13370
|
-
transformPointRelativeToCanvas: transformPointRelativeToCanvas
|
|
13371
|
-
wrapElement: wrapElement
|
|
13372
|
+
transformPointRelativeToCanvas: transformPointRelativeToCanvas
|
|
13372
13373
|
});
|
|
13373
13374
|
|
|
13375
|
+
class CanvasDOMManager extends StaticCanvasDOMManager {
|
|
13376
|
+
constructor(arg0) {
|
|
13377
|
+
let {
|
|
13378
|
+
allowTouchScrolling = false,
|
|
13379
|
+
containerClass = ''
|
|
13380
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
13381
|
+
super(arg0);
|
|
13382
|
+
_defineProperty(this, "upper", void 0);
|
|
13383
|
+
_defineProperty(this, "container", void 0);
|
|
13384
|
+
const {
|
|
13385
|
+
el: lowerCanvasEl
|
|
13386
|
+
} = this.lower;
|
|
13387
|
+
const upperCanvasEl = this.createUpperCanvas();
|
|
13388
|
+
this.upper = {
|
|
13389
|
+
el: upperCanvasEl,
|
|
13390
|
+
ctx: upperCanvasEl.getContext('2d')
|
|
13391
|
+
};
|
|
13392
|
+
this.applyCanvasStyle(lowerCanvasEl, {
|
|
13393
|
+
allowTouchScrolling
|
|
13394
|
+
});
|
|
13395
|
+
this.applyCanvasStyle(upperCanvasEl, {
|
|
13396
|
+
allowTouchScrolling
|
|
13397
|
+
});
|
|
13398
|
+
const container = this.createContainerElement();
|
|
13399
|
+
container.classList.add(containerClass);
|
|
13400
|
+
if (lowerCanvasEl.parentNode) {
|
|
13401
|
+
lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl);
|
|
13402
|
+
}
|
|
13403
|
+
container.append(lowerCanvasEl, upperCanvasEl);
|
|
13404
|
+
this.container = container;
|
|
13405
|
+
}
|
|
13406
|
+
createUpperCanvas() {
|
|
13407
|
+
const {
|
|
13408
|
+
el: lowerCanvasEl
|
|
13409
|
+
} = this.lower;
|
|
13410
|
+
const el = createCanvasElement();
|
|
13411
|
+
// we assign the same classname of the lowerCanvas
|
|
13412
|
+
el.className = lowerCanvasEl.className;
|
|
13413
|
+
// but then we remove the lower-canvas specific className
|
|
13414
|
+
el.classList.remove('lower-canvas');
|
|
13415
|
+
// we add the specific upper-canvas class
|
|
13416
|
+
el.classList.add('upper-canvas');
|
|
13417
|
+
el.setAttribute('data-fabric', 'top');
|
|
13418
|
+
el.style.cssText = lowerCanvasEl.style.cssText;
|
|
13419
|
+
el.setAttribute('draggable', 'true');
|
|
13420
|
+
return el;
|
|
13421
|
+
}
|
|
13422
|
+
createContainerElement() {
|
|
13423
|
+
const container = getFabricDocument().createElement('div');
|
|
13424
|
+
container.setAttribute('data-fabric', 'wrapper');
|
|
13425
|
+
setStyle(container, {
|
|
13426
|
+
position: 'relative'
|
|
13427
|
+
});
|
|
13428
|
+
makeElementUnselectable(container);
|
|
13429
|
+
return container;
|
|
13430
|
+
}
|
|
13431
|
+
|
|
13432
|
+
/**
|
|
13433
|
+
* @private
|
|
13434
|
+
* @param {HTMLCanvasElement} element canvas element to apply styles on
|
|
13435
|
+
*/
|
|
13436
|
+
applyCanvasStyle(element, _ref) {
|
|
13437
|
+
let {
|
|
13438
|
+
allowTouchScrolling: allow
|
|
13439
|
+
} = _ref;
|
|
13440
|
+
setStyle(element, {
|
|
13441
|
+
position: 'absolute',
|
|
13442
|
+
left: 0,
|
|
13443
|
+
top: 0
|
|
13444
|
+
});
|
|
13445
|
+
allowTouchScrolling(element, allow);
|
|
13446
|
+
makeElementUnselectable(element);
|
|
13447
|
+
}
|
|
13448
|
+
setDimensions(size, retinaScaling) {
|
|
13449
|
+
super.setDimensions(size, retinaScaling);
|
|
13450
|
+
const {
|
|
13451
|
+
el,
|
|
13452
|
+
ctx
|
|
13453
|
+
} = this.upper;
|
|
13454
|
+
setCanvasDimensions(el, ctx, size, retinaScaling);
|
|
13455
|
+
}
|
|
13456
|
+
setCSSDimensions(size) {
|
|
13457
|
+
super.setCSSDimensions(size);
|
|
13458
|
+
setCSSDimensions(this.upper.el, size);
|
|
13459
|
+
setCSSDimensions(this.container, size);
|
|
13460
|
+
}
|
|
13461
|
+
cleanupDOM(size) {
|
|
13462
|
+
const container = this.container,
|
|
13463
|
+
{
|
|
13464
|
+
el: lowerCanvasEl
|
|
13465
|
+
} = this.lower,
|
|
13466
|
+
{
|
|
13467
|
+
el: upperCanvasEl
|
|
13468
|
+
} = this.upper;
|
|
13469
|
+
super.cleanupDOM(size);
|
|
13470
|
+
container.removeChild(upperCanvasEl);
|
|
13471
|
+
container.removeChild(lowerCanvasEl);
|
|
13472
|
+
if (container.parentNode) {
|
|
13473
|
+
container.parentNode.replaceChild(lowerCanvasEl, container);
|
|
13474
|
+
}
|
|
13475
|
+
}
|
|
13476
|
+
dispose() {
|
|
13477
|
+
super.dispose();
|
|
13478
|
+
getEnv().dispose(this.upper.el);
|
|
13479
|
+
// @ts-expect-error disposing
|
|
13480
|
+
delete this.upper;
|
|
13481
|
+
// @ts-expect-error disposing
|
|
13482
|
+
delete this.container;
|
|
13483
|
+
}
|
|
13484
|
+
}
|
|
13485
|
+
|
|
13374
13486
|
const DefaultCanvasProperties = {
|
|
13375
13487
|
uniformScaling: true,
|
|
13376
13488
|
uniScaleKey: 'shiftKey',
|
|
@@ -13655,6 +13767,7 @@
|
|
|
13655
13767
|
* Default element class that's given to wrapper (div) element of canvas
|
|
13656
13768
|
* @type String
|
|
13657
13769
|
* @default
|
|
13770
|
+
* @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly
|
|
13658
13771
|
*/
|
|
13659
13772
|
|
|
13660
13773
|
/**
|
|
@@ -13787,6 +13900,17 @@
|
|
|
13787
13900
|
static getDefaults() {
|
|
13788
13901
|
return _objectSpread2(_objectSpread2({}, super.getDefaults()), SelectableCanvas.ownDefaults);
|
|
13789
13902
|
}
|
|
13903
|
+
get upperCanvasEl() {
|
|
13904
|
+
var _this$elements$upper;
|
|
13905
|
+
return (_this$elements$upper = this.elements.upper) === null || _this$elements$upper === void 0 ? void 0 : _this$elements$upper.el;
|
|
13906
|
+
}
|
|
13907
|
+
get contextTop() {
|
|
13908
|
+
var _this$elements$upper2;
|
|
13909
|
+
return (_this$elements$upper2 = this.elements.upper) === null || _this$elements$upper2 === void 0 ? void 0 : _this$elements$upper2.ctx;
|
|
13910
|
+
}
|
|
13911
|
+
get wrapperEl() {
|
|
13912
|
+
return this.elements.container;
|
|
13913
|
+
}
|
|
13790
13914
|
constructor(el) {
|
|
13791
13915
|
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
13792
13916
|
super(el, options);
|
|
@@ -13803,16 +13927,12 @@
|
|
|
13803
13927
|
});
|
|
13804
13928
|
}
|
|
13805
13929
|
initElements(el) {
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13930
|
+
this.elements = new CanvasDOMManager(el, {
|
|
13931
|
+
allowTouchScrolling: this.allowTouchScrolling,
|
|
13932
|
+
containerClass: this.containerClass
|
|
13933
|
+
});
|
|
13810
13934
|
this._createCacheCanvas();
|
|
13811
13935
|
}
|
|
13812
|
-
_initRetinaScaling() {
|
|
13813
|
-
super._initRetinaScaling();
|
|
13814
|
-
this.__initRetinaScaling(this.upperCanvasEl, this.contextTop);
|
|
13815
|
-
}
|
|
13816
13936
|
|
|
13817
13937
|
/**
|
|
13818
13938
|
* @private
|
|
@@ -13876,7 +13996,7 @@
|
|
|
13876
13996
|
this.hasLostContext = false;
|
|
13877
13997
|
}
|
|
13878
13998
|
!this._objectsToRender && (this._objectsToRender = this._chooseObjectsToRender());
|
|
13879
|
-
this.renderCanvas(this.
|
|
13999
|
+
this.renderCanvas(this.getContext(), this._objectsToRender);
|
|
13880
14000
|
}
|
|
13881
14001
|
|
|
13882
14002
|
/**
|
|
@@ -14340,55 +14460,6 @@
|
|
|
14340
14460
|
this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop);
|
|
14341
14461
|
}
|
|
14342
14462
|
}
|
|
14343
|
-
|
|
14344
|
-
/**
|
|
14345
|
-
* Helper for setting width/height
|
|
14346
|
-
* @private
|
|
14347
|
-
* @param {String} prop property (width|height)
|
|
14348
|
-
* @param {Number} value value to set property to
|
|
14349
|
-
*/
|
|
14350
|
-
_setBackstoreDimension(prop, value) {
|
|
14351
|
-
super._setBackstoreDimension(prop, value);
|
|
14352
|
-
this.upperCanvasEl[prop] = value;
|
|
14353
|
-
}
|
|
14354
|
-
|
|
14355
|
-
/**
|
|
14356
|
-
* Helper for setting css width/height
|
|
14357
|
-
* @private
|
|
14358
|
-
* @param {String} prop property (width|height)
|
|
14359
|
-
* @param {String} value value to set property to
|
|
14360
|
-
*/
|
|
14361
|
-
_setCssDimension(prop, value) {
|
|
14362
|
-
super._setCssDimension(prop, value);
|
|
14363
|
-
this.upperCanvasEl.style[prop] = value;
|
|
14364
|
-
this.wrapperEl.style[prop] = value;
|
|
14365
|
-
}
|
|
14366
|
-
|
|
14367
|
-
/**
|
|
14368
|
-
* @private
|
|
14369
|
-
* @throws {CANVAS_INIT_ERROR} If canvas can not be initialized
|
|
14370
|
-
*/
|
|
14371
|
-
_createUpperCanvas() {
|
|
14372
|
-
const lowerCanvasEl = this.lowerCanvasEl;
|
|
14373
|
-
|
|
14374
|
-
// if there is no upperCanvas (most common case) we create one.
|
|
14375
|
-
if (!this.upperCanvasEl) {
|
|
14376
|
-
this.upperCanvasEl = createCanvasElement();
|
|
14377
|
-
}
|
|
14378
|
-
const upperCanvasEl = this.upperCanvasEl;
|
|
14379
|
-
// we assign the same classname of the lowerCanvas
|
|
14380
|
-
upperCanvasEl.className = lowerCanvasEl.className;
|
|
14381
|
-
// but then we remove the lower-canvas specific className
|
|
14382
|
-
upperCanvasEl.classList.remove('lower-canvas');
|
|
14383
|
-
// we add the specific upper-canvas class
|
|
14384
|
-
upperCanvasEl.classList.add('upper-canvas');
|
|
14385
|
-
upperCanvasEl.setAttribute('data-fabric', 'top');
|
|
14386
|
-
this.wrapperEl.appendChild(upperCanvasEl);
|
|
14387
|
-
upperCanvasEl.style.cssText = lowerCanvasEl.style.cssText;
|
|
14388
|
-
this._applyCanvasStyle(upperCanvasEl);
|
|
14389
|
-
upperCanvasEl.setAttribute('draggable', 'true');
|
|
14390
|
-
this.contextTop = upperCanvasEl.getContext('2d');
|
|
14391
|
-
}
|
|
14392
14463
|
_createCacheCanvas() {
|
|
14393
14464
|
this.pixelFindCanvasEl = createCanvasElement();
|
|
14394
14465
|
this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', {
|
|
@@ -14396,46 +14467,13 @@
|
|
|
14396
14467
|
});
|
|
14397
14468
|
this.setTargetFindTolerance(this.targetFindTolerance);
|
|
14398
14469
|
}
|
|
14399
|
-
_initWrapperElement() {
|
|
14400
|
-
const container = getFabricDocument().createElement('div');
|
|
14401
|
-
container.classList.add(this.containerClass);
|
|
14402
|
-
this.wrapperEl = wrapElement(this.lowerCanvasEl, container);
|
|
14403
|
-
this.wrapperEl.setAttribute('data-fabric', 'wrapper');
|
|
14404
|
-
setStyle(this.wrapperEl, {
|
|
14405
|
-
width: "".concat(this.width, "px"),
|
|
14406
|
-
height: "".concat(this.height, "px"),
|
|
14407
|
-
position: 'relative'
|
|
14408
|
-
});
|
|
14409
|
-
makeElementUnselectable(this.wrapperEl);
|
|
14410
|
-
}
|
|
14411
|
-
|
|
14412
|
-
/**
|
|
14413
|
-
* @private
|
|
14414
|
-
* @param {HTMLCanvasElement} element canvas element to apply styles on
|
|
14415
|
-
*/
|
|
14416
|
-
_applyCanvasStyle(element) {
|
|
14417
|
-
const width = this.width || element.width,
|
|
14418
|
-
height = this.height || element.height;
|
|
14419
|
-
setStyle(element, {
|
|
14420
|
-
position: 'absolute',
|
|
14421
|
-
width: width + 'px',
|
|
14422
|
-
height: height + 'px',
|
|
14423
|
-
left: 0,
|
|
14424
|
-
top: 0,
|
|
14425
|
-
'touch-action': this.allowTouchScrolling ? 'manipulation' : NONE,
|
|
14426
|
-
'-ms-touch-action': this.allowTouchScrolling ? 'manipulation' : NONE
|
|
14427
|
-
});
|
|
14428
|
-
element.width = width;
|
|
14429
|
-
element.height = height;
|
|
14430
|
-
makeElementUnselectable(element);
|
|
14431
|
-
}
|
|
14432
14470
|
|
|
14433
14471
|
/**
|
|
14434
14472
|
* Returns context of top canvas where interactions are drawn
|
|
14435
14473
|
* @returns {CanvasRenderingContext2D}
|
|
14436
14474
|
*/
|
|
14437
14475
|
getTopContext() {
|
|
14438
|
-
return this.
|
|
14476
|
+
return this.elements.upper.ctx;
|
|
14439
14477
|
}
|
|
14440
14478
|
|
|
14441
14479
|
/**
|
|
@@ -14444,7 +14482,7 @@
|
|
|
14444
14482
|
* @return {CanvasRenderingContext2D}
|
|
14445
14483
|
*/
|
|
14446
14484
|
getSelectionContext() {
|
|
14447
|
-
return this.
|
|
14485
|
+
return this.elements.upper.ctx;
|
|
14448
14486
|
}
|
|
14449
14487
|
|
|
14450
14488
|
/**
|
|
@@ -14452,7 +14490,7 @@
|
|
|
14452
14490
|
* @return {HTMLCanvasElement}
|
|
14453
14491
|
*/
|
|
14454
14492
|
getSelectionElement() {
|
|
14455
|
-
return this.
|
|
14493
|
+
return this.elements.upper.el;
|
|
14456
14494
|
}
|
|
14457
14495
|
|
|
14458
14496
|
/**
|
|
@@ -14646,17 +14684,6 @@
|
|
|
14646
14684
|
activeObject.setCoords();
|
|
14647
14685
|
}
|
|
14648
14686
|
}
|
|
14649
|
-
cleanupDOM() {
|
|
14650
|
-
const wrapperEl = this.wrapperEl,
|
|
14651
|
-
lowerCanvasEl = this.lowerCanvasEl,
|
|
14652
|
-
upperCanvasEl = this.upperCanvasEl;
|
|
14653
|
-
super.cleanupDOM();
|
|
14654
|
-
wrapperEl.removeChild(upperCanvasEl);
|
|
14655
|
-
wrapperEl.removeChild(lowerCanvasEl);
|
|
14656
|
-
if (wrapperEl.parentNode) {
|
|
14657
|
-
wrapperEl.parentNode.replaceChild(lowerCanvasEl, wrapperEl);
|
|
14658
|
-
}
|
|
14659
|
-
}
|
|
14660
14687
|
|
|
14661
14688
|
/**
|
|
14662
14689
|
* @override clears active selection ref and interactive canvas elements and contexts
|
|
@@ -14672,20 +14699,11 @@
|
|
|
14672
14699
|
|
|
14673
14700
|
// free resources
|
|
14674
14701
|
|
|
14675
|
-
// top canvas
|
|
14676
|
-
// @ts-expect-error disposing
|
|
14677
|
-
this.contextTop = null;
|
|
14678
|
-
// @ts-expect-error disposing
|
|
14679
|
-
this.upperCanvasEl = undefined;
|
|
14680
|
-
|
|
14681
14702
|
// pixel find canvas
|
|
14682
14703
|
// @ts-expect-error disposing
|
|
14683
14704
|
this.pixelFindContext = null;
|
|
14684
14705
|
// @ts-expect-error disposing
|
|
14685
14706
|
this.pixelFindCanvasEl = undefined;
|
|
14686
|
-
|
|
14687
|
-
// @ts-expect-error disposing
|
|
14688
|
-
this.wrapperEl = undefined;
|
|
14689
14707
|
}
|
|
14690
14708
|
|
|
14691
14709
|
/**
|
|
@@ -14764,8 +14782,10 @@
|
|
|
14764
14782
|
_defineProperty(this, "targets", []);
|
|
14765
14783
|
_defineProperty(this, "__disposer", void 0);
|
|
14766
14784
|
const cb = () => {
|
|
14767
|
-
|
|
14768
|
-
|
|
14785
|
+
const activeObject = canvas.getActiveObject();
|
|
14786
|
+
if (isInteractiveTextObject(activeObject)) {
|
|
14787
|
+
activeObject.hiddenTextarea && activeObject.hiddenTextarea.focus();
|
|
14788
|
+
}
|
|
14769
14789
|
};
|
|
14770
14790
|
const el = canvas.upperCanvasEl;
|
|
14771
14791
|
el.addEventListener('click', cb);
|
|
@@ -14795,8 +14815,8 @@
|
|
|
14795
14815
|
}
|
|
14796
14816
|
}
|
|
14797
14817
|
onMouseMove(e) {
|
|
14798
|
-
var _this$
|
|
14799
|
-
((_this$
|
|
14818
|
+
var _this$target;
|
|
14819
|
+
((_this$target = this.target) === null || _this$target === void 0 ? void 0 : _this$target.isEditing) && this.target.updateSelectionOnMouseMove(e);
|
|
14800
14820
|
}
|
|
14801
14821
|
clear() {
|
|
14802
14822
|
this.targets = [];
|
|
@@ -18781,7 +18801,7 @@
|
|
|
18781
18801
|
// regexes, list of properties that are not suppose to change by instances, magic consts.
|
|
18782
18802
|
// this will be a separated effort
|
|
18783
18803
|
const textDefaultValues = {
|
|
18784
|
-
_reNewline:
|
|
18804
|
+
_reNewline: reNewline,
|
|
18785
18805
|
_reSpacesAndTabs: /[ \t\r]/g,
|
|
18786
18806
|
_reSpaceAndTab: /[ \t\r]/,
|
|
18787
18807
|
_reWords: /\S+/g,
|
|
@@ -22740,22 +22760,13 @@
|
|
|
22740
22760
|
}
|
|
22741
22761
|
}
|
|
22742
22762
|
|
|
22743
|
-
/**
|
|
22744
|
-
* Returns coordinates of a pointer relative to object's top left corner in object's plane
|
|
22745
|
-
* @param {Point} [pointer] Pointer to operate upon
|
|
22746
|
-
* @return {Point} Coordinates of a pointer (x, y)
|
|
22747
|
-
*/
|
|
22748
|
-
getLocalPointer(pointer) {
|
|
22749
|
-
return transformPoint(pointer, invertTransform(this.calcTransformMatrix())).add(new Point(this.width / 2, this.height / 2));
|
|
22750
|
-
}
|
|
22751
|
-
|
|
22752
22763
|
/**
|
|
22753
22764
|
* Returns index of a character corresponding to where an object was clicked
|
|
22754
22765
|
* @param {TPointerEvent} e Event object
|
|
22755
22766
|
* @return {Number} Index of a character
|
|
22756
22767
|
*/
|
|
22757
22768
|
getSelectionStartFromPointer(e) {
|
|
22758
|
-
const mouseOffset = this.
|
|
22769
|
+
const mouseOffset = this.canvas.getPointer(e).transform(invertTransform(this.calcTransformMatrix())).add(new Point(-this._getLeftOffset(), -this._getTopOffset()));
|
|
22759
22770
|
let height = 0,
|
|
22760
22771
|
charIndex = 0,
|
|
22761
22772
|
lineIndex = 0;
|
|
@@ -22773,13 +22784,6 @@
|
|
|
22773
22784
|
const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex));
|
|
22774
22785
|
let width = lineLeftOffset;
|
|
22775
22786
|
const jlen = this._textLines[lineIndex].length;
|
|
22776
|
-
// handling of RTL: in order to get things work correctly,
|
|
22777
|
-
// we assume RTL writing is mirrored compared to LTR writing.
|
|
22778
|
-
// so in position detection we mirror the X offset, and when is time
|
|
22779
|
-
// of rendering it, we mirror it again.
|
|
22780
|
-
if (this.direction === 'rtl') {
|
|
22781
|
-
mouseOffset.x = this.width - mouseOffset.x;
|
|
22782
|
-
}
|
|
22783
22787
|
let prevWidth = 0;
|
|
22784
22788
|
for (let j = 0; j < jlen; j++) {
|
|
22785
22789
|
prevWidth = width;
|
|
@@ -28322,6 +28326,7 @@
|
|
|
28322
28326
|
exports.BaseBrush = BaseBrush;
|
|
28323
28327
|
exports.Canvas = Canvas;
|
|
28324
28328
|
exports.Canvas2dFilterBackend = Canvas2dFilterBackend;
|
|
28329
|
+
exports.CanvasDOMManager = CanvasDOMManager;
|
|
28325
28330
|
exports.Circle = Circle;
|
|
28326
28331
|
exports.CircleBrush = CircleBrush;
|
|
28327
28332
|
exports.Color = Color;
|
|
@@ -28346,6 +28351,7 @@
|
|
|
28346
28351
|
exports.Shadow = Shadow;
|
|
28347
28352
|
exports.SprayBrush = SprayBrush;
|
|
28348
28353
|
exports.StaticCanvas = StaticCanvas;
|
|
28354
|
+
exports.StaticCanvasDOMManager = StaticCanvasDOMManager;
|
|
28349
28355
|
exports.Text = Text;
|
|
28350
28356
|
exports.Textbox = Textbox;
|
|
28351
28357
|
exports.Triangle = Triangle;
|