diff --git a/.gitignore b/.gitignore index ab1c68bcf81..8c15ad4298f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,19 @@ change-output.md before_commit /coverage/ .idea/ -**/dist/ -**/dist-extensions/ +e2e/dist/ +/dist-extensions/* +!/dist-extensions/fabric-extensions.min.* +!/dist-extensions/**/*.ts +/dist/* +!/dist/index.node.mjs +!/dist/index.node.mjs.map +!/dist/index.mjs +!/dist/index.mjs.map +!/dist/index.min.js +!/dist/index.min.js.map +!/dist/index.min.mjs +!/dist/index.min.mjs.map /cli_output/ e2e/test-report/ e2e/test-results/ diff --git a/CHANGELOG.md b/CHANGELOG.md index c566f7ac8b7..61bc62800a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [next] +- ci(): Add some prebuilt fabric in the dist folder [#10178](https://github.com/fabricjs/fabric.js/pull/10178) + ## [6.4.2] - Fix(): path parsing performance [#10123](https://github.com/fabricjs/fabric.js/pull/10123) diff --git a/dist-extensions/fabric-extensions.min.js b/dist-extensions/fabric-extensions.min.js new file mode 100644 index 00000000000..5bce47cac5e --- /dev/null +++ b/dist-extensions/fabric-extensions.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("fabric")):"function"==typeof define&&define.amd?define(["exports","fabric"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).fabricExtensions={},t.fabric)}(this,(function(t,e){"use strict";const n={margin:4,width:1,color:"rgb(255,0,0,0.9)"};function o(t,e){return Math.abs(t-e)}const i=["left","center","right"],r=["top","center","bottom"];function c(t){var e,o;const r=n.margin,{activeObject:c,isScale:s,index:f,point:l,list:d}=t,{dis:g,arr:u}=a(l,d,"x");if(g>r/(null!==(e=null===(o=c.canvas)||void 0===o?void 0:o.getZoom())&&void 0!==e?e:1))return[];let x=u[u.length-1].x-l.x;const h=0==f||3==f?-1:1;x*=h;const{width:y,scaleX:m,left:p}=c,b=c._getTransformedDimensions(),v=(x+b.x)/b.x;s?c.set("scaleX",m*v):c.set("width",y*v);const O=[0,x/2*h,x*h];h<0&&O.reverse();const j=O[i.indexOf(c.originX)];return c.set("left",p+j),c.setCoords(),u.map((t=>({x:t.x,y1:t.y,y2:l.y})))}function s(t){var e,o;const i=n.margin,{activeObject:c,isScale:s,index:f,point:l,list:d}=t,{dis:g,arr:u}=a(l,d,"y");if(g>i/(null!==(e=null===(o=c.canvas)||void 0===o?void 0:o.getZoom())&&void 0!==e?e:1))return[];let x=u[u.length-1].y-l.y;const h=f<2?-1:1;x*=h;const{height:y,scaleY:m,top:p}=c,b=c._getTransformedDimensions(),v=(x+b.y)/b.y;s?c.set("scaleY",m*v):c.set("height",y*v);const O=[0,x/2*h,x*h];h<0&&O.reverse();const j=O[r.indexOf(c.originY)];return c.set("top",p+j),c.setCoords(),u.map((t=>({y:t.y,x1:t.x,x2:l.x})))}function a(t,e,n){let i=1/0,r=[];for(const c of e){const e=o(t[n],c[n]);i>e&&(r=[],i=e),i==e&&r.push(c)}return{dis:i,arr:r}}function f(t,e,o){const{width:i,color:r}=n,c=t.getSelectionContext(),s=t.viewportTransform,a=t.getZoom();c.save(),c.transform(...s),c.lineWidth=i/a,c.strokeStyle=r,c.beginPath(),c.moveTo(e.x,e.y),c.lineTo(o.x,o.y),c.stroke(),d(c,a,e),d(c,a,o),c.restore()}const l=2.4;function d(t,e,n){const o=l/e;t.save(),t.translate(n.x,n.y),t.beginPath(),t.moveTo(-o,-o),t.lineTo(o,o),t.moveTo(o,-o),t.lineTo(-o,o),t.stroke(),t.restore()}function g(t,o){!function(t,e){const{width:o,color:i}=n,r=t.getSelectionContext(),c=t.viewportTransform,s=t.getZoom();r.save(),r.transform(...c),r.lineWidth=o/s,r.strokeStyle=i;for(const t of e)d(r,s,t);r.restore()}(t,o.map((t=>{const n="y2"in t,o=n?t.x:t.x1,i=n?t.y1:t.y;return new e.Point(o,i)})))}function u(t,n){const o=n.x;f(t,new e.Point(o,n.y1),new e.Point(o,n.y2))}function x(t,n){const o=n.y;f(t,new e.Point(n.x1,o),new e.Point(n.x2,o))}function h(t){const n=new Set,o=t.canvas;if(!o)return n;const i=t instanceof e.ActiveSelection?t.getObjects():[t];return o.forEachObject((t=>{t.isOnScreen()&&t.visible&&(t.constructor!=e.Group?n.add(t):m(n,t))})),y(n,i),n}function y(t,n){for(const o of n)o.constructor==e.Group?y(t,o.getObjects()):t.delete(o)}function m(t,n){const o=n.getObjects();for(const n of o)n.visible&&(n.constructor!=e.Group?t.add(n):m(t,n))}function p(t){var e,o;const i=n.margin,{activeObject:r,activeObjectRect:c,objectRect:s}=t,a={target:r,list:v(s),aList:v(c),margin:i/(null!==(e=null===(o=r.canvas)||void 0===o?void 0:o.getZoom())&&void 0!==e?e:1)},f=function(t){const{target:e,list:n,aList:o,margin:i}=t,r=o.map((t=>b(t,n,"x"))),c=Math.min(...r.map((t=>t.dis)));if(c>i)return[];const s=[],a=o[0].x2-o[0].x,f=o[0].y2-o[0].y;let l=!1;for(let t=0;tt.x-=y))}}return s}(a),l=function(t){const{target:e,list:n,aList:o,margin:i}=t,r=o.map((t=>b(t,n,"y"))),c=Math.min(...r.map((t=>t.dis)));if(c>i)return[];const s=[],a=o[0].x2-o[0].x,f=o[0].y2-o[0].y;let l=!1;for(let t=0;tt.y-=y))}}return s}(a);return{vLines:f,hLines:l}}function b(t,e,n){let i=1/0,r=-1,c=1;for(let s=0;sa&&(r=s,i=a,c=t[n]>e[s][n]?1:-1)}return{dis:i,index:r,dir:c}}function v(t){const{left:e,top:n,width:o,height:i}=t,r=e+o/2,c=n+i/2;return[{x:e,y:n,x2:e+o,y2:n+i},{x:r,y:c,x2:r,y2:c},{x:e+o,x2:e,y:n+i,y2:n}]}function O(t){const{target:n,centerX:o,centerY:i,width:r,height:c,dir:s}=t;let{x:a,y:f}=t;a-=o*r/2,f-=i*c/2,function(t,e,n){const o=t.translateToCenterPoint(e,"center","center"),i=t.translateToOriginPoint(o,t.originX,t.originY);"x"==n?t.setX(i.x):t.setY(i.y)}(n,new e.Point(a,f),s),n.setCoords()}const j=function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"left",o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"top";return async function(i){const{originX:r=n,originY:c=o}=i;delete i.originX,delete i.originY;for(var s=arguments.length,a=new Array(s>1?s-1:0),f=1;f1&&void 0!==arguments[1]?arguments[1]:{};Object.assign(n,o);const i=new Set,r=new Set;let a=!1;const f=new Map,l=t=>{const n=[t.calcTransformMatrix().toString(),t.width,t.height].join(),o=f.get(n);if(o)return o;const i=t.getCoords(),r=[e.util.makeBoundingBoxFromPoints(i),i];return f.set(n,r),r};function d(t){const e=t.target;e.setCoords(),a=!1,r.clear(),i.clear();const n=h(e),o=e.getBoundingRect();for(const t of n){const n=l(t)[0],{vLines:c,hLines:s}=p({activeObject:e,activeObjectRect:o,objectRect:n});c.forEach((t=>{r.add(JSON.stringify(t))})),s.forEach((t=>{i.add(JSON.stringify(t))}))}}function y(t){const n=t.target;n.setCoords();const o=String(t.transform.action).startsWith("scale");r.clear(),i.clear();const f=h(n);let d=t.transform.corner;n.flipX&&(d=d.replace("l","r").replace("r","l")),n.flipY&&(d=d.replace("t","b").replace("b","t"));let g=["tl","tr","br","bl","mt","mr","mb","ml"].indexOf(d);if(-1==g)return;if(a=g>3,a){if(n.getTotalAngle()%90!=0)return;g-=4}let u=n.getCoords()[g];for(const t of f){const[a,f]=l(t),d={activeObject:n,point:u,list:[...f,new e.Point(a.left+a.width/2,a.top+a.height/2)],isScale:o,index:g},x=c(d),h=s(d);x.forEach((t=>{r.add(JSON.stringify(t))})),h.forEach((t=>{i.add(JSON.stringify(t))})),(x.length||h.length)&&(u=n.getCoords()[g])}}function m(){t.clearContext(t.contextTop)}function b(){if(a){const e=[];for(const t of r)e.push(JSON.parse(t));for(const t of i)e.push(JSON.parse(t));g(t,e)}else{for(const e of r)u(t,JSON.parse(e));for(const e of i)x(t,JSON.parse(e))}}function v(){r.clear(),i.clear(),f.clear(),t.requestRenderAll()}return t.on("object:resizing",y),t.on("object:scaling",y),t.on("object:moving",d),t.on("before:render",m),t.on("after:render",b),t.on("mouse:up",v),()=>{t.off("object:resizing",y),t.off("object:scaling",y),t.off("object:moving",d),t.off("before:render",m),t.off("after:render",b),t.off("mouse:up",v)}},t.installOriginWrapperUpdater=(t,n)=>{e.BaseFabricObject._fromObject=j(e.BaseFabricObject._fromObject,t,n),e.FabricImage.fromObject=j(e.FabricImage.fromObject,t,n),e.Group.fromObject=j(e.Group.fromObject,t,n)},t.originUpdaterWrapper=j})); +//# sourceMappingURL=fabric-extensions.min.js.map diff --git a/dist-extensions/fabric-extensions.min.js.map b/dist-extensions/fabric-extensions.min.js.map new file mode 100644 index 00000000000..6645c7a4638 --- /dev/null +++ b/dist-extensions/fabric-extensions.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"fabric-extensions.min.js","sources":["../extensions/aligning_guidelines/constant.ts","../extensions/aligning_guidelines/util/basic.ts","../extensions/aligning_guidelines/util/collect-point.ts","../extensions/aligning_guidelines/util/draw.ts","../extensions/aligning_guidelines/util/get-objects-by-target.ts","../extensions/aligning_guidelines/util/collect-line.ts","../extensions/data_updaters/origins/index.ts","../extensions/aligning_guidelines/index.ts"],"sourcesContent":["import type { AligningLineConfig } from './typedefs';\n\nexport const aligningLineConfig: AligningLineConfig = {\n /** At what distance from the shape does alignment begin? */\n margin: 4,\n /** Aligning line dimensions */\n width: 1,\n /** Aligning line color */\n color: 'rgb(255,0,0,0.9)',\n};\n","import type { FabricObject, Point } from 'fabric';\n\nexport function getDistance(a: number, b: number) {\n return Math.abs(a - b);\n}\n\nexport function setPositionDir(\n target: FabricObject,\n pos: Point,\n dir: 'x' | 'y',\n) {\n const center = target.translateToCenterPoint(pos, 'center', 'center');\n const position = target.translateToOriginPoint(\n center,\n target.originX,\n target.originY,\n );\n if (dir == 'x') target.setX(position.x);\n else target.setY(position.y);\n}\n","import type { FabricObject, Point, TOriginX, TOriginY } from 'fabric';\nimport { aligningLineConfig } from '../constant';\nimport { getDistance } from './basic';\n\ntype CollectPointProps = {\n activeObject: FabricObject;\n point: Point;\n list: Point[];\n isScale: boolean;\n index: number;\n};\nconst originXArr: TOriginX[] = ['left', 'center', 'right'];\nconst originYArr: TOriginY[] = ['top', 'center', 'bottom'];\n\nexport function collectVerticalPoint(props: CollectPointProps) {\n const aligningLineMargin = aligningLineConfig.margin;\n const { activeObject, isScale, index, point, list } = props;\n const { dis, arr } = getDistanceList(point, list, 'x');\n const margin = aligningLineMargin / (activeObject.canvas?.getZoom() ?? 1);\n if (dis > margin) return [];\n let v = arr[arr.length - 1].x - point.x;\n const dir = index == 0 || index == 3 ? -1 : 1;\n v *= dir;\n\n const { width, scaleX, left } = activeObject;\n const dim = activeObject._getTransformedDimensions();\n const sx = (v + dim.x) / dim.x;\n if (isScale) activeObject.set('scaleX', scaleX * sx);\n else activeObject.set('width', width * sx);\n const dArr = [0, (v / 2) * dir, v * dir];\n if (dir < 0) dArr.reverse();\n const d = dArr[originXArr.indexOf(activeObject.originX)];\n activeObject.set('left', left + d);\n activeObject.setCoords();\n return arr.map((item) => ({\n x: item.x,\n y1: item.y,\n y2: point.y,\n }));\n}\n\nexport function collectHorizontalPoint(props: CollectPointProps) {\n const aligningLineMargin = aligningLineConfig.margin;\n const { activeObject, isScale, index, point, list } = props;\n const { dis, arr } = getDistanceList(point, list, 'y');\n const margin = aligningLineMargin / (activeObject.canvas?.getZoom() ?? 1);\n if (dis > margin) return [];\n let v = arr[arr.length - 1].y - point.y;\n const dir = index < 2 ? -1 : 1;\n v *= dir;\n\n const { height, scaleY, top } = activeObject;\n const dim = activeObject._getTransformedDimensions();\n const sy = (v + dim.y) / dim.y;\n if (isScale) activeObject.set('scaleY', scaleY * sy);\n else activeObject.set('height', height * sy);\n const dArr = [0, (v / 2) * dir, v * dir];\n if (dir < 0) dArr.reverse();\n const d = dArr[originYArr.indexOf(activeObject.originY)];\n activeObject.set('top', top + d);\n activeObject.setCoords();\n return arr.map((item) => ({\n y: item.y,\n x1: item.x,\n x2: point.x,\n }));\n}\n\nfunction getDistanceList(point: Point, list: Point[], type: 'x' | 'y') {\n let dis = Infinity;\n let arr: Point[] = [];\n for (const item of list) {\n const v = getDistance(point[type], item[type]);\n if (dis > v) {\n arr = [];\n dis = v;\n }\n if (dis == v) {\n arr.push(item);\n }\n }\n return { dis, arr };\n}\n","import type { Canvas } from 'fabric';\nimport { Point } from 'fabric';\nimport type { HorizontalLine, VerticalLine } from '../typedefs';\nimport { aligningLineConfig } from '../constant';\n\nfunction drawLine(canvas: Canvas, origin: Point, target: Point) {\n const { width, color } = aligningLineConfig;\n const ctx = canvas.getSelectionContext();\n const viewportTransform = canvas.viewportTransform;\n const zoom = canvas.getZoom();\n ctx.save();\n ctx.transform(...viewportTransform);\n ctx.lineWidth = width / zoom;\n ctx.strokeStyle = color;\n ctx.beginPath();\n ctx.moveTo(origin.x, origin.y);\n ctx.lineTo(target.x, target.y);\n ctx.stroke();\n drawX(ctx, zoom, origin);\n drawX(ctx, zoom, target);\n ctx.restore();\n}\n\nconst xSize = 2.4;\nfunction drawX(ctx: CanvasRenderingContext2D, zoom: number, point: Point) {\n const size = xSize / zoom;\n ctx.save();\n ctx.translate(point.x, point.y);\n ctx.beginPath();\n ctx.moveTo(-size, -size);\n ctx.lineTo(size, size);\n ctx.moveTo(size, -size);\n ctx.lineTo(-size, size);\n ctx.stroke();\n ctx.restore();\n}\nfunction drawPoint(canvas: Canvas, arr: Point[]) {\n const { width, color } = aligningLineConfig;\n const ctx = canvas.getSelectionContext();\n const viewportTransform = canvas.viewportTransform;\n const zoom = canvas.getZoom();\n ctx.save();\n ctx.transform(...viewportTransform);\n ctx.lineWidth = width / zoom;\n ctx.strokeStyle = color;\n for (const item of arr) drawX(ctx, zoom, item);\n ctx.restore();\n}\nexport function drawPointList(\n canvas: Canvas,\n list: Array,\n) {\n const arr = list.map((item) => {\n const isVertical = 'y2' in item;\n const x = isVertical ? item.x : item.x1;\n const y = isVertical ? item.y1 : item.y;\n return new Point(x, y);\n });\n drawPoint(canvas, arr);\n}\n\nexport function drawVerticalLine(canvas: Canvas, coords: VerticalLine) {\n const x = coords.x;\n const origin = new Point(x, coords.y1);\n const target = new Point(x, coords.y2);\n drawLine(canvas, origin, target);\n}\n\nexport function drawHorizontalLine(canvas: Canvas, coords: HorizontalLine) {\n const y = coords.y;\n const origin = new Point(coords.x1, y);\n const target = new Point(coords.x2, y);\n drawLine(canvas, origin, target);\n}\n","import type { FabricObject } from 'fabric';\nimport { ActiveSelection, Group } from 'fabric';\n\nexport function getObjectsByTarget(target: FabricObject) {\n const objects = new Set();\n const canvas = target.canvas;\n if (!canvas) return objects;\n const children =\n target instanceof ActiveSelection ? target.getObjects() : [target];\n\n canvas.forEachObject((o) => {\n if (!o.isOnScreen()) return;\n if (!o.visible) return;\n if (o.constructor == Group) {\n collectObjectsByGroup(objects, o);\n return;\n }\n objects.add(o);\n });\n\n deleteObjectsByList(objects, children);\n return objects;\n}\n\nfunction deleteObjectsByList(objects: Set, list: FabricObject[]) {\n for (const target of list) {\n if (target.constructor == Group) {\n deleteObjectsByList(objects, (target as Group).getObjects());\n } else {\n objects.delete(target);\n }\n }\n}\n\nfunction collectObjectsByGroup(objects: Set, g: Group) {\n const children = g.getObjects();\n for (const child of children) {\n if (!child.visible) continue;\n if (child.constructor == Group) {\n collectObjectsByGroup(objects, child);\n continue;\n }\n objects.add(child);\n }\n}\n","import type { FabricObject, TBBox } from 'fabric';\nimport { Point } from 'fabric';\nimport type { HorizontalLine, VerticalLine } from '../typedefs';\nimport { aligningLineConfig } from '../constant';\nimport { getDistance, setPositionDir } from './basic';\n\ntype CollectLineProps = {\n activeObject: FabricObject;\n activeObjectRect: TBBox;\n objectRect: TBBox;\n};\n\nexport function collectLine(props: CollectLineProps) {\n const aligningLineMargin = aligningLineConfig.margin;\n const { activeObject, activeObjectRect, objectRect } = props;\n const list = makeLineByRect(objectRect);\n const aList = makeLineByRect(activeObjectRect);\n const margin = aligningLineMargin / (activeObject.canvas?.getZoom() ?? 1);\n const opts = { target: activeObject, list, aList, margin };\n const vLines = collectVerticalLine(opts);\n const hLines = collectHorizontalLine(opts);\n\n return { vLines, hLines };\n}\n\ntype CollectItemLineProps = {\n target: FabricObject;\n list: LineProps[];\n aList: LineProps[];\n margin: number;\n};\nfunction collectVerticalLine(props: CollectItemLineProps) {\n const { target, list, aList, margin } = props;\n\n const arr = aList.map((x) => getDistanceLine(x, list, 'x'));\n const min = Math.min(...arr.map((x) => x.dis));\n if (min > margin) return [];\n const lines: VerticalLine[] = [];\n const width = aList[0].x2 - aList[0].x;\n const height = aList[0].y2 - aList[0].y;\n let b = false;\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (min == item.dis) {\n const line = list[item.index];\n const aLine = aList[item.index];\n const x = line.x;\n const y = aLine.y;\n\n const y1 = Math.min(line.y, line.y2, y, aLine.y2);\n const y2 = Math.max(line.y, line.y2, y, aLine.y2);\n // 参考线可画多条\n lines.push({ x, y1, y2 });\n if (b) continue;\n b = true;\n // 对齐只进行一次\n setPos({\n target,\n x,\n y,\n centerX: i - 1,\n centerY: item.index - 1,\n width,\n height,\n dir: 'x',\n });\n const dis = min * item.dir;\n aList.forEach((x) => (x.x -= dis));\n }\n }\n return lines;\n}\n\nfunction collectHorizontalLine(props: CollectItemLineProps) {\n const { target, list, aList, margin } = props;\n\n const arr = aList.map((x) => getDistanceLine(x, list, 'y'));\n const min = Math.min(...arr.map((x) => x.dis));\n if (min > margin) return [];\n const lines: HorizontalLine[] = [];\n const width = aList[0].x2 - aList[0].x;\n const height = aList[0].y2 - aList[0].y;\n let b = false;\n for (let i = 0; i < arr.length; i++) {\n const item = arr[i];\n if (min == item.dis) {\n const line = list[item.index];\n const aLine = aList[item.index];\n const y = line.y;\n const x = aLine.x;\n\n const x1 = Math.min(line.x, line.x2, x, aLine.x2);\n const x2 = Math.max(line.x, line.x2, x, aLine.x2);\n // 参考线可画多条\n lines.push({ y, x1, x2 });\n if (b) continue;\n b = true;\n // 对齐只进行一次\n setPos({\n target,\n x,\n y,\n centerX: item.index - 1,\n centerY: i - 1,\n width,\n height,\n dir: 'y',\n });\n const dis = min * item.dir;\n aList.forEach((x) => (x.y -= dis));\n }\n }\n return lines;\n}\n\ntype LineProps = {\n x: number;\n y: number;\n x2: number;\n y2: number;\n};\nfunction getDistanceLine(\n target: LineProps,\n list: LineProps[],\n type: 'x' | 'y',\n) {\n let dis = Infinity;\n let index = -1;\n /** 1正值 -1负值 */\n let dir = 1;\n for (let i = 0; i < list.length; i++) {\n const v = getDistance(target[type], list[i][type]);\n if (dis > v) {\n index = i;\n dis = v;\n dir = target[type] > list[i][type] ? 1 : -1;\n }\n }\n return { dis, index, dir };\n}\n\nfunction makeLineByRect(rect: TBBox) {\n const { left, top, width, height } = rect;\n const a = { x: left, y: top, x2: left + width, y2: top + height };\n const x = left + width / 2;\n const y = top + height / 2;\n const b = { x, y, x2: x, y2: y };\n const c = { x: left + width, x2: left, y: top + height, y2: top };\n\n return [a, b, c];\n}\n\ntype SnapToPixelProps = {\n target: FabricObject;\n x: number;\n y: number;\n /** -1 0 1 */\n centerX: number;\n /** -1 0 1 */\n centerY: number;\n width: number;\n height: number;\n dir: 'x' | 'y';\n};\nfunction setPos(props: SnapToPixelProps) {\n const { target, centerX, centerY, width, height, dir } = props;\n let { x, y } = props;\n x -= (centerX * width) / 2;\n y -= (centerY * height) / 2;\n setPositionDir(target, new Point(x, y), dir);\n target.setCoords();\n}\n","import {\n Point,\n FabricImage,\n Group,\n BaseFabricObject,\n type FabricObject,\n type TOriginX,\n type TOriginY,\n} from 'fabric';\n\n/**\n * Updates the fromObject function of a class to return a version that can restore old data\n * with values of originX and originY that are different from 'center', 'center'\n * Used to upgrade from fabric 6 to fabric 7\n * @param originalFn the original fromObject function of an object,\n * @param defaultOriginX optional default value for non exported originX,\n * @param defaultOriginY optional default value for non exported originY,\n * @returns a wrapped fromObject function for the object\n */\nexport const originUpdaterWrapper = (\n originalFn: (...args: any[]) => Promise,\n defaultOriginX: TOriginX = 'left',\n defaultOriginY: TOriginY = 'top',\n): ((...args: any[]) => Promise) =>\n async function (this: T, serializedObject, ...args) {\n // we default to left and top because those are defaults before deprecation\n const { originX = defaultOriginX, originY = defaultOriginY } =\n serializedObject;\n // and we do not want to pass those properties on the object anymore\n delete serializedObject.originX;\n delete serializedObject.originY;\n const originalObject = await originalFn.call(\n this,\n serializedObject,\n ...args,\n );\n const actualPosition = new Point(originalObject.left, originalObject.top);\n originalObject.setPositionByOrigin(actualPosition, originX, originY);\n return originalObject;\n };\n\n/**\n * Wraps and override the current fabricJS fromObject static functions\n * Used to upgrade from fabric 6 to fabric 7\n * @param defaultOriginX optional default value for non exported originX,\n * @param defaultOriginY optional default value for non exported originY,\n * @returns a wrapped fromObject function for the object\n */\nexport const installOriginWrapperUpdater = (\n originX?: TOriginX,\n originY?: TOriginY,\n) => {\n // @ts-expect-error the _fromObject parameter could be instantiated differently\n BaseFabricObject._fromObject = originUpdaterWrapper(\n BaseFabricObject._fromObject,\n originX,\n originY,\n );\n // FabricImage and Group do not use _fromObject\n FabricImage.fromObject = originUpdaterWrapper(\n FabricImage.fromObject,\n originX,\n originY,\n );\n Group.fromObject = originUpdaterWrapper(\n Group.fromObject,\n originX,\n originY,\n );\n};\n","import type {\n BasicTransformEvent,\n Canvas,\n FabricObject,\n TBBox,\n TPointerEvent,\n} from 'fabric';\nimport { Point, util } from 'fabric';\nimport {\n collectHorizontalPoint,\n collectVerticalPoint,\n} from './util/collect-point';\nimport {\n drawHorizontalLine,\n drawPointList,\n drawVerticalLine,\n} from './util/draw';\nimport { getObjectsByTarget } from './util/get-objects-by-target';\nimport { collectLine } from './util/collect-line';\nimport type {\n AligningLineConfig,\n HorizontalLine,\n VerticalLine,\n} from './typedefs';\nimport { aligningLineConfig } from './constant';\n\ntype TransformEvent = BasicTransformEvent & {\n target: FabricObject;\n};\n\nexport type { AligningLineConfig } from './typedefs';\n\nexport function initAligningGuidelines(\n canvas: Canvas,\n options: Partial = {},\n) {\n Object.assign(aligningLineConfig, options);\n\n const horizontalLines = new Set();\n const verticalLines = new Set();\n let onlyDrawPoint = false;\n const cacheMap = new Map();\n\n const getCaCheMapValue = (object: FabricObject) => {\n const cacheKey = [\n object.calcTransformMatrix().toString(),\n object.width,\n object.height,\n ].join();\n const cacheValue = cacheMap.get(cacheKey);\n if (cacheValue) return cacheValue;\n const coords = object.getCoords();\n const rect = util.makeBoundingBoxFromPoints(coords);\n const value: [TBBox, Point[]] = [rect, coords];\n cacheMap.set(cacheKey, value);\n return value;\n };\n\n function moving(e: TransformEvent) {\n const activeObject = e.target;\n activeObject.setCoords();\n onlyDrawPoint = false;\n verticalLines.clear();\n horizontalLines.clear();\n\n const objects = getObjectsByTarget(activeObject);\n const activeObjectRect = activeObject.getBoundingRect();\n\n for (const object of objects) {\n const objectRect = getCaCheMapValue(object)[0];\n const { vLines, hLines } = collectLine({\n activeObject,\n activeObjectRect,\n objectRect,\n });\n vLines.forEach((o) => {\n verticalLines.add(JSON.stringify(o));\n });\n hLines.forEach((o) => {\n horizontalLines.add(JSON.stringify(o));\n });\n }\n }\n\n function scalingOrResizing(e: TransformEvent) {\n // br bl tr tl mb ml mt mr\n const activeObject = e.target;\n activeObject.setCoords();\n const isScale = String(e.transform.action).startsWith('scale');\n verticalLines.clear();\n horizontalLines.clear();\n\n const objects = getObjectsByTarget(activeObject);\n let corner = e.transform.corner;\n if (activeObject.flipX) corner = corner.replace('l', 'r').replace('r', 'l');\n if (activeObject.flipY) corner = corner.replace('t', 'b').replace('b', 't');\n let index = ['tl', 'tr', 'br', 'bl', 'mt', 'mr', 'mb', 'ml'].indexOf(\n corner,\n );\n if (index == -1) return;\n onlyDrawPoint = index > 3;\n if (onlyDrawPoint) {\n const angle = activeObject.getTotalAngle();\n if (angle % 90 != 0) return;\n index -= 4;\n }\n let point = activeObject.getCoords()[index];\n for (const object of objects) {\n const [rect, coords] = getCaCheMapValue(object);\n const center = new Point(\n rect.left + rect.width / 2,\n rect.top + rect.height / 2,\n );\n const list = [...coords, center];\n const props = { activeObject, point, list, isScale, index };\n const vLines = collectVerticalPoint(props);\n const hLines = collectHorizontalPoint(props);\n vLines.forEach((o) => {\n verticalLines.add(JSON.stringify(o));\n });\n hLines.forEach((o) => {\n horizontalLines.add(JSON.stringify(o));\n });\n if (vLines.length || hLines.length)\n point = activeObject.getCoords()[index];\n }\n }\n\n function beforeRender() {\n canvas.clearContext(canvas.contextTop);\n }\n function afterRender() {\n if (onlyDrawPoint) {\n const list: Array = [];\n for (const v of verticalLines) list.push(JSON.parse(v));\n for (const h of horizontalLines) list.push(JSON.parse(h));\n drawPointList(canvas, list);\n } else {\n for (const v of verticalLines) drawVerticalLine(canvas, JSON.parse(v));\n for (const h of horizontalLines)\n drawHorizontalLine(canvas, JSON.parse(h));\n }\n }\n function mouseUp() {\n verticalLines.clear();\n horizontalLines.clear();\n cacheMap.clear();\n canvas.requestRenderAll();\n }\n\n canvas.on('object:resizing', scalingOrResizing);\n canvas.on('object:scaling', scalingOrResizing);\n canvas.on('object:moving', moving);\n canvas.on('before:render', beforeRender);\n canvas.on('after:render', afterRender);\n canvas.on('mouse:up', mouseUp);\n\n return () => {\n canvas.off('object:resizing', scalingOrResizing);\n canvas.off('object:scaling', scalingOrResizing);\n canvas.off('object:moving', moving);\n canvas.off('before:render', beforeRender);\n canvas.off('after:render', afterRender);\n canvas.off('mouse:up', mouseUp);\n };\n}\n"],"names":["aligningLineConfig","margin","width","color","getDistance","a","b","Math","abs","originXArr","originYArr","collectVerticalPoint","props","_activeObject$canvas$","_activeObject$canvas","aligningLineMargin","activeObject","isScale","index","point","list","dis","arr","getDistanceList","canvas","getZoom","v","length","x","dir","scaleX","left","dim","_getTransformedDimensions","sx","set","dArr","reverse","d","indexOf","originX","setCoords","map","item","y1","y","y2","collectHorizontalPoint","_activeObject$canvas$2","_activeObject$canvas2","height","scaleY","top","sy","originY","x1","x2","type","Infinity","push","drawLine","origin","target","ctx","getSelectionContext","viewportTransform","zoom","save","transform","lineWidth","strokeStyle","beginPath","moveTo","lineTo","stroke","drawX","restore","xSize","size","translate","drawPointList","drawPoint","isVertical","Point","drawVerticalLine","coords","drawHorizontalLine","getObjectsByTarget","objects","Set","children","ActiveSelection","getObjects","forEachObject","o","isOnScreen","visible","constructor","Group","add","collectObjectsByGroup","deleteObjectsByList","delete","g","child","collectLine","activeObjectRect","objectRect","opts","makeLineByRect","aList","vLines","getDistanceLine","min","lines","i","line","aLine","max","setPos","centerX","centerY","forEach","collectVerticalLine","hLines","collectHorizontalLine","rect","pos","center","translateToCenterPoint","position","translateToOriginPoint","setX","setY","setPositionDir","originUpdaterWrapper","originalFn","defaultOriginX","arguments","undefined","defaultOriginY","async","serializedObject","_len","args","Array","_key","originalObject","call","this","actualPosition","setPositionByOrigin","options","Object","assign","horizontalLines","verticalLines","onlyDrawPoint","cacheMap","Map","getCaCheMapValue","object","cacheKey","calcTransformMatrix","toString","join","cacheValue","get","getCoords","value","util","makeBoundingBoxFromPoints","moving","e","clear","getBoundingRect","JSON","stringify","scalingOrResizing","String","action","startsWith","corner","flipX","replace","flipY","getTotalAngle","beforeRender","clearContext","contextTop","afterRender","parse","h","mouseUp","requestRenderAll","on","off","installOriginWrapperUpdater","BaseFabricObject","_fromObject","FabricImage","fromObject"],"mappings":"8RAEO,MAAMA,EAAyC,CAEpDC,OAAQ,EAERC,MAAO,EAEPC,MAAO,oBCNF,SAASC,EAAYC,EAAWC,GACrC,OAAOC,KAAKC,IAAIH,EAAIC,EACtB,CCOA,MAAMG,EAAyB,CAAC,OAAQ,SAAU,SAC5CC,EAAyB,CAAC,MAAO,SAAU,UAE1C,SAASC,EAAqBC,GAA0B,IAAAC,EAAAC,EAC7D,MAAMC,EAAqBf,EAAmBC,QACxCe,aAAEA,EAAYC,QAAEA,EAAOC,MAAEA,EAAKC,MAAEA,EAAKC,KAAEA,GAASR,GAChDS,IAAEA,EAAGC,IAAEA,GAAQC,EAAgBJ,EAAOC,EAAM,KAElD,GAAIC,EADWN,GAAoDF,QAAlCA,EAAuB,QAAvBC,EAAIE,EAAaQ,cAAbV,IAAmBA,OAAnBA,EAAAA,EAAqBW,iBAASZ,IAAAA,EAAAA,EAAI,GACrD,MAAO,GACzB,IAAIa,EAAIJ,EAAIA,EAAIK,OAAS,GAAGC,EAAIT,EAAMS,EACtC,MAAMC,EAAe,GAATX,GAAuB,GAATA,GAAc,EAAI,EAC5CQ,GAAKG,EAEL,MAAM3B,MAAEA,EAAK4B,OAAEA,EAAMC,KAAEA,GAASf,EAC1BgB,EAAMhB,EAAaiB,4BACnBC,GAAMR,EAAIM,EAAIJ,GAAKI,EAAIJ,EACzBX,EAASD,EAAamB,IAAI,SAAUL,EAASI,GAC5ClB,EAAamB,IAAI,QAASjC,EAAQgC,GACvC,MAAME,EAAO,CAAC,EAAIV,EAAI,EAAKG,EAAKH,EAAIG,GAChCA,EAAM,GAAGO,EAAKC,UAClB,MAAMC,EAAIF,EAAK3B,EAAW8B,QAAQvB,EAAawB,UAG/C,OAFAxB,EAAamB,IAAI,OAAQJ,EAAOO,GAChCtB,EAAayB,YACNnB,EAAIoB,KAAKC,IAAU,CACxBf,EAAGe,EAAKf,EACRgB,GAAID,EAAKE,EACTC,GAAI3B,EAAM0B,KAEd,CAEO,SAASE,EAAuBnC,GAA0B,IAAAoC,EAAAC,EAC/D,MAAMlC,EAAqBf,EAAmBC,QACxCe,aAAEA,EAAYC,QAAEA,EAAOC,MAAEA,EAAKC,MAAEA,EAAKC,KAAEA,GAASR,GAChDS,IAAEA,EAAGC,IAAEA,GAAQC,EAAgBJ,EAAOC,EAAM,KAElD,GAAIC,EADWN,GAAoDiC,QAAlCA,EAAuB,QAAvBC,EAAIjC,EAAaQ,cAAbyB,IAAmBA,OAAnBA,EAAAA,EAAqBxB,iBAASuB,IAAAA,EAAAA,EAAI,GACrD,MAAO,GACzB,IAAItB,EAAIJ,EAAIA,EAAIK,OAAS,GAAGkB,EAAI1B,EAAM0B,EACtC,MAAMhB,EAAMX,EAAQ,GAAK,EAAI,EAC7BQ,GAAKG,EAEL,MAAMqB,OAAEA,EAAMC,OAAEA,EAAMC,IAAEA,GAAQpC,EAC1BgB,EAAMhB,EAAaiB,4BACnBoB,GAAM3B,EAAIM,EAAIa,GAAKb,EAAIa,EACzB5B,EAASD,EAAamB,IAAI,SAAUgB,EAASE,GAC5CrC,EAAamB,IAAI,SAAUe,EAASG,GACzC,MAAMjB,EAAO,CAAC,EAAIV,EAAI,EAAKG,EAAKH,EAAIG,GAChCA,EAAM,GAAGO,EAAKC,UAClB,MAAMC,EAAIF,EAAK1B,EAAW6B,QAAQvB,EAAasC,UAG/C,OAFAtC,EAAamB,IAAI,MAAOiB,EAAMd,GAC9BtB,EAAayB,YACNnB,EAAIoB,KAAKC,IAAU,CACxBE,EAAGF,EAAKE,EACRU,GAAIZ,EAAKf,EACT4B,GAAIrC,EAAMS,KAEd,CAEA,SAASL,EAAgBJ,EAAcC,EAAeqC,GACpD,IAAIpC,EAAMqC,IACNpC,EAAe,GACnB,IAAK,MAAMqB,KAAQvB,EAAM,CACvB,MAAMM,EAAItB,EAAYe,EAAMsC,GAAOd,EAAKc,IACpCpC,EAAMK,IACRJ,EAAM,GACND,EAAMK,GAEJL,GAAOK,GACTJ,EAAIqC,KAAKhB,EAEb,CACA,MAAO,CAAEtB,MAAKC,MAChB,CC7EA,SAASsC,EAASpC,EAAgBqC,EAAeC,GAC/C,MAAM5D,MAAEA,EAAKC,MAAEA,GAAUH,EACnB+D,EAAMvC,EAAOwC,sBACbC,EAAoBzC,EAAOyC,kBAC3BC,EAAO1C,EAAOC,UACpBsC,EAAII,OACJJ,EAAIK,aAAaH,GACjBF,EAAIM,UAAYnE,EAAQgE,EACxBH,EAAIO,YAAcnE,EAClB4D,EAAIQ,YACJR,EAAIS,OAAOX,EAAOjC,EAAGiC,EAAOhB,GAC5BkB,EAAIU,OAAOX,EAAOlC,EAAGkC,EAAOjB,GAC5BkB,EAAIW,SACJC,EAAMZ,EAAKG,EAAML,GACjBc,EAAMZ,EAAKG,EAAMJ,GACjBC,EAAIa,SACN,CAEA,MAAMC,EAAQ,IACd,SAASF,EAAMZ,EAA+BG,EAAc/C,GAC1D,MAAM2D,EAAOD,EAAQX,EACrBH,EAAII,OACJJ,EAAIgB,UAAU5D,EAAMS,EAAGT,EAAM0B,GAC7BkB,EAAIQ,YACJR,EAAIS,QAAQM,GAAOA,GACnBf,EAAIU,OAAOK,EAAMA,GACjBf,EAAIS,OAAOM,GAAOA,GAClBf,EAAIU,QAAQK,EAAMA,GAClBf,EAAIW,SACJX,EAAIa,SACN,CAaO,SAASI,EACdxD,EACAJ,IAdF,SAAmBI,EAAgBF,GACjC,MAAMpB,MAAEA,EAAKC,MAAEA,GAAUH,EACnB+D,EAAMvC,EAAOwC,sBACbC,EAAoBzC,EAAOyC,kBAC3BC,EAAO1C,EAAOC,UACpBsC,EAAII,OACJJ,EAAIK,aAAaH,GACjBF,EAAIM,UAAYnE,EAAQgE,EACxBH,EAAIO,YAAcnE,EAClB,IAAK,MAAMwC,KAAQrB,EAAKqD,EAAMZ,EAAKG,EAAMvB,GACzCoB,EAAIa,SACN,CAWEK,CAAUzD,EANEJ,EAAKsB,KAAKC,IACpB,MAAMuC,EAAa,OAAQvC,EACrBf,EAAIsD,EAAavC,EAAKf,EAAIe,EAAKY,GAC/BV,EAAIqC,EAAavC,EAAKC,GAAKD,EAAKE,EACtC,OAAO,IAAIsC,EAAKA,MAACvD,EAAGiB,EAAE,IAG1B,CAEO,SAASuC,EAAiB5D,EAAgB6D,GAC/C,MAAMzD,EAAIyD,EAAOzD,EAGjBgC,EAASpC,EAFM,IAAI2D,EAAKA,MAACvD,EAAGyD,EAAOzC,IACpB,IAAIuC,EAAKA,MAACvD,EAAGyD,EAAOvC,IAErC,CAEO,SAASwC,EAAmB9D,EAAgB6D,GACjD,MAAMxC,EAAIwC,EAAOxC,EAGjBe,EAASpC,EAFM,IAAI2D,EAAKA,MAACE,EAAO9B,GAAIV,GACrB,IAAIsC,EAAKA,MAACE,EAAO7B,GAAIX,GAEtC,CCtEO,SAAS0C,EAAmBzB,GACjC,MAAM0B,EAAU,IAAIC,IACdjE,EAASsC,EAAOtC,OACtB,IAAKA,EAAQ,OAAOgE,EACpB,MAAME,EACJ5B,aAAkB6B,EAAeA,gBAAG7B,EAAO8B,aAAe,CAAC9B,GAa7D,OAXAtC,EAAOqE,eAAeC,IACfA,EAAEC,cACFD,EAAEE,UACHF,EAAEG,aAAeC,QAIrBV,EAAQW,IAAIL,GAHVM,EAAsBZ,EAASM,GAGnB,IAGhBO,EAAoBb,EAASE,GACtBF,CACT,CAEA,SAASa,EAAoBb,EAA4BpE,GACvD,IAAK,MAAM0C,KAAU1C,EACf0C,EAAOmC,aAAeC,QACxBG,EAAoBb,EAAU1B,EAAiB8B,cAE/CJ,EAAQc,OAAOxC,EAGrB,CAEA,SAASsC,EAAsBZ,EAA4Be,GACzD,MAAMb,EAAWa,EAAEX,aACnB,IAAK,MAAMY,KAASd,EACbc,EAAMR,UACPQ,EAAMP,aAAeC,QAIzBV,EAAQW,IAAIK,GAHVJ,EAAsBZ,EAASgB,GAKrC,CChCO,SAASC,EAAY7F,GAAyB,IAAAC,EAAAC,EACnD,MAAMC,EAAqBf,EAAmBC,QACxCe,aAAEA,EAAY0F,iBAAEA,EAAgBC,WAAEA,GAAe/F,EAIjDgG,EAAO,CAAE9C,OAAQ9C,EAAcI,KAHxByF,EAAeF,GAGeG,MAF7BD,EAAeH,GAEqBzG,OADnCc,GAAoDF,QAAlCA,EAAuB,QAAvBC,EAAIE,EAAaQ,cAAbV,IAAmBA,OAAnBA,EAAAA,EAAqBW,iBAASZ,IAAAA,EAAAA,EAAI,IAEjEkG,EAYR,SAA6BnG,GAC3B,MAAMkD,OAAEA,EAAM1C,KAAEA,EAAI0F,MAAEA,EAAK7G,OAAEA,GAAWW,EAElCU,EAAMwF,EAAMpE,KAAKd,GAAMoF,EAAgBpF,EAAGR,EAAM,OAChD6F,EAAM1G,KAAK0G,OAAO3F,EAAIoB,KAAKd,GAAMA,EAAEP,OACzC,GAAI4F,EAAMhH,EAAQ,MAAO,GACzB,MAAMiH,EAAwB,GACxBhH,EAAQ4G,EAAM,GAAGtD,GAAKsD,EAAM,GAAGlF,EAC/BsB,EAAS4D,EAAM,GAAGhE,GAAKgE,EAAM,GAAGjE,EACtC,IAAIvC,GAAI,EACR,IAAK,IAAI6G,EAAI,EAAGA,EAAI7F,EAAIK,OAAQwF,IAAK,CACnC,MAAMxE,EAAOrB,EAAI6F,GACjB,GAAIF,GAAOtE,EAAKtB,IAAK,CACnB,MAAM+F,EAAOhG,EAAKuB,EAAKzB,OACjBmG,EAAQP,EAAMnE,EAAKzB,OACnBU,EAAIwF,EAAKxF,EACTiB,EAAIwE,EAAMxE,EAEVD,EAAKrC,KAAK0G,IAAIG,EAAKvE,EAAGuE,EAAKtE,GAAID,EAAGwE,EAAMvE,IACxCA,EAAKvC,KAAK+G,IAAIF,EAAKvE,EAAGuE,EAAKtE,GAAID,EAAGwE,EAAMvE,IAG9C,GADAoE,EAAMvD,KAAK,CAAE/B,IAAGgB,KAAIE,OAChBxC,EAAG,SACPA,GAAI,EAEJiH,EAAO,CACLzD,SACAlC,IACAiB,IACA2E,QAASL,EAAI,EACbM,QAAS9E,EAAKzB,MAAQ,EACtBhB,QACAgD,SACArB,IAAK,MAEP,MAAMR,EAAM4F,EAAMtE,EAAKd,IACvBiF,EAAMY,SAAS9F,GAAOA,EAAEA,GAAKP,GAC/B,CACF,CACA,OAAO6F,CACT,CApDiBS,CAAoBf,GAC7BgB,EAqDR,SAA+BhH,GAC7B,MAAMkD,OAAEA,EAAM1C,KAAEA,EAAI0F,MAAEA,EAAK7G,OAAEA,GAAWW,EAElCU,EAAMwF,EAAMpE,KAAKd,GAAMoF,EAAgBpF,EAAGR,EAAM,OAChD6F,EAAM1G,KAAK0G,OAAO3F,EAAIoB,KAAKd,GAAMA,EAAEP,OACzC,GAAI4F,EAAMhH,EAAQ,MAAO,GACzB,MAAMiH,EAA0B,GAC1BhH,EAAQ4G,EAAM,GAAGtD,GAAKsD,EAAM,GAAGlF,EAC/BsB,EAAS4D,EAAM,GAAGhE,GAAKgE,EAAM,GAAGjE,EACtC,IAAIvC,GAAI,EACR,IAAK,IAAI6G,EAAI,EAAGA,EAAI7F,EAAIK,OAAQwF,IAAK,CACnC,MAAMxE,EAAOrB,EAAI6F,GACjB,GAAIF,GAAOtE,EAAKtB,IAAK,CACnB,MAAM+F,EAAOhG,EAAKuB,EAAKzB,OACjBmG,EAAQP,EAAMnE,EAAKzB,OACnB2B,EAAIuE,EAAKvE,EACTjB,EAAIyF,EAAMzF,EAEV2B,EAAKhD,KAAK0G,IAAIG,EAAKxF,EAAGwF,EAAK5D,GAAI5B,EAAGyF,EAAM7D,IACxCA,EAAKjD,KAAK+G,IAAIF,EAAKxF,EAAGwF,EAAK5D,GAAI5B,EAAGyF,EAAM7D,IAG9C,GADA0D,EAAMvD,KAAK,CAAEd,IAAGU,KAAIC,OAChBlD,EAAG,SACPA,GAAI,EAEJiH,EAAO,CACLzD,SACAlC,IACAiB,IACA2E,QAAS7E,EAAKzB,MAAQ,EACtBuG,QAASN,EAAI,EACbjH,QACAgD,SACArB,IAAK,MAEP,MAAMR,EAAM4F,EAAMtE,EAAKd,IACvBiF,EAAMY,SAAS9F,GAAOA,EAAEiB,GAAKxB,GAC/B,CACF,CACA,OAAO6F,CACT,CA7FiBW,CAAsBjB,GAErC,MAAO,CAAEG,SAAQa,SACnB,CAkGA,SAASZ,EACPlD,EACA1C,EACAqC,GAEA,IAAIpC,EAAMqC,IACNxC,GAAS,EAETW,EAAM,EACV,IAAK,IAAIsF,EAAI,EAAGA,EAAI/F,EAAKO,OAAQwF,IAAK,CACpC,MAAMzF,EAAItB,EAAY0D,EAAOL,GAAOrC,EAAK+F,GAAG1D,IACxCpC,EAAMK,IACRR,EAAQiG,EACR9F,EAAMK,EACNG,EAAMiC,EAAOL,GAAQrC,EAAK+F,GAAG1D,GAAQ,GAAK,EAE9C,CACA,MAAO,CAAEpC,MAAKH,QAAOW,MACvB,CAEA,SAASgF,EAAeiB,GACtB,MAAM/F,KAAEA,EAAIqB,IAAEA,EAAGlD,MAAEA,EAAKgD,OAAEA,GAAW4E,EAE/BlG,EAAIG,EAAO7B,EAAQ,EACnB2C,EAAIO,EAAMF,EAAS,EAIzB,MAAO,CANG,CAAEtB,EAAGG,EAAMc,EAAGO,EAAKI,GAAIzB,EAAO7B,EAAO4C,GAAIM,EAAMF,GAG/C,CAAEtB,IAAGiB,IAAGW,GAAI5B,EAAGkB,GAAID,GACnB,CAAEjB,EAAGG,EAAO7B,EAAOsD,GAAIzB,EAAMc,EAAGO,EAAMF,EAAQJ,GAAIM,GAG9D,CAcA,SAASmE,EAAO3G,GACd,MAAMkD,OAAEA,EAAM0D,QAAEA,EAAOC,QAAEA,EAAOvH,MAAEA,EAAKgD,OAAEA,EAAMrB,IAAEA,GAAQjB,EACzD,IAAIgB,EAAEA,EAACiB,EAAEA,GAAMjC,EACfgB,GAAM4F,EAAUtH,EAAS,EACzB2C,GAAM4E,EAAUvE,EAAU,EJlKrB,SACLY,EACAiE,EACAlG,GAEA,MAAMmG,EAASlE,EAAOmE,uBAAuBF,EAAK,SAAU,UACtDG,EAAWpE,EAAOqE,uBACtBH,EACAlE,EAAOtB,QACPsB,EAAOR,SAEE,KAAPzB,EAAYiC,EAAOsE,KAAKF,EAAStG,GAChCkC,EAAOuE,KAAKH,EAASrF,EAC5B,CIsJEyF,CAAexE,EAAQ,IAAIqB,EAAKA,MAACvD,EAAGiB,GAAIhB,GACxCiC,EAAOrB,WACT,CCxJa8F,MAAAA,EAAuB,SAClCC,GAA0C,IAC1CC,EAAwBC,UAAA/G,OAAA,QAAAgH,IAAAD,UAAA,GAAAA,UAAA,GAAG,OAC3BE,EAAwBF,UAAA/G,OAAA,QAAAgH,IAAAD,UAAA,GAAAA,UAAA,GAAG,MAAK,OAEhCG,eAAyBC,GAEvB,MAAMtG,QAAEA,EAAUiG,EAAcnF,QAAEA,EAAUsF,GAC1CE,SAEKA,EAAiBtG,eACjBsG,EAAiBxF,QAAQ,IAAAyF,IAAAA,EAAAL,UAAA/G,OANYqH,MAAIC,MAAAF,EAAAA,EAAAA,OAAAG,EAAA,EAAAA,EAAAH,EAAAG,IAAJF,EAAIE,EAAAR,GAAAA,UAAAQ,GAOhD,MAAMC,QAAuBX,EAAWY,KACtCC,KACAP,KACGE,GAECM,EAAiB,IAAInE,QAAMgE,EAAepH,KAAMoH,EAAe/F,KAErE,OADA+F,EAAeI,oBAAoBD,EAAgB9G,EAASc,GACrD6F,EACR,2BCPI,SACL3H,GAEA,IADAgI,EAAoCd,UAAA/G,OAAA,QAAAgH,IAAAD,UAAA,GAAAA,UAAA,GAAG,CAAA,EAEvCe,OAAOC,OAAO1J,EAAoBwJ,GAElC,MAAMG,EAAkB,IAAIlE,IACtBmE,EAAgB,IAAInE,IAC1B,IAAIoE,GAAgB,EACpB,MAAMC,EAAW,IAAIC,IAEfC,EAAoBC,IACxB,MAAMC,EAAW,CACfD,EAAOE,sBAAsBC,WAC7BH,EAAO/J,MACP+J,EAAO/G,QACPmH,OACIC,EAAaR,EAASS,IAAIL,GAChC,GAAII,EAAY,OAAOA,EACvB,MAAMjF,EAAS4E,EAAOO,YAEhBC,EAA0B,CADnBC,EAAAA,KAAKC,0BAA0BtF,GACLA,GAEvC,OADAyE,EAAS3H,IAAI+H,EAAUO,GAChBA,CAAK,EAGd,SAASG,EAAOC,GACd,MAAM7J,EAAe6J,EAAE/G,OACvB9C,EAAayB,YACboH,GAAgB,EAChBD,EAAckB,QACdnB,EAAgBmB,QAEhB,MAAMtF,EAAUD,EAAmBvE,GAC7B0F,EAAmB1F,EAAa+J,kBAEtC,IAAK,MAAMd,KAAUzE,EAAS,CAC5B,MAAMmB,EAAaqD,EAAiBC,GAAQ,IACtClD,OAAEA,EAAMa,OAAEA,GAAWnB,EAAY,CACrCzF,eACA0F,mBACAC,eAEFI,EAAOW,SAAS5B,IACd8D,EAAczD,IAAI6E,KAAKC,UAAUnF,GAAG,IAEtC8B,EAAOF,SAAS5B,IACd6D,EAAgBxD,IAAI6E,KAAKC,UAAUnF,GAAG,GAE1C,CACF,CAEA,SAASoF,EAAkBL,GAEzB,MAAM7J,EAAe6J,EAAE/G,OACvB9C,EAAayB,YACb,MAAMxB,EAAUkK,OAAON,EAAEzG,UAAUgH,QAAQC,WAAW,SACtDzB,EAAckB,QACdnB,EAAgBmB,QAEhB,MAAMtF,EAAUD,EAAmBvE,GACnC,IAAIsK,EAAST,EAAEzG,UAAUkH,OACrBtK,EAAauK,QAAOD,EAASA,EAAOE,QAAQ,IAAK,KAAKA,QAAQ,IAAK,MACnExK,EAAayK,QAAOH,EAASA,EAAOE,QAAQ,IAAK,KAAKA,QAAQ,IAAK,MACvE,IAAItK,EAAQ,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,KAAM,MAAMqB,QAC3D+I,GAEF,IAAc,GAAVpK,EAAa,OAEjB,GADA2I,EAAgB3I,EAAQ,EACpB2I,EAAe,CAEjB,GADc7I,EAAa0K,gBACf,IAAM,EAAG,OACrBxK,GAAS,CACX,CACA,IAAIC,EAAQH,EAAawJ,YAAYtJ,GACrC,IAAK,MAAM+I,KAAUzE,EAAS,CAC5B,MAAOsC,EAAMzC,GAAU2E,EAAiBC,GAMlCrJ,EAAQ,CAAEI,eAAcG,QAAOC,KADxB,IAAIiE,EAJF,IAAIF,EAAAA,MACjB2C,EAAK/F,KAAO+F,EAAK5H,MAAQ,EACzB4H,EAAK1E,IAAM0E,EAAK5E,OAAS,IAGgBjC,UAASC,SAC9C6F,EAASpG,EAAqBC,GAC9BgH,EAAS7E,EAAuBnC,GACtCmG,EAAOW,SAAS5B,IACd8D,EAAczD,IAAI6E,KAAKC,UAAUnF,GAAG,IAEtC8B,EAAOF,SAAS5B,IACd6D,EAAgBxD,IAAI6E,KAAKC,UAAUnF,GAAG,KAEpCiB,EAAOpF,QAAUiG,EAAOjG,UAC1BR,EAAQH,EAAawJ,YAAYtJ,GACrC,CACF,CAEA,SAASyK,IACPnK,EAAOoK,aAAapK,EAAOqK,WAC7B,CACA,SAASC,IACP,GAAIjC,EAAe,CACjB,MAAMzI,EAA6C,GACnD,IAAK,MAAMM,KAAKkI,EAAexI,EAAKuC,KAAKqH,KAAKe,MAAMrK,IACpD,IAAK,MAAMsK,KAAKrC,EAAiBvI,EAAKuC,KAAKqH,KAAKe,MAAMC,IACtDhH,EAAcxD,EAAQJ,EACxB,KAAO,CACL,IAAK,MAAMM,KAAKkI,EAAexE,EAAiB5D,EAAQwJ,KAAKe,MAAMrK,IACnE,IAAK,MAAMsK,KAAKrC,EACdrE,EAAmB9D,EAAQwJ,KAAKe,MAAMC,GAC1C,CACF,CACA,SAASC,IACPrC,EAAckB,QACdnB,EAAgBmB,QAChBhB,EAASgB,QACTtJ,EAAO0K,kBACT,CASA,OAPA1K,EAAO2K,GAAG,kBAAmBjB,GAC7B1J,EAAO2K,GAAG,iBAAkBjB,GAC5B1J,EAAO2K,GAAG,gBAAiBvB,GAC3BpJ,EAAO2K,GAAG,gBAAiBR,GAC3BnK,EAAO2K,GAAG,eAAgBL,GAC1BtK,EAAO2K,GAAG,WAAYF,GAEf,KACLzK,EAAO4K,IAAI,kBAAmBlB,GAC9B1J,EAAO4K,IAAI,iBAAkBlB,GAC7B1J,EAAO4K,IAAI,gBAAiBxB,GAC5BpJ,EAAO4K,IAAI,gBAAiBT,GAC5BnK,EAAO4K,IAAI,eAAgBN,GAC3BtK,EAAO4K,IAAI,WAAYH,EAAQ,CAEnC,gCDrH2CI,CACzC7J,EACAc,KAGAgJ,EAAgBA,iBAACC,YAAchE,EAC7B+D,EAAAA,iBAAiBC,YACjB/J,EACAc,GAGFkJ,EAAWA,YAACC,WAAalE,EACvBiE,EAAAA,YAAYC,WACZjK,EACAc,GAEF4C,EAAKA,MAACuG,WAAalE,EACjBrC,EAAAA,MAAMuG,WACNjK,EACAc,EACD"} \ No newline at end of file diff --git a/dist-extensions/fabric.d.ts b/dist-extensions/fabric.d.ts new file mode 100644 index 00000000000..df0a56e2dfe --- /dev/null +++ b/dist-extensions/fabric.d.ts @@ -0,0 +1,121 @@ +export { getEnv, getFabricDocument, getFabricWindow, setEnv } from './src/env'; +export { cache } from './src/cache'; +export { VERSION as version, iMatrix } from './src/constants'; +export { config } from './src/config'; +export { classRegistry } from './src/ClassRegistry'; +export { runningAnimations } from './src/util/animation/AnimationRegistry'; +export * from './src/typedefs'; +export * from './src/EventTypeDefs'; +export type { ITextEvents } from './src/shapes/IText/ITextBehavior'; +export { Observable } from './src/Observable'; +export type { TCanvasSizeOptions, TSVGExportOptions, } from './src/canvas/StaticCanvas'; +export type { StaticCanvasOptions } from './src/canvas/StaticCanvasOptions'; +export { StaticCanvas } from './src/canvas/StaticCanvas'; +export { Canvas } from './src/canvas/Canvas'; +export type { CanvasOptions } from './src/canvas/CanvasOptions'; +export { CanvasDOMManager } from './src/canvas/DOMManagers/CanvasDOMManager'; +export { StaticCanvasDOMManager } from './src/canvas/DOMManagers/StaticCanvasDOMManager'; +export type { XY } from './src/Point'; +export { Point } from './src/Point'; +export type { IntersectionType } from './src/Intersection'; +export { Intersection } from './src/Intersection'; +export { Color } from './src/color/Color'; +export * from './src/color/typedefs'; +export * from './src/gradient'; +export * from './src/Pattern'; +export { Shadow } from './src/Shadow'; +export type { SerializedShadowOptions } from './src/Shadow'; +export { BaseBrush } from './src/brushes/BaseBrush'; +export * from './src/brushes/typedefs'; +export { PencilBrush } from './src/brushes/PencilBrush'; +export { CircleBrush } from './src/brushes/CircleBrush'; +export { SprayBrush } from './src/brushes/SprayBrush'; +export { PatternBrush } from './src/brushes/PatternBrush'; +export type * from './src/util/path/typedefs'; +export { FabricObject, +/** + * @deprecated Due to a naming conflict with the + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object JS API}, + * `fabric.Object` has been renamed to `FabricObject` + * + * @example + * import { Object } from 'fabric'; // deprecated + * import { FabricObject } from 'fabric'; // migration path + * + */ +FabricObject as Object, } from './src/shapes/Object/FabricObject'; +/** + * Exported so we can tweak default values + */ +export { FabricObject as BaseFabricObject } from './src/shapes/Object/Object'; +/** + * Exported so we can tweak default values + */ +export { InteractiveFabricObject } from './src/shapes/Object/InteractiveObject'; +export type { TFabricObjectProps, FabricObjectProps, SerializedObjectProps, } from './src/shapes/Object/types'; +export type { SerializedLineProps } from './src/shapes/Line'; +export { Line } from './src/shapes/Line'; +export type { CircleProps, SerializedCircleProps } from './src/shapes/Circle'; +export { Circle } from './src/shapes/Circle'; +export { Triangle } from './src/shapes/Triangle'; +export type { EllipseProps, SerializedEllipseProps, } from './src/shapes/Ellipse'; +export { Ellipse } from './src/shapes/Ellipse'; +export type { RectProps, SerializedRectProps } from './src/shapes/Rect'; +export { Rect } from './src/shapes/Rect'; +export type { PathProps, SerializedPathProps } from './src/shapes/Path'; +export { Path } from './src/shapes/Path'; +export type { SerializedPolylineProps } from './src/shapes/Polyline'; +export { Polyline } from './src/shapes/Polyline'; +export { Polygon } from './src/shapes/Polygon'; +export type { GraphemeBBox, SerializedTextProps, TPathAlign, TPathSide, TextProps, } from './src/shapes/Text/Text'; +export { FabricText, +/** + * @deprecated Due to a naming conflict with the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/Text/Text Web API}, + * `fabric.Text` has been renamed to `FabricText` + * + * @example + * import { Text } from 'fabric'; // deprecated + * import { FabricText } from 'fabric'; // migration path + * + */ +FabricText as Text, } from './src/shapes/Text/Text'; +export type { ITextProps, SerializedITextProps, } from './src/shapes/IText/IText'; +export { IText } from './src/shapes/IText/IText'; +export type { GraphemeData, SerializedTextboxProps, TextboxProps, } from './src/shapes/Textbox'; +export { Textbox } from './src/shapes/Textbox'; +export type { CompleteTextStyleDeclaration, TextStyleDeclaration, TextStyle, } from './src/shapes/Text/StyledText'; +export type { GroupEvents, GroupProps, GroupOwnProps, SerializedGroupProps, } from './src/shapes/Group'; +export { Group } from './src/shapes/Group'; +export * from './src/LayoutManager'; +export type { SerializedLayoutManager } from './src/LayoutManager'; +export type { ActiveSelectionOptions, MultiSelectionStacking, } from './src/shapes/ActiveSelection'; +export { ActiveSelection } from './src/shapes/ActiveSelection'; +export { FabricImage, +/** + * @deprecated Due to a naming conflict with the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image Web API}, + * `fabric.Image` has been renamed to `FabricImage` + * + * @example + * import { Image } from 'fabric'; // deprecated + * import { FabricImage } from 'fabric'; // migration path + * + */ +FabricImage as Image, } from './src/shapes/Image'; +export type { ImageSource, SerializedImageProps, ImageProps, } from './src/shapes/Image'; +export { createCollectionMixin } from './src/Collection'; +export * as util from './src/util'; +export { loadSVGFromString } from './src/parser/loadSVGFromString'; +export { loadSVGFromURL } from './src/parser/loadSVGFromURL'; +export { parseSVGDocument } from './src/parser/parseSVGDocument'; +export { parseAttributes } from './src/parser/parseAttributes'; +export { parseStyleAttribute } from './src/parser/parseStyleAttribute'; +export { parsePointsAttribute } from './src/parser/parsePointsAttribute'; +export { parseTransformAttribute } from './src/parser/parseTransformAttribute'; +export { getCSSRules } from './src/parser/getCSSRules'; +export { parseFontDeclaration } from './src/parser/parseFontDeclaration'; +export { Control } from './src/controls/Control'; +export * as controlsUtils from './src/controls'; +export * from './src/filters'; +//# sourceMappingURL=fabric.d.ts.map \ No newline at end of file diff --git a/dist-extensions/index.d.ts b/dist-extensions/index.d.ts new file mode 100644 index 00000000000..4d2cc5427d5 --- /dev/null +++ b/dist-extensions/index.d.ts @@ -0,0 +1,2 @@ +export * from './fabric'; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.min.js b/dist/index.min.js new file mode 100644 index 00000000000..daadd7a1fb1 --- /dev/null +++ b/dist/index.min.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).fabric={})}(this,(function(t){"use strict";function e(t,e,s){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var s=t[Symbol.toPrimitive];if(void 0!==s){var i=s.call(t,e||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}function s(t,e){var s=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),s.push.apply(s,i)}return s}function i(t){for(var i=1;i=0)continue;s[i]=t[i]}return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||{}.propertyIsEnumerable.call(t,s)&&(r[s]=t[s])}return r}function n(t,e){return e||(e=t.slice(0)),Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))}class o{constructor(){e(this,"browserShadowBlurConstant",1),e(this,"DPI",96),e(this,"devicePixelRatio","undefined"!=typeof window?window.devicePixelRatio:1),e(this,"perfLimitSizeTotal",2097152),e(this,"maxCacheSideLimit",4096),e(this,"minCacheSideLimit",256),e(this,"disableStyleCopyPaste",!1),e(this,"enableGLFiltering",!0),e(this,"textureSize",4096),e(this,"forceGLPutImageData",!1),e(this,"cachesBoundsOfCurve",!1),e(this,"fontPaths",{}),e(this,"NUM_FRACTION_DIGITS",4)}}const a=new class extends o{constructor(t){super(),this.configure(t)}configure(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Object.assign(this,t)}addFonts(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.fontPaths=i(i({},this.fontPaths),t)}removeFonts(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).forEach((t=>{delete this.fontPaths[t]}))}clearFonts(){this.fontPaths={}}restoreDefaults(t){const e=new o,s=(null==t?void 0:t.reduce(((t,s)=>(t[s]=e[s],t)),{}))||e;this.configure(s)}},h=function(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;ithis.testPrecision(e,t))),e.getExtension("WEBGL_lose_context").loseContext(),h("log","WebGL: max texture size ".concat(this.maxTextureSize)))}isSupported(t){return!!this.maxTextureSize&&this.maxTextureSize>=t}}const g={};let f;const p=()=>f||(f={document:document,window:window,isTouchSupported:"ontouchstart"in window||"ontouchstart"in document||window&&window.navigator&&window.navigator.maxTouchPoints>0,WebGLProbe:new d,dispose(){},copyPasteData:g}),m=()=>p().document,v=()=>p().window,y=()=>{var t;return Math.max(null!==(t=a.devicePixelRatio)&&void 0!==t?t:v().devicePixelRatio,1)};const _=new class{constructor(){e(this,"charWidthsCache",{}),e(this,"boundsOfCurveCache",{})}getFontCache(t){let{fontFamily:e,fontStyle:s,fontWeight:i}=t;e=e.toLowerCase(),this.charWidthsCache[e]||(this.charWidthsCache[e]={});const r=this.charWidthsCache[e],n="".concat(s.toLowerCase(),"_").concat((i+"").toLowerCase());return r[n]||(r[n]={}),r[n]}clearFontCache(t){(t=(t||"").toLowerCase())?this.charWidthsCache[t]&&delete this.charWidthsCache[t]:this.charWidthsCache={}}limitDimsByArea(t){const{perfLimitSizeTotal:e}=a,s=Math.sqrt(e*t);return[Math.floor(s),Math.floor(e/s)]}};const x="6.4.2";function C(){}const b=Math.PI/2,S=2*Math.PI,w=Math.PI/180,T=Object.freeze([1,0,0,1,0,0]),O=16,k=.4477152502,D="center",M="left",P="top",E="bottom",A="right",j="none",F=/\r?\n/,L="moving",R="scaling",I="rotating",B="rotate",X="skewing",W="resizing",Y="modifyPoly",V="modifyPath",G="changed",H="scale",z="scaleX",N="scaleY",U="skewX",q="skewY",K="fill",J="stroke",Q="modified",Z="json",$="svg";const tt=new class{constructor(){this[Z]=new Map,this[$]=new Map}has(t){return this[Z].has(t)}getClass(t){const e=this[Z].get(t);if(!e)throw new c("No class registered for ".concat(t));return e}setClass(t,e){e?this[Z].set(e,t):(this[Z].set(t.type,t),this[Z].set(t.type.toLowerCase(),t))}getSVGClass(t){return this[$].get(t)}setSVGClass(t,e){this[$].set(null!=e?e:t.type.toLowerCase(),t)}};const et=new class extends Array{remove(t){const e=this.indexOf(t);e>-1&&this.splice(e,1)}cancelAll(){const t=this.splice(0);return t.forEach((t=>t.abort())),t}cancelByCanvas(t){if(!t)return[];const e=this.filter((e=>{var s;return e.target===t||"object"==typeof e.target&&(null===(s=e.target)||void 0===s?void 0:s.canvas)===t}));return e.forEach((t=>t.abort())),e}cancelByTarget(t){if(!t)return[];const e=this.filter((e=>e.target===t));return e.forEach((t=>t.abort())),e}};class st{constructor(){e(this,"__eventListeners",{})}on(t,e){if(this.__eventListeners||(this.__eventListeners={}),"object"==typeof t)return Object.entries(t).forEach((t=>{let[e,s]=t;this.on(e,s)})),()=>this.off(t);if(e){const s=t;return this.__eventListeners[s]||(this.__eventListeners[s]=[]),this.__eventListeners[s].push(e),()=>this.off(s,e)}return()=>!1}once(t,e){if("object"==typeof t){const e=[];return Object.entries(t).forEach((t=>{let[s,i]=t;e.push(this.once(s,i))})),()=>e.forEach((t=>t()))}if(e){const s=this.on(t,(function(){for(var t=arguments.length,i=new Array(t),r=0;r!1}_removeEventListener(t,e){if(this.__eventListeners[t])if(e){const s=this.__eventListeners[t],i=s.indexOf(e);i>-1&&s.splice(i,1)}else this.__eventListeners[t]=[]}off(t,e){if(this.__eventListeners)if(void 0===t)for(const t in this.__eventListeners)this._removeEventListener(t);else"object"==typeof t?Object.entries(t).forEach((t=>{let[e,s]=t;this._removeEventListener(e,s)})):this._removeEventListener(t,e)}fire(t,e){var s;if(!this.__eventListeners)return;const i=null===(s=this.__eventListeners[t])||void 0===s?void 0:s.concat();if(i)for(let t=0;t{const s=t.indexOf(e);return-1!==s&&t.splice(s,1),t},rt=t=>{if(0===t)return 1;switch(Math.abs(t)/b){case 1:case 3:return 0;case 2:return-1}return Math.cos(t)},nt=t=>{if(0===t)return 0;const e=t/b,s=Math.sign(t);switch(e){case 1:return s;case 2:return 0;case 3:return-s}return Math.sin(t)};class ot{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;"object"==typeof t?(this.x=t.x,this.y=t.y):(this.x=t,this.y=e)}add(t){return new ot(this.x+t.x,this.y+t.y)}addEquals(t){return this.x+=t.x,this.y+=t.y,this}scalarAdd(t){return new ot(this.x+t,this.y+t)}scalarAddEquals(t){return this.x+=t,this.y+=t,this}subtract(t){return new ot(this.x-t.x,this.y-t.y)}subtractEquals(t){return this.x-=t.x,this.y-=t.y,this}scalarSubtract(t){return new ot(this.x-t,this.y-t)}scalarSubtractEquals(t){return this.x-=t,this.y-=t,this}multiply(t){return new ot(this.x*t.x,this.y*t.y)}scalarMultiply(t){return new ot(this.x*t,this.y*t)}scalarMultiplyEquals(t){return this.x*=t,this.y*=t,this}divide(t){return new ot(this.x/t.x,this.y/t.y)}scalarDivide(t){return new ot(this.x/t,this.y/t)}scalarDivideEquals(t){return this.x/=t,this.y/=t,this}eq(t){return this.x===t.x&&this.y===t.y}lt(t){return this.xt.x&&this.y>t.y}gte(t){return this.x>=t.x&&this.y>=t.y}lerp(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.5;return e=Math.max(Math.min(1,e),0),new ot(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)}distanceFrom(t){const e=this.x-t.x,s=this.y-t.y;return Math.sqrt(e*e+s*s)}midPointFrom(t){return this.lerp(t)}min(t){return new ot(Math.min(this.x,t.x),Math.min(this.y,t.y))}max(t){return new ot(Math.max(this.x,t.x),Math.max(this.y,t.y))}toString(){return"".concat(this.x,",").concat(this.y)}setXY(t,e){return this.x=t,this.y=e,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setFromPoint(t){return this.x=t.x,this.y=t.y,this}swap(t){const e=this.x,s=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=s}clone(){return new ot(this.x,this.y)}rotate(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:at;const s=nt(t),i=rt(t),r=this.subtract(e);return new ot(r.x*i-r.y*s,r.x*s+r.y*i).add(e)}transform(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return new ot(t[0]*this.x+t[2]*this.y+(e?0:t[4]),t[1]*this.x+t[3]*this.y+(e?0:t[5]))}}const at=new ot(0,0),ht=t=>!!t&&Array.isArray(t._objects);function ct(t){class s extends t{constructor(){super(...arguments),e(this,"_objects",[])}_onObjectAdded(t){}_onObjectRemoved(t){}_onStackOrderChanged(t){}add(){for(var t=arguments.length,e=new Array(t),s=0;sthis._onObjectAdded(t))),i}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;ithis._onObjectAdded(t))),this._objects.length}remove(){const t=this._objects,e=[];for(var s=arguments.length,i=new Array(s),r=0;r{const i=t.indexOf(s);-1!==i&&(t.splice(i,1),e.push(s),this._onObjectRemoved(s))})),e}forEachObject(t){this.getObjects().forEach(((e,s,i)=>t(e,s,i)))}getObjects(){for(var t=arguments.length,e=new Array(t),s=0;st.isType(...e)))}item(t){return this._objects[t]}isEmpty(){return 0===this._objects.length}size(){return this._objects.length}contains(t,e){return!!this._objects.includes(t)||!!e&&this._objects.some((e=>e instanceof s&&e.contains(t,!0)))}complexity(){return this._objects.reduce(((t,e)=>t+=e.complexity?e.complexity():0),0)}sendObjectToBack(t){return!(!t||t===this._objects[0])&&(it(this._objects,t),this._objects.unshift(t),this._onStackOrderChanged(t),!0)}bringObjectToFront(t){return!(!t||t===this._objects[this._objects.length-1])&&(it(this._objects,t),this._objects.push(t),this._onStackOrderChanged(t),!0)}sendObjectBackwards(t,e){if(!t)return!1;const s=this._objects.indexOf(t);if(0!==s){const i=this.findNewLowerIndex(t,s,e);return it(this._objects,t),this._objects.splice(i,0,t),this._onStackOrderChanged(t),!0}return!1}bringObjectForward(t,e){if(!t)return!1;const s=this._objects.indexOf(t);if(s!==this._objects.length-1){const i=this.findNewUpperIndex(t,s,e);return it(this._objects,t),this._objects.splice(i,0,t),this._onStackOrderChanged(t),!0}return!1}moveObjectTo(t,e){return t!==this._objects[e]&&(it(this._objects,t),this._objects.splice(e,0,t),this._onStackOrderChanged(t),!0)}findNewLowerIndex(t,e,s){let i;if(s){i=e;for(let s=e-1;s>=0;--s)if(t.isOverlapping(this._objects[s])){i=s;break}}else i=e-1;return i}findNewUpperIndex(t,e,s){let i;if(s){i=e;for(let s=e+1;s1&&void 0!==arguments[1]?arguments[1]:{};const o=[],a=new ot(e,s),h=a.add(new ot(i,r));for(let t=this._objects.length-1;t>=0;t--){const e=this._objects[t];e.selectable&&e.visible&&(n&&e.intersectsWithRect(a,h)||e.isContainedWithinRect(a,h)||n&&e.containsPoint(a)||n&&e.containsPoint(h))&&o.push(e)}return o}}return s}class lt extends st{_setOptions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};for(const e in t)this.set(e,t[e])}_setObject(t){for(const e in t)this._set(e,t[e])}set(t,e){return"object"==typeof t?this._setObject(t):this._set(t,e),this}_set(t,e){this[t]=e}toggle(t){const e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this}get(t){return this[t]}}function ut(t){return v().requestAnimationFrame(t)}function dt(t){return v().cancelAnimationFrame(t)}let gt=0;const ft=()=>gt++,pt=()=>{const t=m().createElement("canvas");if(!t||void 0===t.getContext)throw new c("Failed to create `canvas` element");return t},mt=()=>m().createElement("img"),vt=(t,e,s)=>t.toDataURL("image/".concat(e),s),yt=t=>t*w,_t=t=>t/w,xt=t=>t.every(((t,e)=>t===T[e])),Ct=(t,e,s)=>new ot(t).transform(e,s),bt=t=>{const e=1/(t[0]*t[3]-t[1]*t[2]),s=[e*t[3],-e*t[1],-e*t[2],e*t[0],0,0],{x:i,y:r}=new ot(t[4],t[5]).transform(s,!0);return s[4]=-i,s[5]=-r,s},St=(t,e,s)=>[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],s?0:t[0]*e[4]+t[2]*e[5]+t[4],s?0:t[1]*e[4]+t[3]*e[5]+t[5]],wt=(t,e)=>t.reduceRight(((t,s)=>s&&t?St(s,t,e):s||t),void 0)||T.concat(),Tt=t=>{let[e,s]=t;return Math.atan2(s,e)},Ot=t=>{const e=Tt(t),s=Math.pow(t[0],2)+Math.pow(t[1],2),i=Math.sqrt(s),r=(t[0]*t[3]-t[2]*t[1])/i,n=Math.atan2(t[0]*t[2]+t[1]*t[3],s);return{angle:_t(e),scaleX:i,scaleY:r,skewX:_t(n),skewY:0,translateX:t[4]||0,translateY:t[5]||0}},kt=function(t){return[1,0,0,1,t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:0]};function Dt(){let{angle:t=0}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{x:e=0,y:s=0}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=yt(t),r=rt(i),n=nt(i);return[r,n,-n,r,e?e-(r*e-n*s):0,s?s-(n*e+r*s):0]}const Mt=function(t){return[t,0,0,arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,0,0]},Pt=t=>Math.tan(yt(t)),Et=t=>[1,0,Pt(t),1,0,0],At=t=>[1,Pt(t),0,1,0,0],jt=t=>{let{scaleX:e=1,scaleY:s=1,flipX:i=!1,flipY:r=!1,skewX:n=0,skewY:o=0}=t,a=Mt(i?-e:e,r?-s:s);return n&&(a=St(a,Et(n),!0)),o&&(a=St(a,At(o),!0)),a},Ft=t=>{const{translateX:e=0,translateY:s=0,angle:i=0}=t;let r=kt(e,s);i&&(r=St(r,Dt({angle:i})));const n=jt(t);return xt(n)||(r=St(r,n)),r},Lt=function(t){let{signal:e,crossOrigin:s=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise((function(i,r){if(e&&e.aborted)return r(new l("loadImage"));const n=mt();let o;e&&(o=function(t){n.src="",r(t)},e.addEventListener("abort",o,{once:!0}));const a=function(){n.onload=n.onerror=null,o&&(null==e||e.removeEventListener("abort",o)),i(n)};t?(n.onload=a,n.onerror=function(){o&&(null==e||e.removeEventListener("abort",o)),r(new c("Error loading ".concat(n.src)))},s&&(n.crossOrigin=s),n.src=t):a()}))},Rt=function(t){let{signal:e,reviver:s=C}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((i,r)=>{const n=[];e&&e.addEventListener("abort",r,{once:!0}),Promise.all(t.map((t=>tt.getClass(t.type).fromObject(t,{signal:e}).then((e=>(s(t,e),n.push(e),e)))))).then(i).catch((t=>{n.forEach((t=>{t.dispose&&t.dispose()})),r(t)})).finally((()=>{e&&e.removeEventListener("abort",r)}))}))},It=function(t){let{signal:e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((s,i)=>{const r=[];e&&e.addEventListener("abort",i,{once:!0});const n=Object.values(t).map((t=>t&&t.type&&tt.has(t.type)?Rt([t],{signal:e}).then((t=>{let[e]=t;return r.push(e),e})):t)),o=Object.keys(t);Promise.all(n).then((t=>t.reduce(((t,e,s)=>(t[o[s]]=e,t)),{}))).then(s).catch((t=>{r.forEach((t=>{t.dispose&&t.dispose()})),i(t)})).finally((()=>{e&&e.removeEventListener("abort",i)}))}))},Bt=function(t){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[]).reduce(((e,s)=>(s in t&&(e[s]=t[s]),e)),{})},Xt=(t,e)=>Object.keys(t).reduce(((s,i)=>(e(t[i],i,t)&&(s[i]=t[i]),s)),{}),Wt={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#0FF",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000",blanchedalmond:"#FFEBCD",blue:"#00F",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#0FF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgrey:"#A9A9A9",darkgreen:"#006400",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#F0F",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgray:"#D3D3D3",lightgrey:"#D3D3D3",lightgreen:"#90EE90",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#789",lightslategrey:"#789",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",lime:"#0F0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#F0F",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",rebeccapurple:"#639",red:"#F00",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFF",whitesmoke:"#F5F5F5",yellow:"#FF0",yellowgreen:"#9ACD32"},Yt=(t,e,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(e-t)*s:s<.5?e:s<2/3?t+(e-t)*(2/3-s)*6:t),Vt=(t,e,s,i)=>{t/=255,e/=255,s/=255;const r=Math.max(t,e,s),n=Math.min(t,e,s);let o,a;const h=(r+n)/2;if(r===n)o=a=0;else{const i=r-n;switch(a=h>.5?i/(2-r-n):i/(r+n),r){case t:o=(e-s)/i+(e0&&void 0!==arguments[0]?arguments[0]:"1";return parseFloat(t)/(t.endsWith("%")?100:1)},Ht=t=>Math.min(Math.round(t),255).toString(16).toUpperCase().padStart(2,"0"),zt=t=>{let[e,s,i,r=1]=t;const n=Math.round(.3*e+.59*s+.11*i);return[n,n,n,r]};class Nt{constructor(t){if(e(this,"isUnrecognised",!1),t)if(t instanceof Nt)this.setSource([...t._source]);else if(Array.isArray(t)){const[e,s,i,r=1]=t;this.setSource([e,s,i,r])}else this.setSource(this._tryParsingColor(t));else this.setSource([0,0,0,1])}_tryParsingColor(t){return t in Wt&&(t=Wt[t]),"transparent"===t?[255,255,255,0]:Nt.sourceFromHex(t)||Nt.sourceFromRgb(t)||Nt.sourceFromHsl(t)||(this.isUnrecognised=!0)&&[0,0,0,1]}getSource(){return this._source}setSource(t){this._source=t}toRgb(){const[t,e,s]=this.getSource();return"rgb(".concat(t,",").concat(e,",").concat(s,")")}toRgba(){return"rgba(".concat(this.getSource().join(","),")")}toHsl(){const[t,e,s]=Vt(...this.getSource());return"hsl(".concat(t,",").concat(e,"%,").concat(s,"%)")}toHsla(){const[t,e,s,i]=Vt(...this.getSource());return"hsla(".concat(t,",").concat(e,"%,").concat(s,"%,").concat(i,")")}toHex(){return this.toHexa().slice(0,6)}toHexa(){const[t,e,s,i]=this.getSource();return"".concat(Ht(t)).concat(Ht(e)).concat(Ht(s)).concat(Ht(Math.round(255*i)))}getAlpha(){return this.getSource()[3]}setAlpha(t){return this._source[3]=t,this}toGrayscale(){return this.setSource(zt(this.getSource())),this}toBlackWhite(t){const[e,,,s]=zt(this.getSource()),i=e<(t||127)?0:255;return this.setSource([i,i,i,s]),this}overlayWith(t){t instanceof Nt||(t=new Nt(t));const e=this.getSource(),s=t.getSource(),[i,r,n]=e.map(((t,e)=>Math.round(.5*t+.5*s[e])));return this.setSource([i,r,n,e[3]]),this}static fromRgb(t){return Nt.fromRgba(t)}static fromRgba(t){return new Nt(Nt.sourceFromRgb(t))}static sourceFromRgb(t){const e=t.match(/^rgba?\(\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d{0,3}(?:\.\d+)?%?)\s*)?\)$/i);if(e){const[t,s,i]=e.slice(1,4).map((t=>{const e=parseFloat(t);return t.endsWith("%")?Math.round(2.55*e):e}));return[t,s,i,Gt(e[4])]}}static fromHsl(t){return Nt.fromHsla(t)}static fromHsla(t){return new Nt(Nt.sourceFromHsl(t))}static sourceFromHsl(t){const e=t.match(/^hsla?\(\s*([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d*(?:\.\d+)?%?)\s*)?\)$/i);if(!e)return;const s=(Nt.parseAngletoDegrees(e[1])%360+360)%360/360,i=parseFloat(e[2])/100,r=parseFloat(e[3])/100;let n,o,a;if(0===i)n=o=a=r;else{const t=r<=.5?r*(i+1):r+i-r*i,e=2*r-t;n=Yt(e,t,s+1/3),o=Yt(e,t,s),a=Yt(e,t,s-1/3)}return[Math.round(255*n),Math.round(255*o),Math.round(255*a),Gt(e[4])]}static fromHex(t){return new Nt(Nt.sourceFromHex(t))}static sourceFromHex(t){if(t.match(/^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i)){const e=t.slice(t.indexOf("#")+1);let s;s=e.length<=4?e.split("").map((t=>t+t)):e.match(/.{2}/g);const[i,r,n,o=255]=s.map((t=>parseInt(t,16)));return[i,r,n,o/255]}}static parseAngletoDegrees(t){const e=t.toLowerCase(),s=parseFloat(e);return e.includes("rad")?_t(s):e.includes("turn")?360*s:s}}const Ut=(t,e)=>parseFloat(Number(t).toFixed(e)),qt=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:O;const s=/\D{0,2}$/.exec(t),i=parseFloat(t),r=a.DPI;switch(null==s?void 0:s[0]){case"mm":return i*r/25.4;case"cm":return i*r/2.54;case"in":return i*r;case"pt":return i*r/72;case"pc":return i*r/72*12;case"em":return i*e;default:return i}},Kt=t=>{const[e,s]=t.trim().split(" "),[i,r]=(n=e)&&n!==j?[n.slice(1,4),n.slice(5,8)]:n===j?[n,n]:["Mid","Mid"];var n;return{meetOrSlice:s||"meet",alignX:i,alignY:r}},Jt=t=>"matrix("+t.map((t=>Ut(t,a.NUM_FRACTION_DIGITS))).join(" ")+")",Qt=function(t,e){let s,i,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(e)if(e.toLive)s="url(#SVGID_".concat(e.id,")");else{const t=new Nt(e),r=t.getAlpha();s=t.toRgb(),1!==r&&(i=r.toString())}else s="none";return r?"".concat(t,": ").concat(s,"; ").concat(i?"".concat(t,"-opacity: ").concat(i,"; "):""):"".concat(t,'="').concat(s,'" ').concat(i?"".concat(t,'-opacity="').concat(i,'" '):"")},Zt=t=>!!t&&void 0!==t.toLive,$t=t=>!!t&&"function"==typeof t.toObject,te=t=>!!t&&void 0!==t.offsetX&&"source"in t,ee=t=>!!t&&"function"==typeof t._renderText,se=t=>!!t&&"multiSelectionStacking"in t;function ie(t){const e=t&&re(t);let s=0,i=0;if(!t||!e)return{left:s,top:i};let r=t;const n=e.documentElement,o=e.body||{scrollLeft:0,scrollTop:0};for(;r&&(r.parentNode||r.host)&&(r=r.parentNode||r.host,r===e?(s=o.scrollLeft||n.scrollLeft||0,i=o.scrollTop||n.scrollTop||0):(s+=r.scrollLeft||0,i+=r.scrollTop||0),1!==r.nodeType||"fixed"!==r.style.position););return{left:s,top:i}}const re=t=>t.ownerDocument||null,ne=t=>{var e;return(null===(e=t.ownerDocument)||void 0===e?void 0:e.defaultView)||null},oe=function(t,e,s){let{width:i,height:r}=s,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1;t.width=i,t.height=r,n>1&&(t.setAttribute("width",(i*n).toString()),t.setAttribute("height",(r*n).toString()),e.scale(n,n))},ae=(t,e)=>{let{width:s,height:i}=e;s&&(t.style.width="number"==typeof s?"".concat(s,"px"):s),i&&(t.style.height="number"==typeof i?"".concat(i,"px"):i)};function he(t){return void 0!==t.onselectstart&&(t.onselectstart=()=>!1),t.style.userSelect=j,t}class ce{constructor(t){e(this,"_originalCanvasStyle",void 0),e(this,"lower",void 0);const s=this.createLowerCanvas(t);this.lower={el:s,ctx:s.getContext("2d")}}createLowerCanvas(t){const e=(s=t)&&void 0!==s.getContext?t:t&&m().getElementById(t)||pt();var s;if(e.hasAttribute("data-fabric"))throw new c("Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?");return this._originalCanvasStyle=e.style.cssText,e.setAttribute("data-fabric","main"),e.classList.add("lower-canvas"),e}cleanupDOM(t){let{width:e,height:s}=t;const{el:i}=this.lower;i.classList.remove("lower-canvas"),i.removeAttribute("data-fabric"),i.setAttribute("width","".concat(e)),i.setAttribute("height","".concat(s)),i.style.cssText=this._originalCanvasStyle||"",this._originalCanvasStyle=void 0}setDimensions(t,e){const{el:s,ctx:i}=this.lower;oe(s,i,t,e)}setCSSDimensions(t){ae(this.lower.el,t)}calcOffset(){return function(t){var e;const s=t&&re(t),i={left:0,top:0};if(!s)return i;const r=(null===(e=ne(t))||void 0===e?void 0:e.getComputedStyle(t,null))||{};i.left+=parseInt(r.borderLeftWidth,10)||0,i.top+=parseInt(r.borderTopWidth,10)||0,i.left+=parseInt(r.paddingLeft,10)||0,i.top+=parseInt(r.paddingTop,10)||0;let n={left:0,top:0};const o=s.documentElement;void 0!==t.getBoundingClientRect&&(n=t.getBoundingClientRect());const a=ie(t);return{left:n.left+a.left-(o.clientLeft||0)+i.left,top:n.top+a.top-(o.clientTop||0)+i.top}}(this.lower.el)}dispose(){p().dispose(this.lower.el),delete this.lower}}const le={backgroundVpt:!0,backgroundColor:"",overlayVpt:!0,overlayColor:"",includeDefaultValues:!0,svgViewportTransformation:!0,renderOnAddRemove:!0,skipOffscreen:!0,enableRetinaScaling:!0,imageSmoothingEnabled:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,viewportTransform:[...T]};class ue extends(ct(lt)){get lowerCanvasEl(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.el}get contextContainer(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.ctx}static getDefaults(){return ue.ownDefaults}constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,this.constructor.getDefaults()),this.set(e),this.initElements(t),this._setDimensionsImpl({width:this.width||this.elements.lower.el.width||0,height:this.height||this.elements.lower.el.height||0}),this.skipControlsDrawing=!1,this.viewportTransform=[...this.viewportTransform],this.calcViewportBoundaries()}initElements(t){this.elements=new ce(t)}add(){const t=super.add(...arguments);return arguments.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i0&&this.renderOnAddRemove&&this.requestRenderAll(),r}remove(){const t=super.remove(...arguments);return t.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}_onObjectAdded(t){t.canvas&&t.canvas!==this&&(h("warn","Canvas is trying to add an object that belongs to a different canvas.\nResulting to default behavior: removing object from previous canvas and adding to new canvas"),t.canvas.remove(t)),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added",{target:this})}_onObjectRemoved(t){t._set("canvas",void 0),this.fire("object:removed",{target:t}),t.fire("removed",{target:this})}_onStackOrderChanged(){this.renderOnAddRemove&&this.requestRenderAll()}getRetinaScaling(){return this.enableRetinaScaling?y():1}calcOffset(){return this._offset=this.elements.calcOffset()}getWidth(){return this.width}getHeight(){return this.height}setWidth(t,e){return this.setDimensions({width:t},e)}setHeight(t,e){return this.setDimensions({height:t},e)}_setDimensionsImpl(t){let{cssOnly:e=!1,backstoreOnly:s=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e){const e=i({width:this.width,height:this.height},t);this.elements.setDimensions(e,this.getRetinaScaling()),this.hasLostContext=!0,this.width=e.width,this.height=e.height}s||this.elements.setCSSDimensions(t),this.calcOffset()}setDimensions(t,e){this._setDimensionsImpl(t,e),e&&e.cssOnly||this.requestRenderAll()}getZoom(){return this.viewportTransform[0]}setViewportTransform(t){this.viewportTransform=t,this.calcViewportBoundaries(),this.renderOnAddRemove&&this.requestRenderAll()}zoomToPoint(t,e){const s=t,i=[...this.viewportTransform],r=Ct(t,bt(i));i[0]=e,i[3]=e;const n=Ct(r,i);i[4]+=s.x-n.x,i[5]+=s.y-n.y,this.setViewportTransform(i)}setZoom(t){this.zoomToPoint(new ot(0,0),t)}absolutePan(t){const e=[...this.viewportTransform];return e[4]=-t.x,e[5]=-t.y,this.setViewportTransform(e)}relativePan(t){return this.absolutePan(new ot(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))}getElement(){return this.elements.lower.el}clearContext(t){t.clearRect(0,0,this.width,this.height)}getContext(){return this.elements.lower.ctx}clear(){this.remove(...this.getObjects()),this.backgroundImage=void 0,this.overlayImage=void 0,this.backgroundColor="",this.overlayColor="",this.clearContext(this.getContext()),this.fire("canvas:cleared"),this.renderOnAddRemove&&this.requestRenderAll()}renderAll(){this.cancelRequestedRender(),this.destroyed||this.renderCanvas(this.getContext(),this._objects)}renderAndReset(){this.nextRenderHandle=0,this.renderAll()}requestRenderAll(){this.nextRenderHandle||this.disposed||this.destroyed||(this.nextRenderHandle=ut((()=>this.renderAndReset())))}calcViewportBoundaries(){const t=this.width,e=this.height,s=bt(this.viewportTransform),i=Ct({x:0,y:0},s),r=Ct({x:t,y:e},s),n=i.min(r),o=i.max(r);return this.vptCoords={tl:n,tr:new ot(o.x,n.y),bl:new ot(n.x,o.y),br:o}}cancelRequestedRender(){this.nextRenderHandle&&(dt(this.nextRenderHandle),this.nextRenderHandle=0)}drawControls(t){}renderCanvas(t,e){if(this.destroyed)return;const s=this.viewportTransform,i=this.clipPath;this.calcViewportBoundaries(),this.clearContext(t),t.imageSmoothingEnabled=this.imageSmoothingEnabled,t.patternQuality="best",this.fire("before:render",{ctx:t}),this._renderBackground(t),t.save(),t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this._renderObjects(t,e),t.restore(),this.controlsAboveOverlay||this.skipControlsDrawing||this.drawControls(t),i&&(i._set("canvas",this),i.shouldCache(),i._transformDone=!0,i.renderCache({forClipping:!0}),this.drawClipPathOnCanvas(t,i)),this._renderOverlay(t),this.controlsAboveOverlay&&!this.skipControlsDrawing&&this.drawControls(t),this.fire("after:render",{ctx:t}),this.__cleanupTask&&(this.__cleanupTask(),this.__cleanupTask=void 0)}drawClipPathOnCanvas(t,e){const s=this.viewportTransform;t.save(),t.transform(...s),t.globalCompositeOperation="destination-in",e.transform(t),t.scale(1/e.zoomX,1/e.zoomY),t.drawImage(e._cacheCanvas,-e.cacheTranslationX,-e.cacheTranslationY),t.restore()}_renderObjects(t,e){for(let s=0,i=e.length;s!t.excludeFromExport)).map((s=>this._toObject(s,t,e)))},this.__serializeBgOverlay(t,e)),r?{clipPath:r}:null)}_toObject(t,e,s){let i;this.includeDefaultValues||(i=t.includeDefaultValues,t.includeDefaultValues=!1);const r=t[e](s);return this.includeDefaultValues||(t.includeDefaultValues=!!i),r}__serializeBgOverlay(t,e){const s={},i=this.backgroundImage,r=this.overlayImage,n=this.backgroundColor,o=this.overlayColor;return Zt(n)?n.excludeFromExport||(s.background=n.toObject(e)):n&&(s.background=n),Zt(o)?o.excludeFromExport||(s.overlay=o.toObject(e)):o&&(s.overlay=o),i&&!i.excludeFromExport&&(s.backgroundImage=this._toObject(i,t,e)),r&&!r.excludeFromExport&&(s.overlayImage=this._toObject(r,t,e)),s}toSVG(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0;t.reviver=e;const s=[];return this._setSVGPreamble(s,t),this._setSVGHeader(s,t),this.clipPath&&s.push('\n')),this._setSVGBgOverlayColor(s,"background"),this._setSVGBgOverlayImage(s,"backgroundImage",e),this._setSVGObjects(s,e),this.clipPath&&s.push("\n"),this._setSVGBgOverlayColor(s,"overlay"),this._setSVGBgOverlayImage(s,"overlayImage",e),s.push(""),s.join("")}_setSVGPreamble(t,e){e.suppressPreamble||t.push('\n','\n')}_setSVGHeader(t,e){const s=e.width||"".concat(this.width),i=e.height||"".concat(this.height),r=a.NUM_FRACTION_DIGITS,n=e.viewBox;let o;if(n)o='viewBox="'.concat(n.x," ").concat(n.y," ").concat(n.width," ").concat(n.height,'" ');else if(this.svgViewportTransformation){const t=this.viewportTransform;o='viewBox="'.concat(Ut(-t[4]/t[0],r)," ").concat(Ut(-t[5]/t[3],r)," ").concat(Ut(this.width/t[0],r)," ").concat(Ut(this.height/t[3],r),'" ')}else o='viewBox="0 0 '.concat(this.width," ").concat(this.height,'" ');t.push("\n',"Created with Fabric.js ",x,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"\n")}createSVGClipPathMarkup(t){const e=this.clipPath;return e?(e.clipPathId="CLIPPATH_".concat(ft()),'\n').concat(e.toClipPathSVG(t.reviver),"\n")):""}createSVGRefElementsMarkup(){return["background","overlay"].map((t=>{const e=this["".concat(t,"Color")];if(Zt(e)){const s=this["".concat(t,"Vpt")],i=this.viewportTransform,r={isType:()=>!1,width:this.width/(s?i[0]:1),height:this.height/(s?i[3]:1)};return e.toSVG(r,{additionalTransform:s?Jt(i):""})}})).join("")}createSVGFontFacesMarkup(){const t=[],e={},s=a.fontPaths;this._objects.forEach((function e(s){t.push(s),ht(s)&&s._objects.forEach(e)})),t.forEach((t=>{if(!ee(t))return;const{styles:i,fontFamily:r}=t;!e[r]&&s[r]&&(e[r]=!0,i&&Object.values(i).forEach((t=>{Object.values(t).forEach((t=>{let{fontFamily:i=""}=t;!e[i]&&s[i]&&(e[i]=!0)}))})))}));const i=Object.keys(e).map((t=>"\t\t@font-face {\n\t\t\tfont-family: '".concat(t,"';\n\t\t\tsrc: url('").concat(s[t],"');\n\t\t}\n"))).join("");return i?'\t\n"):""}_setSVGObjects(t,e){this.forEachObject((s=>{s.excludeFromExport||this._setSVGObject(t,s,e)}))}_setSVGObject(t,e,s){t.push(e.toSVG(s))}_setSVGBgOverlayImage(t,e,s){const i=this[e];i&&!i.excludeFromExport&&i.toSVG&&t.push(i.toSVG(s))}_setSVGBgOverlayColor(t,e){const s=this["".concat(e,"Color")];if(s)if(Zt(s)){const i=s.repeat||"",r=this.width,n=this.height,o=this["".concat(e,"Vpt")]?Jt(bt(this.viewportTransform)):"";t.push('\n'))}else t.push('\n")}loadFromJSON(t,e){let{signal:s}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!t)return Promise.reject(new c("`json` is undefined"));const i="string"==typeof t?JSON.parse(t):t,{objects:r=[],backgroundImage:n,background:o,overlayImage:a,overlay:h,clipPath:l}=i,u=this.renderOnAddRemove;return this.renderOnAddRemove=!1,Promise.all([Rt(r,{reviver:e,signal:s}),It({backgroundImage:n,backgroundColor:o,overlayImage:a,overlayColor:h,clipPath:l},{signal:s})]).then((t=>{let[e,s]=t;return this.clear(),this.add(...e),this.set(i),this.set(s),this.renderOnAddRemove=u,this}))}clone(t){const e=this.toObject(t);return this.cloneWithoutData().loadFromJSON(e)}cloneWithoutData(){const t=pt();return t.width=this.width,t.height=this.height,new this.constructor(t)}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{format:e="png",quality:s=1,multiplier:i=1,enableRetinaScaling:r=!1}=t,n=i*(r?this.getRetinaScaling():1);return vt(this.toCanvasElement(n,t),e,s)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,{width:e,height:s,left:i,top:r,filter:n}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=(e||this.width)*t,a=(s||this.height)*t,h=this.getZoom(),c=this.width,l=this.height,u=this.skipControlsDrawing,d=h*t,g=this.viewportTransform,f=[d,0,0,d,(g[4]-(i||0))*t,(g[5]-(r||0))*t],p=this.enableRetinaScaling,m=pt(),v=n?this._objects.filter((t=>n(t))):this._objects;return m.width=o,m.height=a,this.enableRetinaScaling=!1,this.viewportTransform=f,this.width=o,this.height=a,this.skipControlsDrawing=!0,this.calcViewportBoundaries(),this.renderCanvas(m.getContext("2d"),v),this.viewportTransform=g,this.width=c,this.height=l,this.calcViewportBoundaries(),this.enableRetinaScaling=p,this.skipControlsDrawing=u,m}dispose(){return!this.disposed&&this.elements.cleanupDOM({width:this.width,height:this.height}),et.cancelByCanvas(this),this.disposed=!0,new Promise(((t,e)=>{const s=()=>{this.destroy(),t(!0)};s.kill=e,this.__cleanupTask&&this.__cleanupTask.kill("aborted"),this.destroyed?t(!1):this.nextRenderHandle?this.__cleanupTask=s:s()}))}destroy(){this.destroyed=!0,this.cancelRequestedRender(),this.forEachObject((t=>t.dispose())),this._objects=[],this.backgroundImage&&this.backgroundImage.dispose(),this.backgroundImage=void 0,this.overlayImage&&this.overlayImage.dispose(),this.overlayImage=void 0,this.elements.dispose()}toString(){return"#")}}e(ue,"ownDefaults",le);const de=["touchstart","touchmove","touchend"];const ge=t=>{const e=ie(t.target),s=function(t){const e=t.changedTouches;return e&&e[0]?e[0]:t}(t);return new ot(s.clientX+e.left,s.clientY+e.top)},fe=t=>de.includes(t.type)||"touch"===t.pointerType,pe=t=>{t.preventDefault(),t.stopPropagation()},me=t=>{let e=0,s=0,i=0,r=0;for(let n=0,o=t.length;ni||!n)&&(i=o),(or||!n)&&(r=a),(a_e(t,St(e,t.calcOwnMatrix())),_e=(t,e)=>{const s=Ot(e),{translateX:i,translateY:n,scaleX:o,scaleY:a}=s,h=r(s,ve),c=new ot(i,n);t.flipX=!1,t.flipY=!1,Object.assign(t,h),t.set({scaleX:o,scaleY:a}),t.setPositionByOrigin(c,D,D)},xe=t=>{t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.rotate(0)},Ce=t=>({scaleX:t.scaleX,scaleY:t.scaleY,skewX:t.skewX,skewY:t.skewY,angle:t.angle,left:t.left,flipX:t.flipX,flipY:t.flipY,top:t.top}),be=(t,e,s)=>{const i=t/2,r=e/2,n=[new ot(-i,-r),new ot(i,-r),new ot(-i,r),new ot(i,r)].map((t=>t.transform(s))),o=me(n);return new ot(o.width,o.height)},Se=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:T;return St(bt(arguments.length>1&&void 0!==arguments[1]?arguments[1]:T),t)},we=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:T,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:T;return t.transform(Se(e,s))},Te=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:T,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:T;return t.transform(Se(e,s),!0)},Oe=(t,e,s)=>{const i=Se(e,s);return _e(t,St(i,t.calcOwnMatrix())),i},ke=(t,e)=>{var s;const{transform:{target:r}}=e;null===(s=r.canvas)||void 0===s||s.fire("object:".concat(t),i(i({},e),{},{target:r})),r.fire(t,e)},De={left:-.5,top:-.5,center:0,bottom:.5,right:.5},Me=t=>"string"==typeof t?De[t]:t-.5,Pe="not-allowed";function Ee(t){return Me(t.originX)===Me(D)&&Me(t.originY)===Me(D)}function Ae(t){return.5-Me(t)}const je=(t,e)=>t[e],Fe=(t,e,s,i)=>({e:t,transform:e,pointer:new ot(s,i)});function Le(t,e){const s=t.getTotalAngle()+_t(Math.atan2(e.y,e.x))+360;return Math.round(s%360/45)}function Re(t,e,s,i,r){var n;let{target:o,corner:a}=t;const h=o.controls[a],c=(null===(n=o.canvas)||void 0===n?void 0:n.getZoom())||1,l=o.padding/c,u=function(t,e,s,i){const r=t.getRelativeCenterPoint(),n=void 0!==s&&void 0!==i?t.translateToGivenOrigin(r,D,D,s,i):new ot(t.left,t.top);return(t.angle?e.rotate(-yt(t.angle),r):e).subtract(n)}(o,new ot(i,r),e,s);return u.x>=l&&(u.x-=l),u.x<=-l&&(u.x+=l),u.y>=l&&(u.y-=l),u.y<=l&&(u.y+=l),u.x-=h.offsetX,u.y-=h.offsetY,u}const Ie=(t,e,s,i)=>{const{target:r,offsetX:n,offsetY:o}=e,a=s-n,h=i-o,c=!je(r,"lockMovementX")&&r.left!==a,l=!je(r,"lockMovementY")&&r.top!==h;return c&&r.set(M,a),l&&r.set(P,h),(c||l)&&ke(L,Fe(t,e,s,i)),c||l};class Be{getSvgStyles(t){const e=this.fillRule?this.fillRule:"nonzero",s=this.strokeWidth?this.strokeWidth:"0",i=this.strokeDashArray?this.strokeDashArray.join(" "):j,r=this.strokeDashOffset?this.strokeDashOffset:"0",n=this.strokeLineCap?this.strokeLineCap:"butt",o=this.strokeLineJoin?this.strokeLineJoin:"miter",a=this.strokeMiterLimit?this.strokeMiterLimit:"4",h=void 0!==this.opacity?this.opacity:"1",c=this.visible?"":" visibility: hidden;",l=t?"":this.getSvgFilter(),u=Qt(K,this.fill);return[Qt(J,this.stroke),"stroke-width: ",s,"; ","stroke-dasharray: ",i,"; ","stroke-linecap: ",n,"; ","stroke-dashoffset: ",r,"; ","stroke-linejoin: ",o,"; ","stroke-miterlimit: ",a,"; ",u,"fill-rule: ",e,"; ","opacity: ",h,";",l,c].join("")}getSvgFilter(){return this.shadow?"filter: url(#SVGID_".concat(this.shadow.id,");"):""}getSvgCommons(){return[this.id?'id="'.concat(this.id,'" '):"",this.clipPath?'clip-path="url(#'.concat(this.clipPath.clipPathId,')" '):""].join("")}getSvgTransform(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const s=t?this.calcTransformMatrix():this.calcOwnMatrix(),i='transform="'.concat(Jt(s));return"".concat(i).concat(e,'" ')}_toSVG(t){return[""]}toSVG(t){return this._createBaseSVGMarkup(this._toSVG(t),{reviver:t})}toClipPathSVG(t){return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(t),{reviver:t})}_createBaseClipPathSVGMarkup(t){let{reviver:e,additionalTransform:s=""}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=[this.getSvgTransform(!0,s),this.getSvgCommons()].join(""),r=t.indexOf("COMMON_PARTS");return t[r]=i,e?e(t.join("")):t.join("")}_createBaseSVGMarkup(t){let{noStyle:e,reviver:s,withShadow:i,additionalTransform:r}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=e?"":'style="'.concat(this.getSvgStyles(),'" '),o=i?'style="'.concat(this.getSvgFilter(),'" '):"",a=this.clipPath,h=this.strokeUniform?'vector-effect="non-scaling-stroke" ':"",c=a&&a.absolutePositioned,l=this.stroke,u=this.fill,d=this.shadow,g=[],f=t.indexOf("COMMON_PARTS");let p;a&&(a.clipPathId="CLIPPATH_".concat(ft()),p='\n').concat(a.toClipPathSVG(s),"\n")),c&&g.push("\n"),g.push("\n");const m=[n,h,e?"":this.addPaintOrder()," ",r?'transform="'.concat(r,'" '):""].join("");return t[f]=m,Zt(u)&&g.push(u.toSVG(this)),Zt(l)&&g.push(l.toSVG(this)),d&&g.push(d.toSVG(this)),a&&g.push(p),g.push(t.join("")),g.push("\n"),c&&g.push("\n"),s?s(g.join("")):g.join("")}addPaintOrder(){return this.paintFirst!==K?' paint-order="'.concat(this.paintFirst,'" '):""}}function Xe(t){return new RegExp("^("+t.join("|")+")\\b","i")}var We;const Ye=String.raw(We||(We=n(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"],["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"]))),Ve="http://www.w3.org/2000/svg",Ge=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+Ye+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+Ye+"))?\\s+(.*)"),He={cx:M,x:M,r:"radius",cy:P,y:P,display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","letter-spacing":"charSpacing","paint-order":"paintFirst","stroke-dasharray":"strokeDashArray","stroke-dashoffset":"strokeDashOffset","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"textAnchor",opacity:"opacity","clip-path":"clipPath","clip-rule":"clipRule","vector-effect":"strokeUniform","image-rendering":"imageSmoothing"},ze="font-size",Ne="clip-path",Ue=Xe(["path","circle","polygon","polyline","ellipse","rect","line","image","text"]),qe=Xe(["symbol","image","marker","pattern","view","svg"]),Ke=Xe(["symbol","g","a","svg","clipPath","defs"]),Je=new RegExp("^\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*$"),Qe=new ot(1,0),Ze=new ot,$e=(t,e)=>t.rotate(e),ts=(t,e)=>new ot(e).subtract(t),es=t=>t.distanceFrom(Ze),ss=(t,e)=>Math.atan2(os(t,e),as(t,e)),is=t=>ss(Qe,t),rs=t=>t.eq(Ze)?t:t.scalarDivide(es(t)),ns=function(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return rs(new ot(-t.y,t.x).scalarMultiply(e?1:-1))},os=(t,e)=>t.x*e.y-t.y*e.x,as=(t,e)=>t.x*e.x+t.y*e.y,hs=(t,e,s)=>{if(t.eq(e)||t.eq(s))return!0;const i=os(e,s),r=os(e,t),n=os(s,t);return i>=0?r>=0&&n<=0:!(r<=0&&n>=0)},cs="(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?",ls=new RegExp("(?:\\s|^)"+cs+cs+"("+Ye+"?(?:px)?)?(?:\\s?|$)(?:$|\\s)");class us{constructor(t){const e="string"==typeof t?us.parseShadow(t):t;Object.assign(this,us.ownDefaults,e),this.id=ft()}static parseShadow(t){const e=t.trim(),[,s=0,i=0,r=0]=(ls.exec(e)||[]).map((t=>parseFloat(t)||0));return{color:(e.replace(ls,"")||"rgb(0,0,0)").trim(),offsetX:s,offsetY:i,blur:r}}toString(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")}toSVG(t){const e=$e(new ot(this.offsetX,this.offsetY),yt(-t.angle)),s=new Nt(this.color);let i=40,r=40;return t.width&&t.height&&(i=100*Ut((Math.abs(e.x)+this.blur)/t.width,a.NUM_FRACTION_DIGITS)+20,r=100*Ut((Math.abs(e.y)+this.blur)/t.height,a.NUM_FRACTION_DIGITS)+20),t.flipX&&(e.x*=-1),t.flipY&&(e.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n')}toObject(){const t={color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling,type:this.constructor.type},e=us.ownDefaults;return this.includeDefaultValues?t:Xt(t,((t,s)=>t!==e[s]))}static async fromObject(t){return new this(t)}}e(us,"ownDefaults",{color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1}),e(us,"type","shadow"),tt.setClass(us,"shadow");const ds=(t,e,s)=>Math.max(t,Math.min(e,s)),gs=[P,M,z,N,"flipX","flipY","originX","originY","angle","opacity","globalCompositeOperation","shadow","visible",U,q],fs=[K,J,"strokeWidth","strokeDashArray","width","height","paintFirst","strokeUniform","strokeLineCap","strokeDashOffset","strokeLineJoin","strokeMiterLimit","backgroundColor","clipPath"],ps={top:0,left:0,width:0,height:0,angle:0,flipX:!1,flipY:!1,scaleX:1,scaleY:1,minScaleLimit:0,skewX:0,skewY:0,originX:M,originY:P,strokeWidth:1,strokeUniform:!1,padding:0,opacity:1,paintFirst:K,fill:"rgb(0,0,0)",fillRule:"nonzero",stroke:null,strokeDashArray:null,strokeDashOffset:0,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:4,globalCompositeOperation:"source-over",backgroundColor:"",shadow:null,visible:!0,includeDefaultValues:!0,excludeFromExport:!1,objectCaching:!0,clipPath:void 0,inverted:!1,absolutePositioned:!1,centeredRotation:!0,centeredScaling:!1,dirty:!0},ms=(t,e,s,i)=>(tt*Math.pow(2,10*(i-=1))*Math.sin((i*r-e)*S/s),ys=(t,e,s,i)=>-s*Math.cos(t/i*b)+s+e,_s=(t,e,s,i)=>(t/=i)<1/2.75?s*(7.5625*t*t)+e:t<2/2.75?s*(7.5625*(t-=1.5/2.75)*t+.75)+e:t<2.5/2.75?s*(7.5625*(t-=2.25/2.75)*t+.9375)+e:s*(7.5625*(t-=2.625/2.75)*t+.984375)+e,xs=(t,e,s,i)=>s-_s(i-t,0,s,i)+e;var Cs=Object.freeze({__proto__:null,defaultEasing:ys,easeInBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return s*(t/=i)*t*((r+1)*t-r)+e},easeInBounce:xs,easeInCirc:(t,e,s,i)=>-s*(Math.sqrt(1-(t/=i)*t)-1)+e,easeInCubic:(t,e,s,i)=>s*(t/i)**3+e,easeInElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(1===(t/=i))return e+s;n||(n=.3*i);const{a:o,s:a,p:h}=ms(r,s,n,1.70158);return-vs(o,a,h,t,i)+e},easeInExpo:(t,e,s,i)=>0===t?e:s*2**(10*(t/i-1))+e,easeInOutBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return(t/=i/2)<1?s/2*(t*t*((1+(r*=1.525))*t-r))+e:s/2*((t-=2)*t*((1+(r*=1.525))*t+r)+2)+e},easeInOutBounce:(t,e,s,i)=>t(t/=i/2)<1?-s/2*(Math.sqrt(1-t**2)-1)+e:s/2*(Math.sqrt(1-(t-=2)*t)+1)+e,easeInOutCubic:(t,e,s,i)=>(t/=i/2)<1?s/2*t**3+e:s/2*((t-2)**3+2)+e,easeInOutElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(2===(t/=i/2))return e+s;n||(n=i*(.3*1.5));const{a:o,s:a,p:h,c:c}=ms(r,s,n,1.70158);return t<1?-.5*vs(o,a,h,t,i)+e:o*Math.pow(2,-10*(t-=1))*Math.sin((t*i-a)*S/h)*.5+c+e},easeInOutExpo:(t,e,s,i)=>0===t?e:t===i?e+s:(t/=i/2)<1?s/2*2**(10*(t-1))+e:s/2*-(2**(-10*--t)+2)+e,easeInOutQuad:(t,e,s,i)=>(t/=i/2)<1?s/2*t**2+e:-s/2*(--t*(t-2)-1)+e,easeInOutQuart:(t,e,s,i)=>(t/=i/2)<1?s/2*t**4+e:-s/2*((t-=2)*t**3-2)+e,easeInOutQuint:(t,e,s,i)=>(t/=i/2)<1?s/2*t**5+e:s/2*((t-2)**5+2)+e,easeInOutSine:(t,e,s,i)=>-s/2*(Math.cos(Math.PI*t/i)-1)+e,easeInQuad:(t,e,s,i)=>s*(t/=i)*t+e,easeInQuart:(t,e,s,i)=>s*(t/=i)*t**3+e,easeInQuint:(t,e,s,i)=>s*(t/i)**5+e,easeInSine:(t,e,s,i)=>-s*Math.cos(t/i*b)+s+e,easeOutBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return s*((t=t/i-1)*t*((r+1)*t+r)+1)+e},easeOutBounce:_s,easeOutCirc:(t,e,s,i)=>s*Math.sqrt(1-(t=t/i-1)*t)+e,easeOutCubic:(t,e,s,i)=>s*((t/i-1)**3+1)+e,easeOutElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(1===(t/=i))return e+s;n||(n=.3*i);const{a:o,s:a,p:h,c:c}=ms(r,s,n,1.70158);return o*2**(-10*t)*Math.sin((t*i-a)*S/h)+c+e},easeOutExpo:(t,e,s,i)=>t===i?e+s:s*-(2**(-10*t/i)+1)+e,easeOutQuad:(t,e,s,i)=>-s*(t/=i)*(t-2)+e,easeOutQuart:(t,e,s,i)=>-s*((t=t/i-1)*t**3-1)+e,easeOutQuint:(t,e,s,i)=>s*((t/i-1)**5+1)+e,easeOutSine:(t,e,s,i)=>s*Math.sin(t/i*b)+e});const bs=()=>!1;class Ss{constructor(t){let{startValue:s,byValue:i,duration:r=500,delay:n=0,easing:o=ys,onStart:a=C,onChange:h=C,onComplete:c=C,abort:l=bs,target:u}=t;e(this,"_state","pending"),e(this,"durationProgress",0),e(this,"valueProgress",0),this.tick=this.tick.bind(this),this.duration=r,this.delay=n,this.easing=o,this._onStart=a,this._onChange=h,this._onComplete=c,this._abort=l,this.target=u,this.startValue=s,this.byValue=i,this.value=this.startValue,this.endValue=Object.freeze(this.calculate(this.duration).value)}get state(){return this._state}isDone(){return"aborted"===this._state||"completed"===this._state}start(){const t=t=>{"pending"===this._state&&(this.startTime=t||+new Date,this._state="running",this._onStart(),this.tick(this.startTime))};this.register(),this.delay>0?setTimeout((()=>ut(t)),this.delay):ut(t)}tick(t){const e=(t||+new Date)-this.startTime,s=Math.min(e,this.duration);this.durationProgress=s/this.duration;const{value:i,valueProgress:r}=this.calculate(s);this.value=Object.freeze(i),this.valueProgress=r,"aborted"!==this._state&&(this._abort(this.value,this.valueProgress,this.durationProgress)?(this._state="aborted",this.unregister()):e>=this.duration?(this.durationProgress=this.valueProgress=1,this._onChange(this.endValue,this.valueProgress,this.durationProgress),this._state="completed",this._onComplete(this.endValue,this.valueProgress,this.durationProgress),this.unregister()):(this._onChange(this.value,this.valueProgress,this.durationProgress),ut(this.tick)))}register(){et.push(this)}unregister(){et.remove(this)}abort(){this._state="aborted",this.unregister()}}const ws=["startValue","endValue"];class Ts extends Ss{constructor(t){let{startValue:e=0,endValue:s=100}=t;super(i(i({},r(t,ws)),{},{startValue:e,byValue:s-e}))}calculate(t){const e=this.easing(t,this.startValue,this.byValue,this.duration);return{value:e,valueProgress:Math.abs((e-this.startValue)/this.byValue)}}}const Os=["startValue","endValue"];class ks extends Ss{constructor(t){let{startValue:e=[0],endValue:s=[100]}=t;super(i(i({},r(t,Os)),{},{startValue:e,byValue:s.map(((t,s)=>t-e[s]))}))}calculate(t){const e=this.startValue.map(((e,s)=>this.easing(t,e,this.byValue[s],this.duration,s)));return{value:e,valueProgress:Math.abs((e[0]-this.startValue[0])/this.byValue[0])}}}const Ds=["startValue","endValue","easing","onChange","onComplete","abort"],Ms=(t,e,s,i)=>e+s*(1-Math.cos(t/i*b)),Ps=t=>t&&((e,s,i)=>t(new Nt(e).toRgba(),s,i));class Es extends Ss{constructor(t){let{startValue:e,endValue:s,easing:n=Ms,onChange:o,onComplete:a,abort:h}=t,c=r(t,Ds);const l=new Nt(e).getSource(),u=new Nt(s).getSource();super(i(i({},c),{},{startValue:l,byValue:u.map(((t,e)=>t-l[e])),easing:n,onChange:Ps(o),onComplete:Ps(a),abort:Ps(h)}))}calculate(t){const[e,s,i,r]=this.startValue.map(((e,s)=>this.easing(t,e,this.byValue[s],this.duration,s))),n=[...[e,s,i].map(Math.round),ds(0,r,1)];return{value:n,valueProgress:n.map(((t,e)=>0!==this.byValue[e]?Math.abs((t-this.startValue[e])/this.byValue[e]):0)).find((t=>0!==t))||0}}}function As(t){const e=(t=>Array.isArray(t.startValue)||Array.isArray(t.endValue))(t)?new ks(t):new Ts(t);return e.start(),e}function js(t){const e=new Es(t);return e.start(),e}class Fs{constructor(t){this.status=t,this.points=[]}includes(t){return this.points.some((e=>e.eq(t)))}append(){for(var t=arguments.length,e=new Array(t),s=0;s!this.includes(t)))),this}static isPointContained(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(e.eq(s))return t.eq(e);if(e.x===s.x)return t.x===e.x&&(i||t.y>=Math.min(e.y,s.y)&&t.y<=Math.max(e.y,s.y));if(e.y===s.y)return t.y===e.y&&(i||t.x>=Math.min(e.x,s.x)&&t.x<=Math.max(e.x,s.x));{const r=ts(e,s),n=ts(e,t).divide(r);return i?Math.abs(n.x)===Math.abs(n.y):n.x===n.y&&n.x>=0&&n.x<=1}}static isPointInPolygon(t,e){const s=new ot(t).setX(Math.min(t.x-1,...e.map((t=>t.x))));let i=0;for(let r=0;r4&&void 0!==arguments[4])||arguments[4],n=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];const o=e.x-t.x,a=e.y-t.y,h=i.x-s.x,c=i.y-s.y,l=t.x-s.x,u=t.y-s.y,d=h*u-c*l,g=o*u-a*l,f=c*o-h*a;if(0!==f){const e=d/f,s=g/f;return(r||0<=e&&e<=1)&&(n||0<=s&&s<=1)?new Fs("Intersection").append(new ot(t.x+e*o,t.y+e*a)):new Fs}if(0===d||0===g){const o=r||n||Fs.isPointContained(t,s,i)||Fs.isPointContained(e,s,i)||Fs.isPointContained(s,t,e)||Fs.isPointContained(i,t,e);return new Fs(o?"Coincident":void 0)}return new Fs("Parallel")}static intersectSegmentLine(t,e,s,i){return Fs.intersectLineLine(t,e,s,i,!1,!0)}static intersectSegmentSegment(t,e,s,i){return Fs.intersectLineLine(t,e,s,i,!1,!1)}static intersectLinePolygon(t,e,s){let i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const r=new Fs,n=s.length;for(let o,a,h,c=0;c0&&(r.status="Intersection"),r}static intersectSegmentPolygon(t,e,s){return Fs.intersectLinePolygon(t,e,s,!1)}static intersectPolygonPolygon(t,e){const s=new Fs,i=t.length,r=[];for(let n=0;n0&&r.length===t.length?new Fs("Coincident"):(s.points.length>0&&(s.status="Intersection"),s)}static intersectPolygonRectangle(t,e,s){const i=e.min(s),r=e.max(s),n=new ot(r.x,i.y),o=new ot(i.x,r.y);return Fs.intersectPolygonPolygon(t,[i,n,r,o])}}class Ls extends lt{getX(){return this.getXY().x}setX(t){this.setXY(this.getXY().setX(t))}getY(){return this.getXY().y}setY(t){this.setXY(this.getXY().setY(t))}getRelativeX(){return this.left}setRelativeX(t){this.left=t}getRelativeY(){return this.top}setRelativeY(t){this.top=t}getXY(){const t=this.getRelativeXY();return this.group?Ct(t,this.group.calcTransformMatrix()):t}setXY(t,e,s){this.group&&(t=Ct(t,bt(this.group.calcTransformMatrix()))),this.setRelativeXY(t,e,s)}getRelativeXY(){return new ot(this.left,this.top)}setRelativeXY(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.originX,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.originY;this.setPositionByOrigin(t,e,s)}isStrokeAccountedForInDimensions(){return!1}getCoords(){const{tl:t,tr:e,br:s,bl:i}=this.aCoords||(this.aCoords=this.calcACoords()),r=[t,e,s,i];if(this.group){const t=this.group.calcTransformMatrix();return r.map((e=>Ct(e,t)))}return r}intersectsWithRect(t,e){return"Intersection"===Fs.intersectPolygonRectangle(this.getCoords(),t,e).status}intersectsWithObject(t){const e=Fs.intersectPolygonPolygon(this.getCoords(),t.getCoords());return"Intersection"===e.status||"Coincident"===e.status||t.isContainedWithinObject(this)||this.isContainedWithinObject(t)}isContainedWithinObject(t){return this.getCoords().every((e=>t.containsPoint(e)))}isContainedWithinRect(t,e){const{left:s,top:i,width:r,height:n}=this.getBoundingRect();return s>=t.x&&s+r<=e.x&&i>=t.y&&i+n<=e.y}isOverlapping(t){return this.intersectsWithObject(t)||this.isContainedWithinObject(t)||t.isContainedWithinObject(this)}containsPoint(t){return Fs.isPointInPolygon(t,this.getCoords())}isOnScreen(){if(!this.canvas)return!1;const{tl:t,br:e}=this.canvas.vptCoords;return!!this.getCoords().some((s=>s.x<=e.x&&s.x>=t.x&&s.y<=e.y&&s.y>=t.y))||(!!this.intersectsWithRect(t,e)||this.containsPoint(t.midPointFrom(e)))}isPartiallyOnScreen(){if(!this.canvas)return!1;const{tl:t,br:e}=this.canvas.vptCoords;if(this.intersectsWithRect(t,e))return!0;return this.getCoords().every((s=>(s.x>=e.x||s.x<=t.x)&&(s.y>=e.y||s.y<=t.y)))&&this.containsPoint(t.midPointFrom(e))}getBoundingRect(){return me(this.getCoords())}getScaledWidth(){return this._getTransformedDimensions().x}getScaledHeight(){return this._getTransformedDimensions().y}scale(t){this._set(z,t),this._set(N,t),this.setCoords()}scaleToWidth(t){const e=this.getBoundingRect().width/this.getScaledWidth();return this.scale(t/this.width/e)}scaleToHeight(t){const e=this.getBoundingRect().height/this.getScaledHeight();return this.scale(t/this.height/e)}getCanvasRetinaScaling(){var t;return(null===(t=this.canvas)||void 0===t?void 0:t.getRetinaScaling())||1}getTotalAngle(){return this.group?_t(Tt(this.calcTransformMatrix())):this.angle}getViewportTransform(){var t;return(null===(t=this.canvas)||void 0===t?void 0:t.viewportTransform)||T.concat()}calcACoords(){const t=Dt({angle:this.angle}),{x:e,y:s}=this.getRelativeCenterPoint(),i=kt(e,s),r=St(i,t),n=this._getTransformedDimensions(),o=n.x/2,a=n.y/2;return{tl:Ct({x:-o,y:-a},r),tr:Ct({x:o,y:-a},r),bl:Ct({x:-o,y:a},r),br:Ct({x:o,y:a},r)}}setCoords(){this.aCoords=this.calcACoords()}transformMatrixKey(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=[];return!t&&this.group&&(e=this.group.transformMatrixKey(t)),e.push(this.top,this.left,this.width,this.height,this.scaleX,this.scaleY,this.angle,this.strokeWidth,this.skewX,this.skewY,+this.flipX,+this.flipY,Me(this.originX),Me(this.originY)),e}calcTransformMatrix(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=this.calcOwnMatrix();if(t||!this.group)return e;const s=this.transformMatrixKey(t),i=this.matrixCache;return i&&i.key.every(((t,e)=>t===s[e]))?i.value:(this.group&&(e=St(this.group.calcTransformMatrix(!1),e)),this.matrixCache={key:s,value:e},e)}calcOwnMatrix(){const t=this.transformMatrixKey(!0),e=this.ownMatrixCache;if(e&&e.key===t)return e.value;const s=this.getRelativeCenterPoint(),i={angle:this.angle,translateX:s.x,translateY:s.y,scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,flipX:this.flipX,flipY:this.flipY},r=Ft(i);return this.ownMatrixCache={key:t,value:r},r}_getNonTransformedDimensions(){return new ot(this.width,this.height).scalarAdd(this.strokeWidth)}_calculateCurrentDimensions(t){return this._getTransformedDimensions(t).transform(this.getViewportTransform(),!0).scalarAdd(2*this.padding)}_getTransformedDimensions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const e=i({scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,width:this.width,height:this.height,strokeWidth:this.strokeWidth},t),s=e.strokeWidth;let r=s,n=0;this.strokeUniform&&(r=0,n=s);const o=e.width+r,a=e.height+r;let h;return h=0===e.skewX&&0===e.skewY?new ot(o*e.scaleX,a*e.scaleY):be(o,a,jt(e)),h.scalarAdd(n)}translateToGivenOrigin(t,e,s,i,r){let n=t.x,o=t.y;const a=Me(i)-Me(e),h=Me(r)-Me(s);if(a||h){const t=this._getTransformedDimensions();n+=a*t.x,o+=h*t.y}return new ot(n,o)}translateToCenterPoint(t,e,s){if(e===D&&s===D)return t;const i=this.translateToGivenOrigin(t,e,s,D,D);return this.angle?i.rotate(yt(this.angle),t):i}translateToOriginPoint(t,e,s){const i=this.translateToGivenOrigin(t,D,D,e,s);return this.angle?i.rotate(yt(this.angle),t):i}getCenterPoint(){const t=this.getRelativeCenterPoint();return this.group?Ct(t,this.group.calcTransformMatrix()):t}getRelativeCenterPoint(){return this.translateToCenterPoint(new ot(this.left,this.top),this.originX,this.originY)}getPointByOrigin(t,e){return this.translateToOriginPoint(this.getRelativeCenterPoint(),t,e)}setPositionByOrigin(t,e,s){const i=this.translateToCenterPoint(t,e,s),r=this.translateToOriginPoint(i,this.originX,this.originY);this.set({left:r.x,top:r.y})}_getLeftTopCoords(){return this.translateToOriginPoint(this.getRelativeCenterPoint(),M,P)}}const Rs=["type"],Is=["extraParam"];let Bs=class t extends Ls{static getDefaults(){return t.ownDefaults}get type(){const t=this.constructor.type;return"FabricObject"===t?"object":t.toLowerCase()}set type(t){h("warn","Setting type has no effect",t)}constructor(s){super(),e(this,"_cacheContext",null),Object.assign(this,t.ownDefaults),this.setOptions(s)}_createCacheCanvas(){this._cacheCanvas=pt(),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas(),this.dirty=!0}_limitCacheSize(t){const e=t.width,s=t.height,i=a.maxCacheSideLimit,r=a.minCacheSideLimit;if(e<=i&&s<=i&&e*s<=a.perfLimitSizeTotal)return ec&&(t.zoomX/=e/c,t.width=c,t.capped=!0),s>l&&(t.zoomY/=s/l,t.height=l,t.capped=!0),t}_getCacheCanvasDimensions(){const t=this.getTotalObjectScaling(),e=this._getTransformedDimensions({skewX:0,skewY:0}),s=e.x*t.x/this.scaleX,i=e.y*t.y/this.scaleY;return{width:s+2,height:i+2,zoomX:t.x,zoomY:t.y,x:s,y:i}}_updateCacheCanvas(){const t=this._cacheCanvas,e=this._cacheContext,s=this._limitCacheSize(this._getCacheCanvasDimensions()),i=a.minCacheSideLimit,r=s.width,n=s.height,o=s.zoomX,h=s.zoomY,c=r!==t.width||n!==t.height,l=this.zoomX!==o||this.zoomY!==h;if(!t||!e)return!1;let u,d,g=c||l,f=0,p=0,m=!1;if(c){const t=this._cacheCanvas.width,e=this._cacheCanvas.height,o=r>t||n>e;m=o||(r<.9*t||n<.9*e)&&t>i&&e>i,o&&!s.capped&&(r>i||n>i)&&(f=.1*r,p=.1*n)}return ee(this)&&this.path&&(g=!0,m=!0,f+=this.getHeightOfLine(0)*this.zoomX,p+=this.getHeightOfLine(0)*this.zoomY),!!g&&(m?(t.width=Math.ceil(r+f),t.height=Math.ceil(n+p)):(e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,t.width,t.height)),u=s.x/2,d=s.y/2,this.cacheTranslationX=Math.round(t.width/2-u)+u,this.cacheTranslationY=Math.round(t.height/2-d)+d,e.translate(this.cacheTranslationX,this.cacheTranslationY),e.scale(o,h),this.zoomX=o,this.zoomY=h,!0)}setOptions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._setOptions(t)}transform(t){const e=this.group&&!this.group._transformDone||this.group&&this.canvas&&t===this.canvas.contextTop,s=this.calcTransformMatrix(!e);t.transform(s[0],s[1],s[2],s[3],s[4],s[5])}getObjectScaling(){if(!this.group)return new ot(Math.abs(this.scaleX),Math.abs(this.scaleY));const t=Ot(this.calcTransformMatrix());return new ot(Math.abs(t.scaleX),Math.abs(t.scaleY))}getTotalObjectScaling(){const t=this.getObjectScaling();if(this.canvas){const e=this.canvas.getZoom(),s=this.getCanvasRetinaScaling();return t.scalarMultiply(e*s)}return t}getObjectOpacity(){let t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t}_constrainScale(t){return Math.abs(t)0&&void 0!==arguments[0]&&arguments[0];if(this.isNotVisible())return!1;const e=this._cacheCanvas,s=this._cacheContext;return!(!e||!s||t||!this._updateCacheCanvas())||!!(this.dirty||this.clipPath&&this.clipPath.absolutePositioned)&&(e&&s&&!t&&(s.save(),s.setTransform(1,0,0,1,0,0),s.clearRect(0,0,e.width,e.height),s.restore()),!0)}_renderBackground(t){if(!this.backgroundColor)return;const e=this._getNonTransformedDimensions();t.fillStyle=this.backgroundColor,t.fillRect(-e.x/2,-e.y/2,e.x,e.y),this._removeShadow(t)}_setOpacity(t){this.group&&!this.group._transformDone?t.globalAlpha=this.getObjectOpacity():t.globalAlpha*=this.opacity}_setStrokeStyles(t,e){const s=e.stroke;s&&(t.lineWidth=e.strokeWidth,t.lineCap=e.strokeLineCap,t.lineDashOffset=e.strokeDashOffset,t.lineJoin=e.strokeLineJoin,t.miterLimit=e.strokeMiterLimit,Zt(s)?"percentage"===s.gradientUnits||s.gradientTransform||s.patternTransform?this._applyPatternForTransformedGradient(t,s):(t.strokeStyle=s.toLive(t),this._applyPatternGradientTransform(t,s)):t.strokeStyle=e.stroke)}_setFillStyles(t,e){let{fill:s}=e;s&&(Zt(s)?(t.fillStyle=s.toLive(t),this._applyPatternGradientTransform(t,s)):t.fillStyle=s)}_setClippingProperties(t){t.globalAlpha=1,t.strokeStyle="transparent",t.fillStyle="#000000"}_setLineDash(t,e){e&&0!==e.length&&(1&e.length&&e.push(...e),t.setLineDash(e))}_setShadow(t){if(!this.shadow)return;const e=this.shadow,s=this.canvas,i=this.getCanvasRetinaScaling(),[r,,,n]=(null==s?void 0:s.viewportTransform)||T,o=r*i,h=n*i,c=e.nonScaling?new ot(1,1):this.getObjectScaling();t.shadowColor=e.color,t.shadowBlur=e.blur*a.browserShadowBlurConstant*(o+h)*(c.x+c.y)/4,t.shadowOffsetX=e.offsetX*o*c.x,t.shadowOffsetY=e.offsetY*h*c.y}_removeShadow(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)}_applyPatternGradientTransform(t,e){if(!Zt(e))return{offsetX:0,offsetY:0};const s=e.gradientTransform||e.patternTransform,i=-this.width/2+e.offsetX||0,r=-this.height/2+e.offsetY||0;return"percentage"===e.gradientUnits?t.transform(this.width,0,0,this.height,i,r):t.transform(1,0,0,1,i,r),s&&t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),{offsetX:i,offsetY:r}}_renderPaintInOrder(t){this.paintFirst===J?(this._renderStroke(t),this._renderFill(t)):(this._renderFill(t),this._renderStroke(t))}_render(t){}_renderFill(t){this.fill&&(t.save(),this._setFillStyles(t,this),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore())}_renderStroke(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeUniform){const e=this.getObjectScaling();t.scale(1/e.x,1/e.y)}this._setLineDash(t,this.strokeDashArray),this._setStrokeStyles(t,this),t.stroke(),t.restore()}}_applyPatternForTransformedGradient(t,e){var s;const i=this._limitCacheSize(this._getCacheCanvasDimensions()),r=pt(),n=this.getCanvasRetinaScaling(),o=i.x/this.scaleX/n,a=i.y/this.scaleY/n;r.width=Math.ceil(o),r.height=Math.ceil(a);const h=r.getContext("2d");h&&(h.beginPath(),h.moveTo(0,0),h.lineTo(o,0),h.lineTo(o,a),h.lineTo(0,a),h.closePath(),h.translate(o/2,a/2),h.scale(i.zoomX/this.scaleX/n,i.zoomY/this.scaleY/n),this._applyPatternGradientTransform(h,e),h.fillStyle=e.toLive(t),h.fill(),t.translate(-this.width/2-this.strokeWidth/2,-this.height/2-this.strokeWidth/2),t.scale(n*this.scaleX/i.zoomX,n*this.scaleY/i.zoomY),t.strokeStyle=null!==(s=h.createPattern(r,"no-repeat"))&&void 0!==s?s:"")}_findCenterFromElement(){return new ot(this.left+this.width/2,this.top+this.height/2)}clone(t){const e=this.toObject(t);return this.constructor.fromObject(e)}cloneAsImage(t){const e=this.toCanvasElement(t);return new(tt.getClass("image"))(e)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const e=Ce(this),s=this.group,i=this.shadow,r=Math.abs,n=t.enableRetinaScaling?y():1,o=(t.multiplier||1)*n,a=t.canvasProvider||(t=>new ue(t,{enableRetinaScaling:!1,renderOnAddRemove:!1,skipOffscreen:!1}));delete this.group,t.withoutTransform&&xe(this),t.withoutShadow&&(this.shadow=null),t.viewportTransform&&Oe(this,this.getViewportTransform()),this.setCoords();const h=pt(),c=this.getBoundingRect(),l=this.shadow,u=new ot;if(l){const t=l.blur,e=l.nonScaling?new ot(1,1):this.getObjectScaling();u.x=2*Math.round(r(l.offsetX)+t)*r(e.x),u.y=2*Math.round(r(l.offsetY)+t)*r(e.y)}const d=c.width+u.x,g=c.height+u.y;h.width=Math.ceil(d),h.height=Math.ceil(g);const f=a(h);"jpeg"===t.format&&(f.backgroundColor="#fff"),this.setPositionByOrigin(new ot(f.width/2,f.height/2),D,D);const p=this.canvas;f._objects=[this],this.set("canvas",f),this.setCoords();const m=f.toCanvasElement(o||1,t);return this.set("canvas",p),this.shadow=i,s&&(this.group=s),this.set(e),this.setCoords(),f._objects=[],f.destroy(),m}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return vt(this.toCanvasElement(t),t.format||"png",t.quality||1)}isType(){for(var t=arguments.length,e=new Array(t),s=0;s{let[i,r]=s;return t[i]=this._animate(i,r,e),t}),{})}_animate(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=t.split("."),n=this.constructor.colorProperties.includes(r[r.length-1]),{abort:o,startValue:a,onChange:h,onComplete:c}=s,l=i(i({},s),{},{target:this,startValue:null!=a?a:r.reduce(((t,e)=>t[e]),this),endValue:e,abort:null==o?void 0:o.bind(this),onChange:(t,e,s)=>{r.reduce(((e,s,i)=>(i===r.length-1&&(e[s]=t),e[s])),this),h&&h(t,e,s)},onComplete:(t,e,s)=>{this.setCoords(),c&&c(t,e,s)}});return n?js(l):As(l)}isDescendantOf(t){const{parent:e,group:s}=this;return e===t||s===t||!!e&&e.isDescendantOf(t)||!!s&&s!==e&&s.isDescendantOf(t)}getAncestors(){const t=[];let e=this;do{e=e.parent,e&&t.push(e)}while(e);return t}findCommonAncestors(t){if(this===t)return{fork:[],otherFork:[],common:[this,...this.getAncestors()]};const e=this.getAncestors(),s=t.getAncestors();if(0===e.length&&s.length>0&&this===s[s.length-1])return{fork:[],otherFork:[t,...s.slice(0,s.length-1)],common:[this]};for(let i,r=0;r-1&&n>o}toObject(){const e=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).concat(t.customProperties,this.constructor.customProperties||[]);let s;const r=a.NUM_FRACTION_DIGITS,{clipPath:n,fill:o,stroke:h,shadow:c,strokeDashArray:l,left:u,top:d,originX:g,originY:f,width:p,height:m,strokeWidth:v,strokeLineCap:y,strokeDashOffset:_,strokeLineJoin:C,strokeUniform:b,strokeMiterLimit:S,scaleX:w,scaleY:T,angle:O,flipX:k,flipY:D,opacity:M,visible:P,backgroundColor:E,fillRule:A,paintFirst:j,globalCompositeOperation:F,skewX:L,skewY:R}=this;n&&!n.excludeFromExport&&(s=n.toObject(e.concat("inverted","absolutePositioned")));const I=t=>Ut(t,r),B=i(i({},Bt(this,e)),{},{type:this.constructor.type,version:x,originX:g,originY:f,left:I(u),top:I(d),width:I(p),height:I(m),fill:$t(o)?o.toObject():o,stroke:$t(h)?h.toObject():h,strokeWidth:I(v),strokeDashArray:l?l.concat():l,strokeLineCap:y,strokeDashOffset:_,strokeLineJoin:C,strokeUniform:b,strokeMiterLimit:I(S),scaleX:I(w),scaleY:I(T),angle:I(O),flipX:k,flipY:D,opacity:I(M),shadow:c?c.toObject():c,visible:P,backgroundColor:E,fillRule:A,paintFirst:j,globalCompositeOperation:F,skewX:I(L),skewY:I(R)},s?{clipPath:s}:null);return this.includeDefaultValues?B:this._removeDefaultValues(B)}toDatalessObject(t){return this.toObject(t)}_removeDefaultValues(t){const e=this.constructor.getDefaults(),s=Object.keys(e).length>0?e:Object.getPrototypeOf(this);return Xt(t,((t,e)=>{if(e===M||e===P||"type"===e)return!0;const i=s[e];return t!==i&&!(Array.isArray(t)&&Array.isArray(i)&&0===t.length&&0===i.length)}))}toString(){return"#<".concat(this.constructor.type,">")}static _fromObject(t){let e=r(t,Rs),s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{extraParam:i}=s,n=r(s,Is);return It(e,n).then((t=>i?(delete t[i],new this(e[i],t)):new this(t)))}static fromObject(t,e){return this._fromObject(t,e)}};e(Bs,"stateProperties",gs),e(Bs,"cacheProperties",fs),e(Bs,"ownDefaults",ps),e(Bs,"type","FabricObject"),e(Bs,"colorProperties",[K,J,"backgroundColor"]),e(Bs,"customProperties",[]),tt.setClass(Bs),tt.setClass(Bs,"object");const Xs=(t,e,s)=>(r,n,o,a)=>{const h=e(r,n,o,a);return h&&ke(t,i(i({},Fe(r,n,o,a)),s)),h};function Ws(t){return(e,s,i,r)=>{const{target:n,originX:o,originY:a}=s,h=n.getRelativeCenterPoint(),c=n.translateToOriginPoint(h,o,a),l=t(e,s,i,r);return n.setPositionByOrigin(c,s.originX,s.originY),l}}const Ys=Xs(W,Ws(((t,e,s,i)=>{const r=Re(e,e.originX,e.originY,s,i);if(Me(e.originX)===Me(D)||Me(e.originX)===Me(A)&&r.x<0||Me(e.originX)===Me(M)&&r.x>0){const{target:t}=e,s=t.strokeWidth/(t.strokeUniform?t.scaleX:1),i=Ee(e)?2:1,n=t.width,o=Math.ceil(Math.abs(r.x*i/t.scaleX)-s);return t.set("width",Math.max(o,0)),n!==t.width}return!1})));function Vs(t,e,s,i,r){i=i||{};const n=this.sizeX||i.cornerSize||r.cornerSize,o=this.sizeY||i.cornerSize||r.cornerSize,a=void 0!==i.transparentCorners?i.transparentCorners:r.transparentCorners,h=a?J:K,c=!a&&(i.cornerStrokeColor||r.cornerStrokeColor);let l,u=e,d=s;t.save(),t.fillStyle=i.cornerColor||r.cornerColor||"",t.strokeStyle=i.cornerStrokeColor||r.cornerStrokeColor||"",n>o?(l=n,t.scale(1,o/n),d=s*n/o):o>n?(l=o,t.scale(n/o,1),u=e*o/n):l=n,t.lineWidth=1,t.beginPath(),t.arc(u,d,l/2,0,S,!1),t[h](),c&&t.stroke(),t.restore()}function Gs(t,e,s,i,r){i=i||{};const n=this.sizeX||i.cornerSize||r.cornerSize,o=this.sizeY||i.cornerSize||r.cornerSize,a=void 0!==i.transparentCorners?i.transparentCorners:r.transparentCorners,h=a?J:K,c=!a&&(i.cornerStrokeColor||r.cornerStrokeColor),l=n/2,u=o/2;t.save(),t.fillStyle=i.cornerColor||r.cornerColor||"",t.strokeStyle=i.cornerStrokeColor||r.cornerStrokeColor||"",t.lineWidth=1,t.translate(e,s);const d=r.getTotalAngle();t.rotate(yt(d)),t["".concat(h,"Rect")](-l,-u,n,o),c&&t.strokeRect(-l,-u,n,o),t.restore()}class Hs{constructor(t){e(this,"visible",!0),e(this,"actionName",H),e(this,"angle",0),e(this,"x",0),e(this,"y",0),e(this,"offsetX",0),e(this,"offsetY",0),e(this,"sizeX",0),e(this,"sizeY",0),e(this,"touchSizeX",0),e(this,"touchSizeY",0),e(this,"cursorStyle","crosshair"),e(this,"withConnection",!1),Object.assign(this,t)}shouldActivate(t,e,s,i){var r;let{tl:n,tr:o,br:a,bl:h}=i;return(null===(r=e.canvas)||void 0===r?void 0:r.getActiveObject())===e&&e.isControlVisible(t)&&Fs.isPointInPolygon(s,[n,o,a,h])}getActionHandler(t,e,s){return this.actionHandler}getMouseDownHandler(t,e,s){return this.mouseDownHandler}getMouseUpHandler(t,e,s){return this.mouseUpHandler}cursorStyleHandler(t,e,s){return e.cursorStyle}getActionName(t,e,s){return e.actionName}getVisibility(t,e){var s,i;return null!==(s=null===(i=t._controlsVisibility)||void 0===i?void 0:i[e])&&void 0!==s?s:this.visible}setVisibility(t,e,s){this.visible=t}positionHandler(t,e,s,i){return new ot(this.x*t.x+this.offsetX,this.y*t.y+this.offsetY).transform(e)}calcCornerCoords(t,e,s,i,r,n){const o=wt([kt(s,i),Dt({angle:t}),Mt((r?this.touchSizeX:this.sizeX)||e,(r?this.touchSizeY:this.sizeY)||e)]);return{tl:new ot(-.5,-.5).transform(o),tr:new ot(.5,-.5).transform(o),br:new ot(.5,.5).transform(o),bl:new ot(-.5,.5).transform(o)}}render(t,e,s,i,r){if("circle"===((i=i||{}).cornerStyle||r.cornerStyle))Vs.call(this,t,e,s,i,r);else Gs.call(this,t,e,s,i,r)}}const zs=(t,e,s)=>s.lockRotation?Pe:e.cursorStyle,Ns=Xs(I,Ws(((t,e,s,i)=>{let{target:r,ex:n,ey:o,theta:a,originX:h,originY:c}=e;const l=r.translateToOriginPoint(r.getRelativeCenterPoint(),h,c);if(je(r,"lockRotation"))return!1;const u=Math.atan2(o-l.y,n-l.x),d=Math.atan2(i-l.y,s-l.x);let g=_t(d-u+a);if(r.snapAngle&&r.snapAngle>0){const t=r.snapAngle,e=r.snapThreshold||t,s=Math.ceil(g/t)*t,i=Math.floor(g/t)*t;Math.abs(g-i){const i=Us(t,s);if(qs(s,0!==e.x&&0===e.y?"x":0===e.x&&0!==e.y?"y":"",i))return Pe;const r=Le(s,e);return"".concat(Ks[r],"-resize")};function Qs(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};const n=e.target,o=r.by,a=Us(t,n);let h,c,l,u,d,g;if(qs(n,o,a))return!1;if(e.gestureScale)c=e.scaleX*e.gestureScale,l=e.scaleY*e.gestureScale;else{if(h=Re(e,e.originX,e.originY,s,i),d="y"!==o?Math.sign(h.x||e.signX||1):1,g="x"!==o?Math.sign(h.y||e.signY||1):1,e.signX||(e.signX=d),e.signY||(e.signY=g),je(n,"lockScalingFlip")&&(e.signX!==d||e.signY!==g))return!1;if(u=n._getTransformedDimensions(),a&&!o){const t=Math.abs(h.x)+Math.abs(h.y),{original:s}=e,i=t/(Math.abs(u.x*s.scaleX/n.scaleX)+Math.abs(u.y*s.scaleY/n.scaleY));c=s.scaleX*i,l=s.scaleY*i}else c=Math.abs(h.x*n.scaleX/u.x),l=Math.abs(h.y*n.scaleY/u.y);Ee(e)&&(c*=2,l*=2),e.signX!==d&&"y"!==o&&(e.originX=Ae(e.originX),c*=-1,e.signX=d),e.signY!==g&&"x"!==o&&(e.originY=Ae(e.originY),l*=-1,e.signY=g)}const f=n.scaleX,p=n.scaleY;return o?("x"===o&&n.set(z,c),"y"===o&&n.set(N,l)):(!je(n,"lockScalingX")&&n.set(z,c),!je(n,"lockScalingY")&&n.set(N,l)),f!==n.scaleX||p!==n.scaleY}const Zs=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i)))),$s=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i,{by:"x"})))),ti=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i,{by:"y"})))),ei=["target","ex","ey","skewingSide"],si={x:{counterAxis:"y",scale:z,skew:U,lockSkewing:"lockSkewingX",origin:"originX",flip:"flipX"},y:{counterAxis:"x",scale:N,skew:q,lockSkewing:"lockSkewingY",origin:"originY",flip:"flipY"}},ii=["ns","nesw","ew","nwse"],ri=(t,e,s)=>{if(0!==e.x&&je(s,"lockSkewingY"))return Pe;if(0!==e.y&&je(s,"lockSkewingX"))return Pe;const i=Le(s,e)%4;return"".concat(ii[i],"-resize")};function ni(t,e,s,n,o){const{target:a}=s,{counterAxis:h,origin:c,lockSkewing:l,skew:u,flip:d}=si[t];if(je(a,l))return!1;const{origin:g,flip:f}=si[h],p=Me(s[g])*(a[f]?-1:1),m=-Math.sign(p)*(a[d]?-1:1),v=.5*-((0===a[u]&&Re(s,D,D,n,o)[t]>0||a[u]>0?1:-1)*m)+.5,y=Xs(X,Ws(((e,s,i,n)=>function(t,e,s){let{target:i,ex:n,ey:o,skewingSide:a}=e,h=r(e,ei);const{skew:c}=si[t],l=s.subtract(new ot(n,o)).divide(new ot(i.scaleX,i.scaleY))[t],u=i[c],d=h[c],g=Math.tan(yt(d)),f="y"===t?i._getTransformedDimensions({scaleX:1,scaleY:1,skewX:0}).x:i._getTransformedDimensions({scaleX:1,scaleY:1}).y,p=2*l*a/Math.max(f,1)+g,m=_t(Math.atan(p));i.set(c,m);const v=u!==i[c];if(v&&"y"===t){const{skewX:t,scaleX:e}=i,s=i._getTransformedDimensions({skewY:u}),r=i._getTransformedDimensions(),n=0!==t?s.x/r.x:1;1!==n&&i.set(z,n*e)}return v}(t,s,new ot(i,n)))));return y(e,i(i({},s),{},{[c]:v,skewingSide:m}),n,o)}const oi=(t,e,s,i)=>ni("x",t,e,s,i),ai=(t,e,s,i)=>ni("y",t,e,s,i);function hi(t,e){return t[e.canvas.altActionKey]}const ci=(t,e,s)=>{const i=hi(t,s);return 0===e.x?i?U:N:0===e.y?i?q:z:""},li=(t,e,s)=>hi(t,s)?ri(0,e,s):Js(t,e,s),ui=(t,e,s,i)=>hi(t,e.target)?ai(t,e,s,i):$s(t,e,s,i),di=(t,e,s,i)=>hi(t,e.target)?oi(t,e,s,i):ti(t,e,s,i),gi=()=>({ml:new Hs({x:-.5,y:0,cursorStyleHandler:li,actionHandler:ui,getActionName:ci}),mr:new Hs({x:.5,y:0,cursorStyleHandler:li,actionHandler:ui,getActionName:ci}),mb:new Hs({x:0,y:.5,cursorStyleHandler:li,actionHandler:di,getActionName:ci}),mt:new Hs({x:0,y:-.5,cursorStyleHandler:li,actionHandler:di,getActionName:ci}),tl:new Hs({x:-.5,y:-.5,cursorStyleHandler:Js,actionHandler:Zs}),tr:new Hs({x:.5,y:-.5,cursorStyleHandler:Js,actionHandler:Zs}),bl:new Hs({x:-.5,y:.5,cursorStyleHandler:Js,actionHandler:Zs}),br:new Hs({x:.5,y:.5,cursorStyleHandler:Js,actionHandler:Zs}),mtr:new Hs({x:0,y:-.5,actionHandler:Ns,cursorStyleHandler:zs,offsetY:-40,withConnection:!0,actionName:B})}),fi=()=>({mr:new Hs({x:.5,y:0,actionHandler:Ys,cursorStyleHandler:li,actionName:W}),ml:new Hs({x:-.5,y:0,actionHandler:Ys,cursorStyleHandler:li,actionName:W})}),pi=()=>i(i({},gi()),fi());class mi extends Bs{static getDefaults(){return i(i({},super.getDefaults()),mi.ownDefaults)}constructor(t){super(),Object.assign(this,this.constructor.createControls(),mi.ownDefaults),this.setOptions(t)}static createControls(){return{controls:gi()}}_updateCacheCanvas(){const t=this.canvas;if(this.noScaleCache&&t&&t._currentTransform){const e=t._currentTransform,s=e.target,i=e.action;if(this===s&&i&&i.startsWith(H))return!1}return super._updateCacheCanvas()}getActiveControl(){const t=this.__corner;return t?{key:t,control:this.controls[t],coord:this.oCoords[t]}:void 0}findControl(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!this.hasControls||!this.canvas)return;this.__corner=void 0;const s=Object.entries(this.oCoords);for(let i=s.length-1;i>=0;i--){const[r,n]=s[i],o=this.controls[r];if(o.shouldActivate(r,this,t,e?n.touchCorner:n.corner))return this.__corner=r,{key:r,control:o,coord:this.oCoords[r]}}}calcOCoords(){const t=this.getViewportTransform(),e=this.getCenterPoint(),s=kt(e.x,e.y),i=Dt({angle:this.getTotalAngle()-(this.group&&this.flipX?180:0)}),r=St(s,i),n=St(t,r),o=St(n,[1/t[0],0,0,1/t[3],0,0]),a=this.group?Ot(this.calcTransformMatrix()):void 0;a&&(a.scaleX=Math.abs(a.scaleX),a.scaleY=Math.abs(a.scaleY));const h=this._calculateCurrentDimensions(a),c={};return this.forEachControl(((t,e)=>{const s=t.positionHandler(h,o,this,t);c[e]=Object.assign(s,this._calcCornerCoords(t,s))})),c}_calcCornerCoords(t,e){const s=this.getTotalAngle();return{corner:t.calcCornerCoords(s,this.cornerSize,e.x,e.y,!1,this),touchCorner:t.calcCornerCoords(s,this.touchCornerSize,e.x,e.y,!0,this)}}setCoords(){super.setCoords(),this.canvas&&(this.oCoords=this.calcOCoords())}forEachControl(t){for(const e in this.controls)t(this.controls[e],e,this)}drawSelectionBackground(t){if(!this.selectionBackgroundColor||this.canvas&&this.canvas._activeObject!==this)return;t.save();const e=this.getRelativeCenterPoint(),s=this._calculateCurrentDimensions(),i=this.getViewportTransform();t.translate(e.x,e.y),t.scale(1/i[0],1/i[3]),t.rotate(yt(this.angle)),t.fillStyle=this.selectionBackgroundColor,t.fillRect(-s.x/2,-s.y/2,s.x,s.y),t.restore()}strokeBorders(t,e){t.strokeRect(-e.x/2,-e.y/2,e.x,e.y)}_drawBorders(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=i({hasControls:this.hasControls,borderColor:this.borderColor,borderDashArray:this.borderDashArray},s);t.save(),t.strokeStyle=r.borderColor,this._setLineDash(t,r.borderDashArray),this.strokeBorders(t,e),r.hasControls&&this.drawControlsConnectingLines(t,e),t.restore()}_renderControls(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{hasBorders:s,hasControls:r}=this,n=i({hasBorders:s,hasControls:r},e),o=this.getViewportTransform(),a=n.hasBorders,h=n.hasControls,c=St(o,this.calcTransformMatrix()),l=Ot(c);t.save(),t.translate(l.translateX,l.translateY),t.lineWidth=1*this.borderScaleFactor,this.group===this.parent&&(t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1),this.flipX&&(l.angle-=180),t.rotate(yt(this.group?l.angle:this.angle)),a&&this.drawBorders(t,l,e),h&&this.drawControls(t,e),t.restore()}drawBorders(t,e,s){let i;if(s&&s.forActiveSelection||this.group){const t=be(this.width,this.height,jt(e)),s=this.isStrokeAccountedForInDimensions()?at:(this.strokeUniform?(new ot).scalarAdd(this.canvas?this.canvas.getZoom():1):new ot(e.scaleX,e.scaleY)).scalarMultiply(this.strokeWidth);i=t.add(s).scalarAdd(this.borderScaleFactor).scalarAdd(2*this.padding)}else i=this._calculateCurrentDimensions().scalarAdd(this.borderScaleFactor);this._drawBorders(t,i,s)}drawControlsConnectingLines(t,e){let s=!1;t.beginPath(),this.forEachControl(((i,r)=>{i.withConnection&&i.getVisibility(this,r)&&(s=!0,t.moveTo(i.x*e.x,i.y*e.y),t.lineTo(i.x*e.x+i.offsetX,i.y*e.y+i.offsetY))})),s&&t.stroke()}drawControls(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.save();const s=this.getCanvasRetinaScaling(),{cornerStrokeColor:r,cornerDashArray:n,cornerColor:o}=this,a=i({cornerStrokeColor:r,cornerDashArray:n,cornerColor:o},e);t.setTransform(s,0,0,s,0,0),t.strokeStyle=t.fillStyle=a.cornerColor,this.transparentCorners||(t.strokeStyle=a.cornerStrokeColor),this._setLineDash(t,a.cornerDashArray),this.forEachControl(((e,s)=>{if(e.getVisibility(this,s)){const i=this.oCoords[s];e.render(t,i.x,i.y,a,this)}})),t.restore()}isControlVisible(t){return this.controls[t]&&this.controls[t].getVisibility(this,t)}setControlVisible(t,e){this._controlsVisibility||(this._controlsVisibility={}),this._controlsVisibility[t]=e}setControlsVisibility(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Object.entries(t).forEach((t=>{let[e,s]=t;return this.setControlVisible(e,s)}))}clearContextTop(t){if(!this.canvas)return;const e=this.canvas.contextTop;if(!e)return;const s=this.canvas.viewportTransform;e.save(),e.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this.transform(e);const i=this.width+4,r=this.height+4;return e.clearRect(-i/2,-r/2,i,r),t||e.restore(),e}onDeselect(t){return!1}onSelect(t){return!1}shouldStartDragging(t){return!1}onDragStart(t){return!1}canDrop(t){return!1}renderDragSourceEffect(t){}renderDropTargetEffect(t){}}function vi(t,e){return e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((s=>{"constructor"!==s&&Object.defineProperty(t.prototype,s,Object.getOwnPropertyDescriptor(e.prototype,s)||Object.create(null))}))})),t}e(mi,"ownDefaults",{noScaleCache:!0,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,cornerSize:13,touchCornerSize:24,transparentCorners:!0,cornerColor:"rgb(178,204,255)",cornerStrokeColor:"",cornerStyle:"rect",cornerDashArray:null,hasControls:!0,borderColor:"rgb(178,204,255)",borderDashArray:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,hasBorders:!0,selectionBackgroundColor:"",selectable:!0,evented:!0,perPixelTargetFind:!1,activeOn:"down",hoverCursor:null,moveCursor:null});class yi extends mi{}vi(yi,[Be]),tt.setClass(yi),tt.setClass(yi,"object");const _i=(t,e,s,i)=>{const r=2*(i=Math.round(i))+1,{data:n}=t.getImageData(e-i,s-i,r,r);for(let t=3;t0)return!1}return!0};class xi{constructor(t){this.options=t,this.strokeProjectionMagnitude=this.options.strokeWidth/2,this.scale=new ot(this.options.scaleX,this.options.scaleY),this.strokeUniformScalar=this.options.strokeUniform?new ot(1/this.options.scaleX,1/this.options.scaleY):new ot(1,1)}createSideVector(t,e){const s=ts(t,e);return this.options.strokeUniform?s.multiply(this.scale):s}projectOrthogonally(t,e,s){return this.applySkew(t.add(this.calcOrthogonalProjection(t,e,s)))}isSkewed(){return 0!==this.options.skewX||0!==this.options.skewY}applySkew(t){const e=new ot(t);return e.y+=e.x*Math.tan(yt(this.options.skewY)),e.x+=e.y*Math.tan(yt(this.options.skewX)),e}scaleUnitVector(t,e){return t.multiply(this.strokeUniformScalar).scalarMultiply(e)}}const Ci=new ot;class bi extends xi{static getOrthogonalRotationFactor(t,e){const s=e?ss(t,e):is(t);return Math.abs(s)2&&void 0!==arguments[2]?arguments[2]:this.strokeProjectionMagnitude;const i=this.createSideVector(t,e),r=ns(i),n=bi.getOrthogonalRotationFactor(r,this.bisector);return this.scaleUnitVector(r,s*n)}projectBevel(){const t=[];return(this.alpha%S==0?[this.B]:[this.B,this.C]).forEach((e=>{t.push(this.projectOrthogonally(this.A,e)),t.push(this.projectOrthogonally(this.A,e,-this.strokeProjectionMagnitude))})),t}projectMiter(){const t=[],e=Math.abs(this.alpha),s=1/Math.sin(e/2),i=this.scaleUnitVector(this.bisector,-this.strokeProjectionMagnitude*s),r=this.options.strokeUniform?es(this.scaleUnitVector(this.bisector,this.options.strokeMiterLimit)):this.options.strokeMiterLimit;return es(i)/this.strokeProjectionMagnitude<=r&&t.push(this.applySkew(this.A.add(i))),t.push(...this.projectBevel()),t}projectRoundNoSkew(t,e){const s=[],i=new ot(bi.getOrthogonalRotationFactor(this.bisector),bi.getOrthogonalRotationFactor(new ot(this.bisector.y,this.bisector.x)));return[new ot(1,0).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(i),new ot(0,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(i)].forEach((i=>{hs(i,t,e)&&s.push(this.A.add(i))})),s}projectRoundWithSkew(t,e){const s=[],{skewX:i,skewY:r,scaleX:n,scaleY:o,strokeUniform:a}=this.options,h=new ot(Math.tan(yt(i)),Math.tan(yt(r))),c=this.strokeProjectionMagnitude,l=a?c/o/Math.sqrt(1/o**2+1/n**2*h.y**2):c/Math.sqrt(1+h.y**2),u=new ot(Math.sqrt(Math.max(c**2-l**2,0)),l),d=a?c/Math.sqrt(1+h.x**2*(1/o)**2/(1/n+1/n*h.x*h.y)**2):c/Math.sqrt(1+h.x**2/(1+h.x*h.y)**2),g=new ot(d,Math.sqrt(Math.max(c**2-d**2,0)));return[g,g.scalarMultiply(-1),u,u.scalarMultiply(-1)].map((t=>this.applySkew(a?t.multiply(this.strokeUniformScalar):t))).forEach((i=>{hs(i,t,e)&&s.push(this.applySkew(this.A).add(i))})),s}projectRound(){const t=[];t.push(...this.projectBevel());const e=this.alpha%S==0,s=this.applySkew(this.A),i=t[e?0:2].subtract(s),r=t[e?1:0].subtract(s),n=e?this.applySkew(this.AB.scalarMultiply(-1)):this.applySkew(this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1)),o=os(i,n)>0,a=o?i:r,h=o?r:i;return this.isSkewed()?t.push(...this.projectRoundWithSkew(a,h)):t.push(...this.projectRoundNoSkew(a,h)),t}projectPoints(){switch(this.options.strokeLineJoin){case"miter":return this.projectMiter();case"round":return this.projectRound();default:return this.projectBevel()}}project(){return this.projectPoints().map((t=>({originPoint:this.A,projectedPoint:t,angle:this.alpha,bisector:this.bisector})))}}class Si extends xi{constructor(t,e,s){super(s),this.A=new ot(t),this.T=new ot(e)}calcOrthogonalProjection(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.strokeProjectionMagnitude;const i=this.createSideVector(t,e);return this.scaleUnitVector(ns(i),s)}projectButt(){return[this.projectOrthogonally(this.A,this.T,this.strokeProjectionMagnitude),this.projectOrthogonally(this.A,this.T,-this.strokeProjectionMagnitude)]}projectRound(){const t=[];if(!this.isSkewed()&&this.A.eq(this.T)){const e=new ot(1,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar);t.push(this.applySkew(this.A.add(e)),this.applySkew(this.A.subtract(e)))}else t.push(...new bi(this.A,this.T,this.T,this.options).projectRound());return t}projectSquare(){const t=[];if(this.A.eq(this.T)){const e=new ot(1,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar);t.push(this.A.add(e),this.A.subtract(e))}else{const e=this.calcOrthogonalProjection(this.A,this.T,this.strokeProjectionMagnitude),s=this.scaleUnitVector(rs(this.createSideVector(this.A,this.T)),-this.strokeProjectionMagnitude),i=this.A.add(s);t.push(i.add(e),i.subtract(e))}return t.map((t=>this.applySkew(t)))}projectPoints(){switch(this.options.strokeLineCap){case"round":return this.projectRound();case"square":return this.projectSquare();default:return this.projectButt()}}project(){return this.projectPoints().map((t=>({originPoint:this.A,projectedPoint:t})))}}const wi=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const i=[];if(0===t.length)return i;const r=t.reduce(((t,e)=>(t[t.length-1].eq(e)||t.push(new ot(e)),t)),[new ot(t[0])]);if(1===r.length)s=!0;else if(!s){const t=r[0],e=((t,e)=>{for(let s=t.length-1;s>=0;s--)if(e(t[s],s,t))return s;return-1})(r,(e=>!e.eq(t)));r.splice(e+1)}return r.forEach(((t,r,n)=>{let o,a;0===r?(a=n[1],o=s?t:n[n.length-1]):r===n.length-1?(o=n[r-1],a=s?t:n[0]):(o=n[r-1],a=n[r+1]),s&&1===n.length?i.push(...new Si(t,t,e).project()):!s||0!==r&&r!==n.length-1?i.push(...new bi(t,o,a,e).project()):i.push(...new Si(t,0===r?a:o,e).project())})),i},Ti=t=>{const e={};return Object.keys(t).forEach((s=>{e[s]={},Object.keys(t[s]).forEach((r=>{e[s][r]=i({},t[s][r])}))})),e},Oi=t=>t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"),ki=t=>{const e=[];for(let s,i=0;i{const s=t.charCodeAt(e);if(isNaN(s))return"";if(s<55296||s>57343)return t.charAt(e);if(55296<=s&&s<=56319){if(t.length<=e+1)throw"High surrogate without following low surrogate";const s=t.charCodeAt(e+1);if(56320>s||s>57343)throw"High surrogate without following low surrogate";return t.charAt(e)+t.charAt(e+1)}if(0===e)throw"Low surrogate without preceding high surrogate";const i=t.charCodeAt(e-1);if(55296>i||i>56319)throw"Low surrogate without preceding high surrogate";return!1};var Mi=Object.freeze({__proto__:null,capitalize:function(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return"".concat(t.charAt(0).toUpperCase()).concat(e?t.slice(1):t.slice(1).toLowerCase())},escapeXml:Oi,graphemeSplit:ki});const Pi=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return t.fill!==e.fill||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth||t.fontSize!==e.fontSize||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.textBackgroundColor!==e.textBackgroundColor||t.deltaY!==e.deltaY||s&&(t.overline!==e.overline||t.underline!==e.underline||t.linethrough!==e.linethrough)},Ei=(t,e)=>{const s=e.split("\n"),i=[];let r=-1,n={};t=Ti(t);for(let e=0;e0&&(Pi(n,o,!0)?i.push({start:r,end:r+1,style:o}):i[i.length-1].end++),n=o||{}}else r+=o.length,n={}}return i},Ai=(t,e)=>{if(!Array.isArray(t))return Ti(t);const s=e.split(F),r={};let n=-1,o=0;for(let e=0;e{var e;return null!==(e=He[t])&&void 0!==e?e:t},Ii=new RegExp("(".concat(Ye,")"),"gi"),Bi=t=>t.replace(Ii," $1 ").replace(/,/gi," ").replace(/\s+/gi," ");var Xi,Wi,Yi,Vi,Gi,Hi,zi;const Ni="(".concat(Ye,")"),Ui=String.raw(Xi||(Xi=n(["(skewX)(",")"],["(skewX)\\(","\\)"])),Ni),qi=String.raw(Wi||(Wi=n(["(skewY)(",")"],["(skewY)\\(","\\)"])),Ni),Ki=String.raw(Yi||(Yi=n(["(rotate)(","(?: "," ",")?)"],["(rotate)\\(","(?: "," ",")?\\)"])),Ni,Ni,Ni),Ji=String.raw(Vi||(Vi=n(["(scale)(","(?: ",")?)"],["(scale)\\(","(?: ",")?\\)"])),Ni,Ni),Qi=String.raw(Gi||(Gi=n(["(translate)(","(?: ",")?)"],["(translate)\\(","(?: ",")?\\)"])),Ni,Ni),Zi=String.raw(Hi||(Hi=n(["(matrix)("," "," "," "," "," ",")"],["(matrix)\\("," "," "," "," "," ","\\)"])),Ni,Ni,Ni,Ni,Ni,Ni),$i="(?:".concat(Zi,"|").concat(Qi,"|").concat(Ki,"|").concat(Ji,"|").concat(Ui,"|").concat(qi,")"),tr="(?:".concat($i,"*)"),er=String.raw(zi||(zi=n(["^s*(?:","?)s*$"],["^\\s*(?:","?)\\s*$"])),tr),sr=new RegExp(er),ir=new RegExp($i),rr=new RegExp($i,"g");function nr(t){const e=[];if(!(t=Bi(t).replace(/\s*([()])\s*/gi,"$1"))||t&&!sr.test(t))return[...T];for(const s of t.matchAll(rr)){const t=ir.exec(s[0]);if(!t)continue;let i=T;const r=t.filter((t=>!!t)),[,n,...o]=r,[a,h,c,l,u,d]=o.map((t=>parseFloat(t)));switch(n){case"translate":i=kt(a,h);break;case B:i=Dt({angle:a},{x:h,y:c});break;case H:i=Mt(a,h);break;case U:i=Et(a);break;case q:i=At(a);break;case"matrix":i=[a,h,c,l,u,d]}e.push(i)}return wt(e)}function or(t,e,s,i){const r=Array.isArray(e);let n,o=e;if(t!==K&&t!==J||e!==j){if("strokeUniform"===t)return"non-scaling-stroke"===e;if("strokeDashArray"===t)o=e===j?null:e.replace(/,/g," ").split(/\s+/).map(parseFloat);else if("transformMatrix"===t)o=s&&s.transformMatrix?St(s.transformMatrix,nr(e)):nr(e);else if("visible"===t)o=e!==j&&"hidden"!==e,s&&!1===s.visible&&(o=!1);else if("opacity"===t)o=parseFloat(e),s&&void 0!==s.opacity&&(o*=s.opacity);else if("textAnchor"===t)o="start"===e?M:"end"===e?A:D;else if("charSpacing"===t)n=qt(e,i)/i*1e3;else if("paintFirst"===t){const t=e.indexOf(K),s=e.indexOf(J);o=K,(t>-1&&s>-1&&s-1)&&(o=J)}else{if("href"===t||"xlink:href"===t||"font"===t||"id"===t)return e;if("imageSmoothing"===t)return"optimizeQuality"===e;n=r?e.map(qt):qt(e,i)}}else o="";return!r&&isNaN(n)?o:n}function ar(t,e){const s=t.match(Ge);if(!s)return;const i=s[1],r=s[3],n=s[4],o=s[5],a=s[6];i&&(e.fontStyle=i),r&&(e.fontWeight=isNaN(parseFloat(r))?r:parseFloat(r)),n&&(e.fontSize=qt(n)),a&&(e.fontFamily=a),o&&(e.lineHeight="normal"===o?1:o)}function hr(t,e){t.replace(/;\s*$/,"").split(";").forEach((t=>{if(!t)return;const[s,i]=t.split(":");e[s.trim().toLowerCase()]=i.trim()}))}function cr(t){const e={},s=t.getAttribute("style");return s?("string"==typeof s?hr(s,e):function(t,e){Object.entries(t).forEach((t=>{let[s,i]=t;void 0!==i&&(e[s.toLowerCase()]=i)}))}(s,e),e):e}const lr={stroke:"strokeOpacity",fill:"fillOpacity"};function ur(t,e,s){if(!t)return{};let r,n={},o=O;t.parentNode&&Ke.test(t.parentNode.nodeName)&&(n=ur(t.parentElement,e,s),n.fontSize&&(r=o=qt(n.fontSize)));const a=i(i(i({},e.reduce(((e,s)=>{const i=t.getAttribute(s);return i&&(e[s]=i),e}),{})),function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s={};for(const r in e)Li(t,r.split(" "))&&(s=i(i({},s),e[r]));return s}(t,s)),cr(t));a[Ne]&&t.setAttribute(Ne,a[Ne]),a[ze]&&(r=qt(a[ze],o),a[ze]="".concat(r));const h={};for(const t in a){const e=Ri(t),s=or(e,a[t],n,r);h[e]=s}h&&h.font&&ar(h.font,h);const c=i(i({},n),h);return Ke.test(t.nodeName)?c:function(t){const e=yi.getDefaults();return Object.entries(lr).forEach((s=>{let[i,r]=s;if(void 0===t[r]||""===t[i])return;if(void 0===t[i]){if(!e[i])return;t[i]=e[i]}if(0===t[i].indexOf("url("))return;const n=new Nt(t[i]);t[i]=n.setAlpha(Ut(n.getAlpha()*t[r],2)).toRgba()})),t}(c)}const dr=["left","top","width","height","visible"],gr=["rx","ry"];class fr extends yi{static getDefaults(){return i(i({},super.getDefaults()),fr.ownDefaults)}constructor(t){super(),Object.assign(this,fr.ownDefaults),this.setOptions(t),this._initRxRy()}_initRxRy(){const{rx:t,ry:e}=this;t&&!e?this.ry=t:e&&!t&&(this.rx=e)}_render(t){const{width:e,height:s}=this,i=-e/2,r=-s/2,n=this.rx?Math.min(this.rx,e/2):0,o=this.ry?Math.min(this.ry,s/2):0,a=0!==n||0!==o;t.beginPath(),t.moveTo(i+n,r),t.lineTo(i+e-n,r),a&&t.bezierCurveTo(i+e-k*n,r,i+e,r+k*o,i+e,r+o),t.lineTo(i+e,r+s-o),a&&t.bezierCurveTo(i+e,r+s-k*o,i+e-k*n,r+s,i+e-n,r+s),t.lineTo(i+n,r+s),a&&t.bezierCurveTo(i+k*n,r+s,i,r+s-k*o,i,r+s-o),t.lineTo(i,r+o),a&&t.bezierCurveTo(i,r+k*o,i+k*n,r,i+n,r),t.closePath(),this._renderPaintInOrder(t)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...gr,...t])}_toSVG(){const{width:t,height:e,rx:s,ry:i}=this;return["\n')]}static async fromElement(t,e,s){const n=ur(t,this.ATTRIBUTE_NAMES,s),{left:o=0,top:a=0,width:h=0,height:c=0,visible:l=!0}=n,u=r(n,dr);return new this(i(i(i({},e),u),{},{left:o,top:a,width:h,height:c,visible:Boolean(l&&h&&c)}))}}e(fr,"type","Rect"),e(fr,"cacheProperties",[...fs,...gr]),e(fr,"ownDefaults",{rx:0,ry:0}),e(fr,"ATTRIBUTE_NAMES",[...ji,"x","y","rx","ry","width","height"]),tt.setClass(fr),tt.setSVGClass(fr);const pr="initialization",mr="added",vr="removed",yr="imperative",_r=(t,e)=>{const{strokeUniform:s,strokeWidth:i,width:r,height:n,group:o}=e,a=o&&o!==t?Se(o.calcTransformMatrix(),t.calcTransformMatrix()):null,h=a?e.getRelativeCenterPoint().transform(a):e.getRelativeCenterPoint(),c=!e.isStrokeAccountedForInDimensions(),l=s&&c?Te(new ot(i,i),void 0,t.calcTransformMatrix()):at,u=!s&&c?i:0,d=be(r+u,n+u,wt([a,e.calcOwnMatrix()],!0)).add(l).scalarDivide(2);return[h.subtract(d),h.add(d)]};class xr{calcLayoutResult(t,e){if(this.shouldPerformLayout(t))return this.calcBoundingBox(e,t)}shouldPerformLayout(t){let{type:e,prevStrategy:s,strategy:i}=t;return e===pr||e===yr||!!s&&i!==s}shouldLayoutClipPath(t){let{type:e,target:{clipPath:s}}=t;return e!==pr&&s&&!s.absolutePositioned}getInitialSize(t,e){return e.size}calcBoundingBox(t,e){const{type:s,target:i}=e;if(s===yr&&e.overrides)return e.overrides;if(0===t.length)return;const{left:r,top:n,width:o,height:a}=me(t.map((t=>_r(i,t))).reduce(((t,e)=>t.concat(e)),[])),h=new ot(o,a),c=new ot(r,n).add(h.scalarDivide(2));if(s===pr){const t=this.getInitialSize(e,{size:h,center:c});return{center:c,relativeCorrection:new ot(0,0),size:t}}return{center:c.transform(i.calcOwnMatrix()),size:h}}}e(xr,"type","strategy");class Cr extends xr{shouldPerformLayout(t){return!0}}e(Cr,"type","fit-content"),tt.setClass(Cr);const br=["strategy"],Sr=["target","strategy","bubbles","prevStrategy"],wr="layoutManager";class Tr{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new Cr;e(this,"strategy",void 0),this.strategy=t,this._subscriptions=new Map}performLayout(t){const e=i(i({bubbles:!0,strategy:this.strategy},t),{},{prevStrategy:this._prevLayoutStrategy,stopPropagation(){this.bubbles=!1}});this.onBeforeLayout(e);const s=this.getLayoutResult(e);s&&this.commitLayout(e,s),this.onAfterLayout(e,s),this._prevLayoutStrategy=e.strategy}attachHandlers(t,e){const{target:s}=e;return[Q,L,W,I,R,X,G,Y,V].map((e=>t.on(e,(t=>this.performLayout(e===Q?{type:"object_modified",trigger:e,e:t,target:s}:{type:"object_modifying",trigger:e,e:t,target:s})))))}subscribe(t,e){this.unsubscribe(t,e);const s=this.attachHandlers(t,e);this._subscriptions.set(t,s)}unsubscribe(t,e){(this._subscriptions.get(t)||[]).forEach((t=>t())),this._subscriptions.delete(t)}unsubscribeTargets(t){t.targets.forEach((e=>this.unsubscribe(e,t)))}subscribeTargets(t){t.targets.forEach((e=>this.subscribe(e,t)))}onBeforeLayout(t){const{target:e,type:s}=t,{canvas:n}=e;if(s===pr||s===mr?this.subscribeTargets(t):s===vr&&this.unsubscribeTargets(t),e.fire("layout:before",{context:t}),n&&n.fire("object:layout:before",{target:e,context:t}),s===yr&&t.deep){const s=r(t,br);e.forEachObject((t=>t.layoutManager&&t.layoutManager.performLayout(i(i({},s),{},{bubbles:!1,target:t}))))}}getLayoutResult(t){const{target:e,strategy:s,type:i}=t,r=s.calcLayoutResult(t,e.getObjects());if(!r)return;const n=i===pr?new ot:e.getRelativeCenterPoint(),{center:o,correction:a=new ot,relativeCorrection:h=new ot}=r,c=n.subtract(o).add(a).transform(i===pr?T:bt(e.calcOwnMatrix()),!0).add(h);return{result:r,prevCenter:n,nextCenter:o,offset:c}}commitLayout(t,e){const{target:s}=t,{result:{size:i},nextCenter:r}=e;var n,o;(s.set({width:i.x,height:i.y}),this.layoutObjects(t,e),t.type===pr)?s.set({left:null!==(n=t.x)&&void 0!==n?n:r.x+i.x*Me(s.originX),top:null!==(o=t.y)&&void 0!==o?o:r.y+i.y*Me(s.originY)}):(s.setPositionByOrigin(r,D,D),s.setCoords(),s.set("dirty",!0))}layoutObjects(t,e){const{target:s}=t;s.forEachObject((i=>{i.group===s&&this.layoutObject(t,e,i)})),t.strategy.shouldLayoutClipPath(t)&&this.layoutObject(t,e,s.clipPath)}layoutObject(t,e,s){let{offset:i}=e;s.set({left:s.left+i.x,top:s.top+i.y})}onAfterLayout(t,e){const{target:s,strategy:n,bubbles:o,prevStrategy:a}=t,h=r(t,Sr),{canvas:c}=s;s.fire("layout:after",{context:t,result:e}),c&&c.fire("object:layout:after",{context:t,result:e,target:s});const l=s.parent;o&&null!=l&&l.layoutManager&&((h.path||(h.path=[])).push(s),l.layoutManager.performLayout(i(i({},h),{},{target:l}))),s.set("dirty",!0)}dispose(){const{_subscriptions:t}=this;t.forEach((t=>t.forEach((t=>t())))),t.clear()}toObject(){return{type:wr,strategy:this.strategy.constructor.type}}toJSON(){return this.toObject()}}tt.setClass(Tr,wr);const Or=["type","objects","layoutManager"];class kr extends Tr{performLayout(){}}class Dr extends(ct(yi)){static getDefaults(){return i(i({},super.getDefaults()),Dr.ownDefaults)}constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),e(this,"_activeObjects",[]),e(this,"__objectSelectionTracker",void 0),e(this,"__objectSelectionDisposer",void 0),Object.assign(this,Dr.ownDefaults),this.setOptions(s),this.groupInit(t,s)}groupInit(t,e){var s;this._objects=[...t],this.__objectSelectionTracker=this.__objectSelectionMonitor.bind(this,!0),this.__objectSelectionDisposer=this.__objectSelectionMonitor.bind(this,!1),this.forEachObject((t=>{this.enterGroup(t,!1)})),this.layoutManager=null!==(s=e.layoutManager)&&void 0!==s?s:new Tr,this.layoutManager.performLayout({type:pr,target:this,targets:[...t],x:e.left,y:e.top})}canEnterGroup(t){return t===this||this.isDescendantOf(t)?(h("error","Group: circular object trees are not supported, this call has no effect"),!1):-1===this._objects.indexOf(t)||(h("error","Group: duplicate objects are not supported inside group, this call has no effect"),!1)}_filterObjectsBeforeEnteringGroup(t){return t.filter(((t,e,s)=>this.canEnterGroup(t)&&s.indexOf(t)===e))}add(){for(var t=arguments.length,e=new Array(t),s=0;s1?e-1:0),i=1;i{s._set(t,e)})),this}_shouldSetNestedCoords(){return this.subTargetCheck}removeAll(){return this._activeObjects=[],this.remove(...this._objects)}__objectSelectionMonitor(t,e){let{target:s}=e;const i=this._activeObjects;if(t)i.push(s),this._set("dirty",!0);else if(i.length>0){const t=i.indexOf(s);t>-1&&(i.splice(t,1),this._set("dirty",!0))}}_watchObject(t,e){t&&this._watchObject(!1,e),t?(e.on("selected",this.__objectSelectionTracker),e.on("deselected",this.__objectSelectionDisposer)):(e.off("selected",this.__objectSelectionTracker),e.off("deselected",this.__objectSelectionDisposer))}enterGroup(t,e){t.group&&t.group.remove(t),t._set("parent",this),this._enterGroup(t,e)}_enterGroup(t,e){e&&_e(t,St(bt(this.calcTransformMatrix()),t.calcTransformMatrix())),this._shouldSetNestedCoords()&&t.setCoords(),t._set("group",this),t._set("canvas",this.canvas),this._watchObject(!0,t);const s=this.canvas&&this.canvas.getActiveObject&&this.canvas.getActiveObject();s&&(s===t||t.isDescendantOf(s))&&this._activeObjects.push(t)}exitGroup(t,e){this._exitGroup(t,e),t._set("parent",void 0),t._set("canvas",void 0)}_exitGroup(t,e){t._set("group",void 0),e||(_e(t,St(this.calcTransformMatrix(),t.calcTransformMatrix())),t.setCoords()),this._watchObject(!1,t);const s=this._activeObjects.length>0?this._activeObjects.indexOf(t):-1;s>-1&&this._activeObjects.splice(s,1)}shouldCache(){const t=yi.prototype.shouldCache.call(this);if(t)for(let t=0;tt.setCoords()))}triggerLayout(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.layoutManager.performLayout(i({target:this,type:yr},t))}render(t){this._transformDone=!0,super.render(t),this._transformDone=!1}__serializeObjects(t,e){const s=this.includeDefaultValues;return this._objects.filter((function(t){return!t.excludeFromExport})).map((function(i){const r=i.includeDefaultValues;i.includeDefaultValues=s;const n=i[t||"toObject"](e);return i.includeDefaultValues=r,n}))}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=this.layoutManager.toObject();return i(i(i({},super.toObject(["subTargetCheck","interactive",...t])),"fit-content"!==e.strategy||this.includeDefaultValues?{layoutManager:e}:{}),{},{objects:this.__serializeObjects("toObject",t)})}toString(){return"#")}dispose(){this.layoutManager.unsubscribeTargets({targets:this.getObjects(),target:this}),this._activeObjects=[],this.forEachObject((t=>{this._watchObject(!1,t),t.dispose()})),super.dispose()}_createSVGBgRect(t){if(!this.backgroundColor)return"";const e=fr.prototype._toSVG.call(this),s=e.indexOf("COMMON_PARTS");e[s]='for="group" ';const i=e.join("");return t?t(i):i}_toSVG(t){const e=["\n"],s=this._createSVGBgRect(t);s&&e.push("\t\t",s);for(let s=0;s\n"),e}getSvgStyles(){const t=void 0!==this.opacity&&1!==this.opacity?"opacity: ".concat(this.opacity,";"):"",e=this.visible?"":" visibility: hidden;";return[t,this.getSvgFilter(),e].join("")}toClipPathSVG(t){const e=[],s=this._createSVGBgRect(t);s&&e.push("\t",s);for(let s=0;s{let[e,s]=t;const r=new this(e,i(i(i({},a),s),{},{layoutManager:new kr}));if(o){const t=tt.getClass(o.type),e=tt.getClass(o.strategy);r.layoutManager=new t(new e)}else r.layoutManager=new Tr;return r.layoutManager.subscribeTargets({type:pr,target:r,targets:r.getObjects()}),r.setCoords(),r}))}}e(Dr,"type","Group"),e(Dr,"ownDefaults",{strokeWidth:0,subTargetCheck:!1,interactive:!1}),tt.setClass(Dr);const Mr=(t,e)=>Math.min(e.width/t.width,e.height/t.height),Pr=(t,e)=>Math.max(e.width/t.width,e.height/t.height),Er="\\s*,?\\s*",Ar="".concat(Er,"(").concat(Ye,")"),jr="".concat(Ar).concat(Ar).concat(Ar).concat(Er,"([01])").concat(Er,"([01])").concat(Ar).concat(Ar),Fr={m:"l",M:"L"},Lr=(t,e,s,i,r,n,o,a,h,c,l)=>{const u=rt(t),d=nt(t),g=rt(e),f=nt(e),p=s*r*g-i*n*f+o,m=i*r*g+s*n*f+a;return["C",c+h*(-s*r*d-i*n*u),l+h*(-i*r*d+s*n*u),p+h*(s*r*f+i*n*g),m+h*(i*r*f-s*n*g),p,m]},Rr=(t,e,s,i)=>{const r=Math.atan2(e,t),n=Math.atan2(i,s);return n>=r?n-r:2*Math.PI-(r-n)};function Ir(t,e,s,i,r,n,o,h){let c;if(a.cachesBoundsOfCurve&&(c=[...arguments].join(),_.boundsOfCurveCache[c]))return _.boundsOfCurveCache[c];const l=Math.sqrt,u=Math.abs,d=[],g=[[0,0],[0,0]];let f=6*t-12*s+6*r,p=-3*t+9*s-9*r+3*o,m=3*s-3*t;for(let t=0;t<2;++t){if(t>0&&(f=6*e-12*i+6*n,p=-3*e+9*i-9*n+3*h,m=3*i-3*e),u(p)<1e-12){if(u(f)<1e-12)continue;const t=-m/f;0{let[i,r,n,o,a,h,c,l]=s;const u=((t,e,s,i,r,n,o)=>{if(0===s||0===i)return[];let a=0,h=0,c=0;const l=Math.PI,u=o*w,d=nt(u),g=rt(u),f=.5*(-g*t-d*e),p=.5*(-g*e+d*t),m=s**2,v=i**2,y=p**2,_=f**2,x=m*v-m*y-v*_;let C=Math.abs(s),b=Math.abs(i);if(x<0){const t=Math.sqrt(1-x/(m*v));C*=t,b*=t}else c=(r===n?-1:1)*Math.sqrt(x/(m*y+v*_));const S=c*C*p/b,T=-c*b*f/C,O=g*S-d*T+.5*t,k=d*S+g*T+.5*e;let D=Rr(1,0,(f-S)/C,(p-T)/b),M=Rr((f-S)/C,(p-T)/b,(-f-S)/C,(-p-T)/b);0===n&&M>0?M-=2*l:1===n&&M<0&&(M+=2*l);const P=Math.ceil(Math.abs(M/l*2)),E=[],A=M/P,j=8/3*Math.sin(A/4)*Math.sin(A/4)/Math.sin(A/2);let F=D+A;for(let t=0;t{let e=0,s=0,i=0,r=0;const n=[];let o,a=0,h=0;for(const c of t){const t=[...c];let l;switch(t[0]){case"l":t[1]+=e,t[2]+=s;case"L":e=t[1],s=t[2],l=["L",e,s];break;case"h":t[1]+=e;case"H":e=t[1],l=["L",e,s];break;case"v":t[1]+=s;case"V":s=t[1],l=["L",e,s];break;case"m":t[1]+=e,t[2]+=s;case"M":e=t[1],s=t[2],i=t[1],r=t[2],l=["M",e,s];break;case"c":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s,t[5]+=e,t[6]+=s;case"C":a=t[3],h=t[4],e=t[5],s=t[6],l=["C",t[1],t[2],a,h,e,s];break;case"s":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s;case"S":"C"===o?(a=2*e-a,h=2*s-h):(a=e,h=s),e=t[3],s=t[4],l=["C",a,h,t[1],t[2],e,s],a=l[3],h=l[4];break;case"q":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s;case"Q":a=t[1],h=t[2],e=t[3],s=t[4],l=["Q",a,h,e,s];break;case"t":t[1]+=e,t[2]+=s;case"T":"Q"===o?(a=2*e-a,h=2*s-h):(a=e,h=s),e=t[1],s=t[2],l=["Q",a,h,e,s];break;case"a":t[6]+=e,t[7]+=s;case"A":Br(e,s,t).forEach((t=>n.push(t))),e=t[6],s=t[7];break;case"z":case"Z":e=i,s=r,l=["Z"]}l?(n.push(l),o=l[0]):o=""}return n},Wr=(t,e,s,i)=>Math.sqrt((s-t)**2+(i-e)**2),Yr=(t,e,s,i,r,n,o,a)=>h=>{const c=h**3,l=(t=>3*t**2*(1-t))(h),u=(t=>3*t*(1-t)**2)(h),d=(t=>(1-t)**3)(h);return new ot(o*c+r*l+s*u+t*d,a*c+n*l+i*u+e*d)},Vr=t=>t**2,Gr=t=>2*t*(1-t),Hr=t=>(1-t)**2,zr=(t,e,s,i,r,n,o,a)=>h=>{const c=Vr(h),l=Gr(h),u=Hr(h),d=3*(u*(s-t)+l*(r-s)+c*(o-r)),g=3*(u*(i-e)+l*(n-i)+c*(a-n));return Math.atan2(g,d)},Nr=(t,e,s,i,r,n)=>o=>{const a=Vr(o),h=Gr(o),c=Hr(o);return new ot(r*a+s*h+t*c,n*a+i*h+e*c)},Ur=(t,e,s,i,r,n)=>o=>{const a=1-o,h=2*(a*(s-t)+o*(r-s)),c=2*(a*(i-e)+o*(n-i));return Math.atan2(c,h)},qr=(t,e,s)=>{let i=new ot(e,s),r=0;for(let e=1;e<=100;e+=1){const s=t(e/100);r+=Wr(i.x,i.y,s.x,s.y),i=s}return r},Kr=(t,e)=>{let s,r=0,n=0,o={x:t.x,y:t.y},a=i({},o),h=.01,c=0;const l=t.iterator,u=t.angleFinder;for(;n1e-4;)a=l(r),c=r,s=Wr(o.x,o.y,a.x,a.y),s+n>e?(r-=h,h/=2):(o=a,r+=h,n+=s);return i(i({},a),{},{angle:u(c)})},Jr=t=>{let e,s,i=0,r=0,n=0,o=0,a=0;const h=[];for(const c of t){const t={x:r,y:n,command:c[0],length:0};switch(c[0]){case"M":s=t,s.x=o=r=c[1],s.y=a=n=c[2];break;case"L":s=t,s.length=Wr(r,n,c[1],c[2]),r=c[1],n=c[2];break;case"C":e=Yr(r,n,c[1],c[2],c[3],c[4],c[5],c[6]),s=t,s.iterator=e,s.angleFinder=zr(r,n,c[1],c[2],c[3],c[4],c[5],c[6]),s.length=qr(e,r,n),r=c[5],n=c[6];break;case"Q":e=Nr(r,n,c[1],c[2],c[3],c[4]),s=t,s.iterator=e,s.angleFinder=Ur(r,n,c[1],c[2],c[3],c[4]),s.length=qr(e,r,n),r=c[3],n=c[4];break;case"Z":s=t,s.destX=o,s.destY=a,s.length=Wr(r,n,o,a),r=o,n=a}i+=s.length,h.push(s)}return h.push({length:i,x:r,y:n}),h},Qr=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Jr(t),r=0;for(;e-s[r].length>0&&r{var e;const s=[],i=null!==(e=t.match(Zr))&&void 0!==e?e:[];for(const t of i){const e=t[0];if("z"===e||"Z"===e){s.push([e]);continue}const i=en[e.toLowerCase()];let r=[];if("a"===e||"A"===e){$r.lastIndex=0;for(let e=null;e=$r.exec(t);)r.push(...e.slice(1))}else r=t.match(tn)||[];for(let t=0;t0&&o?o:e;for(let e=0;e1&&void 0!==arguments[1]?arguments[1]:0,s=new ot(t[0]),i=new ot(t[1]),r=1,n=0;const o=[],a=t.length,h=a>2;let c;for(h&&(r=t[2].xt[c-2].x?1:s.x===t[c-2].x?0:-1,n=s.y>t[c-2].y?1:s.y===t[c-2].y?0:-1),o.push(["L",s.x+r*e,s.y+n*e]),o},nn=(t,e)=>t.map((t=>t.map(((t,s)=>0===s||void 0===e?t:Ut(t,e))).join(" "))).join(" ");function on(t,e){const s=t.style;s&&e&&("string"==typeof e?s.cssText+=";"+e:Object.entries(e).forEach((t=>{let[e,i]=t;return s.setProperty(e,i)})))}const an=(t,e)=>Math.floor(Math.random()*(e-t+1))+t;function hn(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=e.onComplete||C,i=new(v().XMLHttpRequest),r=e.signal,n=function(){i.abort()},o=function(){r&&r.removeEventListener("abort",n),i.onerror=i.ontimeout=C};if(r&&r.aborted)throw new l("request");return r&&r.addEventListener("abort",n,{once:!0}),i.onreadystatechange=function(){4===i.readyState&&(o(),s(i),i.onreadystatechange=C)},i.onerror=i.ontimeout=o,i.open("get",t,!0),i.send(),i}const cn=(t,e)=>{let s=t._findCenterFromElement();t.transformMatrix&&((t=>{if(t.transformMatrix){const{scaleX:e,scaleY:s,angle:i,skewX:r}=Ot(t.transformMatrix);t.flipX=!1,t.flipY=!1,t.set(z,e),t.set(N,s),t.angle=i,t.skewX=r,t.skewY=0}})(t),s=s.transform(t.transformMatrix)),delete t.transformMatrix,e&&(t.scaleX*=e.scaleX,t.scaleY*=e.scaleY,t.cropX=e.cropX,t.cropY=e.cropY,s.x+=e.offsetLeft,s.y+=e.offsetTop,t.width=e.width,t.height=e.height),t.setPositionByOrigin(s,D,D)};var ln=Object.freeze({__proto__:null,addTransformToObject:ye,animate:As,animateColor:js,applyTransformToObject:_e,calcAngleBetweenVectors:ss,calcDimensionsMatrix:jt,calcPlaneChangeMatrix:Se,calcVectorRotation:is,cancelAnimFrame:dt,capValue:ds,composeMatrix:Ft,copyCanvasElement:t=>{var e;const s=pt();return s.width=t.width,s.height=t.height,null===(e=s.getContext("2d"))||void 0===e||e.drawImage(t,0,0),s},cos:rt,createCanvasElement:pt,createImage:mt,createRotateMatrix:Dt,createScaleMatrix:Mt,createSkewXMatrix:Et,createSkewYMatrix:At,createTranslateMatrix:kt,createVector:ts,crossProduct:os,degreesToRadians:yt,dotProduct:as,ease:Cs,enlivenObjectEnlivables:It,enlivenObjects:Rt,findScaleToCover:Pr,findScaleToFit:Mr,getBoundsOfCurve:Ir,getOrthonormalVector:ns,getPathSegmentsInfo:Jr,getPointOnPath:Qr,getPointer:ge,getRandomInt:an,getRegularPolygonPath:(t,e)=>{const s=2*Math.PI/t;let i=-b;t%2==0&&(i+=s/2);const r=new Array(t+1);for(let n=0;n{const e=["instantiated_by_use","style","id","class"];switch(t){case"linearGradient":return e.concat(["x1","y1","x2","y2","gradientUnits","gradientTransform"]);case"radialGradient":return e.concat(["gradientUnits","gradientTransform","cx","cy","r","fx","fy","fr"]);case"stop":return e.concat(["offset","stop-color","stop-opacity"])}return e},getUnitVector:rs,groupSVGElements:(t,e)=>t&&1===t.length?t[0]:new Dr(t,e),hasStyleChanged:Pi,invertTransform:bt,isBetweenVectors:hs,isIdentityMatrix:xt,isTouchEvent:fe,isTransparent:_i,joinPath:nn,loadImage:Lt,magnitude:es,makeBoundingBoxFromPoints:me,makePathSimpler:Xr,matrixToSVG:Jt,mergeClipPaths:(t,e)=>{var s;let i=t,r=e;i.inverted&&!r.inverted&&(i=e,r=t),Oe(r,null===(s=r.group)||void 0===s?void 0:s.calcTransformMatrix(),i.calcTransformMatrix());const n=i.inverted&&r.inverted;return n&&(i.inverted=r.inverted=!1),new Dr([i],{clipPath:r,inverted:n})},multiplyTransformMatrices:St,multiplyTransformMatrixArray:wt,parsePath:sn,parsePreserveAspectRatioAttribute:Kt,parseUnit:qt,pick:Bt,projectStrokeOnPoints:wi,qrDecompose:Ot,radiansToDegrees:_t,removeFromArray:it,removeTransformFromObject:(t,e)=>{const s=bt(e),i=St(s,t.calcOwnMatrix());_e(t,i)},removeTransformMatrixForSvgParsing:cn,request:hn,requestAnimFrame:ut,resetObjectTransform:xe,rotatePoint:(t,e,s)=>t.rotate(s,e),rotateVector:$e,saveObjectTransform:Ce,sendObjectToPlane:Oe,sendPointToPlane:we,sendVectorToPlane:Te,setStyle:on,sin:nt,sizeAfterTransform:be,string:Mi,stylesFromArray:Ai,stylesToArray:Ei,toDataURL:vt,toFixed:Ut,transformPath:(t,e,s)=>(s&&(e=St(e,[1,0,0,1,-s.x,-s.y])),t.map((t=>{const s=[...t];for(let i=1;i1&&void 0!==arguments[1]?arguments[1]:{};super(t),e(this,"upper",void 0),e(this,"container",void 0);const{el:r}=this.lower,n=this.createUpperCanvas();this.upper={el:n,ctx:n.getContext("2d")},this.applyCanvasStyle(r,{allowTouchScrolling:s}),this.applyCanvasStyle(n,{allowTouchScrolling:s,styles:{position:"absolute",left:"0",top:"0"}});const o=this.createContainerElement();o.classList.add(i),r.parentNode&&r.parentNode.replaceChild(o,r),o.append(r,n),this.container=o}createUpperCanvas(){const{el:t}=this.lower,e=pt();return e.className=t.className,e.classList.remove("lower-canvas"),e.classList.add("upper-canvas"),e.setAttribute("data-fabric","top"),e.style.cssText=t.style.cssText,e.setAttribute("draggable","true"),e}createContainerElement(){const t=m().createElement("div");return t.setAttribute("data-fabric","wrapper"),on(t,{position:"relative"}),he(t),t}applyCanvasStyle(t,e){const{styles:s,allowTouchScrolling:r}=e;on(t,i(i({},s),{},{"touch-action":r?"manipulation":j})),he(t)}setDimensions(t,e){super.setDimensions(t,e);const{el:s,ctx:i}=this.upper;oe(s,i,t,e)}setCSSDimensions(t){super.setCSSDimensions(t),ae(this.upper.el,t),ae(this.container,t)}cleanupDOM(t){const e=this.container,{el:s}=this.lower,{el:i}=this.upper;super.cleanupDOM(t),e.removeChild(i),e.removeChild(s),e.parentNode&&e.parentNode.replaceChild(s,e)}dispose(){super.dispose(),p().dispose(this.upper.el),delete this.upper,delete this.container}}class dn extends ue{constructor(){super(...arguments),e(this,"targets",[]),e(this,"_hoveredTargets",[]),e(this,"_objectsToRender",void 0),e(this,"_currentTransform",null),e(this,"_groupSelector",null),e(this,"contextTopDirty",!1)}static getDefaults(){return i(i({},super.getDefaults()),dn.ownDefaults)}get upperCanvasEl(){var t;return null===(t=this.elements.upper)||void 0===t?void 0:t.el}get contextTop(){var t;return null===(t=this.elements.upper)||void 0===t?void 0:t.ctx}get wrapperEl(){return this.elements.container}initElements(t){this.elements=new un(t,{allowTouchScrolling:this.allowTouchScrolling,containerClass:this.containerClass}),this._createCacheCanvas()}_onObjectAdded(t){this._objectsToRender=void 0,super._onObjectAdded(t)}_onObjectRemoved(t){this._objectsToRender=void 0,t===this._activeObject&&(this.fire("before:selection:cleared",{deselected:[t]}),this._discardActiveObject(),this.fire("selection:cleared",{deselected:[t]}),t.fire("deselected",{target:t})),t===this._hoveredTarget&&(this._hoveredTarget=void 0,this._hoveredTargets=[]),super._onObjectRemoved(t)}_onStackOrderChanged(){this._objectsToRender=void 0,super._onStackOrderChanged()}_chooseObjectsToRender(){const t=this._activeObject;return!this.preserveObjectStacking&&t?this._objects.filter((e=>!e.group&&e!==t)).concat(t):this._objects}renderAll(){this.cancelRequestedRender(),this.destroyed||(!this.contextTopDirty||this._groupSelector||this.isDrawingMode||(this.clearContext(this.contextTop),this.contextTopDirty=!1),this.hasLostContext&&(this.renderTopLayer(this.contextTop),this.hasLostContext=!1),!this._objectsToRender&&(this._objectsToRender=this._chooseObjectsToRender()),this.renderCanvas(this.getContext(),this._objectsToRender))}renderTopLayer(t){t.save(),this.isDrawingMode&&this._isCurrentlyDrawing&&(this.freeDrawingBrush&&this.freeDrawingBrush._render(),this.contextTopDirty=!0),this.selection&&this._groupSelector&&(this._drawSelection(t),this.contextTopDirty=!0),t.restore()}renderTop(){const t=this.contextTop;this.clearContext(t),this.renderTopLayer(t),this.fire("after:render",{ctx:t})}setTargetFindTolerance(t){t=Math.round(t),this.targetFindTolerance=t;const e=this.getRetinaScaling(),s=Math.ceil((2*t+1)*e);this.pixelFindCanvasEl.width=this.pixelFindCanvasEl.height=s,this.pixelFindContext.scale(e,e)}isTargetTransparent(t,e,s){const i=this.targetFindTolerance,r=this.pixelFindContext;this.clearContext(r),r.save(),r.translate(-e+i,-s+i),r.transform(...this.viewportTransform);const n=t.selectionBackgroundColor;t.selectionBackgroundColor="",t.render(r),t.selectionBackgroundColor=n,r.restore();const o=Math.round(i*this.getRetinaScaling());return _i(r,o,o,o)}_isSelectionKeyPressed(t){const e=this.selectionKey;return!!e&&(Array.isArray(e)?!!e.find((e=>!!e&&!0===t[e])):t[e])}_shouldClearSelection(t,e){const s=this.getActiveObjects(),i=this._activeObject;return!!(!e||e&&i&&s.length>1&&-1===s.indexOf(e)&&i!==e&&!this._isSelectionKeyPressed(t)||e&&!e.evented||e&&!e.selectable&&i&&i!==e)}_shouldCenterTransform(t,e,s){if(!t)return;let i;return e===H||e===z||e===N||e===W?i=this.centeredScaling||t.centeredScaling:e===B&&(i=this.centeredRotation||t.centeredRotation),i?!s:s}_getOriginFromCorner(t,e){const s={x:t.originX,y:t.originY};return e?(["ml","tl","bl"].includes(e)?s.x=A:["mr","tr","br"].includes(e)&&(s.x=M),["tl","mt","tr"].includes(e)?s.y=E:["bl","mb","br"].includes(e)&&(s.y=P),s):s}_setupCurrentTransform(t,e,s){var r;const n=e.group?we(this.getScenePoint(t),void 0,e.group.calcTransformMatrix()):this.getScenePoint(t),{key:o="",control:a}=e.getActiveControl()||{},h=s&&a?null===(r=a.getActionHandler(t,e,a))||void 0===r?void 0:r.bind(a):Ie,c=((t,e,s,i)=>{if(!e||!t)return"drag";const r=i.controls[e];return r.getActionName(s,r,i)})(s,o,t,e),l=t[this.centeredKey],u=this._shouldCenterTransform(e,c,l)?{x:D,y:D}:this._getOriginFromCorner(e,o),d={target:e,action:c,actionHandler:h,actionPerformed:!1,corner:o,scaleX:e.scaleX,scaleY:e.scaleY,skewX:e.skewX,skewY:e.skewY,offsetX:n.x-e.left,offsetY:n.y-e.top,originX:u.x,originY:u.y,ex:n.x,ey:n.y,lastX:n.x,lastY:n.y,theta:yt(e.angle),width:e.width,height:e.height,shiftKey:t.shiftKey,altKey:l,original:i(i({},Ce(e)),{},{originX:u.x,originY:u.y})};this._currentTransform=d,this.fire("before:transform",{e:t,transform:d})}setCursor(t){this.upperCanvasEl.style.cursor=t}_drawSelection(t){const{x:e,y:s,deltaX:i,deltaY:r}=this._groupSelector,n=new ot(e,s).transform(this.viewportTransform),o=new ot(e+i,s+r).transform(this.viewportTransform),a=this.selectionLineWidth/2;let h=Math.min(n.x,o.x),c=Math.min(n.y,o.y),l=Math.max(n.x,o.x),u=Math.max(n.y,o.y);this.selectionColor&&(t.fillStyle=this.selectionColor,t.fillRect(h,c,l-h,u-c)),this.selectionLineWidth&&this.selectionBorderColor&&(t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,h+=a,c+=a,l-=a,u-=a,yi.prototype._setLineDash.call(this,t,this.selectionDashArray),t.strokeRect(h,c,l-h,u-c))}findTarget(t){if(this.skipTargetFind)return;const e=this.getViewportPoint(t),s=this._activeObject,i=this.getActiveObjects();if(this.targets=[],s&&i.length>=1){if(s.findControl(e,fe(t)))return s;if(i.length>1&&this.searchPossibleTargets([s],e))return s;if(s===this.searchPossibleTargets([s],e)){if(this.preserveObjectStacking){const i=this.targets;this.targets=[];const r=this.searchPossibleTargets(this._objects,e);return t[this.altSelectionKey]&&r&&r!==s?(this.targets=i,s):r}return s}}return this.searchPossibleTargets(this._objects,e)}_pointIsInObjectSelectionArea(t,e){let s=t.getCoords();const i=this.getZoom(),r=t.padding/i;if(r){const[t,e,i,n]=s,o=Math.atan2(e.y-t.y,e.x-t.x),a=rt(o)*r,h=nt(o)*r,c=a+h,l=a-h;s=[new ot(t.x-l,t.y-c),new ot(e.x+c,e.y-l),new ot(i.x+l,i.y+c),new ot(n.x-c,n.y+l)]}return Fs.isPointInPolygon(e,s)}_checkTarget(t,e){if(t&&t.visible&&t.evented&&this._pointIsInObjectSelectionArea(t,we(e,void 0,this.viewportTransform))){if(!this.perPixelTargetFind&&!t.perPixelTargetFind||t.isEditing)return!0;if(!this.isTargetTransparent(t,e.x,e.y))return!0}return!1}_searchPossibleTargets(t,e){let s=t.length;for(;s--;){const i=t[s];if(this._checkTarget(i,e)){if(ht(i)&&i.subTargetCheck){const t=this._searchPossibleTargets(i._objects,e);t&&this.targets.push(t)}return i}}}searchPossibleTargets(t,e){const s=this._searchPossibleTargets(t,e);if(s&&ht(s)&&s.interactive&&this.targets[0]){const t=this.targets;for(let e=t.length-1;e>0;e--){const s=t[e];if(!ht(s)||!s.interactive)return s}return t[0]}return s}getViewportPoint(t){return this._pointer?this._pointer:this.getPointer(t,!0)}getScenePoint(t){return this._absolutePointer?this._absolutePointer:this.getPointer(t)}getPointer(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const s=this.upperCanvasEl,i=s.getBoundingClientRect();let r=ge(t),n=i.width||0,o=i.height||0;n&&o||(P in i&&E in i&&(o=Math.abs(i.top-i.bottom)),A in i&&M in i&&(n=Math.abs(i.right-i.left))),this.calcOffset(),r.x=r.x-this._offset.left,r.y=r.y-this._offset.top,e||(r=we(r,void 0,this.viewportTransform));const a=this.getRetinaScaling();1!==a&&(r.x/=a,r.y/=a);const h=0===n||0===o?new ot(1,1):new ot(s.width/n,s.height/o);return r.multiply(h)}_setDimensionsImpl(t,e){this._resetTransformEventData(),super._setDimensionsImpl(t,e),this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(this.contextTop)}_createCacheCanvas(){this.pixelFindCanvasEl=pt(),this.pixelFindContext=this.pixelFindCanvasEl.getContext("2d",{willReadFrequently:!0}),this.setTargetFindTolerance(this.targetFindTolerance)}getTopContext(){return this.elements.upper.ctx}getSelectionContext(){return this.elements.upper.ctx}getSelectionElement(){return this.elements.upper.el}getActiveObject(){return this._activeObject}getActiveObjects(){const t=this._activeObject;return se(t)?t.getObjects():t?[t]:[]}_fireSelectionEvents(t,e){let s=!1,i=!1;const r=this.getActiveObjects(),n=[],o=[];t.forEach((t=>{r.includes(t)||(s=!0,t.fire("deselected",{e:e,target:t}),o.push(t))})),r.forEach((i=>{t.includes(i)||(s=!0,i.fire("selected",{e:e,target:i}),n.push(i))})),t.length>0&&r.length>0?(i=!0,s&&this.fire("selection:updated",{e:e,selected:n,deselected:o})):r.length>0?(i=!0,this.fire("selection:created",{e:e,selected:n})):t.length>0&&(i=!0,this.fire("selection:cleared",{e:e,deselected:o})),i&&(this._objectsToRender=void 0)}setActiveObject(t,e){const s=this.getActiveObjects(),i=this._setActiveObject(t,e);return this._fireSelectionEvents(s,e),i}_setActiveObject(t,e){const s=this._activeObject;return s!==t&&(!(!this._discardActiveObject(e,t)&&this._activeObject)&&(!t.onSelect({e:e})&&(this._activeObject=t,se(t)&&s!==t&&t.set("canvas",this),t.setCoords(),!0)))}_discardActiveObject(t,e){const s=this._activeObject;return!!s&&(!s.onDeselect({e:t,object:e})&&(this._currentTransform&&this._currentTransform.target===s&&this.endCurrentTransform(t),se(s)&&s===this._hoveredTarget&&(this._hoveredTarget=void 0),this._activeObject=void 0,!0))}discardActiveObject(t){const e=this.getActiveObjects(),s=this.getActiveObject();e.length&&this.fire("before:selection:cleared",{e:t,deselected:[s]});const i=this._discardActiveObject(t);return this._fireSelectionEvents(e,t),i}endCurrentTransform(t){const e=this._currentTransform;this._finalizeCurrentTransform(t),e&&e.target&&(e.target.isMoving=!1),this._currentTransform=null}_finalizeCurrentTransform(t){const e=this._currentTransform,s=e.target,i={e:t,target:s,transform:e,action:e.action};s._scaling&&(s._scaling=!1),s.setCoords(),e.actionPerformed&&(this.fire("object:modified",i),s.fire(Q,i))}setViewportTransform(t){super.setViewportTransform(t);const e=this._activeObject;e&&e.setCoords()}destroy(){const t=this._activeObject;se(t)&&(t.removeAll(),t.dispose()),delete this._activeObject,super.destroy(),this.pixelFindContext=null,this.pixelFindCanvasEl=void 0}clear(){this.discardActiveObject(),this._activeObject=void 0,this.clearContext(this.contextTop),super.clear()}drawControls(t){const e=this._activeObject;e&&e._renderControls(t)}_toObject(t,e,s){const i=this._realizeGroupTransformOnObject(t),r=super._toObject(t,e,s);return t.set(i),r}_realizeGroupTransformOnObject(t){const{group:e}=t;if(e&&se(e)&&this._activeObject===e){const s=Bt(t,["angle","flipX","flipY",M,z,N,U,q,P]);return ye(t,e.calcOwnMatrix()),s}return{}}_setSVGObject(t,e,s){const i=this._realizeGroupTransformOnObject(e);super._setSVGObject(t,e,s),e.set(i)}}e(dn,"ownDefaults",{uniformScaling:!0,uniScaleKey:"shiftKey",centeredScaling:!1,centeredRotation:!1,centeredKey:"altKey",altActionKey:"shiftKey",selection:!0,selectionKey:"shiftKey",selectionColor:"rgba(100, 100, 255, 0.3)",selectionDashArray:[],selectionBorderColor:"rgba(255, 255, 255, 0.3)",selectionLineWidth:1,selectionFullyContained:!1,hoverCursor:"move",moveCursor:"move",defaultCursor:"default",freeDrawingCursor:"crosshair",notAllowedCursor:"not-allowed",perPixelTargetFind:!1,targetFindTolerance:0,skipTargetFind:!1,stopContextMenu:!1,fireRightClick:!1,fireMiddleClick:!1,enablePointerEvents:!1,containerClass:"canvas-container",preserveObjectStacking:!1});class gn{constructor(t){e(this,"targets",[]),e(this,"__disposer",void 0);const s=()=>{const{hiddenTextarea:e}=t.getActiveObject()||{};e&&e.focus()},i=t.upperCanvasEl;i.addEventListener("click",s),this.__disposer=()=>i.removeEventListener("click",s)}exitTextEditing(){this.target=void 0,this.targets.forEach((t=>{t.isEditing&&t.exitEditing()}))}add(t){this.targets.push(t)}remove(t){this.unregister(t),it(this.targets,t)}register(t){this.target=t}unregister(t){t===this.target&&(this.target=void 0)}onMouseMove(t){var e;(null===(e=this.target)||void 0===e?void 0:e.isEditing)&&this.target.updateSelectionOnMouseMove(t)}clear(){this.targets=[],this.target=void 0}dispose(){this.clear(),this.__disposer(),delete this.__disposer}}const fn=["target","oldTarget","fireCanvas","e"],pn={passive:!1},mn=(t,e)=>{const s=t.getViewportPoint(e),i=t.getScenePoint(e);return{viewportPoint:s,scenePoint:i,pointer:s,absolutePointer:i}},vn=function(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i1?e-1:0),i=1;i1&&void 0!==arguments[1]?arguments[1]:{}),e(this,"_isClick",void 0),e(this,"textEditingManager",new gn(this)),["_onMouseDown","_onTouchStart","_onMouseMove","_onMouseUp","_onTouchEnd","_onResize","_onMouseWheel","_onMouseOut","_onMouseEnter","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragProgress","_onDragOver","_onDragEnter","_onDragLeave","_onDrop"].forEach((t=>{this[t]=this[t].bind(this)})),this.addOrRemove(vn,"add")}_getEventPrefix(){return this.enablePointerEvents?"pointer":"mouse"}addOrRemove(t,e){const s=this.upperCanvasEl,i=this._getEventPrefix();t(ne(s),"resize",this._onResize),t(s,i+"down",this._onMouseDown),t(s,"".concat(i,"move"),this._onMouseMove,pn),t(s,"".concat(i,"out"),this._onMouseOut),t(s,"".concat(i,"enter"),this._onMouseEnter),t(s,"wheel",this._onMouseWheel),t(s,"contextmenu",this._onContextMenu),t(s,"dblclick",this._onDoubleClick),t(s,"dragstart",this._onDragStart),t(s,"dragend",this._onDragEnd),t(s,"dragover",this._onDragOver),t(s,"dragenter",this._onDragEnter),t(s,"dragleave",this._onDragLeave),t(s,"drop",this._onDrop),this.enablePointerEvents||t(s,"touchstart",this._onTouchStart,pn)}removeListeners(){this.addOrRemove(yn,"remove");const t=this._getEventPrefix(),e=re(this.upperCanvasEl);yn(e,"".concat(t,"up"),this._onMouseUp),yn(e,"touchend",this._onTouchEnd,pn),yn(e,"".concat(t,"move"),this._onMouseMove,pn),yn(e,"touchmove",this._onMouseMove,pn)}_onMouseWheel(t){this.__onMouseWheel(t)}_onMouseOut(t){const e=this._hoveredTarget,s=i({e:t},mn(this,t));this.fire("mouse:out",i(i({},s),{},{target:e})),this._hoveredTarget=void 0,e&&e.fire("mouseout",i({},s)),this._hoveredTargets.forEach((t=>{this.fire("mouse:out",i(i({},s),{},{target:t})),t&&t.fire("mouseout",i({},s))})),this._hoveredTargets=[]}_onMouseEnter(t){this._currentTransform||this.findTarget(t)||(this.fire("mouse:over",i({e:t},mn(this,t))),this._hoveredTarget=void 0,this._hoveredTargets=[])}_onDragStart(t){this._isClick=!1;const e=this.getActiveObject();if(e&&e.onDragStart(t)){this._dragSource=e;const s={e:t,target:e};return this.fire("dragstart",s),e.fire("dragstart",s),void vn(this.upperCanvasEl,"drag",this._onDragProgress)}pe(t)}_renderDragEffects(t,e,s){let i=!1;const r=this._dropTarget;r&&r!==e&&r!==s&&(r.clearContextTop(),i=!0),null==e||e.clearContextTop(),s!==e&&(null==s||s.clearContextTop());const n=this.contextTop;n.save(),n.transform(...this.viewportTransform),e&&(n.save(),e.transform(n),e.renderDragSourceEffect(t),n.restore(),i=!0),s&&(n.save(),s.transform(n),s.renderDropTargetEffect(t),n.restore(),i=!0),n.restore(),i&&(this.contextTopDirty=!0)}_onDragEnd(t){const e=!!t.dataTransfer&&t.dataTransfer.dropEffect!==j,s=e?this._activeObject:void 0,i={e:t,target:this._dragSource,subTargets:this.targets,dragSource:this._dragSource,didDrop:e,dropTarget:s};yn(this.upperCanvasEl,"drag",this._onDragProgress),this.fire("dragend",i),this._dragSource&&this._dragSource.fire("dragend",i),delete this._dragSource,this._onMouseUp(t)}_onDragProgress(t){const e={e:t,target:this._dragSource,dragSource:this._dragSource,dropTarget:this._draggedoverTarget};this.fire("drag",e),this._dragSource&&this._dragSource.fire("drag",e)}findDragTargets(t){this.targets=[];return{target:this._searchPossibleTargets(this._objects,this.getViewportPoint(t)),targets:[...this.targets]}}_onDragOver(t){const e="dragover",{target:s,targets:i}=this.findDragTargets(t),r=this._dragSource,n={e:t,target:s,subTargets:i,dragSource:r,canDrop:!1,dropTarget:void 0};let o;this.fire(e,n),this._fireEnterLeaveEvents(s,n),s&&(s.canDrop(t)&&(o=s),s.fire(e,n));for(let s=0;s0)return;this.__onMouseUp(t),this._resetTransformEventData(),delete this.mainTouchId;const e=this._getEventPrefix(),s=re(this.upperCanvasEl);yn(s,"touchend",this._onTouchEnd,pn),yn(s,"touchmove",this._onMouseMove,pn),this._willAddMouseDown&&clearTimeout(this._willAddMouseDown),this._willAddMouseDown=setTimeout((()=>{vn(this.upperCanvasEl,"".concat(e,"down"),this._onMouseDown),this._willAddMouseDown=0}),400)}_onMouseUp(t){this.__onMouseUp(t),this._resetTransformEventData();const e=this.upperCanvasEl,s=this._getEventPrefix();if(this._isMainEvent(t)){const t=re(this.upperCanvasEl);yn(t,"".concat(s,"up"),this._onMouseUp),yn(t,"".concat(s,"move"),this._onMouseMove,pn),vn(e,"".concat(s,"move"),this._onMouseMove,pn)}}_onMouseMove(t){const e=this.getActiveObject();!this.allowTouchScrolling&&(!e||!e.shouldStartDragging(t))&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)}_onResize(){this.calcOffset(),this._resetTransformEventData()}_shouldRender(t){const e=this.getActiveObject();return!!e!=!!t||e&&t&&e!==t}__onMouseUp(t){var e;this._cacheTransformEventData(t),this._handleEvent(t,"up:before");const s=this._currentTransform,i=this._isClick,r=this._target,{button:n}=t;if(n)return(this.fireMiddleClick&&1===n||this.fireRightClick&&2===n)&&this._handleEvent(t,"up"),void this._resetTransformEventData();if(this.isDrawingMode&&this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(t);if(!this._isMainEvent(t))return;let o,a,h=!1;if(s&&(this._finalizeCurrentTransform(t),h=s.actionPerformed),!i){const e=r===this._activeObject;this.handleSelection(t),h||(h=this._shouldRender(r)||!e&&r===this._activeObject)}if(r){const e=r.findControl(this.getViewportPoint(t),fe(t)),{key:i,control:n}=e||{};if(a=i,r.selectable&&r!==this._activeObject&&"up"===r.activeOn)this.setActiveObject(r,t),h=!0;else if(n){const e=n.getMouseUpHandler(t,r,n);e&&(o=this.getScenePoint(t),e.call(n,t,s,o.x,o.y))}r.isMoving=!1}if(s&&(s.target!==r||s.corner!==a)){const e=s.target&&s.target.controls[s.corner],i=e&&e.getMouseUpHandler(t,s.target,e);o=o||this.getScenePoint(t),i&&i.call(e,t,s,o.x,o.y)}this._setCursorFromEvent(t,r),this._handleEvent(t,"up"),this._groupSelector=null,this._currentTransform=null,r&&(r.__corner=void 0),h?this.requestRenderAll():i||null!==(e=this._activeObject)&&void 0!==e&&e.isEditing||this.renderTop()}_basicEventHandler(t,e){const{target:s,subTargets:i=[]}=e;this.fire(t,e),s&&s.fire(t,e);for(let r=0;r{s=t.hoverCursor||s})),this.setCursor(s)}handleMultiSelection(t,e){const s=this._activeObject,i=se(s);if(s&&this._isSelectionKeyPressed(t)&&this.selection&&e&&e.selectable&&(s!==e||i)&&(i||!e.isDescendantOf(s)&&!s.isDescendantOf(e))&&!e.onSelect({e:t})&&!s.getActiveControl()){if(i){const i=s.getObjects();if(e===s){const s=this.getViewportPoint(t);if(!(e=this.searchPossibleTargets(i,s)||this.searchPossibleTargets(this._objects,s))||!e.selectable)return!1}e.group===s?(s.remove(e),this._hoveredTarget=e,this._hoveredTargets=[...this.targets],1===s.size()&&this._setActiveObject(s.item(0),t)):(s.multiSelectAdd(e),this._hoveredTarget=s,this._hoveredTargets=[...this.targets]),this._fireSelectionEvents(i,t)}else{s.exitEditing&&s.exitEditing();const i=new(tt.getClass("ActiveSelection"))([],{canvas:this});i.multiSelectAdd(s,e),this._hoveredTarget=i,this._setActiveObject(i,t),this._fireSelectionEvents([s],t)}return!0}return!1}handleSelection(t){if(!this.selection||!this._groupSelector)return!1;const{x:e,y:s,deltaX:i,deltaY:r}=this._groupSelector,n=new ot(e,s),o=n.add(new ot(i,r)),a=n.min(o),h=n.max(o).subtract(a),c=this.collectObjects({left:a.x,top:a.y,width:h.x,height:h.y},{includeIntersecting:!this.selectionFullyContained}),l=n.eq(o)?c[0]?[c[0]]:[]:c.length>1?c.filter((e=>!e.onSelect({e:t}))).reverse():c;if(1===l.length)this.setActiveObject(l[0],t);else if(l.length>1){const e=tt.getClass("ActiveSelection");this.setActiveObject(new e(l,{canvas:this}),t)}return this._groupSelector=null,!0}clear(){this.textEditingManager.clear(),super.clear()}destroy(){this.removeListeners(),this.textEditingManager.dispose(),super.destroy()}}const Cn={x1:0,y1:0,x2:0,y2:0},bn=i(i({},Cn),{},{r1:0,r2:0}),Sn=(t,e)=>isNaN(t)&&"number"==typeof e?e:t,wn=/^(\d+\.\d+)%|(\d+)%$/;function Tn(t){return t&&wn.test(t)}function On(t,e){const s="number"==typeof t?t:"string"==typeof t?parseFloat(t)/(Tn(t)?100:1):NaN;return ds(0,Sn(s,e),1)}const kn=/\s*;\s*/,Dn=/\s*:\s*/;function Mn(t,e){let s,i;const r=t.getAttribute("style");if(r){const t=r.split(kn);""===t[t.length-1]&&t.pop();for(let e=t.length;e--;){const[r,n]=t[e].split(Dn).map((t=>t.trim()));"stop-color"===r?s=n:"stop-opacity"===r&&(i=n)}}const n=new Nt(s||t.getAttribute("stop-color")||"rgb(0,0,0)");return{offset:On(t.getAttribute("offset"),0),color:n.toRgb(),opacity:Sn(parseFloat(i||t.getAttribute("stop-opacity")||""),1)*n.getAlpha()*e}}function Pn(t,e){const s=[],i=t.getElementsByTagName("stop"),r=On(e,1);for(let t=i.length;t--;)s.push(Mn(i[t],r));return s}function En(t){return"linearGradient"===t.nodeName||"LINEARGRADIENT"===t.nodeName?"linear":"radial"}function An(t){return"userSpaceOnUse"===t.getAttribute("gradientUnits")?"pixels":"percentage"}function jn(t,e){return t.getAttribute(e)}function Fn(t,e){return function(t,e){let s,{width:i,height:r,gradientUnits:n}=e;return Object.keys(t).reduce(((e,o)=>{const a=t[o];return"Infinity"===a?s=1:"-Infinity"===a?s=0:(s="string"==typeof a?parseFloat(a):a,"string"==typeof a&&Tn(a)&&(s*=.01,"pixels"===n&&("x1"!==o&&"x2"!==o&&"r2"!==o||(s*=i),"y1"!==o&&"y2"!==o||(s*=r)))),e[o]=s,e}),{})}("linear"===En(t)?function(t){return{x1:jn(t,"x1")||0,y1:jn(t,"y1")||0,x2:jn(t,"x2")||"100%",y2:jn(t,"y2")||0}}(t):function(t){return{x1:jn(t,"fx")||jn(t,"cx")||"50%",y1:jn(t,"fy")||jn(t,"cy")||"50%",r1:0,x2:jn(t,"cx")||"50%",y2:jn(t,"cy")||"50%",r2:jn(t,"r")||"50%"}}(t),i(i({},e),{},{gradientUnits:An(t)}))}class Ln{constructor(t){const{type:e="linear",gradientUnits:s="pixels",coords:r={},colorStops:n=[],offsetX:o=0,offsetY:a=0,gradientTransform:h,id:c}=t||{};Object.assign(this,{type:e,gradientUnits:s,coords:i(i({},"radial"===e?bn:Cn),r),colorStops:n,offsetX:o,offsetY:a,gradientTransform:h,id:c?"".concat(c,"_").concat(ft()):ft()})}addColorStop(t){for(const e in t){const s=new Nt(t[e]);this.colorStops.push({offset:parseFloat(e),color:s.toRgb(),opacity:s.getAlpha()})}return this}toObject(t){return i(i({},Bt(this,t)),{},{type:this.type,coords:i({},this.coords),colorStops:this.colorStops.map((t=>i({},t))),offsetX:this.offsetX,offsetY:this.offsetY,gradientUnits:this.gradientUnits,gradientTransform:this.gradientTransform?[...this.gradientTransform]:void 0})}toSVG(t){let{additionalTransform:e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=[],r=this.gradientTransform?this.gradientTransform.concat():T.concat(),n="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox",o=this.colorStops.map((t=>i({},t))).sort(((t,e)=>t.offset-e.offset));let a=-this.offsetX,h=-this.offsetY;var c;"objectBoundingBox"===n?(a/=t.width,h/=t.height):(a+=t.width/2,h+=t.height/2),(c=t)&&"function"==typeof c._renderPathCommands&&"percentage"!==this.gradientUnits&&(a-=t.pathOffset.x,h-=t.pathOffset.y),r[4]-=a,r[5]-=h;const l=['id="SVGID_'.concat(this.id,'"'),'gradientUnits="'.concat(n,'"'),'gradientTransform="'.concat(e?e+" ":"").concat(Jt(r),'"'),""].join(" ");if("linear"===this.type){const{x1:t,y1:e,x2:i,y2:r}=this.coords;s.push("\n')}else if("radial"===this.type){const{x1:t,y1:e,x2:i,y2:r,r1:n,r2:a}=this.coords,h=n>a;s.push("\n'),h&&(o.reverse(),o.forEach((t=>{t.offset=1-t.offset})));const c=Math.min(n,a);if(c>0){const t=c/Math.max(n,a);o.forEach((e=>{e.offset+=t*(1-e.offset)}))}}return o.forEach((t=>{let{color:e,offset:i,opacity:r}=t;s.push("\n')})),s.push("linear"===this.type?"":"","\n"),s.join("")}toLive(t){const{x1:e,y1:s,x2:i,y2:r,r1:n,r2:o}=this.coords,a="linear"===this.type?t.createLinearGradient(e,s,i,r):t.createRadialGradient(e,s,n,i,r,o);return this.colorStops.forEach((t=>{let{color:e,opacity:s,offset:i}=t;a.addColorStop(i,void 0!==s?new Nt(e).setAlpha(s).toRgba():e)})),a}static async fromObject(t){const{colorStops:e,gradientTransform:s}=t;return new this(i(i({},t),{},{colorStops:e?e.map((t=>i({},t))):void 0,gradientTransform:s?[...s]:void 0}))}static fromElement(t,e,s){const r=An(t),n=e._findCenterFromElement();return new this(i({id:t.getAttribute("id")||void 0,type:En(t),coords:Fn(t,{width:s.viewBoxWidth||s.width,height:s.viewBoxHeight||s.height}),colorStops:Pn(t,s.opacity),gradientUnits:r,gradientTransform:nr(t.getAttribute("gradientTransform")||"")},"pixels"===r?{offsetX:e.width/2-n.x,offsetY:e.height/2-n.y}:{offsetX:0,offsetY:0}))}}e(Ln,"type","Gradient"),tt.setClass(Ln,"gradient"),tt.setClass(Ln,"linear"),tt.setClass(Ln,"radial");const Rn=["type","source","patternTransform"];class In{get type(){return"pattern"}set type(t){h("warn","Setting type has no effect",t)}constructor(t){e(this,"repeat","repeat"),e(this,"offsetX",0),e(this,"offsetY",0),e(this,"crossOrigin",""),this.id=ft(),Object.assign(this,t)}isImageSource(){return!!this.source&&"string"==typeof this.source.src}isCanvasSource(){return!!this.source&&!!this.source.toDataURL}sourceToString(){return this.isImageSource()?this.source.src:this.isCanvasSource()?this.source.toDataURL():""}toLive(t){return this.source&&(!this.isImageSource()||this.source.complete&&0!==this.source.naturalWidth&&0!==this.source.naturalHeight)?t.createPattern(this.source,this.repeat):null}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const{repeat:e,crossOrigin:s}=this;return i(i({},Bt(this,t)),{},{type:"pattern",source:this.sourceToString(),repeat:e,crossOrigin:s,offsetX:Ut(this.offsetX,a.NUM_FRACTION_DIGITS),offsetY:Ut(this.offsetY,a.NUM_FRACTION_DIGITS),patternTransform:this.patternTransform?[...this.patternTransform]:null})}toSVG(t){let{width:e,height:s}=t;const{source:i,repeat:r,id:n}=this,o=Sn(this.offsetX/e,0),a=Sn(this.offsetY/s,0),h="repeat-y"===r||"no-repeat"===r?1+Math.abs(o||0):Sn(i.width/e,0),c="repeat-x"===r||"no-repeat"===r?1+Math.abs(a||0):Sn(i.height/s,0);return[''),''),"",""].join("\n")}static async fromObject(t,e){let{type:s,source:n,patternTransform:o}=t,a=r(t,Rn);const h=await Lt(n,i(i({},e),{},{crossOrigin:a.crossOrigin}));return new this(i(i({},a),{},{patternTransform:o&&o.slice(0),source:h}))}}e(In,"type","Pattern"),tt.setClass(In),tt.setClass(In,"pattern");class Bn{constructor(t){e(this,"color","rgb(0, 0, 0)"),e(this,"width",1),e(this,"shadow",null),e(this,"strokeLineCap","round"),e(this,"strokeLineJoin","round"),e(this,"strokeMiterLimit",10),e(this,"strokeDashArray",null),e(this,"limitedToCanvasSize",!1),this.canvas=t}_setBrushStyles(t){t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,t.setLineDash(this.strokeDashArray||[])}_saveAndTransform(t){const e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])}needsFullRender(){return new Nt(this.color).getAlpha()<1||!!this.shadow}_setShadow(){if(!this.shadow||!this.canvas)return;const t=this.canvas,e=this.shadow,s=t.contextTop,i=t.getZoom()*t.getRetinaScaling();s.shadowColor=e.color,s.shadowBlur=e.blur*i,s.shadowOffsetX=e.offsetX*i,s.shadowOffsetY=e.offsetY*i}_resetShadow(){const t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}_isOutSideCanvas(t){return t.x<0||t.x>this.canvas.getWidth()||t.y<0||t.y>this.canvas.getHeight()}}const Xn=["path","left","top"],Wn=["d"];class Yn extends yi{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{path:s,left:i,top:n}=e,o=r(e,Xn);super(),Object.assign(this,Yn.ownDefaults),this.setOptions(o),this._setPath(t||[],!0),"number"==typeof i&&this.set(M,i),"number"==typeof n&&this.set(P,n)}_setPath(t,e){this.path=Xr(Array.isArray(t)?t:sn(t)),this.setBoundingBox(e)}_findCenterFromElement(){const t=this._calcBoundsFromPath();return new ot(t.left+t.width/2,t.top+t.height/2)}_renderPathCommands(t){const e=-this.pathOffset.x,s=-this.pathOffset.y;t.beginPath();for(const i of this.path)switch(i[0]){case"L":t.lineTo(i[1]+e,i[2]+s);break;case"M":t.moveTo(i[1]+e,i[2]+s);break;case"C":t.bezierCurveTo(i[1]+e,i[2]+s,i[3]+e,i[4]+s,i[5]+e,i[6]+s);break;case"Q":t.quadraticCurveTo(i[1]+e,i[2]+s,i[3]+e,i[4]+s);break;case"Z":t.closePath()}}_render(t){this._renderPathCommands(t),this._renderPaintInOrder(t)}toString(){return"#")}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return i(i({},super.toObject(t)),{},{path:this.path.map((t=>t.slice()))})}toDatalessObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=this.toObject(t);return this.sourcePath&&(delete e.path,e.sourcePath=this.sourcePath),e}_toSVG(){const t=nn(this.path,a.NUM_FRACTION_DIGITS);return["\n')]}_getOffsetTransform(){const t=a.NUM_FRACTION_DIGITS;return" translate(".concat(Ut(-this.pathOffset.x,t),", ").concat(Ut(-this.pathOffset.y,t),")")}toClipPathSVG(t){const e=this._getOffsetTransform();return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})}toSVG(t){const e=this._getOffsetTransform();return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})}complexity(){return this.path.length}setDimensions(){this.setBoundingBox()}setBoundingBox(t){const{width:e,height:s,pathOffset:i}=this._calcDimensions();this.set({width:e,height:s,pathOffset:i}),t&&this.setPositionByOrigin(i,D,D)}_calcBoundsFromPath(){const t=[];let e=0,s=0,i=0,r=0;for(const n of this.path)switch(n[0]){case"L":i=n[1],r=n[2],t.push({x:e,y:s},{x:i,y:r});break;case"M":i=n[1],r=n[2],e=i,s=r;break;case"C":t.push(...Ir(i,r,n[1],n[2],n[3],n[4],n[5],n[6])),i=n[5],r=n[6];break;case"Q":t.push(...Ir(i,r,n[1],n[2],n[1],n[2],n[3],n[4])),i=n[3],r=n[4];break;case"Z":i=e,r=s}return me(t)}_calcDimensions(){const t=this._calcBoundsFromPath();return i(i({},t),{},{pathOffset:new ot(t.left+t.width/2,t.top+t.height/2)})}static fromObject(t){return this._fromObject(t,{extraParam:"path"})}static async fromElement(t,e,s){const n=ur(t,this.ATTRIBUTE_NAMES,s),{d:o}=n;return new this(o,i(i(i({},r(n,Wn)),e),{},{left:void 0,top:void 0}))}}e(Yn,"type","Path"),e(Yn,"cacheProperties",[...fs,"path","fillRule"]),e(Yn,"ATTRIBUTE_NAMES",[...ji,"d"]),tt.setClass(Yn),tt.setSVGClass(Yn);class Vn extends Bn{constructor(t){super(t),e(this,"decimate",.4),e(this,"drawStraightLine",!1),e(this,"straightLineKey","shiftKey"),this._points=[],this._hasStraightLine=!1}needsFullRender(){return super.needsFullRender()||this._hasStraightLine}static drawSegment(t,e,s){const i=e.midPointFrom(s);return t.quadraticCurveTo(e.x,e.y,i.x,i.y),i}onMouseDown(t,e){let{e:s}=e;this.canvas._isMainEvent(s)&&(this.drawStraightLine=!!this.straightLineKey&&s[this.straightLineKey],this._prepareForDrawing(t),this._addPoint(t),this._render())}onMouseMove(t,e){let{e:s}=e;if(this.canvas._isMainEvent(s)&&(this.drawStraightLine=!!this.straightLineKey&&s[this.straightLineKey],(!0!==this.limitedToCanvasSize||!this._isOutSideCanvas(t))&&this._addPoint(t)&&this._points.length>1))if(this.needsFullRender())this.canvas.clearContext(this.canvas.contextTop),this._render();else{const t=this._points,e=t.length,s=this.canvas.contextTop;this._saveAndTransform(s),this.oldEnd&&(s.beginPath(),s.moveTo(this.oldEnd.x,this.oldEnd.y)),this.oldEnd=Vn.drawSegment(s,t[e-2],t[e-1]),s.stroke(),s.restore()}}onMouseUp(t){let{e:e}=t;return!this.canvas._isMainEvent(e)||(this.drawStraightLine=!1,this.oldEnd=void 0,this._finalizeAndAddPath(),!1)}_prepareForDrawing(t){this._reset(),this._addPoint(t),this.canvas.contextTop.moveTo(t.x,t.y)}_addPoint(t){return!(this._points.length>1&&t.eq(this._points[this._points.length-1]))&&(this.drawStraightLine&&this._points.length>1&&(this._hasStraightLine=!0,this._points.pop()),this._points.push(t),!0)}_reset(){this._points=[],this._setBrushStyles(this.canvas.contextTop),this._setShadow(),this._hasStraightLine=!1}_render(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.canvas.contextTop,e=this._points[0],s=this._points[1];if(this._saveAndTransform(t),t.beginPath(),2===this._points.length&&e.x===s.x&&e.y===s.y){const t=this.width/1e3;e.x-=t,s.x+=t}t.moveTo(e.x,e.y);for(let i=1;i=n&&(i=t[e],a.push(i));return a.push(t[o]),a}_finalizeAndAddPath(){this.canvas.contextTop.closePath(),this.decimate&&(this._points=this.decimatePoints(this._points,this.decimate));const t=this.convertPointsToSVGPath(this._points);if(function(t){return"M 0 0 Q 0 0 0 0 L 0 0"===nn(t)}(t))return void this.canvas.requestRenderAll();const e=this.createPath(t);this.canvas.clearContext(this.canvas.contextTop),this.canvas.fire("before:path:created",{path:e}),this.canvas.add(e),this.canvas.requestRenderAll(),e.setCoords(),this._resetShadow(),this.canvas.fire("path:created",{path:e})}}const Gn=["left","top","radius"],Hn=["radius","startAngle","endAngle","counterClockwise"];class zn extends yi{static getDefaults(){return i(i({},super.getDefaults()),zn.ownDefaults)}constructor(t){super(),Object.assign(this,zn.ownDefaults),this.setOptions(t)}_set(t,e){return super._set(t,e),"radius"===t&&this.setRadius(e),this}_render(t){t.beginPath(),t.arc(0,0,this.radius,yt(this.startAngle),yt(this.endAngle),this.counterClockwise),this._renderPaintInOrder(t)}getRadiusX(){return this.get("radius")*this.get(z)}getRadiusY(){return this.get("radius")*this.get(N)}setRadius(t){this.radius=t,this.set({width:2*t,height:2*t})}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...Hn,...t])}_toSVG(){const t=(this.endAngle-this.startAngle)%360;if(0===t)return["\n'];{const{radius:e}=this,s=yt(this.startAngle),i=yt(this.endAngle),r=rt(s)*e,n=nt(s)*e,o=rt(i)*e,a=nt(i)*e,h=t>180?1:0,c=this.counterClockwise?0:1;return['\n"]}}static async fromElement(t,e,s){const n=ur(t,this.ATTRIBUTE_NAMES,s),{left:o=0,top:a=0,radius:h=0}=n;return new this(i(i({},r(n,Gn)),{},{radius:h,left:o-h,top:a-h}))}static fromObject(t){return super._fromObject(t)}}e(zn,"type","Circle"),e(zn,"cacheProperties",[...fs,...Hn]),e(zn,"ownDefaults",{radius:0,startAngle:0,endAngle:360,counterClockwise:!1}),e(zn,"ATTRIBUTE_NAMES",["cx","cy","r",...ji]),tt.setClass(zn),tt.setSVGClass(zn);const Nn=["x1","y1","x2","y2"],Un=["x1","y1","x2","y2"],qn=["x1","x2","y1","y2"];class Kn extends yi{constructor(){let[t,e,s,i]=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[0,0,0,0],r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,Kn.ownDefaults),this.setOptions(r),this.x1=t,this.x2=s,this.y1=e,this.y2=i,this._setWidthHeight();const{left:n,top:o}=r;"number"==typeof n&&this.set(M,n),"number"==typeof o&&this.set(P,o)}_setWidthHeight(){const{x1:t,y1:e,x2:s,y2:i}=this;this.width=Math.abs(s-t),this.height=Math.abs(i-e);const{left:r,top:n,width:o,height:a}=me([{x:t,y:e},{x:s,y:i}]),h=new ot(r+o/2,n+a/2);this.setPositionByOrigin(h,D,D)}_set(t,e){return super._set(t,e),qn.includes(t)&&this._setWidthHeight(),this}_render(t){t.beginPath();const e=this.calcLinePoints();t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.lineWidth=this.strokeWidth;const s=t.strokeStyle;var i;Zt(this.stroke)?t.strokeStyle=this.stroke.toLive(t):t.strokeStyle=null!==(i=this.stroke)&&void 0!==i?i:t.fillStyle;this.stroke&&this._renderStroke(t),t.strokeStyle=s}_findCenterFromElement(){return new ot((this.x1+this.x2)/2,(this.y1+this.y2)/2)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return i(i({},super.toObject(t)),this.calcLinePoints())}_getNonTransformedDimensions(){const t=super._getNonTransformedDimensions();return"butt"===this.strokeLineCap&&(0===this.width&&(t.y-=this.strokeWidth),0===this.height&&(t.x-=this.strokeWidth)),t}calcLinePoints(){const{x1:t,x2:e,y1:s,y2:i,width:r,height:n}=this,o=t<=e?-1:1,a=s<=i?-1:1;return{x1:o*r/2,x2:o*-r/2,y1:a*n/2,y2:a*-n/2}}_toSVG(){const{x1:t,x2:e,y1:s,y2:i}=this.calcLinePoints();return["\n')]}static async fromElement(t,e,s){const i=ur(t,this.ATTRIBUTE_NAMES,s),{x1:n=0,y1:o=0,x2:a=0,y2:h=0}=i;return new this([n,o,a,h],r(i,Nn))}static fromObject(t){let{x1:e,y1:s,x2:n,y2:o}=t,a=r(t,Un);return this._fromObject(i(i({},a),{},{points:[e,s,n,o]}),{extraParam:"points"})}}e(Kn,"type","Line"),e(Kn,"cacheProperties",[...fs,...qn]),e(Kn,"ATTRIBUTE_NAMES",ji.concat(qn)),tt.setClass(Kn),tt.setSVGClass(Kn);class Jn extends yi{static getDefaults(){return i(i({},super.getDefaults()),Jn.ownDefaults)}constructor(t){super(),Object.assign(this,Jn.ownDefaults),this.setOptions(t)}_render(t){const e=this.width/2,s=this.height/2;t.beginPath(),t.moveTo(-e,s),t.lineTo(0,-s),t.lineTo(e,s),t.closePath(),this._renderPaintInOrder(t)}_toSVG(){const t=this.width/2,e=this.height/2;return["']}}e(Jn,"type","Triangle"),e(Jn,"ownDefaults",{width:100,height:100}),tt.setClass(Jn),tt.setSVGClass(Jn);const Qn=["rx","ry"];class Zn extends yi{static getDefaults(){return i(i({},super.getDefaults()),Zn.ownDefaults)}constructor(t){super(),Object.assign(this,Zn.ownDefaults),this.setOptions(t)}_set(t,e){switch(super._set(t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this}getRx(){return this.get("rx")*this.get(z)}getRy(){return this.get("ry")*this.get(N)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...Qn,...t])}_toSVG(){return["\n')]}_render(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,S,!1),t.restore(),this._renderPaintInOrder(t)}static async fromElement(t,e,s){const i=ur(t,this.ATTRIBUTE_NAMES,s);return i.left=(i.left||0)-i.rx,i.top=(i.top||0)-i.ry,new this(i)}}function $n(t){if(!t)return[];const e=t.replace(/,/g," ").trim().split(/\s+/),s=[];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[],s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),e(this,"strokeDiff",void 0),Object.assign(this,so.ownDefaults),this.setOptions(s),this.points=t;const{left:i,top:r}=s;this.initialized=!0,this.setBoundingBox(!0),"number"==typeof i&&this.set(M,i),"number"==typeof r&&this.set(P,r)}isOpen(){return!0}_projectStrokeOnPoints(t){return wi(this.points,t,this.isOpen())}_calcDimensions(t){t=i({scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:this.strokeMiterLimit,strokeUniform:this.strokeUniform,strokeWidth:this.strokeWidth},t||{});const e=this.exactBoundingBox?this._projectStrokeOnPoints(t).map((t=>t.projectedPoint)):this.points;if(0===e.length)return{left:0,top:0,width:0,height:0,pathOffset:new ot,strokeOffset:new ot,strokeDiff:new ot};const s=me(e),r=jt(i(i({},t),{},{scaleX:1,scaleY:1})),n=me(this.points.map((t=>Ct(t,r,!0)))),o=new ot(this.scaleX,this.scaleY);let a=s.left+s.width/2,h=s.top+s.height/2;return this.exactBoundingBox&&(a-=h*Math.tan(yt(this.skewX)),h-=a*Math.tan(yt(this.skewY))),i(i({},s),{},{pathOffset:new ot(a,h),strokeOffset:new ot(n.left,n.top).subtract(new ot(s.left,s.top)).multiply(o),strokeDiff:new ot(s.width,s.height).subtract(new ot(n.width,n.height)).multiply(o)})}_findCenterFromElement(){const t=me(this.points);return new ot(t.left+t.width/2,t.top+t.height/2)}setDimensions(){this.setBoundingBox()}setBoundingBox(t){const{left:e,top:s,width:i,height:r,pathOffset:n,strokeOffset:o,strokeDiff:a}=this._calcDimensions();this.set({width:i,height:r,pathOffset:n,strokeOffset:o,strokeDiff:a}),t&&this.setPositionByOrigin(new ot(e+i/2,s+r/2),D,D)}isStrokeAccountedForInDimensions(){return this.exactBoundingBox}_getNonTransformedDimensions(){return this.exactBoundingBox?new ot(this.width,this.height):super._getNonTransformedDimensions()}_getTransformedDimensions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.exactBoundingBox){let n;if(Object.keys(t).some((t=>this.strokeUniform||this.constructor.layoutProperties.includes(t)))){var e,s;const{width:i,height:r}=this._calcDimensions(t);n=new ot(null!==(e=t.width)&&void 0!==e?e:i,null!==(s=t.height)&&void 0!==s?s:r)}else{var i,r;n=new ot(null!==(i=t.width)&&void 0!==i?i:this.width,null!==(r=t.height)&&void 0!==r?r:this.height)}return n.multiply(new ot(t.scaleX||this.scaleX,t.scaleY||this.scaleY))}return super._getTransformedDimensions(t)}_set(t,e){const s=this.initialized&&this[t]!==e,i=super._set(t,e);return this.exactBoundingBox&&s&&((t===z||t===N)&&this.strokeUniform&&this.constructor.layoutProperties.includes("strokeUniform")||this.constructor.layoutProperties.includes(t))&&this.setDimensions(),i}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return i(i({},super.toObject(t)),{},{points:this.points.map((t=>{let{x:e,y:s}=t;return{x:e,y:s}}))})}_toSVG(){const t=[],e=this.pathOffset.x,s=this.pathOffset.y,i=a.NUM_FRACTION_DIGITS;for(let r=0,n=this.points.length;r\n')]}_render(t){const e=this.points.length,s=this.pathOffset.x,i=this.pathOffset.y;if(e&&!isNaN(this.points[e-1].y)){t.beginPath(),t.moveTo(this.points[0].x-s,this.points[0].y-i);for(let r=0;rvoid 0!==t));this._setStyleDeclaration(s,r,n)}getSelectionStyles(t,e,s){const i=[];for(let r=t;r<(e||t);r++)i.push(this.getStyleAtPosition(r,s));return i}getStyleAtPosition(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t);return e?this.getCompleteStyleDeclaration(s,i):this._getStyleDeclaration(s,i)}setSelectionStyles(t,e,s){for(let i=e;i<(s||e);i++)this._extendStyles(i,t);this._forceClearCache=!0}_getStyleDeclaration(t,e){var s;const i=this.styles&&this.styles[t];return i&&null!==(s=i[e])&&void 0!==s?s:{}}getCompleteStyleDeclaration(t,e){return i(i({},Bt(this,this.constructor._styleProperties)),this._getStyleDeclaration(t,e))}_setStyleDeclaration(t,e,s){this.styles[t][e]=s}_deleteStyleDeclaration(t,e){delete this.styles[t][e]}_getLineStyle(t){return!!this.styles[t]}_setLineStyle(t){this.styles[t]={}}_deleteLineStyle(t){delete this.styles[t]}}e(po,"_styleProperties",ho);const mo=/ +/g,vo=/"/g;function yo(t,e,s,i,r){return"\t\t".concat(function(t,e){let{left:s,top:i,width:r,height:n}=e,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:a.NUM_FRACTION_DIGITS;const h=Qt(K,t,!1),[c,l,u,d]=[s,i,r,n].map((t=>Ut(t,o)));return"')}(t,{left:e,top:s,width:i,height:r}),"\n")}const _o=["textAnchor","textDecoration","dx","dy","top","left","fontSize","strokeWidth"];let xo;class Co extends po{static getDefaults(){return i(i({},super.getDefaults()),Co.ownDefaults)}constructor(t,s){super(),e(this,"__charBounds",[]),Object.assign(this,Co.ownDefaults),this.setOptions(s),this.styles||(this.styles={}),this.text=t,this.initialized=!0,this.path&&this.setPathInfo(),this.initDimensions(),this.setCoords()}setPathInfo(){const t=this.path;t&&(t.segmentsInfo=Jr(t.path))}_splitText(){const t=this._splitTextIntoLines(this.text);return this.textLines=t.lines,this._textLines=t.graphemeLines,this._unwrappedTextLines=t._unwrappedLines,this._text=t.graphemeText,t}initDimensions(){this._splitText(),this._clearCache(),this.dirty=!0,this.path?(this.width=this.path.width,this.height=this.path.height):(this.width=this.calcTextWidth()||this.cursorWidth||this.MIN_TEXT_WIDTH,this.height=this.calcTextHeight()),this.textAlign.includes(lo)&&this.enlargeSpaces()}enlargeSpaces(){let t,e,s,i,r,n,o;for(let a=0,h=this._textLines.length;a')}_getCacheCanvasDimensions(){const t=super._getCacheCanvasDimensions(),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t}_render(t){const e=this.path;e&&!e.isNotVisible()&&e._render(t),this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")}_renderText(t){this.paintFirst===J?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))}_setTextStyles(t,e,s){if(t.textBaseline="alphabetic",this.path)switch(this.pathAlign){case D:t.textBaseline="middle";break;case"ascender":t.textBaseline=P;break;case"descender":t.textBaseline=E}t.font=this._getFontDeclaration(e,s)}calcTextWidth(){let t=this.getLineWidth(0);for(let e=1,s=this._textLines.length;et&&(t=s)}return t}_renderTextLine(t,e,s,i,r,n){this._renderChars(t,e,s,i,r,n)}_renderTextLinesBackground(t){if(!this.textBackgroundColor&&!this.styleHas("textBackgroundColor"))return;const e=t.fillStyle,s=this._getLeftOffset();let i=this._getTopOffset();for(let e=0,r=this._textLines.length;e=0:ie?t%=e:t<0&&(t+=e),this._setGraphemeOnPath(t,s),t+=s.kernedWidth}return{width:i,numOfSpaces:0}}_setGraphemeOnPath(t,e){const s=t+e.kernedWidth/2,i=this.path,r=Qr(i.path,s,i.segmentsInfo);e.renderLeft=r.x-i.pathOffset.x,e.renderTop=r.y-i.pathOffset.y,e.angle=r.angle+(this.pathSide===A?Math.PI:0)}_getGraphemeBox(t,e,s,i,r){const n=this.getCompleteStyleDeclaration(e,s),o=i?this.getCompleteStyleDeclaration(e,s-1):{},a=this._measureChar(t,n,i,o);let h,c=a.kernedWidth,l=a.width;0!==this.charSpacing&&(h=this._getWidthOfCharSpacing(),l+=h,c+=h);const u={width:l,left:0,height:n.fontSize,kernedWidth:c,deltaY:n.deltaY};if(s>0&&!r){const t=this.__charBounds[e][s-1];u.left=t.left+t.width+a.kernedWidth-a.width}return u}getHeightOfLine(t){if(this.__lineHeights[t])return this.__lineHeights[t];let e=this.getHeightOfChar(t,0);for(let s=1,i=this._textLines[t].length;s0){let e=i+u+f;"rtl"===this.direction&&(e=this.width-e-p),m&&v&&(t.fillStyle=v,t.fillRect(e,y+o*_+x,p,this.fontSize/15)),f=n.left,p=n.width,m=d,v=g,_=h,x=c}else p+=n.kernedWidth}let C=i+u+f;"rtl"===this.direction&&(C=this.width-C-p),t.fillStyle=g,d&&g&&t.fillRect(C,y+o*_+x,p-n,this.fontSize/15),s+=h}this._removeShadow(t)}_getFontDeclaration(){let{fontFamily:t=this.fontFamily,fontStyle:e=this.fontStyle,fontWeight:s=this.fontWeight,fontSize:i=this.fontSize}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;const n=t.includes("'")||t.includes('"')||t.includes(",")||Co.genericFonts.includes(t.toLowerCase())?t:'"'.concat(t,'"');return[e,s,"".concat(r?this.CACHE_FONT_SIZE:i,"px"),n].join(" ")}render(t){this.visible&&(this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(this._forceClearCache&&this.initDimensions(),super.render(t)))}graphemeSplit(t){return ki(t)}_splitTextIntoLines(t){const e=t.split(this._reNewline),s=new Array(e.length),i=["\n"];let r=[];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[];return i(i({},super.toObject([...ao,...t])),{},{styles:Ei(this.styles,this.text)},this.path?{path:this.path.toObject()}:{})}set(t,e){const{textLayoutProperties:s}=this.constructor;super.set(t,e);let i=!1,r=!1;if("object"==typeof t)for(const e in t)"path"===e&&this.setPathInfo(),i=i||s.includes(e),r=r||"path"===e;else i=s.includes(t),r="path"===t;return r&&this.setPathInfo(),i&&this.initialized&&(this.initDimensions(),this.setCoords()),this}complexity(){return 1}static async fromElement(t,e,s){const n=ur(t,Co.ATTRIBUTE_NAMES,s),o=i(i({},e),n),{textAnchor:a=M,textDecoration:h="",dx:c=0,dy:l=0,top:u=0,left:d=0,fontSize:g=O,strokeWidth:f=1}=o,p=r(o,_o),m=new this((t.textContent||"").replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," "),i({left:d+c,top:u+l,underline:h.includes("underline"),overline:h.includes("overline"),linethrough:h.includes("line-through"),strokeWidth:0,fontSize:g},p)),v=m.getScaledHeight()/m.height,y=((m.height+m.strokeWidth)*m.lineHeight-m.height)*v,_=m.getScaledHeight()+y;let x=0;return a===D&&(x=m.getScaledWidth()/2),a===A&&(x=m.getScaledWidth()),m.set({left:m.left-x,top:m.top-(_-m.fontSize*(.07+m._fontSizeFraction))/m.lineHeight,strokeWidth:f}),m}static fromObject(t){return this._fromObject(i(i({},t),{},{styles:Ai(t.styles||{},t.text)}),{extraParam:"text"})}}e(Co,"textLayoutProperties",oo),e(Co,"cacheProperties",[...fs,...ao]),e(Co,"ownDefaults",co),e(Co,"type","Text"),e(Co,"genericFonts",["sans-serif","serif","cursive","fantasy","monospace"]),e(Co,"ATTRIBUTE_NAMES",ji.concat("x","y","dx","dy","font-family","font-style","font-weight","font-size","letter-spacing","text-decoration","text-anchor")),vi(Co,[class extends Be{_toSVG(){const t=this._getSVGLeftTopOffsets(),e=this._getSVGTextAndBg(t.textTop,t.textLeft);return this._wrapSVGTextAndBg(e)}toSVG(t){return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,noStyle:!0,withShadow:!0})}_getSVGLeftTopOffsets(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}}_wrapSVGTextAndBg(t){let{textBgRects:e,textSpans:s}=t;const i=this.getSvgTextDecoration(this);return[e.join(""),'\t\t",s.join(""),"\n"]}_getSVGTextAndBg(t,e){const s=[],i=[];let r,n=t;this.backgroundColor&&i.push(...yo(this.backgroundColor,-this.width/2,-this.height/2,this.width,this.height));for(let t=0,o=this._textLines.length;t").concat(Oi(t),"")}_setSVGTextLineText(t,e,s,i){const r=this.getHeightOfLine(e),n=this.textAlign.includes(lo),o=this._textLines[e];let a,h,c,l,u,d="",g=0;i+=r*(1-this._fontSizeFraction)/this.lineHeight;for(let r=0,f=o.length-1;r<=f;r++)u=r===f||this.charSpacing,d+=o[r],c=this.__charBounds[e][r],0===g?(s+=c.kernedWidth-c.width,g+=c.width):g+=c.kernedWidth,n&&!u&&this._reSpaceAndTab.test(o[r])&&(u=!0),u||(a=a||this.getCompleteStyleDeclaration(e,r),h=this.getCompleteStyleDeclaration(e,r+1),u=Pi(a,h,!0)),u&&(l=this._getStyleDeclaration(e,r),t.push(this._createTextCharSpan(d,l,s,i)),d="",a=h,"rtl"===this.direction?s-=g:s+=g,g=0)}_setSVGTextLineBg(t,e,s,i){const r=this._textLines[e],n=this.getHeightOfLine(e)/this.lineHeight;let o,a=0,h=0,c=this.getValueOfPropertyAt(e,0,"textBackgroundColor");for(let l=0;lt[e.replace("-","")])).join(" ")}}]),tt.setClass(Co),tt.setSVGClass(Co);class bo{constructor(t){e(this,"target",void 0),e(this,"__mouseDownInPlace",!1),e(this,"__dragStartFired",!1),e(this,"__isDraggingOver",!1),e(this,"__dragStartSelection",void 0),e(this,"__dragImageDisposer",void 0),e(this,"_dispose",void 0),this.target=t;const s=[this.target.on("dragenter",this.dragEnterHandler.bind(this)),this.target.on("dragover",this.dragOverHandler.bind(this)),this.target.on("dragleave",this.dragLeaveHandler.bind(this)),this.target.on("dragend",this.dragEndHandler.bind(this)),this.target.on("drop",this.dropHandler.bind(this))];this._dispose=()=>{s.forEach((t=>t())),this._dispose=void 0}}isPointerOverSelection(t){const e=this.target,s=e.getSelectionStartFromPointer(t);return e.isEditing&&s>=e.selectionStart&&s<=e.selectionEnd&&e.selectionStart{_.remove()},re(t.target||this.target.hiddenTextarea).body.appendChild(_),null===(s=t.dataTransfer)||void 0===s||s.setDragImage(_,p.x,p.y)}onDragStart(t){this.__dragStartFired=!0;const e=this.target,s=this.isActive();if(s&&t.dataTransfer){const s=this.__dragStartSelection={selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},r=e._text.slice(s.selectionStart,s.selectionEnd).join(""),n=i({text:e.text,value:r},s);t.dataTransfer.setData("text/plain",r),t.dataTransfer.setData("application/fabric",JSON.stringify({value:r,styles:e.getSelectionStyles(s.selectionStart,s.selectionEnd,!0)})),t.dataTransfer.effectAllowed="copyMove",this.setDragImage(t,n)}return e.abortCursorAnimation(),s}canDrop(t){if(this.target.editable&&!this.target.getActiveControl()&&!t.defaultPrevented){if(this.isActive()&&this.__dragStartSelection){const e=this.target.getSelectionStartFromPointer(t),s=this.__dragStartSelection;return es.selectionEnd}return!0}return!1}targetCanDrop(t){return this.target.canDrop(t)}dragEnterHandler(t){let{e:e}=t;const s=this.targetCanDrop(e);!this.__isDraggingOver&&s&&(this.__isDraggingOver=!0)}dragOverHandler(t){const{e:e}=t,s=this.targetCanDrop(e);!this.__isDraggingOver&&s?this.__isDraggingOver=!0:this.__isDraggingOver&&!s&&(this.__isDraggingOver=!1),this.__isDraggingOver&&(e.preventDefault(),t.canDrop=!0,t.dropTarget=this.target)}dragLeaveHandler(){(this.__isDraggingOver||this.isActive())&&(this.__isDraggingOver=!1)}dropHandler(t){var e;const{e:s}=t,i=s.defaultPrevented;this.__isDraggingOver=!1,s.preventDefault();let r=null===(e=s.dataTransfer)||void 0===e?void 0:e.getData("text/plain");if(r&&!i){const e=this.target,i=e.canvas;let n=e.getSelectionStartFromPointer(s);const{styles:o}=s.dataTransfer.types.includes("application/fabric")?JSON.parse(s.dataTransfer.getData("application/fabric")):{},a=r[Math.max(0,r.length-1)],h=0;if(this.__dragStartSelection){const t=this.__dragStartSelection.selectionStart,s=this.__dragStartSelection.selectionEnd;n>t&&n<=s?n=t:n>s&&(n-=s-t),e.removeChars(t,s),delete this.__dragStartSelection}e._reNewline.test(a)&&(e._reNewline.test(e._text[n])||n===e._text.length)&&(r=r.trimEnd()),t.didDrop=!0,t.dropTarget=e,e.insertChars(r,o,n),i.setActiveObject(e),e.enterEditing(s),e.selectionStart=Math.min(n+h,e._text.length),e.selectionEnd=Math.min(e.selectionStart+r.length,e._text.length),e.hiddenTextarea.value=e.text,e._updateTextarea(),e.hiddenTextarea.focus(),e.fire(G,{index:n+h,action:"drop"}),i.fire("text:changed",{target:e}),i.contextTopDirty=!0,i.requestRenderAll()}}dragEndHandler(t){let{e:e}=t;if(this.isActive()&&this.__dragStartFired&&this.__dragStartSelection){var s;const t=this.target,i=this.target.canvas,{selectionStart:r,selectionEnd:n}=this.__dragStartSelection,o=(null===(s=e.dataTransfer)||void 0===s?void 0:s.dropEffect)||j;o===j?(t.selectionStart=r,t.selectionEnd=n,t._updateTextarea(),t.hiddenTextarea.focus()):(t.clearContextTop(),"move"===o&&(t.removeChars(r,n),t.selectionStart=t.selectionEnd=r,t.hiddenTextarea&&(t.hiddenTextarea.value=t.text),t._updateTextarea(),t.fire(G,{index:r,action:"dragend"}),i.fire("text:changed",{target:t}),i.requestRenderAll()),t.exitEditing())}this.__dragImageDisposer&&this.__dragImageDisposer(),delete this.__dragImageDisposer,delete this.__dragStartSelection,this.__isDraggingOver=!1}dispose(){this._dispose&&this._dispose()}}const So=/[ \n\.,;!\?\-]/;class wo extends Co{constructor(){super(...arguments),e(this,"_currentCursorOpacity",1)}initBehavior(){this._tick=this._tick.bind(this),this._onTickComplete=this._onTickComplete.bind(this),this.updateSelectionOnMouseMove=this.updateSelectionOnMouseMove.bind(this)}onDeselect(t){return this.isEditing&&this.exitEditing(),this.selected=!1,super.onDeselect(t)}_animateCursor(t){let{toValue:e,duration:s,delay:i,onComplete:r}=t;return As({startValue:this._currentCursorOpacity,endValue:e,duration:s,delay:i,onComplete:r,abort:()=>!this.canvas||this.selectionStart!==this.selectionEnd,onChange:t=>{this._currentCursorOpacity=t,this.renderCursorOrSelection()}})}_tick(t){this._currentTickState=this._animateCursor({toValue:0,duration:this.cursorDuration/2,delay:Math.max(t||0,100),onComplete:this._onTickComplete})}_onTickComplete(){var t;null===(t=this._currentTickCompleteState)||void 0===t||t.abort(),this._currentTickCompleteState=this._animateCursor({toValue:1,duration:this.cursorDuration,onComplete:this._tick})}initDelayedCursor(t){this.abortCursorAnimation(),this._tick(t?0:this.cursorDelay)}abortCursorAnimation(){let t=!1;[this._currentTickState,this._currentTickCompleteState].forEach((e=>{e&&!e.isDone()&&(t=!0,e.abort())})),this._currentCursorOpacity=1,t&&this.clearContextTop()}restartCursorIfNeeded(){[this._currentTickState,this._currentTickCompleteState].some((t=>!t||t.isDone()))&&this.initDelayedCursor()}selectAll(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this}getSelectedText(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")}findWordBoundaryLeft(t){let e=0,s=t-1;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s--;for(;/\S/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findWordBoundaryRight(t){let e=0,s=t;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s++;for(;/\S/.test(this._text[s])&&s-1;)e++,s--;return t-e}findLineBoundaryRight(t){let e=0,s=t;for(;!/\n/.test(this._text[s])&&s0&&this._reSpace.test(s[t])&&(-1===e||!F.test(s[t-1]))?t-1:t,r=s[i];for(;i>0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=s):(this.selectionStart=s,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}_setEditingProps(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0}fromStringToGraphemeSelection(t,e,s){const i=s.slice(0,t),r=this.graphemeSplit(i).length;if(t===e)return{selectionStart:r,selectionEnd:r};const n=s.slice(t,e);return{selectionStart:r,selectionEnd:r+this.graphemeSplit(n).length}}fromGraphemeToStringSelection(t,e,s){const i=s.slice(0,t).join("").length;if(t===e)return{selectionStart:i,selectionEnd:i};return{selectionStart:i,selectionEnd:i+s.slice(t,e).join("").length}}_updateTextarea(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){const t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}}updateFromTextArea(){if(!this.hiddenTextarea)return;this.cursorOffsetCache={};const t=this.hiddenTextarea;this.text=t.value,this.set("dirty",!0),this.initDimensions(),this.setCoords();const e=this.fromStringToGraphemeSelection(t.selectionStart,t.selectionEnd,t.value);this.selectionEnd=this.selectionStart=e.selectionEnd,this.inCompositionMode||(this.selectionStart=e.selectionStart),this.updateTextareaPosition()}updateTextareaPosition(){if(this.selectionStart===this.selectionEnd){const t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}}_calcTextareaPosition(){if(!this.canvas)return{left:"1px",top:"1px"};const t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),s=this.get2DCursorLocation(t),i=s.lineIndex,r=s.charIndex,n=this.getValueOfPropertyAt(i,r,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.getCanvasRetinaScaling(),h=this.canvas.upperCanvasEl,c=h.width/a,l=h.height/a,u=c-n,d=l-n,g=new ot(e.left+o,e.top+e.topOffset+n).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new ot(h.clientWidth/c,h.clientHeight/l));return g.x<0&&(g.x=0),g.x>u&&(g.x=u),g.y<0&&(g.y=0),g.y>d&&(g.y=d),g.x+=this.canvas._offset.left,g.y+=this.canvas._offset.top,{left:"".concat(g.x,"px"),top:"".concat(g.y,"px"),fontSize:"".concat(n,"px"),charHeight:n}}_saveEditingProps(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}}_restoreEditingProps(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor||this.canvas.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor||this.canvas.moveCursor),delete this._savedProps)}_exitEditing(){const t=this.hiddenTextarea;this.selected=!1,this.isEditing=!1,t&&(t.blur&&t.blur(),t.parentNode&&t.parentNode.removeChild(t)),this.hiddenTextarea=null,this.abortCursorAnimation(),this.selectionStart!==this.selectionEnd&&this.clearContextTop()}exitEditing(){const t=this._textBeforeEdit!==this.text;return this._exitEditing(),this.selectionEnd=this.selectionStart,this._restoreEditingProps(),this._forceClearCache&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire(Q),this.canvas&&(this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this}_removeExtraneousStyles(){for(const t in this.styles)this._textLines[t]||delete this.styles[t]}removeStyleFromTo(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t,!0),{lineIndex:r,charIndex:n}=this.get2DCursorLocation(e,!0);if(s!==r){if(this.styles[s])for(let t=i;t=n&&(t[s-e]=t[i],delete t[i])}}}shiftLineStyles(t,e){const s=Object.assign({},this.styles);for(const i in this.styles){const r=parseInt(i,10);r>t&&(this.styles[r+e]=s[r],s[r-e]||delete this.styles[r])}}insertNewlineStyleObject(t,e,s,r){const n={},o=this._unwrappedTextLines[t].length,a=o===e;let h=!1;s||(s=1),this.shiftLineStyles(t,s);const c=this.styles[t]?this.styles[t][0===e?e:e-1]:void 0;for(const s in this.styles[t]){const i=parseInt(s,10);i>=e&&(h=!0,n[i-e]=this.styles[t][s],a&&0===e||delete this.styles[t][s])}let l=!1;for(h&&!a&&(this.styles[t+s]=n,l=!0),(l||o>e)&&s--;s>0;)r&&r[s-1]?this.styles[t+s]={0:i({},r[s-1])}:c?this.styles[t+s]={0:i({},c)}:delete this.styles[t+s],s--;this._forceClearCache=!0}insertCharStyleObject(t,e,s,r){this.styles||(this.styles={});const n=this.styles[t],o=n?i({},n):{};s||(s=1);for(const t in o){const i=parseInt(t,10);i>=e&&(n[i+s]=o[i],o[i-s]||delete n[i])}if(this._forceClearCache=!0,r){for(;s--;)Object.keys(r[s]).length&&(this.styles[t]||(this.styles[t]={}),this.styles[t][e+s]=i({},r[s]));return}if(!n)return;const a=n[e?e-1:1];for(;a&&s--;)this.styles[t][e+s]=i({},a)}insertNewStyleBlock(t,e,s){const i=this.get2DCursorLocation(e,!0),r=[0];let n,o=0;for(let e=0;e0&&(this.insertCharStyleObject(i.lineIndex,i.charIndex,r[0],s),s=s&&s.slice(r[0]+1)),o&&this.insertNewlineStyleObject(i.lineIndex,i.charIndex+r[0],o),n=1;n0?this.insertCharStyleObject(i.lineIndex+n,0,r[n],s):s&&this.styles[i.lineIndex+n]&&s[0]&&(this.styles[i.lineIndex+n][0]=s[0]),s=s&&s.slice(r[n]+1);r[n]>0&&this.insertCharStyleObject(i.lineIndex+n,0,r[n],s)}removeChars(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t+1;this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}insertChars(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;i>s&&this.removeStyleFromTo(s,i);const r=this.graphemeSplit(t);this.insertNewStyleBlock(r,s,e),this._text=[...this._text.slice(0,s),...r,...this._text.slice(i)],this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}setSelectionStartEndWithShift(t,e,s){s<=t?(e===t?this._selectionDirection=M:this._selectionDirection===A&&(this._selectionDirection=M,this.selectionEnd=t),this.selectionStart=s):s>t&&s{let[s,i]=t;return e.setAttribute(s,i)}));const{top:s,left:i,fontSize:r}=this._calcTextareaPosition();e.style.cssText="position: absolute; top: ".concat(s,"; left: ").concat(i,"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ").concat(r,";"),(this.hiddenTextareaContainer||t.body).appendChild(e),Object.entries({blur:"blur",keydown:"onKeyDown",keyup:"onKeyUp",input:"onInput",copy:"copy",cut:"copy",paste:"paste",compositionstart:"onCompositionStart",compositionupdate:"onCompositionUpdate",compositionend:"onCompositionEnd"}).map((t=>{let[s,i]=t;return e.addEventListener(s,this[i].bind(this))})),this.hiddenTextarea=e}blur(){this.abortCursorAnimation()}onKeyDown(t){if(!this.isEditing)return;const e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown)||!t.ctrlKey&&!t.metaKey)return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}onKeyUp(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())}onInput(t){const e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),!this.isEditing)return;const s=()=>{this.updateFromTextArea(),this.fire(G),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())};if(""===this.hiddenTextarea.value)return this.styles={},void s();const i=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,r=this._text.length,n=i.length,o=this.selectionStart,h=this.selectionEnd,c=o!==h;let l,u,d,g,f=n-r;const m=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),v=o>m.selectionStart;c?(u=this._text.slice(o,h),f+=h-o):nl[0]))),c?(d=o,g=h):v?(d=h-u.length,g=h):(d=h,g=h+u.length),this.removeStyleFromTo(d,g)),y.length){const{copyPasteData:t}=p();e&&y.join("")===t.copiedText&&!a.disableStyleCopyPaste&&(l=t.copiedTextStyle),this.insertNewStyleBlock(y,o,l)}s()}onCompositionStart(){this.inCompositionMode=!0}onCompositionEnd(){this.inCompositionMode=!1}onCompositionUpdate(t){let{target:e}=t;const{selectionStart:s,selectionEnd:i}=e;this.compositionStart=s,this.compositionEnd=i,this.updateTextareaPosition()}copy(){if(this.selectionStart===this.selectionEnd)return;const{copyPasteData:t}=p();t.copiedText=this.getSelectedText(),a.disableStyleCopyPaste?t.copiedTextStyle=void 0:t.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd,!0),this._copyDone=!0}paste(){this.fromPaste=!0}_getWidthBeforeCursor(t,e){let s,i=this._getLineLeftOffset(t);return e>0&&(s=this.__charBounds[t][e-1],i+=s.left+s.width),i}getDownCursorOffset(t,e){const s=this._getSelectionForOffset(t,e),i=this.get2DCursorLocation(s),r=i.lineIndex;if(r===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-s;const n=i.charIndex,o=this._getWidthBeforeCursor(r,n),a=this._getIndexOnLine(r+1,o);return this._textLines[r].slice(n).length+a+1+this.missingNewlineOffset(r)}_getSelectionForOffset(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart}getUpCursorOffset(t,e){const s=this._getSelectionForOffset(t,e),i=this.get2DCursorLocation(s),r=i.lineIndex;if(0===r||t.metaKey||33===t.keyCode)return-s;const n=i.charIndex,o=this._getWidthBeforeCursor(r,n),a=this._getIndexOnLine(r-1,o),h=this._textLines[r].slice(0,n),c=this.missingNewlineOffset(r-1);return-this._textLines[r-1].length+a-h.length+(1-c)}_getIndexOnLine(t,e){const s=this._textLines[t];let i,r,n=this._getLineLeftOffset(t),o=0;for(let a=0,h=s.length;ae){r=!0;const t=n-i,s=n,h=Math.abs(t-e);o=Math.abs(s-e)=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)}moveCursorUp(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)}_moveCursorUpOrDown(t,e){const s=this["get".concat(t,"CursorOffset")](e,this._selectionDirection===A);if(e.shiftKey?this.moveCursorWithShift(s):this.moveCursorWithoutShift(s),0!==s){const t=this.text.length;this.selectionStart=ds(0,this.selectionStart,t),this.selectionEnd=ds(0,this.selectionEnd,t),this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea()}}moveCursorWithShift(t){const e=this._selectionDirection===M?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t}moveCursorWithoutShift(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t}moveCursorLeft(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)}_move(t,e,s){let i;if(t.altKey)i=this["findWordBoundary".concat(s)](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===s?-1:1,!0;i=this["findLineBoundary".concat(s)](this[e])}return void 0!==i&&this[e]!==i&&(this[e]=i,!0)}_moveLeft(t,e){return this._move(t,e,"Left")}_moveRight(t,e){return this._move(t,e,"Right")}moveCursorLeftWithoutShift(t){let e=!0;return this._selectionDirection=M,this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e}moveCursorLeftWithShift(t){return this._selectionDirection===A&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection=M,this._moveLeft(t,"selectionStart")):void 0}moveCursorRight(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)}_moveCursorLeftOrRight(t,e){const s="moveCursor".concat(t).concat(e.shiftKey?"WithShift":"WithoutShift");this._currentCursorOpacity=1,this[s](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())}moveCursorRightWithShift(t){return this._selectionDirection===M&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection=A,this._moveRight(t,"selectionEnd")):void 0}moveCursorRightWithoutShift(t){let e=!0;return this._selectionDirection=A,this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e}}const Oo=t=>!!t.button;class ko extends To{constructor(){super(...arguments),e(this,"draggableTextDelegate",void 0)}initBehavior(){this.on("mousedown",this._mouseDownHandler),this.on("mousedown:before",this._mouseDownHandlerBefore),this.on("mouseup",this.mouseUpHandler),this.on("mousedblclick",this.doubleClickHandler),this.on("tripleclick",this.tripleClickHandler),this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown),this.draggableTextDelegate=new bo(this),super.initBehavior()}shouldStartDragging(){return this.draggableTextDelegate.isActive()}onDragStart(t){return this.draggableTextDelegate.onDragStart(t)}canDrop(t){return this.draggableTextDelegate.canDrop(t)}onMouseDown(t){if(!this.canvas)return;this.__newClickTime=+new Date;const e=t.pointer;this.isTripleClick(e)&&(this.fire("tripleclick",t),pe(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastSelected=this.selected&&!this.getActiveControl()}isTripleClick(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y}doubleClickHandler(t){this.isEditing&&this.selectWord(this.getSelectionStartFromPointer(t.e))}tripleClickHandler(t){this.isEditing&&this.selectLine(this.getSelectionStartFromPointer(t.e))}_mouseDownHandler(t){let{e:e}=t;this.canvas&&this.editable&&!Oo(e)&&!this.getActiveControl()&&(this.draggableTextDelegate.start(e)||(this.canvas.textEditingManager.register(this),this.selected&&(this.inCompositionMode=!1,this.setCursorByClick(e)),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())))}_mouseDownHandlerBefore(t){let{e:e}=t;this.canvas&&this.editable&&!Oo(e)&&(this.selected=this===this.canvas._activeObject)}mouseUpHandler(t){let{e:e,transform:s}=t;const i=this.draggableTextDelegate.end(e);if(this.canvas){this.canvas.textEditingManager.unregister(this);const t=this.canvas._activeObject;if(t&&t!==this)return}!this.editable||this.group&&!this.group.interactive||s&&s.actionPerformed||Oo(e)||i||(this.__lastSelected&&!this.getActiveControl()?(this.selected=!1,this.__lastSelected=!1,this.enterEditing(e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()):this.selected=!0)}setCursorByClick(t){const e=this.getSelectionStartFromPointer(t),s=this.selectionStart,i=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(s,i,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())}getSelectionStartFromPointer(t){const e=this.canvas.getScenePoint(t).transform(bt(this.calcTransformMatrix())).add(new ot(-this._getLeftOffset(),-this._getTopOffset()));let s=0,i=0,r=0;for(let t=0;t0&&(i+=this._textLines[t-1].length+this.missingNewlineOffset(t-1));let n=Math.abs(this._getLineLeftOffset(r));const o=this._textLines[r].length,a=this.__charBounds[r];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:this.selectionStart||0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selectionEnd,s=arguments.length>2?arguments[2]:void 0;return super.getSelectionStyles(t,e,s)}setSelectionStyles(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selectionStart||0,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.selectionEnd;return super.setSelectionStyles(t,e,s)}get2DCursorLocation(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectionStart,e=arguments.length>1?arguments[1]:void 0;return super.get2DCursorLocation(t,e)}render(t){super.render(t),this.cursorOffsetCache={},this.renderCursorOrSelection()}toCanvasElement(t){const e=this.isEditing;this.isEditing=!1;const s=super.toCanvasElement(t);return this.isEditing=e,s}renderCursorOrSelection(){if(!this.isEditing)return;const t=this.clearContextTop(!0);if(!t)return;const e=this._getCursorBoundaries();this.selectionStart===this.selectionEnd?this.renderCursor(t,e):this.renderSelection(t,e),this.canvas.contextTopDirty=!0,t.restore()}_getCursorBoundaries(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectionStart,e=arguments.length>1?arguments[1]:void 0;const s=this._getLeftOffset(),i=this._getTopOffset(),r=this._getCursorBoundariesOffsets(t,e);return{left:s,top:i,leftOffset:r.left,topOffset:r.top}}_getCursorBoundariesOffsets(t,e){return e?this.__getCursorBoundariesOffsets(t):this.cursorOffsetCache&&"top"in this.cursorOffsetCache?this.cursorOffsetCache:this.cursorOffsetCache=this.__getCursorBoundariesOffsets(t)}__getCursorBoundariesOffsets(t){let e=0,s=0;const{charIndex:i,lineIndex:r}=this.get2DCursorLocation(t);for(let t=0;t0?s:0)};return"rtl"===this.direction&&(this.textAlign===A||this.textAlign===lo||this.textAlign===go?a.left*=-1:this.textAlign===M||this.textAlign===uo?a.left=n-(s>0?s:0):this.textAlign!==D&&this.textAlign!==fo||(a.left=n-(s>0?s:0))),a}renderCursorAt(t){const e=this._getCursorBoundaries(t,!0);this._renderCursor(this.canvas.contextTop,e,t)}renderCursor(t,e){this._renderCursor(t,e,this.selectionStart)}_renderCursor(t,e,s){const i=this.get2DCursorLocation(s),r=i.lineIndex,n=i.charIndex>0?i.charIndex-1:0,o=this.getValueOfPropertyAt(r,n,"fontSize"),a=this.getObjectScaling().x*this.canvas.getZoom(),h=this.cursorWidth/a,c=this.getValueOfPropertyAt(r,n,"deltaY"),l=e.topOffset+(1-this._fontSizeFraction)*this.getHeightOfLine(r)/this.lineHeight-o*(1-this._fontSizeFraction);this.inCompositionMode&&this.renderSelection(t,e),t.fillStyle=this.cursorColor||this.getValueOfPropertyAt(r,n,K),t.globalAlpha=this._currentCursorOpacity,t.fillRect(e.left+e.leftOffset-h/2,l+e.top+c,h,o)}renderSelection(t,e){const s={selectionStart:this.inCompositionMode?this.hiddenTextarea.selectionStart:this.selectionStart,selectionEnd:this.inCompositionMode?this.hiddenTextarea.selectionEnd:this.selectionEnd};this._renderSelection(t,s,e)}renderDragSourceEffect(){const t=this.draggableTextDelegate.getDragStartSelection();this._renderSelection(this.canvas.contextTop,t,this._getCursorBoundaries(t.selectionStart,!0))}renderDropTargetEffect(t){const e=this.getSelectionStartFromPointer(t);this.renderCursorAt(e)}_renderSelection(t,e,s){const i=e.selectionStart,r=e.selectionEnd,n=this.textAlign.includes(lo),o=this.get2DCursorLocation(i),a=this.get2DCursorLocation(r),h=o.lineIndex,c=a.lineIndex,l=o.charIndex<0?0:o.charIndex,u=a.charIndex<0?0:a.charIndex;for(let e=h;e<=c;e++){const i=this._getLineLeftOffset(e)||0;let r=this.getHeightOfLine(e),o=0,a=0,d=0;if(e===h&&(a=this.__charBounds[h][l].left),e>=h&&e1)&&(r/=this.lineHeight);let g=s.left+i+a,f=r,p=0;const m=d-a;this.inCompositionMode?(t.fillStyle=this.compositionColor||"black",f=1,p=r):t.fillStyle=this.selectionColor,"rtl"===this.direction&&(this.textAlign===A||this.textAlign===lo||this.textAlign===go?g=this.width-g-m:this.textAlign===M||this.textAlign===uo?g=s.left+i-d:this.textAlign!==D&&this.textAlign!==fo||(g=s.left+i-d)),t.fillRect(g,s.top+s.topOffset+p,m,f),s.topOffset+=o}}getCurrentCharFontSize(){const t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fontSize")}getCurrentCharColor(){const t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,K)}_getCurrentCharIndex(){const t=this.get2DCursorLocation(this.selectionStart,!0),e=t.charIndex>0?t.charIndex-1:0;return{l:t.lineIndex,c:e}}dispose(){this._exitEditing(),this.draggableTextDelegate.dispose(),super.dispose()}}e(Fo,"ownDefaults",jo),e(Fo,"type","IText"),tt.setClass(Fo),tt.setClass(Fo,"i-text");class Lo extends Fo{static getDefaults(){return i(i({},super.getDefaults()),Lo.ownDefaults)}constructor(t,e){super(t,i(i({},Lo.ownDefaults),e))}static createControls(){return{controls:pi()}}initDimensions(){this.initialized&&(this.isEditing&&this.initDelayedCursor(),this._clearCache(),this.dynamicMinWidth=0,this._styleMap=this._generateStyleMap(this._splitText()),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this.textAlign.includes(lo)&&this.enlargeSpaces(),this.height=this.calcTextHeight())}_generateStyleMap(t){let e=0,s=0,i=0;const r={};for(let n=0;n0?(s=0,i++,e++):!this.splitByGrapheme&&this._reSpaceAndTab.test(t.graphemeText[i])&&n>0&&(s++,i++),r[n]={line:e,offset:s},i+=t.graphemeLines[n].length,s+=t.graphemeLines[n].length;return r}styleHas(t,e){if(this._styleMap&&!this.isWrapping){const t=this._styleMap[e];t&&(e=t.line)}return super.styleHas(t,e)}isEmptyStyles(t){if(!this.styles)return!0;let e,s=0,i=t+1,r=!1;const n=this._styleMap[t],o=this._styleMap[t+1];n&&(t=n.line,s=n.offset),o&&(i=o.line,r=i===t,e=o.offset);const a=void 0===t?this.styles:{line:this.styles[t]};for(const t in a)for(const i in a[t]){const n=parseInt(i,10);if(n>=s&&(!r||n{let n=0;const o=e?this.graphemeSplit(t):this.wordSplit(t);return 0===o.length?[{word:[],width:0}]:o.map((t=>{const o=e?[t]:this.graphemeSplit(t),a=this._measureWord(o,r,n);return i=Math.max(a,i),n+=o.length+s.length,{word:o,width:a}}))})),largestWordWidth:i}}_measureWord(t,e){let s,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=0;for(let n=0,o=t.length;n3&&void 0!==arguments[3]?arguments[3]:0;const o=this._getWidthOfCharSpacing(),a=this.splitByGrapheme,h=[],c=a?"":" ";let l=0,u=[],d=0,g=0,f=!0;e-=n;const p=Math.max(e,i,this.dynamicMinWidth),m=r[t];let v;for(d=0,v=0;vp&&!f?(h.push(u),u=[],l=s,f=!0):l+=o,f||a||u.push(c),u=u.concat(e),g=a?0:this._measureWord([c],t,d),d++,f=!1}return v&&h.push(u),i+n>this.dynamicMinWidth&&(this.dynamicMinWidth=i-o+n),h}isEndOfWrapping(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line}missingNewlineOffset(t,e){return this.splitByGrapheme&&!e?this.isEndOfWrapping(t)?1:0:1}_splitTextIntoLines(t){const e=super._splitTextIntoLines(t),s=this._wrapText(e.lines,this.width),i=new Array(s.length);for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject(["minWidth","splitByGrapheme",...t])}}e(Lo,"type","Textbox"),e(Lo,"textLayoutProperties",[...Fo.textLayoutProperties,"width"]),e(Lo,"ownDefaults",{minWidth:20,dynamicMinWidth:2,lockScalingFlip:!0,noScaleCache:!1,_wordJoiners:/[ \t\r]/,splitByGrapheme:!1}),tt.setClass(Lo);class Ro extends xr{shouldPerformLayout(t){return!!t.target.clipPath&&super.shouldPerformLayout(t)}shouldLayoutClipPath(){return!1}calcLayoutResult(t,e){const{target:s}=t,{clipPath:i,group:r}=s;if(!i||!this.shouldPerformLayout(t))return;const{width:n,height:o}=me(_r(s,i)),a=new ot(n,o);if(i.absolutePositioned){return{center:we(i.getRelativeCenterPoint(),void 0,r?r.calcTransformMatrix():void 0),size:a}}{const r=i.getRelativeCenterPoint().transform(s.calcOwnMatrix(),!0);if(this.shouldPerformLayout(t)){const{center:s=new ot,correction:i=new ot}=this.calcBoundingBox(e,t)||{};return{center:s.add(r),correction:i.subtract(r),size:a}}return{center:s.getRelativeCenterPoint().add(r),size:a}}}}e(Ro,"type","clip-path"),tt.setClass(Ro);class Io extends xr{getInitialSize(t,e){let{target:s}=t,{size:i}=e;return new ot(s.width||i.x,s.height||i.y)}}e(Io,"type","fixed"),tt.setClass(Io);class Bo extends Tr{subscribeTargets(t){const e=t.target;t.targets.reduce(((t,e)=>(e.parent&&t.add(e.parent),t)),new Set).forEach((t=>{t.layoutManager.subscribeTargets({target:t,targets:[e]})}))}unsubscribeTargets(t){const e=t.target,s=e.getObjects();t.targets.reduce(((t,e)=>(e.parent&&t.add(e.parent),t)),new Set).forEach((t=>{!s.some((e=>e.parent===t))&&t.layoutManager.unsubscribeTargets({target:t,targets:[e]})}))}}class Xo extends Dr{static getDefaults(){return i(i({},super.getDefaults()),Xo.ownDefaults)}constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,Xo.ownDefaults),this.setOptions(e);const{left:s,top:i,layoutManager:r}=e;this.groupInit(t,{left:s,top:i,layoutManager:null!=r?r:new Bo})}_shouldSetNestedCoords(){return!0}__objectSelectionMonitor(){}multiSelectAdd(){for(var t=arguments.length,e=new Array(t),s=0;s{const e=this._objects.findIndex((e=>e.isInFrontOf(t))),s=-1===e?this.size():e;this.insertAt(s,t)}))}canEnterGroup(t){return this.getObjects().some((e=>e.isDescendantOf(t)||t.isDescendantOf(e)))?(h("error","ActiveSelection: circular object trees are not supported, this call has no effect"),!1):super.canEnterGroup(t)}enterGroup(t,e){t.parent&&t.parent===t.group?t.parent._exitGroup(t):t.group&&t.parent!==t.group&&t.group.remove(t),this._enterGroup(t,e)}exitGroup(t,e){this._exitGroup(t,e),t.parent&&t.parent._enterGroup(t,!0)}_onAfterObjectsChange(t,e){super._onAfterObjectsChange(t,e);const s=new Set;e.forEach((t=>{const{parent:e}=t;e&&s.add(e)})),t===vr?s.forEach((t=>{t._onAfterObjectsChange(mr,e)})):s.forEach((t=>{t._set("dirty",!0)}))}onDeselect(){return this.removeAll(),!1}toString(){return"#")}shouldCache(){return!1}isOnACache(){return!1}_renderControls(t,e,s){t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1;const r=i(i({hasControls:!1},s),{},{forActiveSelection:!0});for(let e=0;e{t.applyTo(o)}));const{imageData:a}=o;return a.width===s&&a.height===i||(r.width=a.width,r.height=a.height),n.putImageData(a,0,0),o}}class Yo{constructor(){let{tileSize:t=a.textureSize}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};e(this,"aPosition",new Float32Array([0,0,0,1,1,0,1,1])),e(this,"resources",{}),this.tileSize=t,this.setupGLContext(t,t),this.captureGPUInfo()}setupGLContext(t,e){this.dispose(),this.createWebGLCanvas(t,e)}createWebGLCanvas(t,e){const s=pt();s.width=t,s.height=e;const i=s.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,depth:!1,stencil:!1,antialias:!1});i&&(i.clearColor(0,0,0,0),this.canvas=s,this.gl=i)}applyFilters(t,e,s,i,r,n){const o=this.gl,a=r.getContext("2d");if(!o||!a)return;let h;n&&(h=this.getCachedTexture(n,e));const c={originalWidth:e.width||e.originalWidth||0,originalHeight:e.height||e.originalHeight||0,sourceWidth:s,sourceHeight:i,destinationWidth:s,destinationHeight:i,context:o,sourceTexture:this.createTexture(o,s,i,h?void 0:e),targetTexture:this.createTexture(o,s,i),originalTexture:h||this.createTexture(o,s,i,h?void 0:e),passes:t.length,webgl:!0,aPosition:this.aPosition,programCache:this.programCache,pass:0,filterBackend:this,targetCanvas:r},l=o.createFramebuffer();return o.bindFramebuffer(o.FRAMEBUFFER,l),t.forEach((t=>{t&&t.applyTo(c)})),function(t){const e=t.targetCanvas,s=e.width,i=e.height,r=t.destinationWidth,n=t.destinationHeight;s===r&&i===n||(e.width=r,e.height=n)}(c),this.copyGLTo2D(o,c),o.bindTexture(o.TEXTURE_2D,null),o.deleteTexture(c.sourceTexture),o.deleteTexture(c.targetTexture),o.deleteFramebuffer(l),a.setTransform(1,0,0,1,0,0),c}dispose(){this.canvas&&(this.canvas=null,this.gl=null),this.clearWebGLCaches()}clearWebGLCaches(){this.programCache={},this.textureCache={}}createTexture(t,e,s,i,r){const{NEAREST:n,TEXTURE_2D:o,RGBA:a,UNSIGNED_BYTE:h,CLAMP_TO_EDGE:c,TEXTURE_MAG_FILTER:l,TEXTURE_MIN_FILTER:u,TEXTURE_WRAP_S:d,TEXTURE_WRAP_T:g}=t,f=t.createTexture();return t.bindTexture(o,f),t.texParameteri(o,l,r||n),t.texParameteri(o,u,r||n),t.texParameteri(o,d,c),t.texParameteri(o,g,c),i?t.texImage2D(o,0,a,a,h,i):t.texImage2D(o,0,a,e,s,0,a,h,null),f}getCachedTexture(t,e,s){const{textureCache:i}=this;if(i[t])return i[t];{const r=this.createTexture(this.gl,e.width,e.height,e,s);return r&&(i[t]=r),r}}evictCachesForKey(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])}copyGLTo2D(t,e){const s=t.canvas,i=e.targetCanvas,r=i.getContext("2d");if(!r)return;r.translate(0,i.height),r.scale(1,-1);const n=s.height-i.height;r.drawImage(s,0,n,i.width,i.height,0,0,i.width,i.height)}copyGLTo2DPutImageData(t,e){const s=e.targetCanvas.getContext("2d"),i=e.destinationWidth,r=e.destinationHeight,n=i*r*4;if(!s)return;const o=new Uint8Array(this.imageBuffer,0,n),a=new Uint8ClampedArray(this.imageBuffer,0,n);t.readPixels(0,0,i,r,t.RGBA,t.UNSIGNED_BYTE,o);const h=new ImageData(a,i,r);s.putImageData(h,0,0)}captureGPUInfo(){if(this.gpuInfo)return this.gpuInfo;const t=this.gl,e={renderer:"",vendor:""};if(!t)return e;const s=t.getExtension("WEBGL_debug_renderer_info");if(s){const i=t.getParameter(s.UNMASKED_RENDERER_WEBGL),r=t.getParameter(s.UNMASKED_VENDOR_WEBGL);i&&(e.renderer=i.toLowerCase()),r&&(e.vendor=r.toLowerCase())}return this.gpuInfo=e,e}}let Vo;function Go(){const{WebGLProbe:t}=p();return t.queryWebGL(pt()),a.enableGLFiltering&&t.isSupported(a.textureSize)?new Yo({tileSize:a.textureSize}):new Wo}function Ho(){return!Vo&&(!(arguments.length>0&&void 0!==arguments[0])||arguments[0])&&(Vo=Go()),Vo}const zo=["filters","resizeFilter","src","crossOrigin","type"],No=["cropX","cropY"];class Uo extends yi{static getDefaults(){return i(i({},super.getDefaults()),Uo.ownDefaults)}constructor(t,s){super(),e(this,"_lastScaleX",1),e(this,"_lastScaleY",1),e(this,"_filterScalingX",1),e(this,"_filterScalingY",1),this.filters=[],Object.assign(this,Uo.ownDefaults),this.setOptions(s),this.cacheKey="texture".concat(ft()),this.setElement("string"==typeof t?(this.canvas&&re(this.canvas.getElement())||m()).getElementById(t):t,s)}getElement(){return this._element}setElement(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.removeTexture(this.cacheKey),this.removeTexture("".concat(this.cacheKey,"_filtered")),this._element=t,this._originalElement=t,this._setWidthHeight(e),t.classList.add(Uo.CSS_CANVAS),0!==this.filters.length&&this.applyFilters(),this.resizeFilter&&this.applyResizeFilters()}removeTexture(t){const e=Ho(!1);e instanceof Yo&&e.evictCachesForKey(t)}dispose(){super.dispose(),this.removeTexture(this.cacheKey),this.removeTexture("".concat(this.cacheKey,"_filtered")),this._cacheContext=null,["_originalElement","_element","_filteredEl","_cacheCanvas"].forEach((t=>{const e=this[t];e&&p().dispose(e),this[t]=void 0}))}getCrossOrigin(){return this._originalElement&&(this._originalElement.crossOrigin||null)}getOriginalSize(){const t=this.getElement();return t?{width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}:{width:0,height:0}}_stroke(t){if(!this.stroke||0===this.strokeWidth)return;const e=this.width/2,s=this.height/2;t.beginPath(),t.moveTo(-e,-s),t.lineTo(e,-s),t.lineTo(e,s),t.lineTo(-e,s),t.lineTo(-e,-s),t.closePath()}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=[];return this.filters.forEach((t=>{t&&e.push(t.toObject())})),i(i({},super.toObject([...No,...t])),{},{src:this.getSrc(),crossOrigin:this.getCrossOrigin(),filters:e},this.resizeFilter?{resizeFilter:this.resizeFilter.toObject()}:{})}hasCrop(){return!!this.cropX||!!this.cropY||this.width\n','\t\n',"\n"),o=' clip-path="url(#imageCrop_'+t+')" '}if(this.imageSmoothing||(a=' image-rendering="optimizeSpeed"'),t.push("\t\n")),this.stroke||this.strokeDashArray){const t=this.fill;this.fill=null,n=['\t\n')],this.fill=t}return r=this.paintFirst!==K?r.concat(n,t):r.concat(t,n),r}getSrc(t){const e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():this.srcFromAttribute?e.getAttribute("src")||"":e.src:this.src||""}getSvgSrc(t){return this.getSrc(t)}setSrc(t){let{crossOrigin:e,signal:s}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Lt(t,{crossOrigin:e,signal:s}).then((t=>{void 0!==e&&this.set({crossOrigin:e}),this.setElement(t)}))}toString(){return'#')}applyResizeFilters(){const t=this.resizeFilter,e=this.minimumScaleTrigger,s=this.getTotalObjectScaling(),i=s.x,r=s.y,n=this._filteredEl||this._originalElement;if(this.group&&this.set("dirty",!0),!t||i>e&&r>e)return this._element=n,this._filterScalingX=1,this._filterScalingY=1,this._lastScaleX=i,void(this._lastScaleY=r);const o=pt(),a=n.width,h=n.height;o.width=a,o.height=h,this._element=o,this._lastScaleX=t.scaleX=i,this._lastScaleY=t.scaleY=r,Ho().applyFilters([t],n,a,h,this._element),this._filterScalingX=o.width/this._originalElement.width,this._filterScalingY=o.height/this._originalElement.height}applyFilters(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.filters||[];if(t=t.filter((t=>t&&!t.isNeutralState())),this.set("dirty",!0),this.removeTexture("".concat(this.cacheKey,"_filtered")),0===t.length)return this._element=this._originalElement,this._filteredEl=void 0,this._filterScalingX=1,void(this._filterScalingY=1);const e=this._originalElement,s=e.naturalWidth||e.width,i=e.naturalHeight||e.height;if(this._element===this._originalElement){const t=pt();t.width=s,t.height=i,this._element=t,this._filteredEl=t}else this._filteredEl&&(this._element=this._filteredEl,this._filteredEl.getContext("2d").clearRect(0,0,s,i),this._lastScaleX=1,this._lastScaleY=1);Ho().applyFilters(t,this._originalElement,s,i,this._element),this._originalElement.width===this._element.width&&this._originalElement.height===this._element.height||(this._filterScalingX=this._element.width/this._originalElement.width,this._filterScalingY=this._element.height/this._originalElement.height)}_render(t){t.imageSmoothingEnabled=this.imageSmoothing,!0!==this.isMoving&&this.resizeFilter&&this._needsResize()&&this.applyResizeFilters(),this._stroke(t),this._renderPaintInOrder(t)}drawCacheOnCanvas(t){t.imageSmoothingEnabled=this.imageSmoothing,super.drawCacheOnCanvas(t)}shouldCache(){return this.needsItsOwnCache()}_renderFill(t){const e=this._element;if(!e)return;const s=this._filterScalingX,i=this._filterScalingY,r=this.width,n=this.height,o=Math.max(this.cropX,0),a=Math.max(this.cropY,0),h=e.naturalWidth||e.width,c=e.naturalHeight||e.height,l=o*s,u=a*i,d=Math.min(r*s,h-l),g=Math.min(n*i,c-u),f=-r/2,p=-n/2,m=Math.min(r,h/s-o),v=Math.min(n,c/i-a);e&&t.drawImage(e,l,u,d,g,f,p,m,v)}_needsResize(){const t=this.getTotalObjectScaling();return t.x!==this._lastScaleX||t.y!==this._lastScaleY}_resetWidthHeight(){this.set(this.getOriginalSize())}_setWidthHeight(){let{width:t,height:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const s=this.getOriginalSize();this.width=t||s.width,this.height=e||s.height}parsePreserveAspectRatioAttribute(){const t=Kt(this.preserveAspectRatio||""),e=this.width,s=this.height,i={width:e,height:s};let r,n=this._element.width,o=this._element.height,a=1,h=1,c=0,l=0,u=0,d=0;return!t||t.alignX===j&&t.alignY===j?(a=e/n,h=s/o):("meet"===t.meetOrSlice&&(a=h=Mr(this._element,i),r=(e-n*a)/2,"Min"===t.alignX&&(c=-r),"Max"===t.alignX&&(c=r),r=(s-o*h)/2,"Min"===t.alignY&&(l=-r),"Max"===t.alignY&&(l=r)),"slice"===t.meetOrSlice&&(a=h=Pr(this._element,i),r=n-e/a,"Mid"===t.alignX&&(u=r/2),"Max"===t.alignX&&(u=r),r=o-s/h,"Mid"===t.alignY&&(d=r/2),"Max"===t.alignY&&(d=r),n=e/a,o=s/h)),{width:n,height:o,scaleX:a,scaleY:h,offsetLeft:c,offsetTop:l,cropX:u,cropY:d}}static fromObject(t,e){let{filters:s,resizeFilter:n,src:o,crossOrigin:a,type:h}=t,c=r(t,zo);return Promise.all([Lt(o,i(i({},e),{},{crossOrigin:a})),s&&Rt(s,e),n&&Rt([n],e),It(c,e)]).then((t=>{let[e,s=[],[r]=[],n={}]=t;return new this(e,i(i({},c),{},{src:o,filters:s,resizeFilter:r},n))}))}static fromURL(t){let{crossOrigin:e=null,signal:s}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2?arguments[2]:void 0;return Lt(t,{crossOrigin:e,signal:s}).then((t=>new this(t,i)))}static async fromElement(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=arguments.length>2?arguments[2]:void 0;const i=ur(t,this.ATTRIBUTE_NAMES,s);return this.fromURL(i["xlink:href"],e,i).catch((t=>(h("log","Unable to parse Image",t),null)))}}function qo(t){if(!qe.test(t.nodeName))return{};const e=t.getAttribute("viewBox");let s,i,r=1,n=1,o=0,a=0;const h=t.getAttribute("width"),c=t.getAttribute("height"),l=t.getAttribute("x")||0,u=t.getAttribute("y")||0,d=!(e&&Je.test(e)),g=!h||!c||"100%"===h||"100%"===c;let f="",p=0,m=0;if(d&&(l||u)&&t.parentNode&&"#document"!==t.parentNode.nodeName&&(f=" translate("+qt(l||"0")+" "+qt(u||"0")+") ",s=(t.getAttribute("transform")||"")+f,t.setAttribute("transform",s),t.removeAttribute("x"),t.removeAttribute("y")),d&&g)return{width:0,height:0};const v={width:0,height:0};if(d)return v.width=qt(h),v.height=qt(c),v;const y=e.match(Je);o=-parseFloat(y[1]),a=-parseFloat(y[2]);const _=parseFloat(y[3]),x=parseFloat(y[4]);v.minX=o,v.minY=a,v.viewBoxWidth=_,v.viewBoxHeight=x,g?(v.width=_,v.height=x):(v.width=qt(h),v.height=qt(c),r=v.width/_,n=v.height/x);const C=Kt(t.getAttribute("preserveAspectRatio")||"");if(C.alignX!==j&&("meet"===C.meetOrSlice&&(n=r=r>n?n:r),"slice"===C.meetOrSlice&&(n=r=r>n?r:n),p=v.width-_*r,m=v.height-x*r,"Mid"===C.alignX&&(p/=2),"Mid"===C.alignY&&(m/=2),"Min"===C.alignX&&(p=0),"Min"===C.alignY&&(m=0)),1===r&&1===n&&0===o&&0===a&&0===l&&0===u)return v;if((l||u)&&"#document"!==t.parentNode.nodeName&&(f=" translate("+qt(l||"0")+" "+qt(u||"0")+") "),s=f+" matrix("+r+" 0 0 "+n+" "+(o*r+p)+" "+(a*n+m)+") ","svg"===t.nodeName){for(i=t.ownerDocument.createElementNS(Ve,"g");t.firstChild;)i.appendChild(t.firstChild);t.appendChild(i)}else i=t,i.removeAttribute("x"),i.removeAttribute("y"),s=i.getAttribute("transform")+s;return i.setAttribute("transform",s),v}e(Uo,"type","Image"),e(Uo,"cacheProperties",[...fs,...No]),e(Uo,"ownDefaults",{strokeWidth:0,srcFromAttribute:!1,minimumScaleTrigger:.5,cropX:0,cropY:0,imageSmoothing:!0}),e(Uo,"CSS_CANVAS","canvas-img"),e(Uo,"ATTRIBUTE_NAMES",[...ji,"x","y","width","height","preserveAspectRatio","xlink:href","crossOrigin","image-rendering"]),tt.setClass(Uo),tt.setSVGClass(Uo);const Ko=t=>t.tagName.replace("svg:",""),Jo=Xe(["pattern","defs","symbol","metadata","clipPath","mask","desc"]);function Qo(t,e){let s,i,r,n,o=[];for(r=0,n=e.length;r{const s=r.getAttribute(t);!e.hasAttribute(t)&&s&&e.setAttribute(t,s)})),!e.children.length)){const t=r.cloneNode(!0);for(;t.firstChild;)e.appendChild(t.firstChild)}e.removeAttribute($o)}const ea=["linearGradient","radialGradient","svg:linearGradient","svg:radialGradient"];function sa(t){const e=t.getElementsByTagName("style");let s,r;const n={};for(s=0,r=e.length;ss.length>1&&t.trim())).forEach((t=>{if((t.match(/{/g)||[]).length>1&&t.trim().startsWith("@"))return;const e=t.split("{"),o={},a=e[1].trim().split(";").filter((function(t){return t.trim()}));for(s=0,r=a.length;s{""!==(t=t.replace(/^svg/i,"").trim())&&(n[t]=i(i({},n[t]||{}),o))}))}))}return n}const ia=t=>tt.getSVGClass(Ko(t).toLowerCase());class ra{constructor(t,e,s,i,r){this.elements=t,this.options=e,this.reviver=s,this.regexUrl=/^url\(['"]?#([^'"]+)['"]?\)/g,this.doc=i,this.clipPaths=r,this.gradientDefs=function(t){const e=Qo(t,ea),s={};let i=e.length;for(;i--;){const r=e[i];r.getAttribute("xlink:href")&&ta(t,r);const n=r.getAttribute("id");n&&(s[n]=r)}return s}(i),this.cssRules=sa(i)}parse(){return Promise.all(this.elements.map((t=>this.createObject(t))))}async createObject(t){const e=ia(t);if(e){const s=await e.fromElement(t,this.options,this.cssRules);return this.resolveGradient(s,t,K),this.resolveGradient(s,t,J),s instanceof Uo&&s._originalElement?cn(s,s.parsePreserveAspectRatioAttribute()):cn(s),await this.resolveClipPath(s,t),this.reviver&&this.reviver(t,s),s}return null}extractPropertyDefinition(t,e,s){const i=t[e],r=this.regexUrl;if(!r.test(i))return;r.lastIndex=0;const n=r.exec(i)[1];return r.lastIndex=0,s[n]}resolveGradient(t,e,s){const r=this.extractPropertyDefinition(t,s,this.gradientDefs);if(r){const n=e.getAttribute(s+"-opacity"),o=Ln.fromElement(r,t,i(i({},this.options),{},{opacity:n}));t.set(s,o)}}async resolveClipPath(t,e){const s=this.extractPropertyDefinition(t,"clipPath",this.clipPaths);if(s){const i=bt(t.calcTransformMatrix()),r=s[0].parentElement;let n=e;for(;n.parentElement&&n.getAttribute("clip-path")!==t.clipPath;)n=n.parentElement;n.parentElement.appendChild(r);const o=nr("".concat(n.getAttribute("transform")||""," ").concat(r.getAttribute("originalTransform")||""));r.setAttribute("transform","matrix(".concat(o.join(","),")"));const a=await Promise.all(s.map((t=>ia(t).fromElement(t,this.options,this.cssRules).then((t=>(cn(t),t.fillRule=t.clipRule,delete t.clipRule,t)))))),h=1===a.length?a[0]:new Dr(a),c=St(i,h.calcTransformMatrix());h.clipPath&&await this.resolveClipPath(h,n);const{scaleX:l,scaleY:u,angle:d,skewX:g,translateX:f,translateY:p}=Ot(c);h.set({flipX:!1,flipY:!1}),h.set({scaleX:l,scaleY:u,angle:d,skewX:g,skewY:0}),h.setPositionByOrigin(new ot(f,p),D,D),t.clipPath=h}else delete t.clipPath}}const na=t=>Ue.test(Ko(t)),oa=()=>({objects:[],elements:[],options:{},allElements:[]});async function aa(t,e){let{crossOrigin:s,signal:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(r&&r.aborted)return h("log",new l("parseSVGDocument")),oa();const n=t.documentElement;!function(t){const e=Qo(t,["use","svg:use"]),s=["x","y","xlink:href","href","transform"];for(const i of e){const e=i.attributes,r={};for(const t of e)t.value&&(r[t.name]=t.value);const n=(r["xlink:href"]||r.href||"").slice(1);if(""===n)return;const o=t.getElementById(n);if(null===o)return;let a=o.cloneNode(!0);const h=a.attributes,c={};for(const t of h)t.value&&(c[t.name]=t.value);const{x:l=0,y:u=0,transform:d=""}=r,g="".concat(d," ").concat(c.transform||""," translate(").concat(l,", ").concat(u,")");if(qo(a),/^svg$/i.test(a.nodeName)){const t=a.ownerDocument.createElementNS(Ve,"g");Object.entries(c).forEach((e=>{let[s,i]=e;return t.setAttributeNS(Ve,s,i)})),t.append(...a.childNodes),a=t}for(const t of e){if(!t)continue;const{name:e,value:i}=t;if(!s.includes(e))if("style"===e){const t={};hr(i,t),Object.entries(c).forEach((e=>{let[s,i]=e;t[s]=i})),hr(c.style||"",t);const s=Object.entries(t).map((t=>t.join(":"))).join(";");a.setAttribute(e,s)}else!c[e]&&a.setAttribute(e,i)}a.setAttribute("transform",g),a.setAttribute("instantiated_by_use","1"),a.removeAttribute("id"),i.parentNode.replaceChild(a,i)}}(t);const o=Array.from(n.getElementsByTagName("*")),a=i(i({},qo(n)),{},{crossOrigin:s,signal:r}),c=o.filter((t=>(qo(t),na(t)&&!function(t){let e=t;for(;e&&(e=e.parentElement);)if(e&&e.nodeName&&Jo.test(Ko(e))&&!e.getAttribute("instantiated_by_use"))return!0;return!1}(t))));if(!c||c&&!c.length)return i(i({},oa()),{},{options:a,allElements:o});const u={};o.filter((t=>"clipPath"===Ko(t))).forEach((t=>{t.setAttribute("originalTransform",t.getAttribute("transform")||"");const e=t.getAttribute("id");u[e]=Array.from(t.getElementsByTagName("*")).filter((t=>na(t)))}));const d=new ra(c,a,e,t,u);return{objects:await d.parse(),elements:c,options:a,allElements:o}}const ha=Y,ca=t=>function(e,s,i){const{points:r,pathOffset:n}=i;return new ot(r[t]).subtract(n).transform(St(i.getViewportTransform(),i.calcTransformMatrix()))},la=(t,e,s,i)=>{const{target:r,pointIndex:n}=e,o=r,a=we(new ot(s,i),void 0,o.calcOwnMatrix());return o.points[n]=a.add(o.pathOffset),o.setDimensions(),!0},ua=(t,e)=>function(s,r,n,o){const a=r.target,h=new ot(a.points[(t>0?t:a.points.length)-1]),c=h.subtract(a.pathOffset).transform(a.calcOwnMatrix()),l=e(s,i(i({},r),{},{pointIndex:t}),n,o),u=h.subtract(a.pathOffset).transform(a.calcOwnMatrix()).subtract(c);return a.left-=u.x,a.top-=u.y,l},da=t=>Xs(ha,ua(t,la));const ga=(t,e,s)=>{const{path:i,pathOffset:r}=t,n=i[e];return new ot(n[s]-r.x,n[s+1]-r.y).transform(St(t.getViewportTransform(),t.calcTransformMatrix()))};function fa(t,e,s){const{commandIndex:i,pointIndex:r}=this;return ga(s,i,r)}function pa(t,e,s,r){const{target:n}=e,{commandIndex:o,pointIndex:a}=this,h=((t,e,s,i,r)=>{const{path:n,pathOffset:o}=t,a=n[(i>0?i:n.length)-1],h=new ot(a[r],a[r+1]),c=h.subtract(o).transform(t.calcOwnMatrix()),l=we(new ot(e,s),void 0,t.calcOwnMatrix());n[i][r]=l.x+o.x,n[i][r+1]=l.y+o.y,t.setDimensions();const u=h.subtract(t.pathOffset).transform(t.calcOwnMatrix()).subtract(c);return t.left-=u.x,t.top-=u.y,t.set("dirty",!0),!0})(n,s,r,o,a);return ke(this.actionName,i(i({},Fe(t,e,s,r)),{},{commandIndex:o,pointIndex:a})),h}class ma extends Hs{constructor(t){super(t)}render(t,e,s,r,n){const o=i(i({},r),{},{cornerColor:this.controlFill,cornerStrokeColor:this.controlStroke,transparentCorners:!this.controlFill});super.render(t,e,s,o,n)}}class va extends ma{constructor(t){super(t)}render(t,e,s,i,r){const{path:n}=r,{commandIndex:o,pointIndex:a,connectToCommandIndex:h,connectToPointIndex:c}=this;t.save(),t.strokeStyle=this.controlStroke,this.connectionDashArray&&t.setLineDash(this.connectionDashArray);const[l]=n[o],u=ga(r,h,c);if("Q"===l){const i=ga(r,o,a+2);t.moveTo(i.x,i.y),t.lineTo(e,s)}else t.moveTo(e,s);t.lineTo(u.x,u.y),t.stroke(),t.restore(),super.render(t,e,s,i,r)}}const ya=(t,e,s,r,n,o)=>new(s?va:ma)(i(i({commandIndex:t,pointIndex:e,actionName:"modifyPath",positionHandler:fa,actionHandler:pa,connectToCommandIndex:n,connectToPointIndex:o},r),s?r.controlPointStyle:r.pointStyle));var _a=Object.freeze({__proto__:null,changeWidth:Ys,createObjectDefaultControls:gi,createPathControls:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s={};let i="M";return t.path.forEach(((t,r)=>{const n=t[0];switch("Z"!==n&&(s["c_".concat(r,"_").concat(n)]=ya(r,t.length-2,!1,e)),n){case"C":s["c_".concat(r,"_C_CP_1")]=ya(r,1,!0,e,r-1,(t=>"C"===t?5:"Q"===t?3:1)(i)),s["c_".concat(r,"_C_CP_2")]=ya(r,3,!0,e,r,5);break;case"Q":s["c_".concat(r,"_Q_CP_1")]=ya(r,1,!0,e,r,3)}i=n})),s},createPolyActionHandler:da,createPolyControls:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s={};for(let r=0;r<("number"==typeof t?t:t.points.length);r++)s["p".concat(r)]=new Hs(i({actionName:ha,positionHandler:ca(r),actionHandler:da(r)},e));return s},createPolyPositionHandler:ca,createResizeControls:fi,createTextboxDefaultControls:pi,dragHandler:Ie,factoryPolyActionHandler:ua,getLocalPoint:Re,polyActionHandler:la,renderCircleControl:Vs,renderSquareControl:Gs,rotationStyleHandler:zs,rotationWithSnapping:Ns,scaleCursorStyleHandler:Js,scaleOrSkewActionName:ci,scaleSkewCursorStyleHandler:li,scalingEqually:Zs,scalingX:$s,scalingXOrSkewingY:ui,scalingY:ti,scalingYOrSkewingX:di,skewCursorStyleHandler:ri,skewHandlerX:oi,skewHandlerY:ai,wrapWithFireEvent:Xs,wrapWithFixedAnchor:Ws});const xa=t=>void 0!==t.webgl,Ca="precision highp float",ba="\n ".concat(Ca,";\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }"),Sa=["type"],wa=["type"],Ta=new RegExp(Ca,"g");class Oa{get type(){return this.constructor.type}constructor(){let t=r(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},Sa);Object.assign(this,this.constructor.defaults,t)}getFragmentSource(){return ba}getVertexSource(){return"\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }"}createProgram(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.getFragmentSource(),s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.getVertexSource();const{WebGLProbe:{GLPrecision:i="highp"}}=p();"highp"!==i&&(e=e.replace(Ta,Ca.replace("highp",i)));const r=t.createShader(t.VERTEX_SHADER),n=t.createShader(t.FRAGMENT_SHADER),o=t.createProgram();if(!r||!n||!o)throw new c("Vertex, fragment shader or program creation error");if(t.shaderSource(r,s),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new c("Vertex shader compile error for ".concat(this.type,": ").concat(t.getShaderInfoLog(r)));if(t.shaderSource(n,e),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new c("Fragment shader compile error for ".concat(this.type,": ").concat(t.getShaderInfoLog(n)));if(t.attachShader(o,r),t.attachShader(o,n),t.linkProgram(o),!t.getProgramParameter(o,t.LINK_STATUS))throw new c('Shader link error for "'.concat(this.type,'" ').concat(t.getProgramInfoLog(o)));const a=this.getUniformLocations(t,o)||{};return a.uStepW=t.getUniformLocation(o,"uStepW"),a.uStepH=t.getUniformLocation(o,"uStepH"),{program:o,attributeLocations:this.getAttributeLocations(t,o),uniformLocations:a}}getAttributeLocations(t,e){return{aPosition:t.getAttribLocation(e,"aPosition")}}getUniformLocations(t,e){const s=this.constructor.uniformLocations,i={};for(let r=0;r1){const s=t.destinationWidth,i=t.destinationHeight;t.sourceWidth===s&&t.sourceHeight===i||(e.deleteTexture(t.targetTexture),t.targetTexture=t.filterBackend.createTexture(e,s,i)),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.targetTexture,0)}else e.bindFramebuffer(e.FRAMEBUFFER,null),e.finish()}_swapTextures(t){t.passes--,t.pass++;const e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e}isNeutralState(t){return!1}applyTo(t){xa(t)?(this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)):this.applyTo2d(t)}applyTo2d(t){}getCacheKey(){return this.type}retrieveShader(t){const e=this.getCacheKey();return t.programCache[e]||(t.programCache[e]=this.createProgram(t.context)),t.programCache[e]}applyToWebGL(t){const e=t.context,s=this.retrieveShader(t);0===t.pass&&t.originalTexture?e.bindTexture(e.TEXTURE_2D,t.originalTexture):e.bindTexture(e.TEXTURE_2D,t.sourceTexture),e.useProgram(s.program),this.sendAttributeData(e,s.attributeLocations,t.aPosition),e.uniform1f(s.uniformLocations.uStepW,1/t.sourceWidth),e.uniform1f(s.uniformLocations.uStepH,1/t.sourceHeight),this.sendUniformData(e,s.uniformLocations),e.viewport(0,0,t.destinationWidth,t.destinationHeight),e.drawArrays(e.TRIANGLE_STRIP,0,4)}bindAdditionalTexture(t,e,s){t.activeTexture(s),t.bindTexture(t.TEXTURE_2D,e),t.activeTexture(t.TEXTURE0)}unbindAdditionalTexture(t,e){t.activeTexture(e),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE0)}sendUniformData(t,e){}createHelpLayer(t){if(!t.helpLayer){const e=pt();e.width=t.sourceWidth,e.height=t.sourceHeight,t.helpLayer=e}}toObject(){const t=Object.keys(this.constructor.defaults||{});return i({type:this.type},t.reduce(((t,e)=>(t[e]=this[e],t)),{}))}toJSON(){return this.toObject()}static async fromObject(t,e){return new this(r(t,wa))}}e(Oa,"type","BaseFilter"),e(Oa,"uniformLocations",[]);const ka={multiply:"gl_FragColor.rgb *= uColor.rgb;\n",screen:"gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n",add:"gl_FragColor.rgb += uColor.rgb;\n",difference:"gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n",subtract:"gl_FragColor.rgb -= uColor.rgb;\n",lighten:"gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n",darken:"gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n",exclusion:"gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n",overlay:"\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n ",tint:"\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n "};class Da extends Oa{getCacheKey(){return"".concat(this.type,"_").concat(this.mode)}getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ".concat(ka[this.mode],"\n }\n }\n ")}applyTo2d(t){let{imageData:{data:e}}=t;const s=new Nt(this.color).getSource(),i=s[0]*this.alpha,r=s[1]*this.alpha,n=s[2]*this.alpha,o=1-this.alpha;for(let t=0;tnew this(i(i({},o),{},{image:t}))))}}e(Ea,"type","BlendImage"),e(Ea,"defaults",{mode:"multiply",alpha:1}),e(Ea,"uniformLocations",["uTransformMatrix","uImage"]),tt.setClass(Ea);class Aa extends Oa{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n "}applyTo(t){xa(t)?(this.aspectRatio=t.sourceWidth/t.sourceHeight,t.passes++,this._setupFrameBuffer(t),this.horizontal=!0,this.applyToWebGL(t),this._swapTextures(t),this._setupFrameBuffer(t),this.horizontal=!1,this.applyToWebGL(t),this._swapTextures(t)):this.applyTo2d(t)}applyTo2d(t){t.imageData=this.simpleBlur(t)}simpleBlur(t){let{ctx:e,imageData:s,filterBackend:{resources:i}}=t;const{width:r,height:n}=s;i.blurLayer1||(i.blurLayer1=pt(),i.blurLayer2=pt());const o=i.blurLayer1,a=i.blurLayer2;o.width===r&&o.height===n||(a.width=o.width=r,a.height=o.height=n);const h=o.getContext("2d"),c=a.getContext("2d"),l=15,u=.06*this.blur*.5;let d,g,f,p;for(h.putImageData(s,0,0),c.clearRect(0,0,r,n),p=-15;p<=l;p++)d=(Math.random()-.5)/4,g=p/l,f=u*g*r+d,c.globalAlpha=1-Math.abs(g),c.drawImage(o,f,d),h.drawImage(a,0,0),c.globalAlpha=1,c.clearRect(0,0,a.width,a.height);for(p=-15;p<=l;p++)d=(Math.random()-.5)/4,g=p/l,f=u*g*n+d,c.globalAlpha=1-Math.abs(g),c.drawImage(o,d,f),h.drawImage(a,0,0),c.globalAlpha=1,c.clearRect(0,0,a.width,a.height);e.drawImage(o,0,0);const m=e.getImageData(0,0,o.width,o.height);return h.globalAlpha=1,h.clearRect(0,0,o.width,o.height),m}sendUniformData(t,e){const s=this.chooseRightDelta();t.uniform2fv(e.uDelta,s)}isNeutralState(){return 0===this.blur}chooseRightDelta(){let t=1;const e=[0,0];this.horizontal?this.aspectRatio>1&&(t=1/this.aspectRatio):this.aspectRatio<1&&(t=this.aspectRatio);const s=t*this.blur*.12;return this.horizontal?e[0]=s:e[1]=s,e}}e(Aa,"type","Blur"),e(Aa,"defaults",{blur:0}),e(Aa,"uniformLocations",["uDelta"]),tt.setClass(Aa);class ja extends Oa{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n"}applyTo2d(t){let{imageData:{data:e}}=t;const s=Math.round(255*this.brightness);for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:{};super(t),this.subFilters=t.subFilters||[]}applyTo(t){xa(t)&&(t.passes+=this.subFilters.length-1),this.subFilters.forEach((e=>{e.applyTo(t)}))}toObject(){return{type:this.type,subFilters:this.subFilters.map((t=>t.toObject()))}}isNeutralState(){return!this.subFilters.some((t=>!t.isNeutralState()))}static fromObject(t,e){return Promise.all((t.subFilters||[]).map((t=>tt.getClass(t.type).fromObject(t,e)))).then((t=>new this({subFilters:t})))}}e(Ga,"type","Composed"),tt.setClass(Ga);class Ha extends Oa{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }"}isNeutralState(){return 0===this.contrast}applyTo2d(t){let{imageData:{data:e}}=t;const s=Math.floor(255*this.contrast),i=259*(s+255)/(255*(259-s));for(let t=0;t=a||m<0||m>=o||(y=4*(v*o+m),_=i[S*r+b],u+=s[y]*_,d+=s[y+1]*_,g+=s[y+2]*_,l||(f+=s[y+3]*_));c[p]=u,c[p+1]=d,c[p+2]=g,c[p+3]=l?s[p+3]:f}t.imageData=h}sendUniformData(t,e){t.uniform1fv(e.uMatrix,this.matrix)}toObject(){return i(i({},super.toObject()),{},{opaque:this.opaque,matrix:[...this.matrix]})}}e(Na,"type","Convolute"),e(Na,"defaults",{opaque:!1,matrix:[0,0,0,0,1,0,0,0,0]}),e(Na,"uniformLocations",["uMatrix","uOpaque","uHalfSize","uSize"]),tt.setClass(Na);const Ua="Gamma";class qa extends Oa{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n"}constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(t),this.gamma=t.gamma||this.constructor.defaults.gamma.concat()}applyTo2d(t){let{imageData:{data:e}}=t;const s=this.gamma,i=1/s[0],r=1/s[1],n=1/s[2];this.rgbValues||(this.rgbValues={r:new Uint8Array(256),g:new Uint8Array(256),b:new Uint8Array(256)});const o=this.rgbValues;for(let t=0;t<256;t++)o.r[t]=255*Math.pow(t/255,i),o.g[t]=255*Math.pow(t/255,r),o.b[t]=255*Math.pow(t/255,n);for(let t=0;tr[0]&&i>r[1]&&o>r[2]&&s"\n color += texture2D(uTexture, vTexCoord + ".concat(t,") * uTaps[").concat(e,"] + texture2D(uTexture, vTexCoord - ").concat(t,") * uTaps[").concat(e,"];\n sum += 2.0 * uTaps[").concat(e,"];\n "))).join("\n"),"\n gl_FragColor = color / sum;\n }\n ")}applyToForWebgl(t){t.passes++,this.width=t.sourceWidth,this.horizontal=!0,this.dW=Math.round(this.width*this.scaleX),this.dH=t.sourceHeight,this.tempScale=this.dW/this.width,this.taps=this.getTaps(),t.destinationWidth=this.dW,super.applyTo(t),t.sourceWidth=t.destinationWidth,this.height=t.sourceHeight,this.horizontal=!1,this.dH=Math.round(this.height*this.scaleY),this.tempScale=this.dH/this.height,this.taps=this.getTaps(),t.destinationHeight=this.dH,super.applyTo(t),t.sourceHeight=t.destinationHeight}applyTo(t){xa(t)?this.applyToForWebgl(t):this.applyTo2d(t)}isNeutralState(){return 1===this.scaleX&&1===this.scaleY}lanczosCreate(t){return e=>{if(e>=t||e<=-t)return 0;if(e<1.1920929e-7&&e>-1.1920929e-7)return 1;const s=(e*=Math.PI)/t;return Math.sin(e)/e*Math.sin(s)/s}}applyTo2d(t){const e=t.imageData,s=this.scaleX,i=this.scaleY;this.rcpScaleX=1/s,this.rcpScaleY=1/i;const r=e.width,n=e.height,o=Math.round(r*s),a=Math.round(n*i);let h;h="sliceHack"===this.resizeType?this.sliceByTwo(t,r,n,o,a):"hermite"===this.resizeType?this.hermiteFastResize(t,r,n,o,a):"bilinear"===this.resizeType?this.bilinearFiltering(t,r,n,o,a):"lanczos"===this.resizeType?this.lanczosResize(t,r,n,o,a):new ImageData(o,a),t.imageData=h}sliceByTwo(t,e,s,i,r){const n=t.imageData,o=.5;let a=!1,h=!1,c=e*o,l=s*o;const u=t.filterBackend.resources;let d=0,g=0;const f=e;let p=0;u.sliceByTwo||(u.sliceByTwo=pt());const m=u.sliceByTwo;(m.width<1.5*e||m.height=e)){D=Math.floor(1e3*Math.abs(x-m.x)),p[D]||(p[D]={});for(let t=v.y-f;t<=v.y+f;t++)t<0||t>=s||(M=Math.floor(1e3*Math.abs(t-m.y)),p[D][M]||(p[D][M]=h(Math.sqrt(Math.pow(D*u,2)+Math.pow(M*d,2))/1e3)),C=p[D][M],C>0&&(b=4*(t*e+x),S+=C,w+=C*n[b],T+=C*n[b+1],O+=C*n[b+2],k+=C*n[b+3]))}b=4*(_*i+y),a[b]=w/S,a[b+1]=T/S,a[b+2]=O/S,a[b+3]=k/S}return++y1&&n<-1||(l=2*n*n*n-3*n*n+1,l>0&&(s=4*(t+i*e),v+=l*c[s+3],g+=l,c[s+3]<255&&(l=l*c[s+3]/250),f+=l*c[s],p+=l*c[s+1],m+=l*c[s+2],d+=l))}}u[r]=f/d,u[r+1]=p/d,u[r+2]=m/d,u[r+3]=v/g}return l}}e(sh,"type","Resize"),e(sh,"defaults",{resizeType:"hermite",scaleX:1,scaleY:1,lanczosLobes:3}),e(sh,"uniformLocations",["uDelta","uTaps"]),tt.setClass(sh);class ih extends Oa{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n"}applyTo2d(t){let{imageData:{data:e}}=t;const s=-this.saturation;for(let t=0;t{const s=pt(),i=pt().getContext("webgl"),r={imageBuffer:new ArrayBuffer(t*e*4)},n={destinationWidth:t,destinationHeight:e,targetCanvas:s};let o;s.width=t,s.height=e,o=v().performance.now(),Yo.prototype.copyGLTo2D.call(r,i,n);const a=v().performance.now()-o;o=v().performance.now(),Yo.prototype.copyGLTo2DPutImageData.call(r,i,n);return a>v().performance.now()-o},t.isWebGLPipelineState=xa,t.loadSVGFromString=function(t,e,s){return aa((new(v().DOMParser)).parseFromString(t.trim(),"text/xml"),e,s)},t.loadSVGFromURL=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return new Promise(((e,i)=>{hn(t.replace(/^\n\s*/,"").trim(),{onComplete:t=>{const s=t.responseXML;s&&e(s),i()},signal:s.signal})})).then((t=>aa(t,e,s))).catch((()=>oa()))},t.parseAttributes=ur,t.parseFontDeclaration=ar,t.parsePointsAttribute=$n,t.parseSVGDocument=aa,t.parseStyleAttribute=cr,t.parseTransformAttribute=nr,t.runningAnimations=et,t.setEnv=t=>{f=t},t.setFilterBackend=function(t){Vo=t},t.util=ln,t.version=x})); +//# sourceMappingURL=index.min.js.map diff --git a/dist/index.min.js.map b/dist/index.min.js.map new file mode 100644 index 00000000000..fa87ed25d03 --- /dev/null +++ b/dist/index.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.min.js","sources":["../src/config.ts","../src/util/internals/console.ts","../src/filters/GLProbes/GLProbe.ts","../src/filters/GLProbes/WebGLProbe.ts","../src/env/browser.ts","../src/env/index.ts","../src/cache.ts","../src/constants.ts","../src/ClassRegistry.ts","../src/util/animation/AnimationRegistry.ts","../src/Observable.ts","../src/util/internals/removeFromArray.ts","../src/util/misc/cos.ts","../src/util/misc/sin.ts","../src/Point.ts","../src/Collection.ts","../src/CommonMethods.ts","../src/util/animation/AnimationFrameProvider.ts","../src/util/internals/uid.ts","../src/util/misc/dom.ts","../src/util/misc/radiansDegreesConversion.ts","../src/util/misc/matrix.ts","../src/util/misc/objectEnlive.ts","../src/util/misc/pick.ts","../src/color/color_map.ts","../src/color/util.ts","../src/color/Color.ts","../src/color/constants.ts","../src/util/misc/toFixed.ts","../src/util/misc/svgParsing.ts","../src/util/typeAssertions.ts","../src/util/dom_misc.ts","../src/canvas/DOMManagers/util.ts","../src/canvas/DOMManagers/StaticCanvasDOMManager.ts","../src/canvas/StaticCanvasOptions.ts","../src/canvas/StaticCanvas.ts","../src/util/dom_event.ts","../src/util/misc/boundingBoxFromPoints.ts","../src/util/misc/objectTransforms.ts","../src/util/misc/planeChange.ts","../src/controls/fireEvent.ts","../src/util/misc/resolveOrigin.ts","../src/controls/util.ts","../src/controls/drag.ts","../src/shapes/Object/FabricObjectSVGExportMixin.ts","../src/parser/getSvgRegex.ts","../src/parser/constants.ts","../src/util/misc/vectors.ts","../src/Shadow.ts","../src/util/misc/capValue.ts","../src/shapes/Object/defaultValues.ts","../src/util/animation/easing.ts","../src/util/animation/AnimationBase.ts","../src/util/animation/ValueAnimation.ts","../src/util/animation/ArrayAnimation.ts","../src/util/animation/ColorAnimation.ts","../src/util/animation/animate.ts","../src/Intersection.ts","../src/shapes/Object/ObjectGeometry.ts","../src/shapes/Object/Object.ts","../src/controls/wrapWithFireEvent.ts","../src/controls/wrapWithFixedAnchor.ts","../src/controls/changeWidth.ts","../src/controls/controlRendering.ts","../src/controls/Control.ts","../src/controls/rotate.ts","../src/controls/scale.ts","../src/controls/skew.ts","../src/controls/scaleSkew.ts","../src/controls/commonControls.ts","../src/shapes/Object/InteractiveObject.ts","../src/util/applyMixins.ts","../src/shapes/Object/FabricObject.ts","../src/util/misc/isTransparent.ts","../src/util/misc/projectStroke/StrokeProjectionsBase.ts","../src/util/misc/projectStroke/StrokeLineJoinProjections.ts","../src/util/misc/projectStroke/StrokeLineCapProjections.ts","../src/util/misc/projectStroke/index.ts","../src/util/internals/findRight.ts","../src/util/internals/cloneStyles.ts","../src/util/lang_string.ts","../src/util/misc/textStyles.ts","../src/parser/attributes.ts","../src/parser/selectorMatches.ts","../src/parser/elementMatchesRule.ts","../src/parser/doesSomeParentMatch.ts","../src/parser/normalizeAttr.ts","../src/util/internals/cleanupSvgAttribute.ts","../src/parser/parseTransformAttribute.ts","../src/parser/normalizeValue.ts","../src/parser/parseFontDeclaration.ts","../src/parser/parseStyleString.ts","../src/parser/parseStyleAttribute.ts","../src/parser/parseStyleObject.ts","../src/parser/setStrokeFillOpacity.ts","../src/parser/parseAttributes.ts","../src/parser/getGlobalStylesForElement.ts","../src/shapes/Rect.ts","../src/LayoutManager/constants.ts","../src/LayoutManager/LayoutStrategies/utils.ts","../src/LayoutManager/LayoutStrategies/LayoutStrategy.ts","../src/LayoutManager/LayoutStrategies/FitContentLayout.ts","../src/LayoutManager/LayoutManager.ts","../src/shapes/Group.ts","../src/util/misc/groupSVGElements.ts","../src/util/misc/findScaleTo.ts","../src/util/path/regex.ts","../src/util/path/index.ts","../src/util/dom_style.ts","../src/util/misc/mergeClipPaths.ts","../src/util/internals/getRandomInt.ts","../src/util/internals/dom_request.ts","../src/util/transform_matrix_removal.ts","../src/util/misc/rotatePoint.ts","../src/canvas/DOMManagers/CanvasDOMManager.ts","../src/canvas/SelectableCanvas.ts","../src/canvas/CanvasOptions.ts","../src/canvas/TextEditingManager.ts","../src/canvas/Canvas.ts","../src/gradient/constants.ts","../src/util/internals/ifNaN.ts","../src/parser/percent.ts","../src/gradient/parser/parseColorStops.ts","../src/gradient/parser/misc.ts","../src/gradient/parser/parseCoords.ts","../src/gradient/Gradient.ts","../src/Pattern/Pattern.ts","../src/brushes/BaseBrush.ts","../src/shapes/Path.ts","../src/brushes/PencilBrush.ts","../src/shapes/Circle.ts","../src/shapes/Line.ts","../src/shapes/Triangle.ts","../src/shapes/Ellipse.ts","../src/parser/parsePointsAttribute.ts","../src/shapes/Polyline.ts","../src/shapes/Polygon.ts","../src/shapes/Text/constants.ts","../src/shapes/Text/StyledText.ts","../src/shapes/Text/TextSVGExportMixin.ts","../src/shapes/Text/Text.ts","../src/shapes/IText/DraggableTextDelegate.ts","../src/shapes/IText/ITextBehavior.ts","../src/shapes/IText/ITextKeyBehavior.ts","../src/shapes/IText/ITextClickBehavior.ts","../src/shapes/IText/constants.ts","../src/shapes/IText/IText.ts","../src/shapes/Textbox.ts","../src/LayoutManager/LayoutStrategies/ClipPathLayout.ts","../src/LayoutManager/LayoutStrategies/FixedLayout.ts","../src/LayoutManager/ActiveSelectionLayoutManager.ts","../src/shapes/ActiveSelection.ts","../src/filters/Canvas2dFilterBackend.ts","../src/filters/WebGLFilterBackend.ts","../src/filters/FilterBackend.ts","../src/shapes/Image.ts","../src/parser/applyViewboxTransform.ts","../src/parser/getTagName.ts","../src/parser/hasInvalidAncestor.ts","../src/parser/getMultipleNodes.ts","../src/parser/recursivelyParseGradientsXlink.ts","../src/parser/getGradientDefs.ts","../src/parser/getCSSRules.ts","../src/parser/elements_parser.ts","../src/parser/parseSVGDocument.ts","../src/parser/parseUseDirectives.ts","../src/controls/polyControl.ts","../src/controls/pathControl.ts","../src/filters/utils.ts","../src/filters/shaders/baseFilter.ts","../src/filters/BaseFilter.ts","../src/filters/shaders/blendColor.ts","../src/filters/BlendColor.ts","../src/filters/shaders/blendImage.ts","../src/filters/BlendImage.ts","../src/filters/Blur.ts","../src/filters/shaders/blur.ts","../src/filters/Brightness.ts","../src/filters/shaders/brightness.ts","../src/filters/ColorMatrix.ts","../src/filters/shaders/colorMatrix.ts","../src/filters/ColorMatrixFilters.ts","../src/filters/Composed.ts","../src/filters/Contrast.ts","../src/filters/shaders/constrast.ts","../src/filters/shaders/convolute.ts","../src/filters/Convolute.ts","../src/filters/shaders/gamma.ts","../src/filters/Gamma.ts","../src/filters/shaders/grayscale.ts","../src/filters/Grayscale.ts","../src/filters/HueRotation.ts","../src/filters/Invert.ts","../src/filters/shaders/invert.ts","../src/filters/Noise.ts","../src/filters/shaders/noise.ts","../src/filters/Pixelate.ts","../src/filters/shaders/pixelate.ts","../src/filters/RemoveColor.ts","../src/filters/shaders/removeColor.ts","../src/filters/Resize.ts","../src/filters/Saturation.ts","../src/filters/shaders/saturation.ts","../src/filters/Vibrance.ts","../src/filters/shaders/vibrance.ts","../src/brushes/CircleBrush.ts","../src/brushes/PatternBrush.ts","../src/brushes/SprayBrush.ts","../src/parser/loadSVGFromString.ts","../src/parser/loadSVGFromURL.ts"],"sourcesContent":["export type TConfiguration = Partial;\n\nclass BaseConfiguration {\n /**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\n browserShadowBlurConstant = 1;\n\n /**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\n DPI = 96;\n\n /**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n devicePixelRatio =\n typeof window !== 'undefined' ? window.devicePixelRatio : 1; // eslint-disable-line no-restricted-globals\n\n /**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n perfLimitSizeTotal = 2097152;\n\n /**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\n maxCacheSideLimit = 4096;\n\n /**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n minCacheSideLimit = 256;\n\n /**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n * @deprecated\n */\n disableStyleCopyPaste = false;\n\n /**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\n enableGLFiltering = true;\n\n /**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n *\n * In order to support old hardware set to `2048` to avoid OOM\n *\n * @since 2.0.0\n * @type Number\n * @default\n */\n textureSize = 4096;\n\n /**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\n forceGLPutImageData = false;\n\n /**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from\n * the curve is very hard to hit any cache.\n * Enable only if you know why it could be useful.\n * Candidate for removal/simplification\n * @default false\n */\n cachesBoundsOfCurve = false;\n\n /**\n * Map of font files\n * Map of font files\n */\n fontPaths: Record = {};\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * Used in exporting methods (`toObject`, `toJSON`, `toSVG`)\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n */\n NUM_FRACTION_DIGITS = 4;\n}\n\nexport class Configuration extends BaseConfiguration {\n constructor(config?: TConfiguration) {\n super();\n this.configure(config);\n }\n\n configure(config: TConfiguration = {}) {\n Object.assign(this, config);\n }\n\n /**\n * Map of font files\n */\n addFonts(\n paths: Record = {},\n ) {\n this.fontPaths = {\n ...this.fontPaths,\n ...paths,\n };\n }\n\n removeFonts(fontFamilys: string[] = []) {\n fontFamilys.forEach((fontFamily) => {\n delete this.fontPaths[fontFamily];\n });\n }\n\n clearFonts() {\n this.fontPaths = {};\n }\n\n restoreDefaults(keys?: (keyof T)[]) {\n const defaults = new BaseConfiguration() as T;\n const config =\n keys?.reduce((acc, key) => {\n acc[key] = defaults[key];\n return acc;\n }, {} as T) || defaults;\n this.configure(config);\n }\n}\n\nexport const config = new Configuration();\n","export const log = (\n severity: 'log' | 'warn' | 'error',\n ...optionalParams: any[]\n) =>\n // eslint-disable-next-line no-restricted-syntax\n console[severity]('fabric', ...optionalParams);\n\nexport class FabricError extends Error {\n constructor(message?: string, options?: ErrorOptions) {\n super(`fabric: ${message}`, options);\n }\n}\n\nexport class SignalAbortedError extends FabricError {\n constructor(context: string) {\n super(`${context} 'options.signal' is in 'aborted' state`);\n }\n}\n","export type GLPrecision = 'lowp' | 'mediump' | 'highp';\n\nexport abstract class GLProbe {\n declare GLPrecision: GLPrecision | undefined;\n abstract queryWebGL(canvas: HTMLCanvasElement): void;\n abstract isSupported(textureSize: number): boolean;\n}\n","import { log } from '../../util/internals/console';\nimport { GLProbe } from './GLProbe';\nimport type { GLPrecision } from './GLProbe';\n\n/**\n * Lazy initialize WebGL constants\n */\nexport class WebGLProbe extends GLProbe {\n declare maxTextureSize?: number;\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {GLPrecision} Precision to test can be any of following\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n private testPrecision(\n gl: WebGLRenderingContext,\n precision: GLPrecision,\n ): boolean {\n const fragmentSource = `precision ${precision} float;\\nvoid main(){}`;\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n if (!fragmentShader) {\n return false;\n }\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);\n }\n\n /**\n * query browser for WebGL\n */\n queryWebGL(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext('webgl');\n if (gl) {\n this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this.GLPrecision = (['highp', 'mediump', 'lowp'] as const).find(\n (precision) => this.testPrecision(gl, precision),\n );\n gl.getExtension('WEBGL_lose_context')!.loseContext();\n log('log', `WebGL: max texture size ${this.maxTextureSize}`);\n }\n }\n\n isSupported(textureSize: number) {\n return !!this.maxTextureSize && this.maxTextureSize >= textureSize;\n }\n}\n","/* eslint-disable no-restricted-globals */\nimport { WebGLProbe } from '../filters/GLProbes/WebGLProbe';\nimport type { TCopyPasteData, TFabricEnv } from './types';\n\nconst copyPasteData: TCopyPasteData = {};\n\nexport const getEnv = (): TFabricEnv => {\n return {\n document,\n window,\n isTouchSupported:\n 'ontouchstart' in window ||\n 'ontouchstart' in document ||\n (window && window.navigator && window.navigator.maxTouchPoints > 0),\n WebGLProbe: new WebGLProbe(),\n dispose() {\n // noop\n },\n copyPasteData,\n };\n};\n","/**\n * This file is consumed by fabric.\n * The `./node` and `./browser` files define the env variable that is used by this module.\n * The `./browser` module is defined to be the default env and doesn't set the env at all.\n * This is done in order to support isomorphic usage for browser and node applications\n * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env.\n */\n\nimport { config } from '../config';\nimport { getEnv as getBrowserEnv } from './browser';\nimport type { TFabricEnv } from './types';\nimport type { DOMWindow } from 'jsdom';\n\nlet env: TFabricEnv;\n\n/**\n * Sets the environment variables used by fabric.\\\n * This is exposed for special cases, such as configuring a test environment, and should be used with care.\n *\n * **CAUTION**: Must be called before using the package.\n *\n * @example\n * Passing `window` and `document` objects to fabric (in case they are mocked or something)\n * import { getEnv, setEnv } from 'fabric';\n * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in.\n * setEnv({ ...getEnv(), window, document });\n * // done with setup, using fabric is now safe\n */\nexport const setEnv = (value: TFabricEnv) => {\n env = value;\n};\n\n/**\n * In order to support SSR we **MUST** access the browser env only after the window has loaded\n */\nexport const getEnv = () => env || (env = getBrowserEnv());\n\nexport const getFabricDocument = (): Document => getEnv().document;\n\nexport const getFabricWindow = (): (Window & typeof globalThis) | DOMWindow =>\n getEnv().window;\n\n/**\n * @returns the config value if defined, fallbacks to the environment value\n */\nexport const getDevicePixelRatio = () =>\n Math.max(config.devicePixelRatio ?? getFabricWindow().devicePixelRatio, 1);\n","import { config } from './config';\nimport type { TRectBounds } from './typedefs';\n\nexport class Cache {\n /**\n * Cache of widths of chars in text rendering.\n */\n charWidthsCache: Record<\n /** fontFamily */ string,\n Record<\n /** fontStyleCacheKey */ string,\n Record\n >\n > = {};\n\n /**\n * @return {Object} reference to cache\n */\n getFontCache({\n fontFamily,\n fontStyle,\n fontWeight,\n }: {\n fontFamily: string;\n fontStyle: string;\n fontWeight: string | number;\n }) {\n fontFamily = fontFamily.toLowerCase();\n if (!this.charWidthsCache[fontFamily]) {\n this.charWidthsCache[fontFamily] = {};\n }\n const fontCache = this.charWidthsCache[fontFamily];\n const cacheKey = `${fontStyle.toLowerCase()}_${(\n fontWeight + ''\n ).toLowerCase()}`;\n if (!fontCache[cacheKey]) {\n fontCache[cacheKey] = {};\n }\n return fontCache[cacheKey];\n }\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @param {String} [fontFamily] font family to clear\n */\n clearFontCache(fontFamily?: string) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n this.charWidthsCache = {};\n } else if (this.charWidthsCache[fontFamily]) {\n delete this.charWidthsCache[fontFamily];\n }\n }\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @param {number} ar aspect ratio\n * @return {number[]} Limited dimensions X and Y\n */\n limitDimsByArea(ar: number) {\n const { perfLimitSizeTotal } = config;\n const roughWidth = Math.sqrt(perfLimitSizeTotal * ar);\n // we are not returning a point on purpose, to avoid circular dependencies\n // this is an internal utility\n return [\n Math.floor(roughWidth),\n Math.floor(perfLimitSizeTotal / roughWidth),\n ];\n }\n\n /**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\n boundsOfCurveCache: Record = {};\n}\n\nexport const cache = new Cache();\n","import type { TMat2D } from './typedefs';\n// use this syntax so babel plugin see this import here\nimport { version } from '../package.json';\n\nexport const VERSION = version;\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport const halfPI = Math.PI / 2;\nexport const twoMathPi = Math.PI * 2;\nexport const PiBy180 = Math.PI / 180;\n\nexport const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]) as TMat2D;\nexport const DEFAULT_SVG_FONT_SIZE = 16;\nexport const ALIASING_LIMIT = 2;\n\n/* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\nexport const kRect = 1 - 0.5522847498;\n\nexport const CENTER = 'center';\nexport const LEFT = 'left';\nexport const TOP = 'top';\nexport const BOTTOM = 'bottom';\nexport const RIGHT = 'right';\nexport const NONE = 'none';\n\nexport const reNewline = /\\r?\\n/;\n\nexport const MOVING = 'moving';\nexport const SCALING = 'scaling';\nexport const ROTATING = 'rotating';\nexport const ROTATE = 'rotate';\nexport const SKEWING = 'skewing';\nexport const RESIZING = 'resizing';\nexport const MODIFY_POLY = 'modifyPoly';\nexport const MODIFY_PATH = 'modifyPath';\nexport const CHANGED = 'changed';\nexport const SCALE = 'scale';\nexport const SCALE_X = 'scaleX';\nexport const SCALE_Y = 'scaleY';\nexport const SKEW_X = 'skewX';\nexport const SKEW_Y = 'skewY';\nexport const FILL = 'fill';\nexport const STROKE = 'stroke';\nexport const MODIFIED = 'modified';\n","import { FabricError } from './util/internals/console';\n\n/*\n * This Map connects the objects type value with their\n * class implementation. It used from any object to understand which are\n * the classes to enlive when requesting a object.type = 'path' for example.\n * Objects uses it for clipPath, Canvas uses it for everything.\n * This is necessary for generic code to run and enlive instances from serialized representation.\n * You can customize which classes get enlived from SVG parsing using this classRegistry.\n * The Registry start empty and gets filled in depending which files you import.\n * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from\n * different sources you will need to import all fabric because you may need all classes.\n */\n\nexport const JSON = 'json';\nexport const SVG = 'svg';\n\nexport class ClassRegistry {\n declare [JSON]: Map;\n declare [SVG]: Map;\n\n constructor() {\n this[JSON] = new Map();\n this[SVG] = new Map();\n }\n\n has(classType: string): boolean {\n return this[JSON].has(classType);\n }\n\n getClass(classType: string): T {\n const constructor = this[JSON].get(classType);\n if (!constructor) {\n throw new FabricError(`No class registered for ${classType}`);\n }\n return constructor;\n }\n\n setClass(classConstructor: any, classType?: string) {\n if (classType) {\n this[JSON].set(classType, classConstructor);\n } else {\n this[JSON].set(classConstructor.type, classConstructor);\n // legacy\n // @TODO: needs to be removed in fabric 7 or 8\n this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);\n }\n }\n\n getSVGClass(SVGTagName: string): any {\n return this[SVG].get(SVGTagName);\n }\n\n setSVGClass(classConstructor: any, SVGTagName?: string) {\n this[SVG].set(\n SVGTagName ?? classConstructor.type.toLowerCase(),\n classConstructor,\n );\n }\n}\n\nexport const classRegistry = new ClassRegistry();\n","import type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type { AnimationBase } from './AnimationBase';\n\n/**\n * Array holding all running animations\n */\nclass AnimationRegistry extends Array {\n /**\n * Remove a single animation using an animation context\n * @param {AnimationBase} context\n */\n remove(context: AnimationBase) {\n const index = this.indexOf(context);\n index > -1 && this.splice(index, 1);\n }\n\n /**\n * Cancel all running animations on the next frame\n */\n cancelAll() {\n const animations = this.splice(0);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations attached to a canvas on the next frame\n * @param {StaticCanvas} canvas\n */\n cancelByCanvas(canvas: StaticCanvas) {\n if (!canvas) {\n return [];\n }\n const animations = this.filter(\n (animation) =>\n animation.target === canvas ||\n (typeof animation.target === 'object' &&\n (animation.target as FabricObject)?.canvas === canvas),\n );\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations for target on the next frame\n * @param target\n */\n cancelByTarget(target: AnimationBase['target']) {\n if (!target) {\n return [];\n }\n const animations = this.filter((animation) => animation.target === target);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n}\n\nexport const runningAnimations = new AnimationRegistry();\n","export type TEventCallback = (options: T) => any;\n\ntype EventRegistryObject = {\n [K in keyof E]?: TEventCallback;\n};\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\nexport class Observable {\n private __eventListeners: Record =\n {} as Record;\n\n /**\n * Observes specified event\n * @alias on\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n on(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n on(handlers: EventRegistryObject): VoidFunction;\n on(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (!this.__eventListeners) {\n this.__eventListeners = {} as Record;\n }\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this.on(eventName as K, handler as TEventCallback);\n });\n return () => this.off(arg0);\n } else if (handler) {\n const eventName = arg0;\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n return () => this.off(eventName, handler);\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * Observes specified event **once**\n * @alias once\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n once(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n once(handlers: EventRegistryObject): VoidFunction;\n once(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n const disposers: VoidFunction[] = [];\n Object.entries(arg0).forEach(([eventName, handler]) => {\n disposers.push(this.once(eventName as K, handler as TEventCallback));\n });\n return () => disposers.forEach((d) => d());\n } else if (handler) {\n const disposer = this.on(\n arg0,\n function onceHandler(this: Observable, ...args) {\n handler.call(this, ...args);\n disposer();\n },\n );\n return disposer;\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * @private\n * @param {string} eventName\n * @param {Function} [handler]\n */\n private _removeEventListener(\n eventName: K,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n\n if (handler) {\n const eventListener = this.__eventListeners[eventName];\n const index = eventListener.indexOf(handler);\n index > -1 && eventListener.splice(index, 1);\n } else {\n this.__eventListeners[eventName] = [];\n }\n }\n\n /**\n * Unsubscribe all event listeners for eventname.\n * Do not use this pattern. You could kill internal fabricJS events.\n * We know we should have protected events for internal flows, but we don't have yet\n * @deprecated\n * @param {string} eventName event name (eg. 'after:render')\n */\n off(eventName: K): void;\n /**\n * unsubscribe an event listener\n * @param {string} eventName event name (eg. 'after:render')\n * @param {TEventCallback} handler event listener to unsubscribe\n */\n off(eventName: K, handler: TEventCallback): void;\n /**\n * unsubscribe event listeners\n * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n */\n off(handlers: EventRegistryObject): void;\n /**\n * unsubscribe all event listeners\n */\n off(): void;\n off(\n arg0?: K | EventRegistryObject,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners) {\n return;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (typeof arg0 === 'undefined') {\n for (const eventName in this.__eventListeners) {\n this._removeEventListener(eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (typeof arg0 === 'object') {\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this._removeEventListener(eventName as K, handler as TEventCallback);\n });\n } else {\n this._removeEventListener(arg0, handler);\n }\n }\n\n /**\n * Fires event with an optional options object\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n */\n fire(eventName: K, options?: EventSpec[K]) {\n if (!this.__eventListeners) {\n return;\n }\n\n const listenersForEvent = this.__eventListeners[eventName]?.concat();\n if (listenersForEvent) {\n for (let i = 0; i < listenersForEvent.length; i++) {\n listenersForEvent[i].call(this, options || {});\n }\n }\n }\n}\n","/**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\nexport const removeFromArray = (array: T[], value: T): T[] => {\n const idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the cosin value for angle.\n */\nexport const cos = (angle: TRadian): number => {\n if (angle === 0) {\n return 1;\n }\n const angleSlice = Math.abs(angle) / halfPI;\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n case 2:\n return -1;\n }\n return Math.cos(angle);\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the sin value for angle.\n */\nexport const sin = (angle: TRadian): number => {\n if (angle === 0) {\n return 0;\n }\n const angleSlice = angle / halfPI;\n const value = Math.sign(angle);\n switch (angleSlice) {\n case 1:\n return value;\n case 2:\n return 0;\n case 3:\n return -value;\n }\n return Math.sin(angle);\n};\n","import type { TMat2D, TRadian } from './typedefs';\nimport { cos } from './util/misc/cos';\nimport { sin } from './util/misc/sin';\n\nexport interface XY {\n x: number;\n y: number;\n}\n\n/**\n * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com)\n */\nexport class Point implements XY {\n declare x: number;\n\n declare y: number;\n\n constructor();\n constructor(x: number, y: number);\n constructor(point?: XY);\n constructor(arg0: number | XY = 0, y = 0) {\n if (typeof arg0 === 'object') {\n this.x = arg0.x;\n this.y = arg0.y;\n } else {\n this.x = arg0;\n this.y = y;\n }\n }\n\n /**\n * Adds another point to this one and returns another one\n * @param {XY} that\n * @return {Point} new Point instance with added values\n */\n add(that: XY): Point {\n return new Point(this.x + that.x, this.y + that.y);\n }\n\n /**\n * Adds another point to this one\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n addEquals(that: XY): Point {\n this.x += that.x;\n this.y += that.y;\n return this;\n }\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {Point} new Point with added value\n */\n scalarAdd(scalar: number): Point {\n return new Point(this.x + scalar, this.y + scalar);\n }\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarAddEquals(scalar: number): Point {\n this.x += scalar;\n this.y += scalar;\n return this;\n }\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {XY} that\n * @return {Point} new Point object with subtracted values\n */\n subtract(that: XY): Point {\n return new Point(this.x - that.x, this.y - that.y);\n }\n\n /**\n * Subtracts another point from this point\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n subtractEquals(that: XY): Point {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n }\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarSubtract(scalar: number): Point {\n return new Point(this.x - scalar, this.y - scalar);\n }\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarSubtractEquals(scalar: number): Point {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n }\n\n /**\n * Multiplies this point by another value and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n multiply(that: XY): Point {\n return new Point(this.x * that.x, this.y * that.y);\n }\n\n /**\n * Multiplies this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarMultiply(scalar: number): Point {\n return new Point(this.x * scalar, this.y * scalar);\n }\n\n /**\n * Multiplies this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarMultiplyEquals(scalar: number): Point {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n }\n\n /**\n * Divides this point by another and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n divide(that: XY): Point {\n return new Point(this.x / that.x, this.y / that.y);\n }\n\n /**\n * Divides this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarDivide(scalar: number): Point {\n return new Point(this.x / scalar, this.y / scalar);\n }\n\n /**\n * Divides this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarDivideEquals(scalar: number): Point {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n }\n\n /**\n * Returns true if this point is equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n eq(that: XY): boolean {\n return this.x === that.x && this.y === that.y;\n }\n\n /**\n * Returns true if this point is less than another one\n * @param {XY} that\n * @return {Boolean}\n */\n lt(that: XY): boolean {\n return this.x < that.x && this.y < that.y;\n }\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n lte(that: XY): boolean {\n return this.x <= that.x && this.y <= that.y;\n }\n\n /**\n\n * Returns true if this point is greater another one\n * @param {XY} that\n * @return {Boolean}\n */\n gt(that: XY): boolean {\n return this.x > that.x && this.y > that.y;\n }\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n gte(that: XY): boolean {\n return this.x >= that.x && this.y >= that.y;\n }\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {XY} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {Point}\n */\n lerp(that: XY, t = 0.5): Point {\n t = Math.max(Math.min(1, t), 0);\n return new Point(\n this.x + (that.x - this.x) * t,\n this.y + (that.y - this.y) * t,\n );\n }\n\n /**\n * Returns distance from this point and another one\n * @param {XY} that\n * @return {Number}\n */\n distanceFrom(that: XY): number {\n const dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /**\n * Returns the point between this point and another one\n * @param {XY} that\n * @return {Point}\n */\n midPointFrom(that: XY): Point {\n return this.lerp(that);\n }\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {XY} that\n * @return {Point}\n */\n min(that: XY): Point {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n }\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {XY} that\n * @return {Point}\n */\n max(that: XY): Point {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n }\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY(x: number, y: number) {\n this.x = x;\n this.y = y;\n return this;\n }\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX(x: number) {\n this.x = x;\n return this;\n }\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY(y: number) {\n this.y = y;\n return this;\n }\n\n /**\n * Sets x/y of this point from another point\n * @param {XY} that\n * @chainable\n */\n setFromPoint(that: XY) {\n this.x = that.x;\n this.y = that.y;\n return this;\n }\n\n /**\n * Swaps x/y of this point and another point\n * @param {XY} that\n */\n swap(that: XY) {\n const x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n }\n\n /**\n * return a cloned instance of the point\n * @return {Point}\n */\n clone(): Point {\n return new Point(this.x, this.y);\n }\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {XY} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\n rotate(radians: TRadian, origin: XY = ZERO): Point {\n // TODO benchmark and verify the add and subtract how much cost\n // and then in case early return if no origin is passed\n const sinus = sin(radians),\n cosinus = cos(radians);\n const p = this.subtract(origin);\n const rotated = new Point(\n p.x * cosinus - p.y * sinus,\n p.x * sinus + p.y * cosinus,\n );\n return rotated.add(origin);\n }\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {TMat2D} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\n transform(t: TMat2D, ignoreOffset = false): Point {\n return new Point(\n t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]),\n t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5]),\n );\n }\n}\n\nexport const ZERO = new Point(0, 0);\n","import type { Constructor, TBBox } from './typedefs';\nimport { removeFromArray } from './util/internals/removeFromArray';\nimport { Point } from './Point';\nimport type { ActiveSelection } from './shapes/ActiveSelection';\nimport type { Group } from './shapes/Group';\nimport type { InteractiveFabricObject } from './shapes/Object/InteractiveObject';\nimport type { FabricObject } from './shapes/Object/FabricObject';\n\nexport const isCollection = (\n fabricObject?: FabricObject,\n): fabricObject is Group | ActiveSelection => {\n return !!fabricObject && Array.isArray((fabricObject as Group)._objects);\n};\n\nexport function createCollectionMixin(Base: TBase) {\n class Collection extends Base {\n /**\n * @type {FabricObject[]}\n * @TODO needs to end up in the constructor too\n */\n _objects: FabricObject[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectAdded(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectRemoved(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onStackOrderChanged(object: FabricObject) {\n // subclasses should override this method\n }\n\n /**\n * Adds objects to collection\n * Objects should be instances of (or inherit from) FabricObject\n * @param {...FabricObject[]} objects to add\n * @returns {number} new array length\n */\n add(...objects: FabricObject[]): number {\n const size = this._objects.push(...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {number} index Index to insert object at\n * @param {...FabricObject[]} objects Object(s) to insert\n * @returns {number} new array length\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n this._objects.splice(index, 0, ...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return this._objects.length;\n }\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @private\n * @param {...FabricObject[]} objects objects to remove\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const array = this._objects,\n removed: FabricObject[] = [];\n objects.forEach((object) => {\n const index = array.indexOf(object);\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n array.splice(index, 1);\n removed.push(object);\n this._onObjectRemoved(object);\n }\n });\n return removed;\n }\n\n /**\n * Executes given function for each object in this group\n * A simple shortcut for getObjects().forEach, before es6 was more complicated,\n * now is just a shortcut.\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n */\n forEachObject(\n callback: (\n object: FabricObject,\n index: number,\n array: FabricObject[],\n ) => any,\n ) {\n this.getObjects().forEach((object, index, objects) =>\n callback(object, index, objects),\n );\n }\n\n /**\n * Returns an array of children objects of this instance\n * @param {...String} [types] When specified, only objects of these types are returned\n * @return {Array}\n */\n getObjects(...types: string[]) {\n if (types.length === 0) {\n return [...this._objects];\n }\n return this._objects.filter((o) => o.isType(...types));\n }\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Object} object at index\n */\n item(index: number) {\n return this._objects[index];\n }\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty() {\n return this._objects.length === 0;\n }\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size() {\n return this._objects.length;\n }\n\n /**\n * Returns true if collection contains an object.\\\n * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons**\n * instead of `a.contains(b)` use `b.isDescendantOf(a)`\n * @param {Object} object Object to check against\n * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`\n * @return {Boolean} `true` if collection contains an object\n */\n contains(object: FabricObject, deep?: boolean): boolean {\n if (this._objects.includes(object)) {\n return true;\n } else if (deep) {\n return this._objects.some(\n (obj) =>\n obj instanceof Collection &&\n (obj as unknown as Collection).contains(object, true),\n );\n }\n return false;\n }\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity() {\n return this._objects.reduce((memo, current) => {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @returns {boolean} true if change occurred\n */\n sendObjectToBack(object: FabricObject) {\n if (!object || object === this._objects[0]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @returns {boolean} true if change occurred\n */\n bringObjectToFront(object: FabricObject) {\n if (!object || object === this._objects[this._objects.length - 1]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.push(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional parameter, `intersecting` allows to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @returns {boolean} true if change occurred\n */\n sendObjectBackwards(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n const newIdx = this.findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional parameter, intersecting allows to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @returns {boolean} true if change occurred\n */\n bringObjectForward(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n const newIdx = this.findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {number} index Position to move to\n * @returns {boolean} true if change occurred\n */\n moveObjectTo(object: FabricObject, index: number) {\n if (object === this._objects[index]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n findNewLowerIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse down the stack looking for the nearest intersecting object\n for (let i = idx - 1; i >= 0; --i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n }\n\n findNewUpperIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse up the stack looking for the nearest intersecting object\n for (let i = idx + 1; i < this._objects.length; ++i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n }\n\n /**\n * Given a bounding box, return all the objects of the collection that are contained in the bounding box.\n * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well.\n * This is meant to work with selection. Is not a generic method.\n * @param {TBBox} bbox a bounding box in scene coordinates\n * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting\n * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise\n */\n collectObjects(\n { left, top, width, height }: TBBox,\n { includeIntersecting = true }: { includeIntersecting?: boolean } = {},\n ) {\n const objects: InteractiveFabricObject[] = [],\n tl = new Point(left, top),\n br = tl.add(new Point(width, height));\n\n // we iterate reverse order to collect top first in case of click.\n for (let i = this._objects.length - 1; i >= 0; i--) {\n const object = this._objects[i] as unknown as InteractiveFabricObject;\n if (\n object.selectable &&\n object.visible &&\n ((includeIntersecting && object.intersectsWithRect(tl, br)) ||\n object.isContainedWithinRect(tl, br) ||\n (includeIntersecting && object.containsPoint(tl)) ||\n (includeIntersecting && object.containsPoint(br)))\n ) {\n objects.push(object);\n }\n }\n\n return objects;\n }\n }\n\n // https://github.com/microsoft/TypeScript/issues/32080\n return Collection as typeof Collection & TBase;\n}\n","import { Observable } from './Observable';\n\nexport class CommonMethods extends Observable {\n /**\n * Sets object's properties from options, for initialization only\n * @protected\n * @param {Object} [options] Options object\n */\n protected _setOptions(options: any = {}) {\n for (const prop in options) {\n this.set(prop, options[prop]);\n }\n }\n\n /**\n * @private\n */\n _setObject(obj: Record) {\n for (const prop in obj) {\n this._set(prop, obj[prop]);\n }\n }\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n */\n set(key: string | Record, value?: any) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n return this;\n }\n\n _set(key: string, value: any) {\n this[key as keyof this] = value;\n }\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n */\n toggle(property: string) {\n const value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n }\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get(property: string): any {\n return this[property as keyof this];\n }\n}\n","import { getFabricWindow } from '../../env';\n\nexport function requestAnimFrame(callback: FrameRequestCallback): number {\n return getFabricWindow().requestAnimationFrame(callback);\n}\n\nexport function cancelAnimFrame(handle: number): void {\n return getFabricWindow().cancelAnimationFrame(handle);\n}\n","let id = 0;\n\nexport const uid = () => id++;\n","import { getFabricDocument } from '../../env';\nimport type { ImageFormat } from '../../typedefs';\nimport { FabricError } from '../internals/console';\n/**\n * Creates canvas element\n * @return {CanvasElement} initialized canvas element\n */\nexport const createCanvasElement = (): HTMLCanvasElement => {\n const element = getFabricDocument().createElement('canvas');\n if (!element || typeof element.getContext === 'undefined') {\n throw new FabricError('Failed to create `canvas` element');\n }\n return element;\n};\n\n/**\n * Creates image element (works on client and node)\n * @return {HTMLImageElement} HTML image element\n */\nexport const createImage = (): HTMLImageElement =>\n getFabricDocument().createElement('img');\n\n/**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @return {CanvasElement} initialized canvas element\n */\nexport const copyCanvasElement = (\n canvas: HTMLCanvasElement,\n): HTMLCanvasElement => {\n const newCanvas = createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d')?.drawImage(canvas, 0, 0);\n return newCanvas;\n};\n\n/**\n * since 2.6.0 moved from canvas instance to utility.\n * possibly useless\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @return {String} data url\n */\nexport const toDataURL = (\n canvasEl: HTMLCanvasElement,\n format: ImageFormat,\n quality: number,\n) => canvasEl.toDataURL(`image/${format}`, quality);\n\nexport const isHTMLCanvas = (\n canvas?: HTMLCanvasElement | string,\n): canvas is HTMLCanvasElement => {\n return !!canvas && (canvas as HTMLCanvasElement).getContext !== undefined;\n};\n","import type { TRadian, TDegree } from '../../typedefs';\nimport { PiBy180 } from '../../constants';\n\n/**\n * Transforms degrees to radians.\n * @param {TDegree} degrees value in degrees\n * @return {TRadian} value in radians\n */\nexport const degreesToRadians = (degrees: TDegree): TRadian =>\n (degrees * PiBy180) as TRadian;\n\n/**\n * Transforms radians to degrees.\n * @param {TRadian} radians value in radians\n * @return {TDegree} value in degrees\n */\nexport const radiansToDegrees = (radians: TRadian): TDegree =>\n (radians / PiBy180) as TDegree;\n","import { iMatrix } from '../../constants';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TDegree, TRadian, TMat2D } from '../../typedefs';\nimport { cos } from './cos';\nimport { degreesToRadians, radiansToDegrees } from './radiansDegreesConversion';\nimport { sin } from './sin';\n\nexport type TRotateMatrixArgs = {\n angle?: TDegree;\n};\n\nexport type TTranslateMatrixArgs = {\n translateX?: number;\n translateY?: number;\n};\n\nexport type TScaleMatrixArgs = {\n scaleX?: number;\n scaleY?: number;\n flipX?: boolean;\n flipY?: boolean;\n skewX?: TDegree;\n skewY?: TDegree;\n};\n\nexport type TComposeMatrixArgs = TTranslateMatrixArgs &\n TRotateMatrixArgs &\n TScaleMatrixArgs;\n\nexport type TQrDecomposeOut = Required<\n Omit\n>;\n\nexport const isIdentityMatrix = (mat: TMat2D) =>\n mat.every((value, index) => value === iMatrix[index]);\n\n/**\n * Apply transform t to point p\n * @deprecated use {@link Point#transform}\n * @param {Point | XY} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\nexport const transformPoint = (\n p: XY,\n t: TMat2D,\n ignoreOffset?: boolean,\n): Point => new Point(p).transform(t, ignoreOffset);\n\n/**\n * Invert transformation t\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\nexport const invertTransform = (t: TMat2D): TMat2D => {\n const a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0] as TMat2D,\n { x, y } = new Point(t[4], t[5]).transform(r, true);\n r[4] = -x;\n r[5] = -y;\n return r;\n};\n\n/**\n * Multiply matrix A by matrix B to nest transformations\n * @param {TMat2D} a First transformMatrix\n * @param {TMat2D} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {TMat2D} The product of the two transform matrices\n */\nexport const multiplyTransformMatrices = (\n a: TMat2D,\n b: TMat2D,\n is2x2?: boolean,\n): TMat2D =>\n [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5],\n ] as TMat2D;\n\n/**\n * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it\n *\n * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))`\n *\n * @param matrices an array of matrices\n * @param [is2x2] flag to multiply matrices as 2x2 matrices\n * @returns the multiplication product\n */\nexport const multiplyTransformMatrixArray = (\n matrices: (TMat2D | undefined | null | false)[],\n is2x2?: boolean,\n) =>\n matrices.reduceRight(\n (product: TMat2D, curr) =>\n curr && product\n ? multiplyTransformMatrices(curr, product, is2x2)\n : curr || product,\n undefined as unknown as TMat2D,\n ) || iMatrix.concat();\n\nexport const calcPlaneRotation = ([a, b]: TMat2D) =>\n Math.atan2(b, a) as TRadian;\n\n/**\n * Decomposes standard 2x3 matrix into transform components\n * @param {TMat2D} a transformMatrix\n * @return {Object} Components of transform\n */\nexport const qrDecompose = (a: TMat2D): TQrDecomposeOut => {\n const angle = calcPlaneRotation(a),\n denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),\n scaleX = Math.sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);\n return {\n angle: radiansToDegrees(angle),\n scaleX,\n scaleY,\n skewX: radiansToDegrees(skewX),\n skewY: 0 as TDegree,\n translateX: a[4] || 0,\n translateY: a[5] || 0,\n };\n};\n\n/**\n * Generate a translation matrix\n *\n * A translation matrix in the form of\n * [ 1 0 x ]\n * [ 0 1 y ]\n * [ 0 0 1 ]\n *\n * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details\n *\n * @param {number} x translation on X axis\n * @param {number} [y] translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createTranslateMatrix = (x: number, y = 0): TMat2D => [\n 1,\n 0,\n 0,\n 1,\n x,\n y,\n];\n\n/**\n * Generate a rotation matrix around around a point (x,y), defaulting to (0,0)\n *\n * A matrix in the form of\n * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x]\n * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y]\n * [0 0 1 ]\n *\n *\n * @param {TDegree} angle rotation in degrees\n * @param {XY} [pivotPoint] pivot point to rotate around\n * @returns {TMat2D} matrix\n */\nexport function createRotateMatrix(\n { angle = 0 }: TRotateMatrixArgs = {},\n { x = 0, y = 0 }: Partial = {},\n): TMat2D {\n const angleRadiant = degreesToRadians(angle),\n cosValue = cos(angleRadiant),\n sinValue = sin(angleRadiant);\n return [\n cosValue,\n sinValue,\n -sinValue,\n cosValue,\n x ? x - (cosValue * x - sinValue * y) : 0,\n y ? y - (sinValue * x + cosValue * y) : 0,\n ];\n}\n\n/**\n * Generate a scale matrix around the point (0,0)\n *\n * A matrix in the form of\n * [x 0 0]\n * [0 y 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale\n *\n * @param {number} x scale on X axis\n * @param {number} [y] scale on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createScaleMatrix = (x: number, y: number = x): TMat2D => [\n x,\n 0,\n 0,\n y,\n 0,\n 0,\n];\n\nexport const angleToSkew = (angle: TDegree) =>\n Math.tan(degreesToRadians(angle));\n\nexport const skewToAngle = (value: TRadian) =>\n radiansToDegrees(Math.atan(value));\n\n/**\n * Generate a skew matrix for the X axis\n *\n * A matrix in the form of\n * [1 x 0]\n * [0 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx\n *\n * @param {TDegree} skewValue translation on X axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewXMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n 0,\n angleToSkew(skewValue),\n 1,\n 0,\n 0,\n];\n\n/**\n * Generate a skew matrix for the Y axis\n *\n * A matrix in the form of\n * [1 0 0]\n * [y 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy\n *\n * @param {TDegree} skewValue translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewYMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n angleToSkew(skewValue),\n 0,\n 1,\n 0,\n 0,\n];\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @return {Number[]} transform matrix\n */\nexport const calcDimensionsMatrix = ({\n scaleX = 1,\n scaleY = 1,\n flipX = false,\n flipY = false,\n skewX = 0 as TDegree,\n skewY = 0 as TDegree,\n}: TScaleMatrixArgs) => {\n let matrix = createScaleMatrix(\n flipX ? -scaleX : scaleX,\n flipY ? -scaleY : scaleY,\n );\n if (skewX) {\n matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true);\n }\n if (skewY) {\n matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true);\n }\n return matrix;\n};\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\nexport const composeMatrix = (options: TComposeMatrixArgs): TMat2D => {\n const { translateX = 0, translateY = 0, angle = 0 as TDegree } = options;\n let matrix = createTranslateMatrix(translateX, translateY);\n if (angle) {\n matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ angle }));\n }\n const scaleMatrix = calcDimensionsMatrix(options);\n if (!isIdentityMatrix(scaleMatrix)) {\n matrix = multiplyTransformMatrices(matrix, scaleMatrix);\n }\n return matrix;\n};\n","import { noop } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {},\n) =>\n new Promise(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n >(\n serializedObj: Record,\n instance: T,\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor & {\n fromObject(options: any, context: Abortable): Promise;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n }),\n ),\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record,\n>(\n serializedObject: any,\n { signal }: Abortable = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n /**\n * clipPath or shadow or gradient or text on a path or a pattern,\n * or the backgroundImage or overlayImage of canvas\n * If we have a type and there is a classe registered for it, we enlive it.\n * If there is no class registered for it we return the value as is\n * */\n if (value.type && classRegistry.has(value.type)) {\n return enlivenObjects([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n","/**\n * Populates an object with properties of another object\n * @param {Object} source Source object\n * @param {string[]} properties Properties names to include\n * @returns object populated with the picked keys\n */\nexport const pick = >(\n source: T,\n keys: (keyof T)[] = [],\n) => {\n return keys.reduce((o, key) => {\n if (key in source) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n\nexport const pickBy = >(\n source: T,\n predicate: (value: T[K], key: K, collection: T) => boolean,\n) => {\n return (Object.keys(source) as (keyof T)[]).reduce((o, key) => {\n if (predicate(source[key], key, source)) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n","/**\n * Map of the 148 color names with HEX code\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\nexport const ColorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#0FF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000',\n blanchedalmond: '#FFEBCD',\n blue: '#00F',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#0FF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#F0F',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#789',\n lightslategrey: '#789',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#0F0',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#F0F',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#639',\n red: '#F00',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FF0',\n yellowgreen: '#9ACD32',\n};\n","import type { TRGBAColorSource } from './typedefs';\n\n/**\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\nexport const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n};\n\n/**\n * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson}\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @param {Number} a Alpha color value pass through\n * @return {TRGBColorSource} Hsl color\n */\nexport const rgb2Hsl = (\n r: number,\n g: number,\n b: number,\n a: number,\n): TRGBAColorSource => {\n r /= 255;\n g /= 255;\n b /= 255;\n const maxValue = Math.max(r, g, b),\n minValue = Math.min(r, g, b);\n\n let h!: number, s: number;\n const l = (maxValue + minValue) / 2;\n\n if (maxValue === minValue) {\n h = s = 0; // achromatic\n } else {\n const d = maxValue - minValue;\n s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue);\n switch (maxValue) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a];\n};\n\nexport const fromAlphaToFloat = (value = '1') =>\n parseFloat(value) / (value.endsWith('%') ? 100 : 1);\n\n/**\n * Convert a value in the inclusive range [0, 255] to hex\n */\nexport const hexify = (value: number) =>\n Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0');\n\n/**\n * Calculate the grey average value for rgb and pass through alpha\n */\nexport const greyAverage = ([\n r,\n g,\n b,\n a = 1,\n]: TRGBAColorSource): TRGBAColorSource => {\n const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11);\n return [avg, avg, avg, a];\n};\n","import { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { ColorNameMap } from './color_map';\nimport { reHSLa, reHex, reRGBa } from './constants';\nimport type { TRGBAColorSource, TColorArg } from './typedefs';\nimport {\n hue2rgb,\n hexify,\n rgb2Hsl,\n fromAlphaToFloat,\n greyAverage,\n} from './util';\n\n/**\n * @class Color common color operations\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors}\n */\nexport class Color {\n private declare _source: TRGBAColorSource;\n isUnrecognised = false;\n\n /**\n *\n * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list\n */\n constructor(color?: TColorArg) {\n if (!color) {\n // we default to black as canvas does\n this.setSource([0, 0, 0, 1]);\n } else if (color instanceof Color) {\n this.setSource([...color._source]);\n } else if (Array.isArray(color)) {\n const [r, g, b, a = 1] = color;\n this.setSource([r, g, b, a]);\n } else {\n this.setSource(this._tryParsingColor(color));\n }\n }\n\n /**\n * @private\n * @param {string} [color] Color value to parse\n * @returns {TRGBAColorSource}\n */\n protected _tryParsingColor(color: string) {\n if (color in ColorNameMap) {\n color = ColorNameMap[color as keyof typeof ColorNameMap];\n }\n return color === 'transparent'\n ? ([255, 255, 255, 0] as TRGBAColorSource)\n : Color.sourceFromHex(color) ||\n Color.sourceFromRgb(color) ||\n Color.sourceFromHsl(color) ||\n // color is not recognized\n // we default to black as canvas does\n // eslint-disable-next-line no-constant-binary-expression\n ((this.isUnrecognised = true) && ([0, 0, 0, 1] as TRGBAColorSource));\n }\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {TRGBAColorSource}\n */\n getSource() {\n return this._source;\n }\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {TRGBAColorSource} source\n */\n setSource(source: TRGBAColorSource) {\n this._source = source;\n }\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb() {\n const [r, g, b] = this.getSource();\n return `rgb(${r},${g},${b})`;\n }\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba() {\n return `rgba(${this.getSource().join(',')})`;\n }\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl() {\n const [h, s, l] = rgb2Hsl(...this.getSource());\n return `hsl(${h},${s}%,${l}%)`;\n }\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla() {\n const [h, s, l, a] = rgb2Hsl(...this.getSource());\n return `hsla(${h},${s}%,${l}%,${a})`;\n }\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex() {\n const fullHex = this.toHexa();\n return fullHex.slice(0, 6);\n }\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa() {\n const [r, g, b, a] = this.getSource();\n return `${hexify(r)}${hexify(g)}${hexify(b)}${hexify(Math.round(a * 255))}`;\n }\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha() {\n return this.getSource()[3];\n }\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {Color} thisArg\n */\n setAlpha(alpha: number) {\n this._source[3] = alpha;\n return this;\n }\n\n /**\n * Transforms color to its grayscale representation\n * @return {Color} thisArg\n */\n toGrayscale() {\n this.setSource(greyAverage(this.getSource()));\n return this;\n }\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {Color} thisArg\n */\n toBlackWhite(threshold: number) {\n const [average, , , a] = greyAverage(this.getSource()),\n bOrW = average < (threshold || 127) ? 0 : 255;\n this.setSource([bOrW, bOrW, bOrW, a]);\n return this;\n }\n\n /**\n * Overlays color with another color\n * @param {String|Color} otherColor\n * @return {Color} thisArg\n */\n overlayWith(otherColor: string | Color) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n const source = this.getSource(),\n otherAlpha = 0.5,\n otherSource = otherColor.getSource(),\n [R, G, B] = source.map((value, index) =>\n Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha),\n );\n\n this.setSource([R, G, B, source[3]]);\n return this;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {Color}\n */\n static fromRgb(color: string): Color {\n return Color.fromRgba(color);\n }\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromRgba(color: string): Color {\n return new Color(Color.sourceFromRgb(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromRgb(color: string): TRGBAColorSource | undefined {\n const match = color.match(reRGBa());\n if (match) {\n const [r, g, b] = match.slice(1, 4).map((value) => {\n const parsedValue = parseFloat(value);\n return value.endsWith('%')\n ? Math.round(parsedValue * 2.55)\n : parsedValue;\n });\n return [r, g, b, fromAlphaToFloat(match[4])];\n }\n }\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf Color\n * @return {Color}\n */\n static fromHsl(color: string): Color {\n return Color.fromHsla(color);\n }\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromHsla(color: string): Color {\n return new Color(Color.sourceFromHsl(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {TRGBAColorSource | undefined} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n static sourceFromHsl(color: string): TRGBAColorSource | undefined {\n const match = color.match(reHSLa());\n if (!match) {\n return;\n }\n const match1degrees = Color.parseAngletoDegrees(match[1]);\n\n const h = (((match1degrees % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / 100,\n l = parseFloat(match[3]) / 100;\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n fromAlphaToFloat(match[4]),\n ];\n }\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf Color\n * @param {String} color Color value ex: FF5555\n * @return {Color}\n */\n static fromHex(color: string): Color {\n return new Color(Color.sourceFromHex(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromHex(color: string): TRGBAColorSource | undefined {\n if (color.match(reHex())) {\n const value = color.slice(color.indexOf('#') + 1),\n isShortNotation = value.length <= 4;\n let expandedValue: string[];\n if (isShortNotation) {\n expandedValue = value.split('').map((hex) => hex + hex);\n } else {\n expandedValue = value.match(/.{2}/g)!;\n }\n const [r, g, b, a = 255] = expandedValue.map((hexCouple) =>\n parseInt(hexCouple, 16),\n );\n return [r, g, b, a / 255];\n }\n }\n\n /**\n * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad)\n * into degrees without the 'deg' suffix\n * @static\n * @memberOf Color\n * @param {String} value ex: 0deg, 0.5turn, 2rad\n * @return {Number} number in degrees or NaN if inputs are invalid\n */\n static parseAngletoDegrees(value: string): number {\n const lowercase = value.toLowerCase();\n const numeric = parseFloat(lowercase);\n\n if (lowercase.includes('rad')) {\n return radiansToDegrees(numeric);\n }\n\n if (lowercase.includes('turn')) {\n return numeric * 360;\n }\n\n // Value is probably just a number already in degrees eg '50'\n return numeric;\n }\n}\n","/**\n * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`)\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb\n * Formal syntax at the time of writing:\n * =\n * rgb( [ | none ]{3} [ / [ | none ] ]? ) |\n * rgb( [ | none ]{3} [ / [ | none ] ]? )\n * = | \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an rgba or rgb CSS color value\n *\n * /^ # Beginning of the string\n * rgba? # \"rgb\" or \"rgba\"\n * \\(\\s* # Opening parenthesis and optional whitespace\n * (\\d{0,3} # 0 to three digits R channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the first color component\n * %? # Optional percent sign after the first color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits G channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the second color component\n * %? # Optional percent sign after the second color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits B channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the third color component\n * %? # Optional percent sign after the third color component\n * \\s* # Optional whitespace\n * (?: # Beginning of non-capturing group for alpha value\n * \\s* # Optional whitespace\n * [,/] # Comma or slash separator for alpha value\n * \\s* # Optional whitespace\n * (\\d{0,3} # Zero to three digits\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for alpha value\n * %? # Optional percent sign after alpha value\n * \\s* # Optional whitespace\n * )? # End of non-capturing group for alpha value (optional)\n * \\) # Closing parenthesis\n * $ # End of the string\n *\n * The alpha channel can be in the format 0.4 .7 or 1 or 73%\n *\n * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color.\n * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us\n */\nexport const reRGBa = () =>\n /^rgba?\\(\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl\n * Formal syntax at the time of writing:\n * =\n * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? )\n *\n * =\n * |\n * \n *\n * =\n * |\n * \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an hsla or hsl CSS color value\n *\n * /^hsla?\\( // Matches the beginning of the string and the opening parenthesis of \"hsl\" or \"hsla\"\n * \\s* // Matches any whitespace characters (space, tab, etc.) zero or more times\n * (\\d{0,3} // Hue: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Hue: Optional (non capture group) decimal with one or more digits.\n * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad\n * ) // Hue: End capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Saturation: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group\n * %?) // Saturation: match optional % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Lightness: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group\n * %?) // Lightness: match % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * (?: // Alpha: Begins a non-capturing group for the alpha value\n * \\s* // Matches any whitespace characters zero or more times\n * [,/] // Matches a comma or forward slash\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d*(?:\\.\\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group\n * \\s* // Matches any whitespace characters zero or more times\n * )? // Makes the alpha value group optional\n * \\) // Matches the closing parenthesis\n * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode\n *\n * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color.\n * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us.\n */\nexport const reHSLa = () =>\n /^hsla?\\(\\s*([+-]?\\d{0,3}(?:\\.\\d+)?(?:deg|turn|rad)?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d*(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n */\nexport const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i;\n","/**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @param {number|string} number number to operate on\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {number}\n */\nexport const toFixed = (number: number | string, fractionDigits: number) =>\n parseFloat(Number(number).toFixed(fractionDigits));\n","import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return ``;\n};\n","import type { FabricObject } from '../shapes/Object/Object';\nimport type { TFiller } from '../typedefs';\nimport type { FabricText } from '../shapes/Text/Text';\nimport type { Pattern } from '../Pattern';\nimport type { Path } from '../shapes/Path';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\n\nexport const isFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && (filler as TFiller).toLive !== undefined;\n};\n\nexport const isSerializableFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && typeof (filler as TFiller).toObject === 'function';\n};\n\nexport const isPattern = (filler: TFiller): filler is Pattern => {\n return (\n !!filler && (filler as Pattern).offsetX !== undefined && 'source' in filler\n );\n};\n\nexport const isTextObject = (\n fabricObject?: FabricObject,\n): fabricObject is FabricText => {\n return (\n !!fabricObject &&\n typeof (fabricObject as FabricText)._renderText === 'function'\n );\n};\n\nexport const isPath = (fabricObject?: FabricObject): fabricObject is Path => {\n // we could use instanceof but that would mean pulling in Text code for a simple check\n // @todo discuss what to do and how to do\n return (\n !!fabricObject &&\n typeof (fabricObject as Path)._renderPathCommands === 'function'\n );\n};\n\nexport const isActiveSelection = (\n fabricObject?: FabricObject,\n): fabricObject is ActiveSelection =>\n !!fabricObject && 'multiSelectionStacking' in fabricObject;\n","/**\n * Returns element scroll offsets\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\nexport function getScrollLeftTop(element: HTMLElement | null) {\n const doc = element && getDocumentFromElement(element);\n let left = 0,\n top = 0;\n if (!element || !doc) {\n return { left, top };\n }\n let elementLoop: HTMLElement | Document | ShadowRoot = element;\n const docElement = doc.documentElement,\n body = doc.body || {\n scrollLeft: 0,\n scrollTop: 0,\n };\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (\n elementLoop &&\n (elementLoop.parentNode || (elementLoop as unknown as ShadowRoot).host)\n ) {\n elementLoop = (elementLoop.parentNode ||\n (elementLoop as unknown as ShadowRoot).host) as\n | HTMLElement\n | Document\n | ShadowRoot;\n if (elementLoop === doc) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n } else {\n left += (elementLoop as HTMLElement).scrollLeft || 0;\n top += (elementLoop as HTMLElement).scrollTop || 0;\n }\n\n if (\n elementLoop.nodeType === 1 &&\n (elementLoop as HTMLElement).style.position === 'fixed'\n ) {\n break;\n }\n }\n\n return { left, top };\n}\n\nexport const getDocumentFromElement = (el: HTMLElement) =>\n el.ownerDocument || null;\n\nexport const getWindowFromElement = (el: HTMLElement) =>\n el.ownerDocument?.defaultView || null;\n","import { NONE } from '../../constants';\nimport type { TSize } from '../../typedefs';\nimport {\n getDocumentFromElement,\n getWindowFromElement,\n getScrollLeftTop,\n} from '../../util/dom_misc';\n\nexport const setCanvasDimensions = (\n el: HTMLCanvasElement,\n ctx: CanvasRenderingContext2D,\n { width, height }: TSize,\n retinaScaling = 1,\n) => {\n el.width = width;\n el.height = height;\n if (retinaScaling > 1) {\n el.setAttribute('width', (width * retinaScaling).toString());\n el.setAttribute('height', (height * retinaScaling).toString());\n ctx.scale(retinaScaling, retinaScaling);\n }\n};\n\nexport type CSSDimensions = {\n width: number | string;\n height: number | string;\n};\n\nexport const setCSSDimensions = (\n el: HTMLElement,\n { width, height }: Partial,\n) => {\n width && (el.style.width = typeof width === 'number' ? `${width}px` : width);\n height &&\n (el.style.height = typeof height === 'number' ? `${height}px` : height);\n};\n\n/**\n * Returns offset for a given element\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\nexport function getElementOffset(element: HTMLElement) {\n const doc = element && getDocumentFromElement(element),\n offset = { left: 0, top: 0 };\n\n if (!doc) {\n return offset;\n }\n const elemStyle: CSSStyleDeclaration =\n getWindowFromElement(element)?.getComputedStyle(element, null) ||\n ({} as CSSStyleDeclaration);\n offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;\n offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;\n offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;\n offset.top += parseInt(elemStyle.paddingTop, 10) || 0;\n\n let box = { left: 0, top: 0 };\n\n const docElem = doc.documentElement;\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n const scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left:\n box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top,\n };\n}\n\n/**\n * Makes element unselectable\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\nexport function makeElementUnselectable(element: HTMLElement) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = () => false;\n }\n element.style.userSelect = NONE;\n return element;\n}\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport type { CSSDimensions } from './util';\nimport { setCSSDimensions, getElementOffset } from './util';\nimport { createCanvasElement, isHTMLCanvas } from '../../util/misc/dom';\nimport { setCanvasDimensions } from './util';\nimport { FabricError } from '../../util/internals/console';\n\nexport type CanvasItem = {\n el: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n};\n\nexport class StaticCanvasDOMManager {\n /**\n * Keeps a copy of the canvas style before setting retina scaling and other potions\n * in order to return it to original state on dispose\n * @type string\n */\n private _originalCanvasStyle?: string;\n\n lower: CanvasItem;\n\n constructor(arg0?: string | HTMLCanvasElement) {\n const el = this.createLowerCanvas(arg0);\n this.lower = { el, ctx: el.getContext('2d')! };\n }\n\n protected createLowerCanvas(arg0?: HTMLCanvasElement | string) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n const el = isHTMLCanvas(arg0)\n ? arg0\n : (arg0 &&\n (getFabricDocument().getElementById(arg0) as HTMLCanvasElement)) ||\n createCanvasElement();\n if (el.hasAttribute('data-fabric')) {\n throw new FabricError(\n 'Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?',\n );\n }\n this._originalCanvasStyle = el.style.cssText;\n el.setAttribute('data-fabric', 'main');\n el.classList.add('lower-canvas');\n return el;\n }\n\n cleanupDOM({ width, height }: TSize) {\n const { el } = this.lower;\n // restore canvas style and attributes\n el.classList.remove('lower-canvas');\n el.removeAttribute('data-fabric');\n // restore canvas size to original size in case retina scaling was applied\n el.setAttribute('width', `${width}`);\n el.setAttribute('height', `${height}`);\n el.style.cssText = this._originalCanvasStyle || '';\n this._originalCanvasStyle = undefined;\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n const { el, ctx } = this.lower;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial) {\n setCSSDimensions(this.lower.el, size);\n }\n\n /**\n * Calculates canvas element offset relative to the document\n */\n calcOffset() {\n return getElementOffset(this.lower.el);\n }\n\n dispose() {\n getEnv().dispose(this.lower.el);\n // @ts-expect-error disposing\n delete this.lower;\n }\n}\n","import { iMatrix } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TFiller, TMat2D, TOptions } from '../typedefs';\n\ninterface CanvasDrawableOptions {\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n backgroundVpt: boolean;\n\n /**\n * Background color of canvas instance.\n * @type {(String|TFiller)}\n * @default\n */\n backgroundColor: TFiller | string;\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n backgroundImage?: FabricObject;\n\n /**\n * if set to false overlay image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n overlayVpt: boolean;\n\n /**\n * Overlay color of canvas instance.\n * @since 1.3.9\n * @type {(String|TFiller)}\n * @default\n */\n overlayColor: TFiller | string;\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n overlayImage?: FabricObject;\n}\n\ninterface CanvasRenderingOptions {\n /**\n * Indicates whether {@link StaticCanvas#add}, {@link StaticCanvas#insertAt} and {@link StaticCanvas#remove},\n * {@link StaticCanvas#moveTo}, {@link StaticCanvas#clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are queued and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: boolean;\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @type Boolean\n * @default true\n */\n skipOffscreen: boolean;\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: boolean;\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: boolean;\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type FabricObject\n */\n clipPath?: FabricObject;\n}\n\nexport interface CanvasExportOptions {\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: boolean;\n\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: boolean;\n}\n\nexport interface StaticCanvasOptions\n extends CanvasDrawableOptions,\n CanvasRenderingOptions,\n CanvasExportOptions {\n /**\n * Width in virtual/logical pixels of the canvas.\n * The canvas can be larger than width if retina scaling is active\n * @type number\n */\n width: number;\n\n /**\n * Height in virtual/logical pixels of the canvas.\n * The canvas can be taller than width if retina scaling is active\n * @type height\n */\n height: number;\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n controlsAboveOverlay: boolean;\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n allowTouchScrolling: boolean;\n\n /**\n * The transformation (a Canvas 2D API transform matrix) which focuses the viewport\n * @type Array\n * @example Default transform\n * canvas.viewportTransform = [1, 0, 0, 1, 0, 0];\n * @example Scale by 70% and translate toward bottom-right by 50, without skewing\n * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];\n * @default\n */\n viewportTransform: TMat2D;\n}\n\nexport const staticCanvasDefaults: TOptions = {\n backgroundVpt: true,\n backgroundColor: '',\n overlayVpt: true,\n overlayColor: '',\n\n includeDefaultValues: true,\n svgViewportTransformation: true,\n\n renderOnAddRemove: true,\n skipOffscreen: true,\n enableRetinaScaling: true,\n imageSmoothingEnabled: true,\n\n /**\n * @todo move to Canvas\n */\n controlsAboveOverlay: false,\n /**\n * @todo move to Canvas\n */\n allowTouchScrolling: false,\n\n viewportTransform: [...iMatrix],\n};\n","import { config } from '../config';\nimport { CENTER, VERSION } from '../constants';\nimport type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs';\nimport type { Gradient } from '../gradient/Gradient';\nimport { createCollectionMixin, isCollection } from '../Collection';\nimport { CommonMethods } from '../CommonMethods';\nimport type { Pattern } from '../Pattern';\nimport { Point } from '../Point';\nimport type { TCachedFabricObject } from '../shapes/Object/Object';\nimport type {\n Abortable,\n Constructor,\n TCornerPoint,\n TDataUrlOptions,\n TFiller,\n TMat2D,\n TSize,\n TSVGReviver,\n TToCanvasElementOptions,\n TValidToObjectMethod,\n TOptions,\n} from '../typedefs';\nimport {\n cancelAnimFrame,\n requestAnimFrame,\n} from '../util/animation/AnimationFrameProvider';\nimport { runningAnimations } from '../util/animation/AnimationRegistry';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement, toDataURL } from '../util/misc/dom';\nimport { invertTransform, transformPoint } from '../util/misc/matrix';\nimport type { EnlivenObjectOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { toFixed } from '../util/misc/toFixed';\nimport { isFiller, isPattern, isTextObject } from '../util/typeAssertions';\nimport { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager';\nimport type { CSSDimensions } from './DOMManagers/util';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\nimport { staticCanvasDefaults } from './StaticCanvasOptions';\nimport { log, FabricError } from '../util/internals/console';\nimport { getDevicePixelRatio } from '../env';\n\n/**\n * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset\n * Better try to restrict with types to avoid confusion.\n */\nexport type TCanvasSizeOptions =\n | {\n backstoreOnly?: true;\n cssOnly?: false;\n }\n | {\n backstoreOnly?: false;\n cssOnly?: true;\n };\n\nexport type TSVGExportOptions = {\n suppressPreamble?: boolean;\n viewBox?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n encoding?: 'UTF-8'; // test Encoding type and see what happens\n width?: string;\n height?: string;\n reviver?: TSVGReviver;\n};\n\n/**\n * Static canvas class\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260\nexport class StaticCanvas<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends StaticCanvasEvents = StaticCanvasEvents,\n >\n extends createCollectionMixin(CommonMethods)\n implements StaticCanvasOptions\n{\n declare width: number;\n declare height: number;\n\n // background\n declare backgroundVpt: boolean;\n declare backgroundColor: TFiller | string;\n declare backgroundImage?: FabricObject;\n // overlay\n declare overlayVpt: boolean;\n declare overlayColor: TFiller | string;\n declare overlayImage?: FabricObject;\n\n declare clipPath?: FabricObject;\n\n declare includeDefaultValues: boolean;\n\n // rendering config\n declare renderOnAddRemove: boolean;\n declare skipOffscreen: boolean;\n declare enableRetinaScaling: boolean;\n declare imageSmoothingEnabled: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare controlsAboveOverlay: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare allowTouchScrolling: boolean;\n\n declare viewportTransform: TMat2D;\n\n /**\n * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries}\n */\n declare vptCoords: TCornerPoint;\n\n /**\n * A reference to the canvas actual HTMLCanvasElement.\n * Can be use to read the raw pixels, but never write or manipulate\n * @type HTMLCanvasElement\n */\n get lowerCanvasEl() {\n return this.elements.lower?.el;\n }\n\n get contextContainer() {\n return this.elements.lower?.ctx;\n }\n\n /**\n * If true the Canvas is in the process or has been disposed/destroyed.\n * No more rendering operation will be executed on this canvas.\n * @type boolean\n */\n declare destroyed?: boolean;\n\n /**\n * Started the process of disposing but not done yet.\n * WIll likely complete the render cycle already scheduled but stopping adding more.\n * @type boolean\n */\n declare disposed?: boolean;\n\n declare _offset: { left: number; top: number };\n protected declare hasLostContext: boolean;\n protected declare nextRenderHandle: number;\n\n declare elements: StaticCanvasDOMManager;\n\n /**\n * When true control drawing is skipped.\n * This boolean is used to avoid toDataURL to export controls.\n * Usage of this boolean to build up other flows and features is not supported\n * @type Boolean\n * @default false\n */\n protected declare skipControlsDrawing: boolean;\n\n static ownDefaults = staticCanvasDefaults;\n\n // reference to\n protected declare __cleanupTask?: {\n (): void;\n kill: (reason?: any) => void;\n };\n\n static getDefaults(): Record {\n return StaticCanvas.ownDefaults;\n }\n\n constructor(\n el?: string | HTMLCanvasElement,\n options: TOptions = {},\n ) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof StaticCanvas).getDefaults(),\n );\n this.set(options);\n this.initElements(el);\n this._setDimensionsImpl({\n width: this.width || this.elements.lower.el.width || 0,\n height: this.height || this.elements.lower.el.height || 0,\n });\n this.skipControlsDrawing = false;\n this.viewportTransform = [...this.viewportTransform];\n this.calcViewportBoundaries();\n }\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new StaticCanvasDOMManager(el);\n }\n\n add(...objects: FabricObject[]) {\n const size = super.add(...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n insertAt(index: number, ...objects: FabricObject[]) {\n const size = super.insertAt(index, ...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return removed;\n }\n\n _onObjectAdded(obj: FabricObject) {\n if (obj.canvas && (obj.canvas as StaticCanvas) !== this) {\n log(\n 'warn',\n 'Canvas is trying to add an object that belongs to a different canvas.\\n' +\n 'Resulting to default behavior: removing object from previous canvas and adding to new canvas',\n );\n obj.canvas.remove(obj);\n }\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added', { target: this });\n }\n\n _onObjectRemoved(obj: FabricObject) {\n obj._set('canvas', undefined);\n this.fire('object:removed', { target: obj });\n obj.fire('removed', { target: this });\n }\n\n _onStackOrderChanged() {\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * @private\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling() {\n return this.enableRetinaScaling ? getDevicePixelRatio() : 1;\n }\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n */\n calcOffset() {\n return (this._offset = this.elements.calcOffset());\n }\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth(): number {\n return this.width;\n }\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight(): number {\n return this.height;\n }\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setWidth(\n value: TSize['width'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setWidth(\n value: CSSDimensions['width'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setWidth(value: number, options?: never) {\n return this.setDimensions({ width: value }, options);\n }\n\n /**s\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setHeight(\n value: TSize['height'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setHeight(\n value: CSSDimensions['height'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setHeight(value: CSSDimensions['height'], options?: never) {\n return this.setDimensions({ height: value }, options);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: Partial,\n { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {},\n ) {\n if (!cssOnly) {\n const size = {\n width: this.width,\n height: this.height,\n ...(dimensions as Partial),\n };\n this.elements.setDimensions(size, this.getRetinaScaling());\n this.hasLostContext = true;\n this.width = size.width;\n this.height = size.height;\n }\n if (!backstoreOnly) {\n this.elements.setCSSDimensions(dimensions);\n }\n\n this.calcOffset();\n }\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n */\n setDimensions(\n dimensions: Partial,\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setDimensions(\n dimensions: Partial,\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setDimensions(dimensions: Partial, options?: never): void;\n setDimensions(\n dimensions: Partial,\n options?: TCanvasSizeOptions,\n ) {\n this._setDimensionsImpl(dimensions, options);\n if (!options || !options.cssOnly) {\n this.requestRenderAll();\n }\n }\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom() {\n return this.viewportTransform[0];\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n this.viewportTransform = vpt;\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Sets zoom level of this canvas instance, the zoom centered around point\n * meaning that following zoom to point with the same point will have the visual\n * effect of the zoom originating from that point. The point won't move.\n * It has nothing to do with canvas center or visual center of the viewport.\n * @param {Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n zoomToPoint(point: Point, value: number) {\n // TODO: just change the scale, preserve other transformations\n const before = point,\n vpt: TMat2D = [...this.viewportTransform];\n const newPoint = transformPoint(point, invertTransform(vpt));\n vpt[0] = value;\n vpt[3] = value;\n const after = transformPoint(newPoint, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n this.setViewportTransform(vpt);\n }\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n setZoom(value: number) {\n this.zoomToPoint(new Point(0, 0), value);\n }\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {Point} point to move to\n */\n absolutePan(point: Point) {\n const vpt: TMat2D = [...this.viewportTransform];\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n }\n\n /**\n * Pans viewpoint relatively\n * @param {Point} point (position vector) to move by\n */\n relativePan(point: Point) {\n return this.absolutePan(\n new Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5],\n ),\n );\n }\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement(): HTMLCanvasElement {\n return this.elements.lower.el;\n }\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n */\n clearContext(ctx: CanvasRenderingContext2D) {\n ctx.clearRect(0, 0, this.width, this.height);\n }\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext(): CanvasRenderingContext2D {\n return this.elements.lower.ctx;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n this.remove(...this.getObjects());\n this.backgroundImage = undefined;\n this.overlayImage = undefined;\n this.backgroundColor = '';\n this.overlayColor = '';\n this.clearContext(this.getContext());\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Renders the canvas\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n this.renderCanvas(this.getContext(), this._objects);\n }\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n */\n renderAndReset() {\n this.nextRenderHandle = 0;\n this.renderAll();\n }\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n */\n requestRenderAll() {\n if (!this.nextRenderHandle && !this.disposed && !this.destroyed) {\n this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset());\n }\n }\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport\n */\n calcViewportBoundaries(): TCornerPoint {\n const width = this.width,\n height = this.height,\n iVpt = invertTransform(this.viewportTransform),\n a = transformPoint({ x: 0, y: 0 }, iVpt),\n b = transformPoint({ x: width, y: height }, iVpt),\n // we don't support vpt flipping\n // but the code is robust enough to mostly work with flipping\n min = a.min(b),\n max = a.max(b);\n return (this.vptCoords = {\n tl: min,\n tr: new Point(max.x, min.y),\n bl: new Point(min.x, max.y),\n br: max,\n });\n }\n\n cancelRequestedRender() {\n if (this.nextRenderHandle) {\n cancelAnimFrame(this.nextRenderHandle);\n this.nextRenderHandle = 0;\n }\n }\n\n drawControls(_ctx: CanvasRenderingContext2D) {\n // Static canvas has no controls\n }\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n */\n renderCanvas(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n if (this.destroyed) {\n return;\n }\n\n const v = this.viewportTransform,\n path = this.clipPath;\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n // @ts-expect-error node-canvas stuff\n ctx.patternQuality = 'best';\n this.fire('before:render', { ctx });\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n if (path) {\n path._set('canvas', this);\n // needed to setup a couple of variables\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCanvas(ctx, path as TCachedFabricObject);\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n this.fire('after:render', { ctx });\n\n if (this.__cleanupTask) {\n this.__cleanupTask();\n this.__cleanupTask = undefined;\n }\n }\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n const v = this.viewportTransform;\n ctx.save();\n ctx.transform(...v);\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n ctx.globalCompositeOperation = 'destination-in';\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n for (let i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay(\n ctx: CanvasRenderingContext2D,\n property: 'background' | 'overlay',\n ) {\n const fill = this[`${property}Color`],\n object = this[`${property}Image`],\n v = this.viewportTransform,\n needsVpt = this[`${property}Vpt`];\n if (!fill && !object) {\n return;\n }\n const isAFiller = isFiller(fill);\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */)! : fill;\n if (needsVpt) {\n ctx.transform(...v);\n }\n if (isAFiller) {\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n const m = ((fill as Gradient<'linear'>).gradientTransform ||\n (fill as Pattern).patternTransform) as TMat2D;\n m && ctx.transform(...m);\n }\n ctx.fill();\n ctx.restore();\n }\n if (object) {\n ctx.save();\n const { skipOffscreen } = this;\n // if the object doesn't move with the viewport,\n // the offscreen concept does not apply;\n this.skipOffscreen = needsVpt;\n if (needsVpt) {\n ctx.transform(...v);\n }\n object.render(ctx);\n this.skipOffscreen = skipOffscreen;\n ctx.restore();\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n * @deprecated migrate to `getCenterPoint`\n */\n getCenter() {\n return {\n top: this.height / 2,\n left: this.width / 2,\n };\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * @return {Point}\n */\n getCenterPoint() {\n return new Point(this.width / 2, this.height / 2);\n }\n\n /**\n * Centers object horizontally in the canvas\n */\n centerObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getCenterPoint().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically in the canvas\n * @param {FabricObject} object Object to center vertically\n */\n centerObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n centerObject(object: FabricObject) {\n return this._centerObject(object, this.getCenterPoint());\n }\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObject(object: FabricObject) {\n return this._centerObject(object, this.getVpCenter());\n }\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getVpCenter().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getVpCenter().y),\n );\n }\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {Point} vpCenter, viewport center\n */\n getVpCenter(): Point {\n return transformPoint(\n this.getCenterPoint(),\n invertTransform(this.viewportTransform),\n );\n }\n\n /**\n * @private\n * @param {FabricObject} object Object to center\n * @param {Point} center Center point\n */\n _centerObject(object: FabricObject, center: Point) {\n object.setXY(center, CENTER, CENTER);\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Returns dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON(propertiesToInclude?: string[]) {\n return this.toDatalessObject(propertiesToInclude);\n }\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n }\n\n /**\n * Returns Object representation of canvas\n * this alias is provided because if you call JSON.stringify on an instance,\n * the toJSON object will be invoked if it exists.\n * Having a toJSON method means you can do JSON.stringify(myCanvas)\n * @return {Object} JSON compatible object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example JSON without default values\n * var json = canvas.toJSON();\n */\n toJSON() {\n return this.toObject();\n }\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n }\n\n /**\n * @private\n */\n _toObjectMethod(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const clipPath = this.clipPath;\n const clipPathData =\n clipPath && !clipPath.excludeFromExport\n ? this._toObject(clipPath, methodName, propertiesToInclude)\n : null;\n return {\n version: VERSION,\n ...pick(this, propertiesToInclude as (keyof this)[]),\n objects: this._objects\n .filter((object) => !object.excludeFromExport)\n .map((instance) =>\n this._toObject(instance, methodName, propertiesToInclude),\n ),\n ...this.__serializeBgOverlay(methodName, propertiesToInclude),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n let originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n const object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = !!originalValue;\n }\n return object;\n }\n\n /**\n * @private\n */\n __serializeBgOverlay(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const data: any = {},\n bgImage = this.backgroundImage,\n overlayImage = this.overlayImage,\n bgColor = this.backgroundColor,\n overlayColor = this.overlayColor;\n\n if (isFiller(bgColor)) {\n if (!bgColor.excludeFromExport) {\n data.background = bgColor.toObject(propertiesToInclude);\n }\n } else if (bgColor) {\n data.background = bgColor;\n }\n\n if (isFiller(overlayColor)) {\n if (!overlayColor.excludeFromExport) {\n data.overlay = overlayColor.toObject(propertiesToInclude);\n }\n } else if (overlayColor) {\n data.overlay = overlayColor;\n }\n\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(\n bgImage,\n methodName,\n propertiesToInclude,\n );\n }\n if (overlayImage && !overlayImage.excludeFromExport) {\n data.overlayImage = this._toObject(\n overlayImage,\n methodName,\n propertiesToInclude,\n );\n }\n\n return data;\n }\n\n /* _TO_SVG_START_ */\n\n declare svgViewportTransformation: boolean;\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-coordinate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG(options: TSVGExportOptions = {}, reviver?: TSVGReviver) {\n options.reviver = reviver;\n const markup: string[] = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n if (this.clipPath) {\n markup.push(`\\n`);\n }\n this._setSVGBgOverlayColor(markup, 'background');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n this._setSVGObjects(markup, reviver);\n if (this.clipPath) {\n markup.push('\\n');\n }\n this._setSVGBgOverlayColor(markup, 'overlay');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n }\n\n /**\n * @private\n */\n _setSVGPreamble(markup: string[], options: TSVGExportOptions): void {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n',\n );\n }\n\n /**\n * @private\n */\n _setSVGHeader(markup: string[], options: TSVGExportOptions): void {\n const width = options.width || `${this.width}`,\n height = options.height || `${this.height}`,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,\n optViewBox = options.viewBox;\n let viewBox: string;\n if (optViewBox) {\n viewBox = `viewBox=\"${optViewBox.x} ${optViewBox.y} ${optViewBox.width} ${optViewBox.height}\" `;\n } else if (this.svgViewportTransformation) {\n const vpt = this.viewportTransform;\n viewBox = `viewBox=\"${toFixed(\n -vpt[4] / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS)} ${toFixed(\n this.width / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS)}\" `;\n } else {\n viewBox = `viewBox=\"0 0 ${this.width} ${this.height}\" `;\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ',\n VERSION,\n '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n this.createSVGClipPathMarkup(options),\n '\\n',\n );\n }\n\n createSVGClipPathMarkup(options: TSVGExportOptions): string {\n const clipPath = this.clipPath;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n return `\\n${clipPath.toClipPathSVG(\n options.reviver,\n )}\\n`;\n }\n return '';\n }\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup(): string {\n return (['background', 'overlay'] as const)\n .map((prop) => {\n const fill = this[`${prop}Color`];\n if (isFiller(fill)) {\n const shouldTransform = this[`${prop}Vpt`],\n vpt = this.viewportTransform,\n object = {\n // otherwise circular dependency\n isType: () => false,\n width: this.width / (shouldTransform ? vpt[0] : 1),\n height: this.height / (shouldTransform ? vpt[3] : 1),\n };\n return fill.toSVG(object as FabricObject, {\n additionalTransform: shouldTransform ? matrixToSVG(vpt) : '',\n });\n }\n })\n .join('');\n }\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup(): string {\n const objects: FabricObject[] = [],\n fontList: Record = {},\n fontPaths = config.fontPaths;\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n if (isCollection(object)) {\n object._objects.forEach(add);\n }\n });\n\n objects.forEach((obj) => {\n if (!isTextObject(obj)) {\n return;\n }\n const { styles, fontFamily } = obj;\n if (fontList[fontFamily] || !fontPaths[fontFamily]) {\n return;\n }\n fontList[fontFamily] = true;\n if (!styles) {\n return;\n }\n Object.values(styles).forEach((styleRow) => {\n Object.values(styleRow).forEach(({ fontFamily = '' }) => {\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n });\n });\n });\n\n const fontListMarkup = Object.keys(fontList)\n .map(\n (fontFamily) =>\n `\\t\\t@font-face {\\n\\t\\t\\tfont-family: '${fontFamily}';\\n\\t\\t\\tsrc: url('${fontPaths[fontFamily]}');\\n\\t\\t}\\n`,\n )\n .join('');\n\n if (fontListMarkup) {\n return `\\t\\n`;\n }\n return '';\n }\n\n /**\n * @private\n */\n _setSVGObjects(markup: string[], reviver?: TSVGReviver) {\n this.forEachObject((fabricObject) => {\n if (fabricObject.excludeFromExport) {\n return;\n }\n this._setSVGObject(markup, fabricObject, reviver);\n });\n }\n\n /**\n * This is its own function because the Canvas ( non static ) requires extra code here\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n markup.push(instance.toSVG(reviver));\n }\n\n /**\n * @private\n */\n _setSVGBgOverlayImage(\n markup: string[],\n property: 'overlayImage' | 'backgroundImage',\n reviver?: TSVGReviver,\n ) {\n const bgOrOverlay = this[property];\n if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) {\n markup.push(bgOrOverlay.toSVG(reviver));\n }\n }\n\n /**\n * @TODO this seems to handle patterns but fail at gradients.\n * @private\n */\n _setSVGBgOverlayColor(markup: string[], property: 'background' | 'overlay') {\n const filler = this[`${property}Color`];\n if (!filler) {\n return;\n }\n if (isFiller(filler)) {\n const repeat = (filler as Pattern).repeat || '',\n finalWidth = this.width,\n finalHeight = this.height,\n shouldInvert = this[`${property}Vpt`],\n additionalTransform = shouldInvert\n ? matrixToSVG(invertTransform(this.viewportTransform))\n : '';\n markup.push(\n `\\n`,\n );\n } else {\n markup.push(\n '\\n',\n );\n }\n }\n /* _TO_SVG_END_ */\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n *\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n *\n * @param {String|Object} json JSON string or object\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @param {Object} [options] options\n * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {Promise} instance\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll());\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * }).then((canvas) => {\n * ... canvas is restored, add your code.\n * });\n *\n */\n loadFromJSON(\n json: string | Record,\n reviver?: EnlivenObjectOptions['reviver'],\n { signal }: Abortable = {},\n ): Promise {\n if (!json) {\n return Promise.reject(new FabricError('`json` is undefined'));\n }\n\n // parse json if it wasn't already\n const serialized = typeof json === 'string' ? JSON.parse(json) : json;\n const {\n objects = [],\n backgroundImage,\n background,\n overlayImage,\n overlay,\n clipPath,\n } = serialized;\n const renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n return Promise.all([\n enlivenObjects(objects, {\n reviver,\n signal,\n }),\n enlivenObjectEnlivables(\n {\n backgroundImage,\n backgroundColor: background,\n overlayImage,\n overlayColor: overlay,\n clipPath,\n },\n { signal },\n ),\n ]).then(([enlived, enlivedMap]) => {\n this.clear();\n this.add(...enlived);\n this.set(serialized);\n this.set(enlivedMap);\n this.renderOnAddRemove = renderOnAddRemove;\n return this;\n });\n }\n\n /**\n * Clones canvas instance\n * @param {string[]} [properties] Array of properties to include in the cloned canvas and children\n */\n clone(properties: string[]) {\n const data = this.toObject(properties);\n const canvas = this.cloneWithoutData();\n return canvas.loadFromJSON(data);\n }\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size.\n */\n cloneWithoutData() {\n const el = createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n return new (this.constructor as Constructor)(el);\n }\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link https://jsfiddle.net/xsjua1rd/ demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n * @example Generate dataURL with objects that overlap a specified object\n * var myObject;\n * var dataURL = canvas.toDataURL({\n * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject)\n * });\n */\n toDataURL(options = {} as TDataUrlOptions): string {\n const {\n format = 'png',\n quality = 1,\n multiplier = 1,\n enableRetinaScaling = false,\n } = options;\n const finalMultiplier =\n multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1);\n\n return toDataURL(\n this.toCanvasElement(finalMultiplier, options),\n format,\n quality,\n );\n }\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [options] Cropping informations\n * @param {Number} [options.left] Cropping left offset.\n * @param {Number} [options.top] Cropping top offset.\n * @param {Number} [options.width] Cropping width.\n * @param {Number} [options.height] Cropping height.\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n */\n toCanvasElement(\n multiplier = 1,\n { width, height, left, top, filter } = {} as TToCanvasElementOptions,\n ): HTMLCanvasElement {\n const scaledWidth = (width || this.width) * multiplier,\n scaledHeight = (height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n originalSkipControlsDrawing = this.skipControlsDrawing,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (left || 0)) * multiplier,\n translateY = (vp[5] - (top || 0)) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY] as TMat2D,\n originalRetina = this.enableRetinaScaling,\n canvasEl = createCanvasElement(),\n objectsToRender = filter\n ? this._objects.filter((obj) => filter(obj))\n : this._objects;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.enableRetinaScaling = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.skipControlsDrawing = true;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d')!, objectsToRender);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.enableRetinaScaling = originalRetina;\n this.skipControlsDrawing = originalSkipControlsDrawing;\n return canvasEl;\n }\n\n /**\n * Waits until rendering has settled to destroy the canvas\n * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed\n * @throws if aborted by a consequent call\n */\n dispose() {\n !this.disposed &&\n this.elements.cleanupDOM({ width: this.width, height: this.height });\n runningAnimations.cancelByCanvas(this);\n this.disposed = true;\n return new Promise((resolve, reject) => {\n const task = () => {\n this.destroy();\n resolve(true);\n };\n task.kill = reject;\n if (this.__cleanupTask) {\n this.__cleanupTask.kill('aborted');\n }\n\n if (this.destroyed) {\n resolve(false);\n } else if (this.nextRenderHandle) {\n this.__cleanupTask = task;\n } else {\n task();\n }\n });\n }\n\n /**\n * Clears the canvas element, disposes objects and frees resources.\n *\n * Invoked as part of the **async** operation of {@link dispose}.\n *\n * **CAUTION**:\n *\n * This method is **UNSAFE**.\n * You may encounter a race condition using it if there's a requested render.\n * Call this method only if you are sure rendering has settled.\n * Consider using {@link dispose} as it is **SAFE**\n *\n * @private\n */\n destroy() {\n this.destroyed = true;\n this.cancelRequestedRender();\n this.forEachObject((object) => object.dispose());\n this._objects = [];\n if (this.backgroundImage) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = undefined;\n if (this.overlayImage) {\n this.overlayImage.dispose();\n }\n this.overlayImage = undefined;\n this.elements.dispose();\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString() {\n return `#`;\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport { getScrollLeftTop } from './dom_misc';\n\nconst touchEvents = ['touchstart', 'touchmove', 'touchend'];\n\nfunction getTouchInfo(event: TouchEvent | MouseEvent): MouseEvent | Touch {\n const touchProp = (event as TouchEvent).changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event as MouseEvent;\n}\n\nexport const getPointer = (event: TPointerEvent): Point => {\n const element = event.target as HTMLElement,\n scroll = getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top);\n};\n\nexport const isTouchEvent = (event: TPointerEvent) =>\n touchEvents.includes(event.type) ||\n (event as PointerEvent).pointerType === 'touch';\n\nexport const stopEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n};\n","import type { XY } from '../../Point';\nimport type { TBBox } from '../../typedefs';\n\n/**\n * Calculates bounding box (left, top, width, height) from given `points`\n * @param {XY[]} points\n * @return {Object} Object with left, top, width, height properties\n */\nexport const makeBoundingBoxFromPoints = (points: XY[]): TBBox => {\n let left = 0,\n top = 0,\n width = 0,\n height = 0;\n\n for (let i = 0, len = points.length; i < len; i++) {\n const { x, y } = points[i];\n if (x > width || !i) width = x;\n if (x < left || !i) left = x;\n if (y > height || !i) height = y;\n if (y < top || !i) top = y;\n }\n\n return {\n left,\n top,\n width: width - left,\n height: height - top,\n };\n};\n","import { Point } from '../../Point';\nimport { CENTER } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from './matrix';\n\n/**\n * given an object and a transform, apply the inverse transform to the object,\n * this is equivalent to remove from that object that transformation, so that\n * added in a space with the removed transform, the object will be the same as before.\n * Removing from an object a transform that scale by 2 is like scaling it by 1/2.\n * Removing from an object a transform that rotate by 30deg is like rotating by 30deg\n * in the opposite direction.\n * This util is used to add objects inside transformed groups or nested groups.\n * @param {FabricObject} object the object you want to transform\n * @param {TMat2D} transform the destination transform\n */\nexport const removeTransformFromObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const inverted = invertTransform(transform),\n finalTransform = multiplyTransformMatrices(\n inverted,\n object.calcOwnMatrix(),\n );\n applyTransformToObject(object, finalTransform);\n};\n\n/**\n * given an object and a transform, apply the transform to the object.\n * this is equivalent to change the space where the object is drawn.\n * Adding to an object a transform that scale by 2 is like scaling it by 2.\n * This is used when removing an object from an active selection for example.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const addTransformToObject = (object: FabricObject, transform: TMat2D) =>\n applyTransformToObject(\n object,\n multiplyTransformMatrices(transform, object.calcOwnMatrix()),\n );\n\n/**\n * discard an object transform state and apply the one from the matrix.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const applyTransformToObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const { translateX, translateY, scaleX, scaleY, ...otherOptions } =\n qrDecompose(transform),\n center = new Point(translateX, translateY);\n object.flipX = false;\n object.flipY = false;\n Object.assign(object, otherOptions);\n object.set({ scaleX, scaleY });\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n/**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @param {FabricObject} target object to transform\n */\nexport const resetObjectTransform = (target: FabricObject) => {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n};\n\n/**\n * Extract Object transform values\n * @param {FabricObject} target object to read from\n * @return {Object} Components of transform\n */\nexport const saveObjectTransform = (target: FabricObject) => ({\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top,\n});\n\n/**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform.\n * Use to calculate the boxes around objects for controls.\n * @param {Number} width\n * @param {Number} height\n * @param {TMat2D} t\n * @returns {Point} size\n */\nexport const sizeAfterTransform = (\n width: number,\n height: number,\n t: TMat2D,\n) => {\n const dimX = width / 2,\n dimY = height / 2,\n points = [\n new Point(-dimX, -dimY),\n new Point(dimX, -dimY),\n new Point(-dimX, dimY),\n new Point(dimX, dimY),\n ].map((p) => p.transform(t)),\n bbox = makeBoundingBoxFromPoints(points);\n return new Point(bbox.width, bbox.height);\n};\n","import { iMatrix } from '../../constants';\nimport type { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { invertTransform, multiplyTransformMatrices } from './matrix';\nimport { applyTransformToObject } from './objectTransforms';\n\n/**\n * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\\\n * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`)\n * @param [from]\n * @param [to]\n * @returns\n */\nexport const calcPlaneChangeMatrix = (\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n) => multiplyTransformMatrices(invertTransform(to), from);\n\n/**\n * Sends a point from the source coordinate plane to the destination coordinate plane.\\\n * From the canvas/viewer's perspective the point remains unchanged.\n *\n * @example Send point from canvas plane to group plane\n * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 });\n * var group = new Group([obj], { strokeWidth: 0 });\n * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix());\n * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix());\n * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group\n *\n * @param {Point} point\n * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane.\n * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane.\n * @returns {Point} transformed point\n */\nexport const sendPointToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to));\n\n/**\n * See {@link sendPointToPlane}\n */\nexport const sendVectorToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to), true);\n\n/**\n *\n * A util that abstracts applying transform to objects.\\\n * Sends `object` to the destination coordinate plane by applying the relevant transformations.\\\n * Changes the space/plane where `object` is drawn.\\\n * From the canvas/viewer's perspective `object` remains unchanged.\n *\n * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer\n * let obj, obj2;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * // render\n * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix());\n * obj.clipPath = undefined;\n * obj2.clipPath = clipPath;\n * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer\n *\n * @example Clip an object's clip path with an existing object\n * let obj, existingObj;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix());\n * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo);\n * clipPath.clipPath = existingObj;\n *\n * @param {FabricObject} object\n * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas.\n * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane.\n * @returns {Matrix} the transform matrix that was applied to `object`\n */\nexport const sendObjectToPlane = (\n object: FabricObject,\n from?: TMat2D,\n to?: TMat2D,\n): TMat2D => {\n const t = calcPlaneChangeMatrix(from, to);\n applyTransformToObject(\n object,\n multiplyTransformMatrices(t, object.calcOwnMatrix()),\n );\n return t;\n};\n","import type {\n ObjectModificationEvents,\n TModificationEvents,\n} from '../EventTypeDefs';\n\nexport const fireEvent = (\n eventName: TModificationEvents,\n options: ObjectModificationEvents[typeof eventName],\n) => {\n const {\n transform: { target },\n } = options;\n target.canvas?.fire(`object:${eventName}`, {\n ...options,\n target,\n });\n target.fire(eventName, options);\n};\n","import type { TOriginX, TOriginY } from '../../typedefs';\n\nconst originOffset = {\n left: -0.5,\n top: -0.5,\n center: 0,\n bottom: 0.5,\n right: 0.5,\n};\n/**\n * Resolves origin value relative to center\n * @private\n * @param {TOriginX | TOriginY} originValue originX / originY\n * @returns number\n */\n\nexport const resolveOrigin = (\n originValue: TOriginX | TOriginY | number,\n): number =>\n typeof originValue === 'string'\n ? originOffset[originValue]\n : originValue - 0.5;\n","import type {\n TPointerEvent,\n Transform,\n TransformAction,\n BasicTransformEvent,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TOriginX, TOriginY } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\nimport { CENTER } from '../constants';\n\nexport const NOT_ALLOWED_CURSOR = 'not-allowed';\n\n/**\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {FabricObject} [target] inserted back to help overriding. Unused\n */\nexport const getActionFromCorner = (\n alreadySelected: boolean,\n corner: string | undefined,\n e: TPointerEvent,\n target: FabricObject,\n) => {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n const control = target.controls[corner];\n return control.getActionName(e, control, target);\n};\n\n/**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\nexport function isTransformCentered(transform: Transform) {\n return (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) &&\n resolveOrigin(transform.originY) === resolveOrigin(CENTER)\n );\n}\n\nexport function invertOrigin(origin: TOriginX | TOriginY) {\n return -resolveOrigin(origin) + 0.5;\n}\n\nexport const isLocked = (\n target: FabricObject,\n lockingKey:\n | 'lockMovementX'\n | 'lockMovementY'\n | 'lockRotation'\n | 'lockScalingX'\n | 'lockScalingY'\n | 'lockSkewingX'\n | 'lockSkewingY'\n | 'lockScalingFlip',\n) => target[lockingKey];\n\nexport const commonEventInfo: TransformAction<\n Transform,\n BasicTransformEvent\n> = (eventData, transform, x, y) => {\n return {\n e: eventData,\n transform,\n pointer: new Point(x, y),\n };\n};\n\n/**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n * @param {Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\nexport function findCornerQuadrant(\n fabricObject: FabricObject,\n control: Control,\n): number {\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle(),\n cornerAngle =\n angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round((cornerAngle % 360) / 45);\n}\n\n/**\n * @returns the normalized point (rotated relative to center) in local coordinates\n */\nfunction normalizePoint(\n target: FabricObject,\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n): Point {\n const center = target.getRelativeCenterPoint(),\n p =\n typeof originX !== 'undefined' && typeof originY !== 'undefined'\n ? target.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n )\n : new Point(target.left, target.top),\n p2 = target.angle\n ? point.rotate(-degreesToRadians(target.angle), center)\n : point;\n return p2.subtract(p);\n}\n\n/**\n * Transforms a point to the offset from the given origin\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\nexport function getLocalPoint(\n { target, corner }: Transform,\n originX: TOriginX,\n originY: TOriginY,\n x: number,\n y: number,\n) {\n const control = target.controls[corner],\n zoom = target.canvas?.getZoom() || 1,\n padding = target.padding / zoom,\n localPoint = normalizePoint(target, new Point(x, y), originX, originY);\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { LEFT, TOP, MOVING } from '../constants';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo, isLocked } from './util';\n\n/**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\nexport const dragHandler: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target, offsetX, offsetY } = transform,\n newLeft = x - offsetX,\n newTop = y - offsetY,\n moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,\n moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;\n moveX && target.set(LEFT, newLeft);\n moveY && target.set(TOP, newTop);\n if (moveX || moveY) {\n fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));\n }\n return moveX || moveY;\n};\n","import type { TSVGReviver } from '../../typedefs';\nimport { uid } from '../../util/internals/uid';\nimport { colorPropToSVG, matrixToSVG } from '../../util/misc/svgParsing';\nimport { FILL, NONE, STROKE } from '../../constants';\nimport type { FabricObject } from './FabricObject';\nimport { isFiller } from '../../util/typeAssertions';\n\nexport class FabricObjectSVGExportMixin {\n /**\n * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed.\n * This reference is a UID in the fabric namespace and is temporary stored here.\n * @type {String}\n */\n declare clipPathId?: string;\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(\n this: FabricObjectSVGExportMixin & FabricObject,\n skipShadow?: boolean,\n ) {\n const fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray\n ? this.strokeDashArray.join(' ')\n : NONE,\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = colorPropToSVG(FILL, this.fill),\n stroke = colorPropToSVG(STROKE, this.stroke);\n\n return [\n stroke,\n 'stroke-width: ',\n strokeWidth,\n '; ',\n 'stroke-dasharray: ',\n strokeDashArray,\n '; ',\n 'stroke-linecap: ',\n strokeLineCap,\n '; ',\n 'stroke-dashoffset: ',\n strokeDashOffset,\n '; ',\n 'stroke-linejoin: ',\n strokeLineJoin,\n '; ',\n 'stroke-miterlimit: ',\n strokeMiterLimit,\n '; ',\n fill,\n 'fill-rule: ',\n fillRule,\n '; ',\n 'opacity: ',\n opacity,\n ';',\n filter,\n visibility,\n ].join('');\n }\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';\n }\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons(\n this: FabricObjectSVGExportMixin & FabricObject & { id?: string },\n ) {\n return [\n this.id ? `id=\"${this.id}\" ` : '',\n this.clipPath\n ? `clip-path=\"url(#${\n (this.clipPath as FabricObjectSVGExportMixin & FabricObject)\n .clipPathId\n })\" `\n : '',\n ].join('');\n }\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform(\n this: FabricObjectSVGExportMixin & FabricObject,\n full?: boolean,\n additionalTransform = '',\n ) {\n const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = `transform=\"${matrixToSVG(transform)}`;\n return `${svgTransform}${additionalTransform}\" `;\n }\n\n /**\n * Returns svg representation of an instance\n * This function is implemented in each subclass\n * This is just because typescript otherwise cryies all the time\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(_reviver?: TSVGReviver): string[] {\n return [''];\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver,\n });\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver,\n })\n );\n }\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n reviver,\n additionalTransform = '',\n }: { reviver?: TSVGReviver; additionalTransform?: string } = {},\n ) {\n const commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n }\n\n /**\n * @private\n */\n _createBaseSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n noStyle,\n reviver,\n withShadow,\n additionalTransform,\n }: {\n noStyle?: boolean;\n reviver?: TSVGReviver;\n withShadow?: boolean;\n additionalTransform?: string;\n } = {},\n ): string {\n const styleInfo = noStyle ? '' : `style=\"${this.getSvgStyles()}\" `,\n shadowInfo = withShadow ? `style=\"${this.getSvgFilter()}\" ` : '',\n clipPath = this.clipPath as FabricObjectSVGExportMixin & FabricObject,\n vectorEffect = this.strokeUniform\n ? 'vector-effect=\"non-scaling-stroke\" '\n : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke,\n fill = this.fill,\n shadow = this.shadow,\n markup = [],\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n let clipPathMarkup;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n clipPathMarkup = `\\n${clipPath.toClipPathSVG(reviver)}\\n`;\n }\n if (absoluteClipPath) {\n markup.push('\\n');\n }\n markup.push(\n '\\n',\n );\n const commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(),\n ' ',\n additionalTransform ? `transform=\"${additionalTransform}\" ` : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (isFiller(fill)) {\n markup.push(fill.toSVG(this));\n }\n if (isFiller(stroke)) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n }\n\n addPaintOrder(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.paintFirst !== FILL ? ` paint-order=\"${this.paintFirst}\" ` : '';\n }\n}\n","export function getSvgRegex(arr: string[]) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n}\n","import { getSvgRegex } from './getSvgRegex';\nimport { LEFT, TOP } from '../constants';\n\nexport const reNum = String.raw`(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)`;\n\nexport const svgNS = 'http://www.w3.org/2000/svg';\n\nexport const reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' +\n reNum +\n '))?\\\\s+(.*)',\n);\n\nexport const svgValidTagNames = [\n 'path',\n 'circle',\n 'polygon',\n 'polyline',\n 'ellipse',\n 'rect',\n 'line',\n 'image',\n 'text',\n ],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = [\n 'pattern',\n 'defs',\n 'symbol',\n 'metadata',\n 'clipPath',\n 'mask',\n 'desc',\n ],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n attributesMap = {\n cx: LEFT,\n x: LEFT,\n r: 'radius',\n cy: TOP,\n y: TOP,\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing',\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n\nexport const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n\nexport const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n\nexport const svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n// matches, e.g.: +14.56e-12, etc.\nexport const reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*' +\n '$',\n);\n","import type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n\nconst unitVectorX = new Point(1, 0);\nconst zero = new Point();\n\n/**\n * Rotates `vector` with `radians`\n * @param {Point} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotateVector = (vector: Point, radians: TRadian) =>\n vector.rotate(radians);\n\n/**\n * Creates a vector from points represented as a point\n *\n * @param {Point} from\n * @param {Point} to\n * @returns {Point} vector\n */\nexport const createVector = (from: XY, to: XY): Point =>\n new Point(to).subtract(from);\n\n/**\n * return the magnitude of a vector\n * @return {number}\n */\nexport const magnitude = (point: Point) => point.distanceFrom(zero);\n\n/**\n * Calculates the angle between 2 vectors\n * @param {Point} a\n * @param {Point} b\n * @returns the angle in radians from `a` to `b`\n */\nexport const calcAngleBetweenVectors = (a: Point, b: Point): TRadian =>\n Math.atan2(crossProduct(a, b), dotProduct(a, b)) as TRadian;\n\n/**\n * Calculates the angle between the x axis and the vector\n * @param {Point} v\n * @returns the angle in radians of `v`\n */\nexport const calcVectorRotation = (v: Point) =>\n calcAngleBetweenVectors(unitVectorX, v);\n\n/**\n * @param {Point} v\n * @returns {Point} vector representing the unit vector pointing to the direction of `v`\n */\nexport const getUnitVector = (v: Point): Point =>\n v.eq(zero) ? v : v.scalarDivide(magnitude(v));\n\n/**\n * @param {Point} v\n * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true`\n * @returns {Point} the unit orthogonal vector\n */\nexport const getOrthonormalVector = (\n v: Point,\n counterClockwise = true,\n): Point =>\n getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1));\n\n/**\n * Cross product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number} the magnitude of Z vector\n */\nexport const crossProduct = (a: Point, b: Point): number =>\n a.x * b.y - a.y * b.x;\n\n/**\n * Dot product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number}\n */\nexport const dotProduct = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\n\n/**\n * Checks if the vector is between two others. It is considered\n * to be inside when the vector to be tested is between the\n * initial vector and the final vector (included) in a counterclockwise direction.\n * @param {Point} t vector to be tested\n * @param {Point} a initial vector\n * @param {Point} b final vector\n * @returns {boolean} true if the vector is among the others\n */\nexport const isBetweenVectors = (t: Point, a: Point, b: Point): boolean => {\n if (t.eq(a) || t.eq(b)) return true;\n const AxB = crossProduct(a, b),\n AxT = crossProduct(a, t),\n BxT = crossProduct(b, t);\n return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0);\n};\n","import { classRegistry } from './ClassRegistry';\nimport { Color } from './color/Color';\nimport { config } from './config';\nimport { reNum } from './parser/constants';\nimport { Point } from './Point';\nimport type { FabricObject } from './shapes/Object/FabricObject';\nimport type { TClassProperties } from './typedefs';\nimport { uid } from './util/internals/uid';\nimport { pickBy } from './util/misc/pick';\nimport { degreesToRadians } from './util/misc/radiansDegreesConversion';\nimport { toFixed } from './util/misc/toFixed';\nimport { rotateVector } from './util/misc/vectors';\n\n/**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * - (?:\\s|^): This part captures either a whitespace character (\\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down:\n * - (-?\\d+): Captures an optional minus sign followed by one or more digits (integer part of the number).\n * - (?:\\.\\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number).\n * - (?:px)?: Optionally captures the \"px\" unit.\n * - (?:\\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: Similar to the previous step, this captures the vertical offset.\n\n(\\d+(?:\\.\\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign.\n\n(?:\\s+(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and \"px\" unit.\n\n(?:$|\\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.\n */\n// eslint-disable-next-line max-len\n\nconst shadowOffsetRegex = '(-?\\\\d+(?:\\\\.\\\\d*)?(?:px)?(?:\\\\s?|$))?';\n\nconst reOffsetsAndBlur = new RegExp(\n '(?:\\\\s|^)' +\n shadowOffsetRegex +\n shadowOffsetRegex +\n '(' +\n reNum +\n '?(?:px)?)?(?:\\\\s?|$)(?:$|\\\\s)',\n);\n\nexport const shadowDefaultValues: Partial> = {\n color: 'rgb(0,0,0)',\n blur: 0,\n offsetX: 0,\n offsetY: 0,\n affectStroke: false,\n includeDefaultValues: true,\n nonScaling: false,\n};\n\nexport type SerializedShadowOptions = {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n affectStroke: boolean;\n nonScaling: boolean;\n type: string;\n};\n\nexport class Shadow {\n /**\n * Shadow color\n * @type String\n * @default\n */\n declare color: string;\n\n /**\n * Shadow blur\n * @type Number\n */\n declare blur: number;\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n declare offsetX: number;\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n declare offsetY: number;\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n declare affectStroke: boolean;\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n declare includeDefaultValues: boolean;\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n declare nonScaling: boolean;\n\n declare id: number;\n\n static ownDefaults = shadowDefaultValues;\n\n static type = 'shadow';\n\n /**\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n */\n constructor(options: Partial>);\n constructor(svgAttribute: string);\n constructor(arg0: string | Partial>) {\n const options: Partial> =\n typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;\n Object.assign(this, Shadow.ownDefaults, options);\n this.id = uid();\n }\n\n /**\n * @param {String} value Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n static parseShadow(value: string) {\n const shadowStr = value.trim(),\n [, offsetX = 0, offsetY = 0, blur = 0] = (\n reOffsetsAndBlur.exec(shadowStr) || []\n ).map((value) => parseFloat(value) || 0),\n color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim();\n\n return {\n color,\n offsetX,\n offsetY,\n blur,\n };\n }\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n }\n\n /**\n * Returns SVG representation of a shadow\n * @param {FabricObject} object\n * @return {String} SVG representation of a shadow\n */\n toSVG(object: FabricObject) {\n const offset = rotateVector(\n new Point(this.offsetX, this.offsetY),\n degreesToRadians(-object.angle),\n ),\n BLUR_BOX = 20,\n color = new Color(this.color);\n let fBoxX = 40,\n fBoxY = 40;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX =\n toFixed(\n (Math.abs(offset.x) + this.blur) / object.width,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n fBoxY =\n toFixed(\n (Math.abs(offset.y) + this.blur) / object.height,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return `\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\n\\t\\n\\n`;\n }\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject() {\n const data: SerializedShadowOptions = {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling,\n type: (this.constructor as typeof Shadow).type,\n };\n const defaults = Shadow.ownDefaults as SerializedShadowOptions;\n return !this.includeDefaultValues\n ? pickBy(data, (value, key) => value !== defaults[key])\n : data;\n }\n\n static async fromObject(options: Partial>) {\n return new this(options);\n }\n}\n\nclassRegistry.setClass(Shadow, 'shadow');\n","export const capValue = (min: number, value: number, max: number) =>\n Math.max(min, Math.min(value, max));\n","import {\n TOP,\n LEFT,\n SCALE_Y,\n SCALE_X,\n SKEW_X,\n SKEW_Y,\n FILL,\n STROKE,\n} from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { InteractiveFabricObject } from './InteractiveObject';\nimport type { FabricObject } from './Object';\n\nexport const stateProperties = [\n TOP,\n LEFT,\n SCALE_X,\n SCALE_Y,\n 'flipX',\n 'flipY',\n 'originX',\n 'originY',\n 'angle',\n 'opacity',\n 'globalCompositeOperation',\n 'shadow',\n 'visible',\n SKEW_X,\n SKEW_Y,\n];\n\nexport const cacheProperties = [\n FILL,\n STROKE,\n 'strokeWidth',\n 'strokeDashArray',\n 'width',\n 'height',\n 'paintFirst',\n 'strokeUniform',\n 'strokeLineCap',\n 'strokeDashOffset',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'backgroundColor',\n 'clipPath',\n];\n\nexport const fabricObjectDefaultValues: Partial<\n TClassProperties\n> = {\n // see composeMatrix() to see order of transforms. First defaults listed based on this\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n angle: 0,\n flipX: false,\n flipY: false,\n scaleX: 1,\n scaleY: 1,\n minScaleLimit: 0,\n skewX: 0,\n skewY: 0,\n originX: LEFT,\n originY: TOP,\n strokeWidth: 1,\n strokeUniform: false,\n padding: 0,\n opacity: 1,\n paintFirst: FILL,\n fill: 'rgb(0,0,0)',\n fillRule: 'nonzero',\n stroke: null,\n strokeDashArray: null,\n strokeDashOffset: 0,\n strokeLineCap: 'butt',\n strokeLineJoin: 'miter',\n strokeMiterLimit: 4,\n globalCompositeOperation: 'source-over',\n backgroundColor: '',\n shadow: null,\n visible: true,\n includeDefaultValues: true,\n excludeFromExport: false,\n objectCaching: true,\n clipPath: undefined,\n inverted: false,\n absolutePositioned: false,\n centeredRotation: true,\n centeredScaling: false,\n dirty: true,\n} as const;\n\nexport const interactiveObjectDefaultValues: Partial<\n TClassProperties\n> = {\n noScaleCache: true,\n lockMovementX: false,\n lockMovementY: false,\n lockRotation: false,\n lockScalingX: false,\n lockScalingY: false,\n lockSkewingX: false,\n lockSkewingY: false,\n lockScalingFlip: false,\n cornerSize: 13,\n touchCornerSize: 24,\n transparentCorners: true,\n cornerColor: 'rgb(178,204,255)',\n cornerStrokeColor: '',\n cornerStyle: 'rect',\n cornerDashArray: null,\n hasControls: true,\n borderColor: 'rgb(178,204,255)',\n borderDashArray: null,\n borderOpacityWhenMoving: 0.4,\n borderScaleFactor: 1,\n hasBorders: true,\n selectionBackgroundColor: '',\n selectable: true,\n evented: true,\n perPixelTargetFind: false,\n activeOn: 'down',\n hoverCursor: null,\n moveCursor: null,\n};\n","/**\n * Easing functions\n * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner}\n */\n\nimport { twoMathPi, halfPI } from '../../constants';\nimport type { TEasingFunction } from './types';\n\nconst normalize = (a: number, c: number, p: number, s: number) => {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = (p / twoMathPi) * Math.asin(1);\n } else {\n s = (p / twoMathPi) * Math.asin(c / a);\n }\n }\n return { a, c, p, s };\n};\n\nconst elastic = (\n a: number,\n s: number,\n p: number,\n t: number,\n d: number,\n): number =>\n a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * twoMathPi) / p);\n\n/**\n * Default sinusoidal easing\n */\nexport const defaultEasing: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Cubic easing in\n */\nexport const easeInCubic: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 3 + b;\n\n/**\n * Cubic easing out\n */\nexport const easeOutCubic: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 3 + 1) + b;\n\n/**\n * Cubic easing in and out\n */\nexport const easeInOutCubic: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 3 + b;\n }\n return (c / 2) * ((t - 2) ** 3 + 2) + b;\n};\n\n/**\n * Quartic easing in\n */\nexport const easeInQuart: TEasingFunction = (t, b, c, d) =>\n c * (t /= d) * t ** 3 + b;\n\n/**\n * Quartic easing out\n */\nexport const easeOutQuart: TEasingFunction = (t, b, c, d) =>\n -c * ((t = t / d - 1) * t ** 3 - 1) + b;\n\n/**\n * Quartic easing in and out\n */\nexport const easeInOutQuart: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 4 + b;\n }\n return (-c / 2) * ((t -= 2) * t ** 3 - 2) + b;\n};\n\n/**\n * Quintic easing in\n */\nexport const easeInQuint: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 5 + b;\n\n/**\n * Quintic easing out\n */\nexport const easeOutQuint: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 5 + 1) + b;\n\n/**\n * Quintic easing in and out\n */\nexport const easeInOutQuint: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 5 + b;\n }\n return (c / 2) * ((t - 2) ** 5 + 2) + b;\n};\n\n/**\n * Sinusoidal easing in\n */\nexport const easeInSine: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Sinusoidal easing out\n */\nexport const easeOutSine: TEasingFunction = (t, b, c, d) =>\n c * Math.sin((t / d) * halfPI) + b;\n\n/**\n * Sinusoidal easing in and out\n */\nexport const easeInOutSine: TEasingFunction = (t, b, c, d) =>\n (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b;\n\n/**\n * Exponential easing in\n */\nexport const easeInExpo: TEasingFunction = (t, b, c, d) =>\n t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b;\n\n/**\n * Exponential easing out\n */\nexport const easeOutExpo: TEasingFunction = (t, b, c, d) =>\n t === d ? b + c : c * -(2 ** ((-10 * t) / d) + 1) + b;\n\n/**\n * Exponential easing in and out\n */\nexport const easeInOutExpo: TEasingFunction = (t, b, c, d) => {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * 2 ** (10 * (t - 1)) + b;\n }\n return (c / 2) * -(2 ** (-10 * --t) + 2) + b;\n};\n\n/**\n * Circular easing in\n */\nexport const easeInCirc: TEasingFunction = (t, b, c, d) =>\n -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n\n/**\n * Circular easing out\n */\nexport const easeOutCirc: TEasingFunction = (t, b, c, d) =>\n c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n\n/**\n * Circular easing in and out\n */\nexport const easeInOutCirc: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (-c / 2) * (Math.sqrt(1 - t ** 2) - 1) + b;\n }\n return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n};\n\n/**\n * Elastic easing in\n */\nexport const easeInElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP } = normalize(a, c, p, s);\n return -elastic(normA, normS, normP, t, d) + b;\n};\n\n/**\n * Elastic easing out\n */\nexport const easeOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n return (\n normA * 2 ** (-10 * t) * Math.sin(((t * d - normS) * twoMathPi) / normP) +\n normC +\n b\n );\n};\n\n/**\n * Elastic easing in and out\n */\nexport const easeInOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(normA, normS, normP, t, d) + b;\n }\n return (\n normA *\n Math.pow(2, -10 * (t -= 1)) *\n Math.sin(((t * d - normS) * twoMathPi) / normP) *\n 0.5 +\n normC +\n b\n );\n};\n\n/**\n * Backwards easing in\n */\nexport const easeInBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * (t /= d) * t * ((s + 1) * t - s) + b;\n\n/**\n * Backwards easing out\n */\nexport const easeOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n\n/**\n * Backwards easing in and out\n */\nexport const easeInOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n return (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n};\n\n/**\n * Bouncing easing out\n */\nexport const easeOutBounce: TEasingFunction = (t, b, c, d) => {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n};\n\n/**\n * Bouncing easing in\n */\nexport const easeInBounce: TEasingFunction = (t, b, c, d) =>\n c - easeOutBounce(d - t, 0, c, d) + b;\n\n/**\n * Bouncing easing in and out\n */\nexport const easeInOutBounce: TEasingFunction = (t, b, c, d) =>\n t < d / 2\n ? easeInBounce(t * 2, 0, c, d) * 0.5 + b\n : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n\n/**\n * Quadratic easing in\n */\nexport const easeInQuad: TEasingFunction = (t, b, c, d) => c * (t /= d) * t + b;\n\n/**\n * Quadratic easing out\n */\nexport const easeOutQuad: TEasingFunction = (t, b, c, d) =>\n -c * (t /= d) * (t - 2) + b;\n\n/**\n * Quadratic easing in and out\n */\nexport const easeInOutQuad: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 2 + b;\n }\n return (-c / 2) * (--t * (t - 2) - 1) + b;\n};\n","import { noop } from '../../constants';\nimport { requestAnimFrame } from './AnimationFrameProvider';\nimport { runningAnimations } from './AnimationRegistry';\nimport { defaultEasing } from './easing';\nimport type {\n AnimationState,\n TAbortCallback,\n TBaseAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultAbort = () => false;\n\nexport abstract class AnimationBase<\n T extends number | number[] = number | number[],\n> {\n declare readonly startValue: T;\n declare readonly endValue: T;\n declare readonly duration: number;\n declare readonly delay: number;\n\n protected declare readonly byValue: T;\n protected declare readonly easing: TEasingFunction;\n\n private declare readonly _onStart: VoidFunction;\n private declare readonly _onChange: TOnAnimationChangeCallback;\n private declare readonly _onComplete: TOnAnimationChangeCallback;\n private declare readonly _abort: TAbortCallback;\n\n /**\n * Used to register the animation to a target object\n * so that it can be cancelled within the object context\n */\n declare readonly target?: unknown;\n\n private _state: AnimationState = 'pending';\n /**\n * Time %, or the ratio of `timeElapsed / duration`\n * @see tick\n */\n durationProgress = 0;\n /**\n * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)`\n */\n valueProgress = 0;\n /**\n * Current value\n */\n declare value: T;\n /**\n * Animation start time ms\n */\n private declare startTime: number;\n\n constructor({\n startValue,\n byValue,\n duration = 500,\n delay = 0,\n easing = defaultEasing,\n onStart = noop,\n onChange = noop,\n onComplete = noop,\n abort = defaultAbort,\n target,\n }: TBaseAnimationOptions) {\n this.tick = this.tick.bind(this);\n\n this.duration = duration;\n this.delay = delay;\n this.easing = easing;\n this._onStart = onStart;\n this._onChange = onChange;\n this._onComplete = onComplete;\n this._abort = abort;\n this.target = target;\n\n this.startValue = startValue;\n this.byValue = byValue;\n this.value = this.startValue;\n this.endValue = Object.freeze(this.calculate(this.duration).value);\n }\n\n get state() {\n return this._state;\n }\n\n isDone() {\n return this._state === 'aborted' || this._state === 'completed';\n }\n\n /**\n * Calculate the current value based on the easing parameters\n * @param timeElapsed in ms\n * @protected\n */\n protected abstract calculate(timeElapsed: number): {\n value: T;\n valueProgress: number;\n };\n\n start() {\n const firstTick: FrameRequestCallback = (timestamp) => {\n if (this._state !== 'pending') return;\n this.startTime = timestamp || +new Date();\n this._state = 'running';\n this._onStart();\n this.tick(this.startTime);\n };\n\n this.register();\n\n // setTimeout(cb, 0) will run cb on the next frame, causing a delay\n // we don't want that\n if (this.delay > 0) {\n setTimeout(() => requestAnimFrame(firstTick), this.delay);\n } else {\n requestAnimFrame(firstTick);\n }\n }\n\n private tick(t: number) {\n const durationMs = (t || +new Date()) - this.startTime;\n const boundDurationMs = Math.min(durationMs, this.duration);\n this.durationProgress = boundDurationMs / this.duration;\n const { value, valueProgress } = this.calculate(boundDurationMs);\n this.value = Object.freeze(value);\n this.valueProgress = valueProgress;\n\n if (this._state === 'aborted') {\n return;\n } else if (\n this._abort(this.value, this.valueProgress, this.durationProgress)\n ) {\n this._state = 'aborted';\n this.unregister();\n } else if (durationMs >= this.duration) {\n this.durationProgress = this.valueProgress = 1;\n this._onChange(this.endValue, this.valueProgress, this.durationProgress);\n this._state = 'completed';\n this._onComplete(\n this.endValue,\n this.valueProgress,\n this.durationProgress,\n );\n this.unregister();\n } else {\n this._onChange(this.value, this.valueProgress, this.durationProgress);\n requestAnimFrame(this.tick);\n }\n }\n\n private register() {\n runningAnimations.push(this as unknown as AnimationBase);\n }\n\n private unregister() {\n runningAnimations.remove(this as unknown as AnimationBase);\n }\n\n abort() {\n this._state = 'aborted';\n this.unregister();\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ValueAnimationOptions } from './types';\n\nexport class ValueAnimation extends AnimationBase {\n constructor({\n startValue = 0,\n endValue = 100,\n ...otherOptions\n }: ValueAnimationOptions) {\n super({\n ...otherOptions,\n startValue,\n byValue: endValue - startValue,\n });\n }\n\n protected calculate(timeElapsed: number) {\n const value = this.easing(\n timeElapsed,\n this.startValue,\n this.byValue,\n this.duration,\n );\n return {\n value,\n valueProgress: Math.abs((value - this.startValue) / this.byValue),\n };\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ArrayAnimationOptions } from './types';\n\nexport class ArrayAnimation extends AnimationBase {\n constructor({\n startValue = [0],\n endValue = [100],\n ...options\n }: ArrayAnimationOptions) {\n super({\n ...options,\n startValue,\n byValue: endValue.map((value, i) => value - startValue[i]),\n });\n }\n protected calculate(timeElapsed: number) {\n const values = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n );\n return {\n value: values,\n valueProgress: Math.abs(\n (values[0] - this.startValue[0]) / this.byValue[0],\n ),\n };\n }\n}\n","import { Color } from '../../color/Color';\nimport type { TRGBAColorSource } from '../../color/typedefs';\nimport { halfPI } from '../../constants';\nimport { capValue } from '../misc/capValue';\nimport { AnimationBase } from './AnimationBase';\nimport type {\n ColorAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultColorEasing: TEasingFunction = (\n timeElapsed,\n startValue,\n byValue,\n duration,\n) => {\n const durationProgress = 1 - Math.cos((timeElapsed / duration) * halfPI);\n return startValue + byValue * durationProgress;\n};\n\nconst wrapColorCallback = (\n callback?: TOnAnimationChangeCallback,\n) =>\n callback &&\n ((rgba: TRGBAColorSource, valueProgress: number, durationProgress: number) =>\n callback(new Color(rgba).toRgba(), valueProgress, durationProgress));\n\nexport class ColorAnimation extends AnimationBase {\n constructor({\n startValue,\n endValue,\n easing = defaultColorEasing,\n onChange,\n onComplete,\n abort,\n ...options\n }: ColorAnimationOptions) {\n const startColor = new Color(startValue).getSource();\n const endColor = new Color(endValue).getSource();\n super({\n ...options,\n startValue: startColor,\n byValue: endColor.map(\n (value, i) => value - startColor[i],\n ) as TRGBAColorSource,\n easing,\n onChange: wrapColorCallback(onChange),\n onComplete: wrapColorCallback(onComplete),\n abort: wrapColorCallback(abort),\n });\n }\n protected calculate(timeElapsed: number) {\n const [r, g, b, a] = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n ) as TRGBAColorSource;\n const value = [\n ...[r, g, b].map(Math.round),\n capValue(0, a, 1),\n ] as TRGBAColorSource;\n return {\n value,\n valueProgress:\n // to correctly calculate the change ratio we must find a changed value\n value\n .map((p, i) =>\n this.byValue[i] !== 0\n ? Math.abs((p - this.startValue[i]) / this.byValue[i])\n : 0,\n )\n .find((p) => p !== 0) || 0,\n };\n }\n}\n","import { ValueAnimation } from './ValueAnimation';\nimport { ArrayAnimation } from './ArrayAnimation';\nimport { ColorAnimation } from './ColorAnimation';\nimport type {\n ValueAnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n} from './types';\nimport type { TColorArg } from '../../color/typedefs';\n\nexport type TAnimation =\n T extends TColorArg\n ? ColorAnimation\n : T extends number[]\n ? ArrayAnimation\n : ValueAnimation;\n\nconst isArrayAnimation = (\n options: ArrayAnimationOptions | ValueAnimationOptions,\n): options is ArrayAnimationOptions => {\n return Array.isArray(options.startValue) || Array.isArray(options.endValue);\n};\n\n/**\n * Changes value(s) from startValue to endValue within a certain period of time,\n * invoking callbacks as the value(s) change.\n *\n * @example\n * animate({\n * startValue: 1,\n * endValue: 0,\n * onChange: (v) => {\n * obj.set('opacity', v);\n * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll`\n * canvas.renderAll();\n * }\n * });\n *\n * @example Using lists:\n * animate({\n * startValue: [1, 2, 3],\n * endValue: [2, 4, 6],\n * onChange: ([x, y, zoom]) => {\n * canvas.zoomToPoint(new Point(x, y), zoom);\n * canvas.renderAll();\n * }\n * });\n *\n */\nexport function animate(options: ArrayAnimationOptions): ArrayAnimation;\nexport function animate(options: ValueAnimationOptions): ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n>(\n options: T,\n): T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n R extends T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation,\n>(options: T): R {\n const animation = (\n isArrayAnimation(options)\n ? new ArrayAnimation(options)\n : new ValueAnimation(options)\n ) as R;\n animation.start();\n return animation;\n}\n\nexport function animateColor(options: ColorAnimationOptions) {\n const animation = new ColorAnimation(options);\n animation.start();\n return animation;\n}\n","import { Point } from './Point';\nimport { createVector } from './util/misc/vectors';\n\n/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\nexport type IntersectionType = 'Intersection' | 'Coincident' | 'Parallel';\n\nexport class Intersection {\n declare points: Point[];\n\n declare status?: IntersectionType;\n\n constructor(status?: IntersectionType) {\n this.status = status;\n this.points = [];\n }\n\n /**\n * Used to verify if a point is alredy in the collection\n * @param {Point} point\n * @returns {boolean}\n */\n private includes(point: Point): boolean {\n return this.points.some((p) => p.eq(point));\n }\n\n /**\n * Appends points of intersection\n * @param {...Point[]} points\n * @return {Intersection} thisArg\n * @chainable\n */\n private append(...points: Point[]): Intersection {\n this.points = this.points.concat(\n points.filter((point) => {\n return !this.includes(point);\n }),\n );\n return this;\n }\n\n /**\n * check if point T is on the segment or line defined between A and B\n *\n * @param {Point} T the point we are checking for\n * @param {Point} A one extremity of the segment\n * @param {Point} B the other extremity of the segment\n * @param [infinite] if true checks if `T` is on the line defined by `A` and `B`\n * @returns true if `T` is contained\n */\n static isPointContained(T: Point, A: Point, B: Point, infinite = false) {\n if (A.eq(B)) {\n // Edge case: the segment is a point, we check for coincidence,\n // infinite param has no meaning because there are infinite lines to consider\n return T.eq(A);\n } else if (A.x === B.x) {\n // Edge case: horizontal line.\n // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y\n return (\n T.x === A.x &&\n (infinite || (T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)))\n );\n } else if (A.y === B.y) {\n // Edge case: vertical line.\n // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x\n return (\n T.y === A.y &&\n (infinite || (T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)))\n );\n } else {\n // Generic case: sloped line.\n // we check that AT has the same slope as AB\n // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size\n // for the infinite case we check the absolute value of the slope, since direction is meaningless\n const AB = createVector(A, B);\n const AT = createVector(A, T);\n const s = AT.divide(AB);\n return infinite\n ? Math.abs(s.x) === Math.abs(s.y)\n : s.x === s.y && s.x >= 0 && s.x <= 1;\n }\n }\n\n /**\n * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points}\n * @see https://en.wikipedia.org/wiki/Point_in_polygon\n * @param point\n * @param points polygon points\n * @returns\n */\n static isPointInPolygon(point: Point, points: Point[]) {\n const other = new Point(point).setX(\n Math.min(point.x - 1, ...points.map((p) => p.x)),\n );\n let hits = 0;\n for (let index = 0; index < points.length; index++) {\n const inter = this.intersectSegmentSegment(\n // polygon side\n points[index],\n points[(index + 1) % points.length],\n // ray\n point,\n other,\n );\n if (inter.includes(point)) {\n // point is on the polygon side\n return true;\n }\n hits += Number(inter.status === 'Intersection');\n }\n return hits % 2 === 1;\n }\n\n /**\n * Checks if a line intersects another\n * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection}\n * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule}\n * @static\n * @param {Point} a1\n * @param {Point} a2\n * @param {Point} b1\n * @param {Point} b2\n * @param {boolean} [aInfinite=true] check segment intersection by passing `false`\n * @param {boolean} [bInfinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLineLine(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n aInfinite = true,\n bInfinite = true,\n ): Intersection {\n const a2xa1x = a2.x - a1.x,\n a2ya1y = a2.y - a1.y,\n b2xb1x = b2.x - b1.x,\n b2yb1y = b2.y - b1.y,\n a1xb1x = a1.x - b1.x,\n a1yb1y = a1.y - b1.y,\n uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x,\n ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x,\n uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y;\n if (uB !== 0) {\n const ua = uaT / uB,\n ub = ubT / uB;\n if (\n (aInfinite || (0 <= ua && ua <= 1)) &&\n (bInfinite || (0 <= ub && ub <= 1))\n ) {\n return new Intersection('Intersection').append(\n new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y),\n );\n } else {\n return new Intersection();\n }\n } else {\n if (uaT === 0 || ubT === 0) {\n const segmentsCoincide =\n aInfinite ||\n bInfinite ||\n Intersection.isPointContained(a1, b1, b2) ||\n Intersection.isPointContained(a2, b1, b2) ||\n Intersection.isPointContained(b1, a1, a2) ||\n Intersection.isPointContained(b2, a1, a2);\n return new Intersection(segmentsCoincide ? 'Coincident' : undefined);\n } else {\n return new Intersection('Parallel');\n }\n }\n }\n\n /**\n * Checks if a segment intersects a line\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} s1 boundary point of segment\n * @param {Point} s2 other boundary point of segment\n * @param {Point} l1 point on line\n * @param {Point} l2 other point on line\n * @return {Intersection}\n */\n static intersectSegmentLine(\n s1: Point,\n s2: Point,\n l1: Point,\n l2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(s1, s2, l1, l2, false, true);\n }\n\n /**\n * Checks if a segment intersects another\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point} b1 boundary point of segment\n * @param {Point} b2 other boundary point of segment\n * @return {Intersection}\n */\n static intersectSegmentSegment(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(a1, a2, b1, b2, false, false);\n }\n\n /**\n * Checks if line intersects polygon\n *\n * @todo account for stroke\n *\n * @static\n * @see {@link intersectSegmentPolygon} for segment intersection\n * @param {Point} a1 point on line\n * @param {Point} a2 other point on line\n * @param {Point[]} points polygon points\n * @param {boolean} [infinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLinePolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n infinite = true,\n ): Intersection {\n const result = new Intersection();\n const length = points.length;\n\n for (let i = 0, b1, b2, inter; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false);\n if (inter.status === 'Coincident') {\n return inter;\n }\n result.append(...inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if segment intersects polygon\n * @static\n * @see {@link intersectLinePolygon} for line intersection\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point[]} points polygon points\n * @return {Intersection}\n */\n static intersectSegmentPolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n ): Intersection {\n return Intersection.intersectLinePolygon(a1, a2, points, false);\n }\n\n /**\n * Checks if polygon intersects another polygon\n *\n * @todo account for stroke\n *\n * @static\n * @param {Point[]} points1\n * @param {Point[]} points2\n * @return {Intersection}\n */\n static intersectPolygonPolygon(\n points1: Point[],\n points2: Point[],\n ): Intersection {\n const result = new Intersection(),\n length = points1.length;\n const coincidences: Intersection[] = [];\n\n for (let i = 0; i < length; i++) {\n const a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectSegmentPolygon(a1, a2, points2);\n if (inter.status === 'Coincident') {\n coincidences.push(inter);\n result.append(a1, a2);\n } else {\n result.append(...inter.points);\n }\n }\n\n if (coincidences.length > 0 && coincidences.length === points1.length) {\n return new Intersection('Coincident');\n } else if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @see {@link intersectPolygonPolygon} for polygon intersection\n * @param {Point[]} points polygon points\n * @param {Point} r1 top left point of rect\n * @param {Point} r2 bottom right point of rect\n * @return {Intersection}\n */\n static intersectPolygonRectangle(\n points: Point[],\n r1: Point,\n r2: Point,\n ): Intersection {\n const min = r1.min(r2),\n max = r1.max(r2),\n topRight = new Point(max.x, min.y),\n bottomLeft = new Point(min.x, max.y);\n\n return Intersection.intersectPolygonPolygon(points, [\n min,\n topRight,\n max,\n bottomLeft,\n ]);\n }\n}\n","import type {\n TBBox,\n TCornerPoint,\n TDegree,\n TMat2D,\n TOriginX,\n TOriginY,\n} from '../../typedefs';\nimport { SCALE_X, SCALE_Y, iMatrix } from '../../constants';\nimport { Intersection } from '../../Intersection';\nimport { Point } from '../../Point';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n createRotateMatrix,\n createTranslateMatrix,\n composeMatrix,\n invertTransform,\n multiplyTransformMatrices,\n transformPoint,\n calcPlaneRotation,\n} from '../../util/misc/matrix';\nimport { radiansToDegrees } from '../../util/misc/radiansDegreesConversion';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type { ControlProps } from './types/ControlProps';\nimport { resolveOrigin } from '../../util/misc/resolveOrigin';\nimport type { Group } from '../Group';\nimport { calcDimensionsMatrix } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport { CommonMethods } from '../../CommonMethods';\nimport type { BaseProps } from './types/BaseProps';\nimport type { FillStrokeProps } from './types/FillStrokeProps';\nimport { CENTER, LEFT, TOP } from '../../constants';\n\ntype TMatrixCache = {\n key: number[];\n value: TMat2D;\n};\n\ntype TACoords = TCornerPoint;\n\nexport class ObjectGeometry\n extends CommonMethods\n implements\n Pick,\n BaseProps,\n Pick\n{\n // #region Geometry\n\n declare padding: number;\n\n /**\n * Describe object's corner position in scene coordinates.\n * The coordinates are derived from the following:\n * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth.\n * The coordinates do not depend on viewport changes.\n * The coordinates get updated with {@link setCoords}.\n * You can calculate them without updating with {@link calcACoords()}\n */\n declare aCoords: TACoords;\n\n /**\n * storage cache for object transform matrix\n */\n declare ownMatrixCache?: TMatrixCache;\n\n /**\n * storage cache for object full transform matrix\n */\n declare matrixCache?: TMatrixCache;\n\n /**\n * A Reference of the Canvas where the object is actually added\n * @type StaticCanvas | Canvas;\n * @default undefined\n * @private\n */\n declare canvas?: StaticCanvas | Canvas;\n\n /**\n * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane\n */\n getX(): number {\n return this.getXY().x;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane\n */\n setX(value: number) {\n this.setXY(this.getXY().setX(value));\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane\n */\n getY(): number {\n return this.getXY().y;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane\n */\n setY(value: number) {\n this.setXY(this.getXY().setY(value));\n }\n\n /**\n * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getX}\n */\n getRelativeX(): number {\n return this.left;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this method is identical to {@link setX}\n */\n setRelativeX(value: number) {\n this.left = value;\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getY}\n */\n getRelativeY(): number {\n return this.top;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link setY}\n */\n setRelativeY(value: number) {\n this.top = value;\n }\n\n /**\n * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane\n */\n getXY(): Point {\n const relativePosition = this.getRelativeXY();\n return this.group\n ? transformPoint(relativePosition, this.group.calcTransformMatrix())\n : relativePosition;\n }\n\n /**\n * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate.\n * You can specify {@link originX} and {@link originY} values,\n * that otherwise are the object's current values.\n * @example Set object's bottom left corner to point (5,5) on canvas\n * object.setXY(new Point(5, 5), 'left', 'bottom').\n * @param {Point} point position in scene coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setXY(point: Point, originX?: TOriginX, originY?: TOriginY) {\n if (this.group) {\n point = transformPoint(\n point,\n invertTransform(this.group.calcTransformMatrix()),\n );\n }\n this.setRelativeXY(point, originX, originY);\n }\n\n /**\n * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n */\n getRelativeXY(): Point {\n return new Point(this.left, this.top);\n }\n\n /**\n * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas)\n * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setRelativeXY(\n point: Point,\n originX: TOriginX = this.originX,\n originY: TOriginY = this.originY,\n ) {\n this.setPositionByOrigin(point, originX, originY);\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return false;\n }\n\n /**\n * @return {Point[]} [tl, tr, br, bl] in the scene plane\n */\n getCoords(): Point[] {\n const { tl, tr, br, bl } =\n this.aCoords || (this.aCoords = this.calcACoords());\n const coords = [tl, tr, br, bl];\n if (this.group) {\n const t = this.group.calcTransformMatrix();\n return coords.map((p) => transformPoint(p, t));\n }\n return coords;\n }\n\n /**\n * Checks if object intersects with the scene rect formed by {@link tl} and {@link br}\n */\n intersectsWithRect(tl: Point, br: Point): boolean {\n const intersection = Intersection.intersectPolygonRectangle(\n this.getCoords(),\n tl,\n br,\n );\n return intersection.status === 'Intersection';\n }\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject(other: ObjectGeometry): boolean {\n const intersection = Intersection.intersectPolygonPolygon(\n this.getCoords(),\n other.getCoords(),\n );\n\n return (\n intersection.status === 'Intersection' ||\n intersection.status === 'Coincident' ||\n other.isContainedWithinObject(this) ||\n this.isContainedWithinObject(other)\n );\n }\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject(other: ObjectGeometry): boolean {\n const points = this.getCoords();\n return points.every((point) => other.containsPoint(point));\n }\n\n /**\n * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br}\n */\n isContainedWithinRect(tl: Point, br: Point): boolean {\n const { left, top, width, height } = this.getBoundingRect();\n return (\n left >= tl.x &&\n left + width <= br.x &&\n top >= tl.y &&\n top + height <= br.y\n );\n }\n\n isOverlapping(other: T): boolean {\n return (\n this.intersectsWithObject(other) ||\n this.isContainedWithinObject(other) ||\n other.isContainedWithinObject(this)\n );\n }\n\n /**\n * Checks if point is inside the object\n * @param {Point} point Point to check against\n * @return {Boolean} true if point is inside the object\n */\n containsPoint(point: Point): boolean {\n return Intersection.isPointInPolygon(point, this.getCoords());\n }\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n const points = this.getCoords();\n // if some point is on screen, the object is on screen.\n if (\n points.some(\n (point) =>\n point.x <= br.x &&\n point.x >= tl.x &&\n point.y <= br.y &&\n point.y >= tl.y,\n )\n ) {\n return true;\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n // check if the object is so big that it contains the entire viewport\n return this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n const allPointsAreOutside = this.getCoords().every(\n (point) =>\n (point.x >= br.x || point.x <= tl.x) &&\n (point.y >= br.y || point.y <= tl.y),\n );\n // check if the object is so big that it contains the entire viewport\n return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect(): TBBox {\n return makeBoundingBoxFromPoints(this.getCoords());\n }\n\n /**\n * Returns width of an object's bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} width value\n */\n getScaledWidth(): number {\n return this._getTransformedDimensions().x;\n }\n\n /**\n * Returns height of an object bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} height value\n */\n getScaledHeight(): number {\n return this._getTransformedDimensions().y;\n }\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {void}\n */\n scale(value: number): void {\n this._set(SCALE_X, value);\n this._set(SCALE_Y, value);\n this.setCoords();\n }\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {void}\n */\n scaleToWidth(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n }\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {void}\n */\n scaleToHeight(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n }\n\n getCanvasRetinaScaling() {\n return this.canvas?.getRetinaScaling() || 1;\n }\n\n /**\n * Returns the object angle relative to canvas counting also the group property\n * @returns {TDegree}\n */\n getTotalAngle(): TDegree {\n return this.group\n ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix()))\n : this.angle;\n }\n\n /**\n * Retrieves viewportTransform from Object's canvas if available\n * @return {TMat2D}\n */\n getViewportTransform(): TMat2D {\n return this.canvas?.viewportTransform || (iMatrix.concat() as TMat2D);\n }\n\n /**\n * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates.\n * those never change with zoom or viewport changes.\n * @return {TCornerPoint}\n */\n calcACoords(): TCornerPoint {\n const rotateMatrix = createRotateMatrix({ angle: this.angle }),\n { x, y } = this.getRelativeCenterPoint(),\n tMatrix = createTranslateMatrix(x, y),\n finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n return {\n // corners\n tl: transformPoint({ x: -w, y: -h }, finalMatrix),\n tr: transformPoint({ x: w, y: -h }, finalMatrix),\n bl: transformPoint({ x: -w, y: h }, finalMatrix),\n br: transformPoint({ x: w, y: h }, finalMatrix),\n };\n }\n\n /**\n * Sets corner and controls position coordinates based on current angle, width and height, left and top.\n * aCoords are used to quickly find an object on the canvas.\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n */\n setCoords(): void {\n this.aCoords = this.calcACoords();\n }\n\n transformMatrixKey(skipGroup = false): number[] {\n let prefix: number[] = [];\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup);\n }\n prefix.push(\n this.top,\n this.left,\n this.width,\n this.height,\n this.scaleX,\n this.scaleY,\n this.angle,\n this.strokeWidth,\n this.skewX,\n this.skewY,\n +this.flipX,\n +this.flipY,\n resolveOrigin(this.originX),\n resolveOrigin(this.originY),\n );\n\n return prefix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {TMat2D} transform matrix for the object\n */\n calcTransformMatrix(skipGroup = false): TMat2D {\n let matrix = this.calcOwnMatrix();\n if (skipGroup || !this.group) {\n return matrix;\n }\n const key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache;\n if (cache && cache.key.every((x, i) => x === key[i])) {\n return cache.value;\n }\n if (this.group) {\n matrix = multiplyTransformMatrices(\n this.group.calcTransformMatrix(false),\n matrix,\n );\n }\n this.matrixCache = {\n key,\n value: matrix,\n };\n return matrix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {TMat2D} transform matrix for the object\n */\n calcOwnMatrix(): TMat2D {\n const key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache;\n if (cache && cache.key === key) {\n return cache.value;\n }\n const center = this.getRelativeCenterPoint(),\n options = {\n angle: this.angle,\n translateX: center.x,\n translateY: center.y,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY,\n },\n value = composeMatrix(options);\n this.ownMatrixCache = {\n key,\n value,\n };\n return value;\n }\n\n /**\n * Calculate object dimensions from its properties\n * @private\n * @returns {Point} dimensions\n */\n _getNonTransformedDimensions(): Point {\n return new Point(this.width, this.height).scalarAdd(this.strokeWidth);\n }\n\n /**\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * @private\n * @param {object} [options] transform options\n * @returns {Point} dimensions\n */\n _calculateCurrentDimensions(options?: any): Point {\n return this._getTransformedDimensions(options)\n .transform(this.getViewportTransform(), true)\n .scalarAdd(2 * this.padding);\n }\n\n // #region Origin\n\n declare top: number;\n declare left: number;\n declare width: number;\n declare height: number;\n declare flipX: boolean;\n declare flipY: boolean;\n declare scaleX: number;\n declare scaleY: number;\n declare skewX: number;\n declare skewY: number;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originX: TOriginX;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originY: TOriginY;\n declare angle: TDegree;\n declare strokeWidth: number;\n declare strokeUniform: boolean;\n\n /**\n * Object containing this object.\n * can influence its size and position\n */\n declare group?: Group;\n\n /**\n * Calculate object bounding box dimensions from its properties scale, skew.\n * This bounding box is aligned with object angle and not with canvas axis or screen.\n * @param {Object} [options]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @private\n * @returns {Point} dimensions\n */\n _getTransformedDimensions(options: any = {}): Point {\n const dimOptions = {\n // if scaleX or scaleY are negative numbers,\n // this will return dimensions that are negative.\n // and this will break assumptions around the codebase\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n width: this.width,\n height: this.height,\n strokeWidth: this.strokeWidth,\n ...options,\n };\n // stroke is applied before/after transformations are applied according to `strokeUniform`\n const strokeWidth = dimOptions.strokeWidth;\n let preScalingStrokeValue = strokeWidth,\n postScalingStrokeValue = 0;\n\n if (this.strokeUniform) {\n preScalingStrokeValue = 0;\n postScalingStrokeValue = strokeWidth;\n }\n const dimX = dimOptions.width + preScalingStrokeValue,\n dimY = dimOptions.height + preScalingStrokeValue,\n noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0;\n let finalDimensions;\n if (noSkew) {\n finalDimensions = new Point(\n dimX * dimOptions.scaleX,\n dimY * dimOptions.scaleY,\n );\n } else {\n finalDimensions = sizeAfterTransform(\n dimX,\n dimY,\n calcDimensionsMatrix(dimOptions),\n );\n }\n\n return finalDimensions.scalarAdd(postScalingStrokeValue);\n }\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToGivenOrigin(\n point: Point,\n fromOriginX: TOriginX,\n fromOriginY: TOriginY,\n toOriginX: TOriginX,\n toOriginY: TOriginY,\n ): Point {\n let x = point.x,\n y = point.y;\n const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX),\n offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY);\n\n if (offsetX || offsetY) {\n const dim = this._getTransformedDimensions();\n x += offsetX * dim.x;\n y += offsetY * dim.y;\n }\n\n return new Point(x, y);\n }\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToCenterPoint(\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n if (originX === CENTER && originY === CENTER) {\n return point;\n }\n const p = this.translateToGivenOrigin(\n point,\n originX,\n originY,\n CENTER,\n CENTER,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), point);\n }\n return p;\n }\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {Point} center The point which corresponds to center of the object\n * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToOriginPoint(\n center: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n const p = this.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), center);\n }\n return p;\n }\n\n /**\n * Returns the center coordinates of the object relative to canvas\n * @return {Point}\n */\n getCenterPoint(): Point {\n const relCenter = this.getRelativeCenterPoint();\n return this.group\n ? transformPoint(relCenter, this.group.calcTransformMatrix())\n : relCenter;\n }\n\n /**\n * Returns the center coordinates of the object relative to it's parent\n * @return {Point}\n */\n getRelativeCenterPoint(): Point {\n return this.translateToCenterPoint(\n new Point(this.left, this.top),\n this.originX,\n this.originY,\n );\n }\n\n /**\n * Returns the position of the object as if it has a different origin.\n * Take an object that has left, top set to 100, 100 with origin 'left', 'top'.\n * Return the values of left top ( wrapped in a point ) that you would need to keep\n * the same position if origin where different.\n * Alternatively you can use this to also find which point in the parent plane is a specific origin\n * ( where is the bottom right corner of my object? )\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n getPointByOrigin(originX: TOriginX, originY: TOriginY): Point {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n }\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {Point} pos The new position of the object\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin(pos: Point, originX: TOriginX, originY: TOriginY) {\n const center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(\n center,\n this.originX,\n this.originY,\n );\n this.set({ left: position.x, top: position.y });\n }\n\n /**\n * @private\n */\n _getLeftTopCoords() {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n LEFT,\n TOP,\n );\n }\n}\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport {\n ALIASING_LIMIT,\n CENTER,\n iMatrix,\n LEFT,\n SCALE_X,\n SCALE_Y,\n STROKE,\n FILL,\n TOP,\n VERSION,\n} from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport { Shadow } from '../../Shadow';\nimport type {\n TDegree,\n TFiller,\n TSize,\n TCacheCanvasDimensions,\n Abortable,\n TOptions,\n ImageFormat,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { runningAnimations } from '../../util/animation/AnimationRegistry';\nimport { capValue } from '../../util/misc/capValue';\nimport { createCanvasElement, toDataURL } from '../../util/misc/dom';\nimport { invertTransform, qrDecompose } from '../../util/misc/matrix';\nimport { enlivenObjectEnlivables } from '../../util/misc/objectEnlive';\nimport {\n resetObjectTransform,\n saveObjectTransform,\n} from '../../util/misc/objectTransforms';\nimport { sendObjectToPlane } from '../../util/misc/planeChange';\nimport { pick, pickBy } from '../../util/misc/pick';\nimport { toFixed } from '../../util/misc/toFixed';\nimport type { Group } from '../Group';\nimport { StaticCanvas } from '../../canvas/StaticCanvas';\nimport {\n isFiller,\n isSerializableFiller,\n isTextObject,\n} from '../../util/typeAssertions';\nimport type { FabricImage } from '../Image';\nimport {\n cacheProperties,\n fabricObjectDefaultValues,\n stateProperties,\n} from './defaultValues';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { SerializedObjectProps } from './types/SerializedObjectProps';\nimport type { ObjectProps } from './types/ObjectProps';\nimport { getDevicePixelRatio, getEnv } from '../../env';\nimport { log } from '../../util/internals/console';\nimport type { TColorArg } from '../../color/typedefs';\nimport type { TAnimation } from '../../util/animation/animate';\nimport { animate, animateColor } from '../../util/animation/animate';\nimport type {\n AnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n ValueAnimationOptions,\n} from '../../util/animation/types';\nimport { ObjectGeometry } from './ObjectGeometry';\n\ntype TAncestor = FabricObject;\ntype TCollection = Group;\n\nexport type Ancestors =\n | [FabricObject | Group]\n | [FabricObject | Group, ...Group[]]\n | Group[];\n\nexport type AncestryComparison = {\n /**\n * common ancestors of `this` and`other`(may include`this` | `other`)\n */\n common: Ancestors;\n /**\n * ancestors that are of `this` only\n */\n fork: Ancestors;\n /**\n * ancestors that are of `other` only\n */\n otherFork: Ancestors;\n};\n\nexport type TCachedFabricObject = T &\n Required<\n Pick<\n T,\n | 'zoomX'\n | 'zoomY'\n | '_cacheCanvas'\n | '_cacheContext'\n | 'cacheTranslationX'\n | 'cacheTranslationY'\n >\n > & {\n _cacheContext: CanvasRenderingContext2D;\n };\n\nexport type ObjectToCanvasElementOptions = {\n format?: ImageFormat;\n /** Multiplier to scale by */\n multiplier?: number;\n /** Cropping left offset. Introduced in v1.2.14 */\n left?: number;\n /** Cropping top offset. Introduced in v1.2.14 */\n top?: number;\n /** Cropping width. Introduced in v1.2.14 */\n width?: number;\n /** Cropping height. Introduced in v1.2.14 */\n height?: number;\n /** Enable retina scaling for clone image. Introduce in 1.6.4 */\n enableRetinaScaling?: boolean;\n /** Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 */\n withoutTransform?: boolean;\n /** Remove current object shadow. Introduced in 2.4.2 */\n withoutShadow?: boolean;\n /** Account for canvas viewport transform */\n viewportTransform?: boolean;\n /** Function to create the output canvas to export onto */\n canvasProvider?: (el?: HTMLCanvasElement) => T;\n};\n\ntype toDataURLOptions = ObjectToCanvasElementOptions & {\n quality?: number;\n};\n\n/**\n * Root object class from which all 2d shape classes inherit from\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n * @fires modified\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\nexport class FabricObject<\n Props extends TOptions = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends ObjectGeometry\n implements ObjectProps\n{\n declare minScaleLimit: number;\n\n declare opacity: number;\n\n declare paintFirst: 'fill' | 'stroke';\n declare fill: string | TFiller | null;\n declare fillRule: CanvasFillRule;\n declare stroke: string | TFiller | null;\n declare strokeDashArray: number[] | null;\n declare strokeDashOffset: number;\n declare strokeLineCap: CanvasLineCap;\n declare strokeLineJoin: CanvasLineJoin;\n declare strokeMiterLimit: number;\n\n declare globalCompositeOperation: GlobalCompositeOperation;\n declare backgroundColor: string;\n\n declare shadow: Shadow | null;\n\n declare visible: boolean;\n\n declare includeDefaultValues: boolean;\n declare excludeFromExport: boolean;\n\n declare objectCaching: boolean;\n\n declare clipPath?: FabricObject;\n declare inverted: boolean;\n declare absolutePositioned: boolean;\n declare centeredRotation: boolean;\n declare centeredScaling: boolean;\n\n /**\n * This list of properties is used to check if the state of an object is changed.\n * This state change now is only used for children of groups to understand if a group\n * needs its cache regenerated during a .set call\n * @type Array\n */\n static stateProperties: string[] = stateProperties;\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n static cacheProperties: string[] = cacheProperties;\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n declare dirty: boolean;\n\n /**\n * Quick access for the _cacheCanvas rendering context\n * This is part of the objectCaching feature\n * since 1.7.0\n * @type boolean\n * @default undefined\n * @private\n */\n _cacheContext: CanvasRenderingContext2D | null = null;\n\n /**\n * A reference to the HTMLCanvasElement that is used to contain the cache of the object\n * this canvas element is resized and cleared as needed\n * Is marked private, you can read it, don't use it since it is handled by fabric\n * since 1.7.0\n * @type HTMLCanvasElement\n * @default undefined\n * @private\n */\n declare _cacheCanvas?: HTMLCanvasElement;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, X axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomX?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomY?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationX?: number;\n\n /**\n * translation of the cacheCanvas away from the center, for subpixel accuracy and crispness\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationY?: number;\n\n /**\n * A reference to the parent of the object, usually a Group\n * @type number\n * @default undefined\n * @private\n */\n declare group?: Group;\n\n /**\n * Indicate if the object is sitting on a cache dedicated to it\n * or is part of a larger cache for many object ( a group for example)\n * @type number\n * @default undefined\n * @private\n */\n declare ownCaching?: boolean;\n\n /**\n * Private. indicates if the object inside a group is on a transformed context or not\n * or is part of a larger cache for many object ( a group for example)\n * @type boolean\n * @default undefined\n * @private\n */\n declare _transformDone?: boolean;\n\n static ownDefaults = fabricObjectDefaultValues;\n\n static getDefaults(): Record {\n return FabricObject.ownDefaults;\n }\n\n /**\n * The class type.\n * This is used for serialization and deserialization purposes and internally it can be used\n * to identify classes.\n * When we transform a class in a plain JS object we need a way to recognize which class it was,\n * and the type is the way we do that. It has no other purposes and you should not give one.\n * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type).\n * To idenfity a class use instanceof class ( instanceof Rect ).\n * We do not do that in fabricJS code because we want to try to have code splitting possible.\n */\n static type = 'FabricObject';\n\n /**\n * Legacy identifier of the class. Prefer using utils like isType or instanceOf\n * Will be removed in fabric 7 or 8.\n * The setter exists to avoid type errors in old code and possibly current deserialization code.\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n const name = (this.constructor as typeof FabricObject).type;\n if (name === 'FabricObject') {\n return 'object';\n }\n return name.toLowerCase();\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, FabricObject.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas() {\n this._cacheCanvas = createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n }\n\n /**\n * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize(\n dims: TSize & { zoomX: number; zoomY: number; capped: boolean } & any,\n ) {\n const width = dims.width,\n height = dims.height,\n max = config.maxCacheSideLimit,\n min = config.minCacheSideLimit;\n if (\n width <= max &&\n height <= max &&\n width * height <= config.perfLimitSizeTotal\n ) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n const ar = width / height,\n [limX, limY] = cache.limitDimsByArea(ar),\n x = capValue(min, limX, max),\n y = capValue(min, limY, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const objectScale = this.getTotalObjectScaling(),\n // calculate dimensions without skewing\n dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),\n neededX = (dim.x * objectScale.x) / this.scaleX,\n neededY = (dim.y * objectScale.y) / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.x,\n zoomY: objectScale.y,\n x: neededX,\n y: neededY,\n };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const canvas = this._cacheCanvas!,\n context = this._cacheContext,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = config.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n zoomX = dims.zoomX,\n zoomY = dims.zoomY,\n dimensionsChanged = width !== canvas.width || height !== canvas.height,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY;\n\n if (!canvas || !context) {\n return false;\n }\n\n let drawingWidth,\n drawingHeight,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\n if (dimensionsChanged) {\n const canvasWidth = (this._cacheCanvas as HTMLCanvasElement).width,\n canvasHeight = (this._cacheCanvas as HTMLCanvasElement).height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking =\n (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize &&\n canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (\n sizeGrowing &&\n !dims.capped &&\n (width > minCacheSize || height > minCacheSize)\n ) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (isTextObject(this) && this.path) {\n shouldRedraw = true;\n shouldResizeCanvas = true;\n // IMHO in those lines we are using zoomX and zoomY not the this version.\n additionalWidth += this.getHeightOfLine(0) * this.zoomX!;\n additionalHeight += this.getHeightOfLine(0) * this.zoomY!;\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX =\n Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY =\n Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n context.translate(this.cacheTranslationX, this.cacheTranslationY);\n context.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n }\n\n /**\n * Sets object's properties from options, for class constructor only.\n * Needs to be overridden for different defaults.\n * @protected\n * @param {Object} [options] Options object\n */\n protected setOptions(options: Record = {}) {\n this._setOptions(options);\n }\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform(ctx: CanvasRenderingContext2D) {\n const needFullTransform =\n (this.group && !this.group._transformDone) ||\n (this.group && this.canvas && ctx === (this.canvas as Canvas).contextTop);\n const m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Point}\n */\n getObjectScaling() {\n // if the object is a top level one, on the canvas, we go for simple aritmetic\n // otherwise the complex method with angles will return approximations and decimals\n // and will likely kill the cache when not needed\n // https://github.com/fabricjs/fabric.js/issues/7157\n if (!this.group) {\n return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY));\n }\n // if we are inside a group total zoom calculation is complex, we defer to generic matrices\n const options = qrDecompose(this.calcTransformMatrix());\n return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY));\n }\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling() {\n const scale = this.getObjectScaling();\n if (this.canvas) {\n const zoom = this.canvas.getZoom();\n const retina = this.getCanvasRetinaScaling();\n return scale.scalarMultiply(zoom * retina);\n }\n return scale;\n }\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity() {\n let opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n }\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @todo: this is a control action issue, not a geometry one\n * @private\n * @param {Number} value, unconstrained\n * @return {Number} constrained value;\n */\n _constrainScale(value: number): number {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\n return value;\n }\n\n /**\n * Handles setting values on the instance and handling internal side effects\n * @protected\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (key === SCALE_X || key === SCALE_Y) {\n value = this._constrainScale(value);\n }\n if (key === SCALE_X && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n // i don't like this automatic initialization here\n } else if (key === 'shadow' && value && !(value instanceof Shadow)) {\n value = new Shadow(value);\n }\n\n const isChanged = this[key as keyof this] !== value;\n this[key as keyof this] = value;\n\n // invalidate caches\n if (\n isChanged &&\n (this.constructor as typeof FabricObject).cacheProperties.includes(key)\n ) {\n this.dirty = true;\n }\n // a dirty child makes the parent dirty.\n // but a non dirty child does not make the parent not dirty.\n // the parent could be dirty for some other reason.\n this.parent &&\n (this.dirty ||\n (isChanged &&\n (this.constructor as typeof FabricObject).stateProperties.includes(\n key,\n ))) &&\n this.parent._set('dirty', true);\n\n return this;\n }\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf FabricObject.prototype\n * @return {Boolean}\n */\n isNotVisible() {\n return (\n this.opacity === 0 ||\n (!this.width && !this.height && this.strokeWidth === 0) ||\n !this.visible\n );\n }\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.shouldCache()) {\n this.renderCache();\n (this as TCachedFabricObject).drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n this.drawObject(ctx);\n this.dirty = false;\n }\n ctx.restore();\n }\n\n drawSelectionBackground(_ctx: CanvasRenderingContext2D) {\n /* no op */\n }\n\n renderCache(options?: any) {\n options = options || {};\n if (!this._cacheCanvas || !this._cacheContext) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty() && this._cacheContext) {\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n }\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas() {\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke() {\n return (\n this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0\n );\n }\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill() {\n return this.fill && this.fill !== 'transparent';\n }\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache() {\n if (\n this.paintFirst === STROKE &&\n this.hasFill() &&\n this.hasStroke() &&\n !!this.shadow\n ) {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache() {\n this.ownCaching =\n this.needsItsOwnCache() ||\n (this.objectCaching && (!this.parent || !this.parent.isOnACache()));\n return this.ownCaching;\n }\n\n /**\n * Check if this object will cast a shadow with an offset.\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n * @deprecated\n */\n willDrawShadow() {\n return (\n !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0)\n );\n }\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {FabricObject} clipPath\n */\n drawClipPathOnCache(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (clipPath.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (clipPath.absolutePositioned) {\n const m = invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {boolean} forClipping apply clipping styles\n */\n drawObject(ctx: CanvasRenderingContext2D, forClipping?: boolean) {\n const originalFill = this.fill,\n originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n }\n this._render(ctx);\n this._drawClipPath(ctx, this.clipPath);\n this.fill = originalFill;\n this.stroke = originalStroke;\n }\n\n /**\n * Prepare clipPath state and cache and draw it on instance's cache\n * @param {CanvasRenderingContext2D} ctx\n * @param {FabricObject} clipPath\n */\n _drawClipPath(ctx: CanvasRenderingContext2D, clipPath?: FabricObject) {\n if (!clipPath) {\n return;\n }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n clipPath._set('canvas', this.canvas);\n clipPath.shouldCache();\n clipPath._transformDone = true;\n clipPath.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx, clipPath as TCachedFabricObject);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(this: TCachedFabricObject, ctx: CanvasRenderingContext2D) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(\n this._cacheCanvas,\n -this.cacheTranslationX,\n -this.cacheTranslationY,\n );\n }\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty(skipCanvas = false) {\n if (this.isNotVisible()) {\n return false;\n }\n const canvas = this._cacheCanvas;\n const ctx = this._cacheContext;\n if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned)) {\n if (canvas && ctx && !skipCanvas) {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n }\n return true;\n }\n }\n return false;\n }\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n if (!this.backgroundColor) {\n return;\n }\n const dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y);\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity(ctx: CanvasRenderingContext2D) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n }\n\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n decl: Pick<\n this,\n | 'stroke'\n | 'strokeWidth'\n | 'strokeLineCap'\n | 'strokeDashOffset'\n | 'strokeLineJoin'\n | 'strokeMiterLimit'\n >,\n ) {\n const stroke = decl.stroke;\n if (stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n if (isFiller(stroke)) {\n if (\n (stroke as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (stroke as Gradient<'linear'>).gradientTransform ||\n (stroke as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, stroke);\n } else {\n // is a simple gradient or pattern\n ctx.strokeStyle = stroke.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, stroke);\n }\n } else {\n // is a color\n ctx.strokeStyle = decl.stroke as string;\n }\n }\n }\n\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n if (fill) {\n if (isFiller(fill)) {\n ctx.fillStyle = fill.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, fill);\n } else {\n ctx.fillStyle = fill;\n }\n }\n }\n\n _setClippingProperties(ctx: CanvasRenderingContext2D) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n }\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n */\n _setLineDash(ctx: CanvasRenderingContext2D, dashArray?: number[] | null) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies of the dash array when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push(...dashArray);\n }\n ctx.setLineDash(dashArray);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n const shadow = this.shadow,\n canvas = this.canvas,\n retinaScaling = this.getCanvasRetinaScaling(),\n [sx, , , sy] = canvas?.viewportTransform || iMatrix,\n multX = sx * retinaScaling,\n multY = sy * retinaScaling,\n scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling();\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur =\n (shadow.blur *\n config.browserShadowBlurConstant *\n (multX + multY) *\n (scaling.x + scaling.y)) /\n 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TFiller} filler {@link Pattern} or {@link Gradient}\n */\n _applyPatternGradientTransform(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n if (!isFiller(filler)) {\n return { offsetX: 0, offsetY: 0 };\n }\n const t =\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform;\n const offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if ((filler as Gradient<'linear'>).gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n }\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} _ctx Context to render on\n */\n _render(_ctx: CanvasRenderingContext2D) {\n // placeholder to be overridden\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._setFillStyles(ctx, this);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform) {\n const scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.x, 1 / scaling.y);\n }\n this._setLineDash(ctx, this.strokeDashArray);\n this._setStrokeStyles(ctx, this);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Gradient} filler\n */\n _applyPatternForTransformedGradient(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n const dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = createCanvasElement(),\n retinaScaling = this.getCanvasRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n // in case width and height are less than 1px, we have to round up.\n // since the pattern is no-repeat, this is fine\n pCanvas.width = Math.ceil(width);\n pCanvas.height = Math.ceil(height);\n const pCtx = pCanvas.getContext('2d');\n if (!pCtx) {\n return;\n }\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling,\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx)!;\n pCtx.fill();\n ctx.translate(\n -this.width / 2 - this.strokeWidth / 2,\n -this.height / 2 - this.strokeWidth / 2,\n );\n ctx.scale(\n (retinaScaling * this.scaleX) / dims.zoomX,\n (retinaScaling * this.scaleY) / dims.zoomY,\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat') ?? '';\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement() {\n return new Point(this.left + this.width / 2, this.top + this.height / 2);\n }\n\n /**\n * Clones an instance.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {Promise}\n */\n clone(propertiesToInclude?: string[]): Promise {\n const objectForm = this.toObject(propertiesToInclude);\n return (this.constructor as typeof FabricObject).fromObject(\n objectForm,\n ) as unknown as Promise;\n }\n\n /**\n * Creates an instance of Image out of an object\n * makes use of toCanvasElement.\n * Once this method was based on toDataUrl and loadImage, so it also had a quality\n * and format option. toCanvasElement is faster and produce no loss of quality.\n * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.\n * toCanvasElement and then toBlob from the obtained canvas is also a good option.\n * @todo fix the export type, it could not be Image but the type that getClass return for 'image'.\n * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {FabricImage} Object cloned as image.\n */\n cloneAsImage(options: ObjectToCanvasElementOptions): FabricImage {\n const canvasEl = this.toCanvasElement(options);\n // TODO: how to import Image w/o an import cycle?\n const ImageClass = classRegistry.getClass('image');\n return new ImageClass(canvasEl);\n }\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {ObjectToCanvasElementOptions} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform\n * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas\n * @return {HTMLCanvasElement} Returns DOM element with the FabricObject\n */\n toCanvasElement(options: ObjectToCanvasElementOptions = {}) {\n const origParams = saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1,\n multiplier = (options.multiplier || 1) * retinaScaling,\n canvasProvider: (el: HTMLCanvasElement) => StaticCanvas =\n options.canvasProvider ||\n ((el: HTMLCanvasElement) =>\n new StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n }));\n delete this.group;\n if (options.withoutTransform) {\n resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n if (options.viewportTransform) {\n sendObjectToPlane(this, this.getViewportTransform());\n }\n\n this.setCoords();\n const el = createCanvasElement(),\n boundingRect = this.getBoundingRect(),\n shadow = this.shadow,\n shadowOffset = new Point();\n\n if (shadow) {\n const shadowBlur = shadow.blur;\n const scaling = shadow.nonScaling\n ? new Point(1, 1)\n : this.getObjectScaling();\n // consider non scaling shadow.\n shadowOffset.x =\n 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x);\n shadowOffset.y =\n 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y);\n }\n const width = boundingRect.width + shadowOffset.x,\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n const canvas = canvasProvider(el);\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(\n new Point(canvas.width / 2, canvas.height / 2),\n CENTER,\n CENTER,\n );\n const originalCanvas = this.canvas;\n // static canvas and canvas have both an array of InteractiveObjects\n // @ts-expect-error this needs to be fixed somehow, or ignored globally\n canvas._objects = [this];\n this.set('canvas', canvas);\n this.setCoords();\n const canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.set('canvas', originalCanvas);\n this.shadow = originalShadow;\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams);\n this.setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n // since render has settled it is safe to destroy canvas\n canvas.destroy();\n return canvasEl;\n }\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL(options: toDataURLOptions = {}) {\n return toDataURL(\n this.toCanvasElement(options),\n options.format || 'png',\n options.quality || 1,\n );\n }\n\n /**\n * Returns true if any of the specified types is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType(...types: string[]) {\n return (\n types.includes((this.constructor as typeof FabricObject).type) ||\n types.includes(this.type)\n );\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity() {\n return 1;\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {TDegree} angle Angle value (in degrees)\n */\n rotate(angle: TDegree) {\n const { centeredRotation, originX, originY } = this;\n\n if (centeredRotation) {\n const { x, y } = this.getRelativeCenterPoint();\n this.originX = CENTER;\n this.originY = CENTER;\n this.left = x;\n this.top = y;\n }\n\n this.set('angle', angle);\n\n if (centeredRotation) {\n const { x, y } = this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n this.left = x;\n this.top = y;\n this.originX = originX;\n this.originY = originY;\n }\n }\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup() {\n // implemented by sub-classes, as needed.\n }\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation(ctx: CanvasRenderingContext2D) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n\n /**\n * cancel instance's running animations\n * override if necessary to dispose artifacts such as `clipPath`\n */\n dispose() {\n runningAnimations.cancelByTarget(this);\n this.off();\n this._set('canvas', undefined);\n // clear caches\n this._cacheCanvas && getEnv().dispose(this._cacheCanvas);\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n // #region Animation methods\n /**\n * List of properties to consider for animating colors.\n * @type String[]\n */\n static colorProperties: string[] = [FILL, STROKE, 'backgroundColor'];\n\n /**\n * Animates object's properties\n * @param {Record} animatable map of keys and end values\n * @param {Partial>} options\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @return {Record>} map of animation contexts\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n */\n animate(\n animatable: Record,\n options?: Partial>,\n ): Record> {\n return Object.entries(animatable).reduce(\n (acc, [key, endValue]) => {\n acc[key] = this._animate(key, endValue, options);\n return acc;\n },\n {} as Record>,\n );\n }\n\n /**\n * @private\n * @param {String} key Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n */\n _animate(\n key: string,\n endValue: T,\n options: Partial> = {},\n ): TAnimation {\n const path = key.split('.');\n const propIsColor = (\n this.constructor as typeof FabricObject\n ).colorProperties.includes(path[path.length - 1]);\n const { abort, startValue, onChange, onComplete } = options;\n const animationOptions = {\n ...options,\n target: this,\n // path.reduce... is the current value in case start value isn't provided\n startValue:\n startValue ?? path.reduce((deep: any, key) => deep[key], this),\n endValue,\n abort: abort?.bind(this),\n onChange: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n path.reduce((deep: Record, key, index) => {\n if (index === path.length - 1) {\n deep[key] = value;\n }\n return deep[key];\n }, this);\n onChange &&\n // @ts-expect-error generic callback arg0 is wrong\n onChange(value, valueProgress, durationProgress);\n },\n onComplete: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n this.setCoords();\n onComplete &&\n // @ts-expect-error generic callback arg0 is wrong\n onComplete(value, valueProgress, durationProgress);\n },\n } as AnimationOptions;\n\n return (\n propIsColor\n ? animateColor(animationOptions as ColorAnimationOptions)\n : animate(\n animationOptions as ValueAnimationOptions | ArrayAnimationOptions,\n )\n ) as TAnimation;\n }\n\n // #region Object stacking methods\n\n /**\n * A reference to the parent of the object\n * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref\n */\n declare parent?: Group;\n\n /**\n * Checks if object is descendant of target\n * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons\n * @param {TAncestor} target\n * @returns {boolean}\n */\n isDescendantOf(target: TAncestor): boolean {\n const { parent, group } = this;\n return (\n parent === target ||\n group === target ||\n // walk up\n (!!parent && parent.isDescendantOf(target)) ||\n (!!group && group !== parent && group.isDescendantOf(target))\n );\n }\n\n /**\n * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top\n */\n getAncestors(): Ancestors {\n const ancestors: TAncestor[] = [];\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let parent: TAncestor | undefined = this;\n do {\n parent = parent.parent;\n parent && ancestors.push(parent);\n } while (parent);\n return ancestors as Ancestors;\n }\n\n /**\n * Compare ancestors\n *\n * @param {StackedObject} other\n * @returns {AncestryComparison} an object that represent the ancestry situation.\n */\n findCommonAncestors(other: T): AncestryComparison {\n if (this === other) {\n return {\n fork: [],\n otherFork: [],\n common: [this, ...this.getAncestors()],\n } as AncestryComparison;\n }\n const ancestors = this.getAncestors();\n const otherAncestors = other.getAncestors();\n // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case\n if (\n ancestors.length === 0 &&\n otherAncestors.length > 0 &&\n this === otherAncestors[otherAncestors.length - 1]\n ) {\n return {\n fork: [],\n otherFork: [\n other,\n ...otherAncestors.slice(0, otherAncestors.length - 1),\n ],\n common: [this],\n } as AncestryComparison;\n }\n // compare ancestors\n for (let i = 0, ancestor; i < ancestors.length; i++) {\n ancestor = ancestors[i];\n if (ancestor === other) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n for (let j = 0; j < otherAncestors.length; j++) {\n if (this === otherAncestors[j]) {\n return {\n fork: [],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: [this, ...ancestors],\n } as AncestryComparison;\n }\n if (ancestor === otherAncestors[j]) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n }\n }\n // nothing shared\n return {\n fork: [this, ...ancestors],\n otherFork: [other, ...otherAncestors],\n common: [],\n } as AncestryComparison;\n }\n\n /**\n *\n * @param {StackedObject} other\n * @returns {boolean}\n */\n hasCommonAncestors(other: T): boolean {\n const commonAncestors = this.findCommonAncestors(other);\n return commonAncestors && !!commonAncestors.common.length;\n }\n\n /**\n *\n * @param {FabricObject} other object to compare against\n * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined`\n */\n isInFrontOf(other: T): boolean | undefined {\n if (this === other) {\n return undefined;\n }\n const ancestorData = this.findCommonAncestors(other);\n\n if (ancestorData.fork.includes(other as any)) {\n return true;\n }\n if (ancestorData.otherFork.includes(this as any)) {\n return false;\n }\n // if there isn't a common ancestor, we take the canvas.\n // if there is no canvas, there is nothing to compare\n const firstCommonAncestor = ancestorData.common[0] || this.canvas;\n if (!firstCommonAncestor) {\n return undefined;\n }\n const headOfFork = ancestorData.fork.pop(),\n headOfOtherFork = ancestorData.otherFork.pop(),\n thisIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfFork as any,\n ),\n otherIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfOtherFork as any,\n );\n return thisIndex > -1 && thisIndex > otherIndex;\n }\n\n // #region Serialization\n /**\n * Define a list of custom properties that will be serialized when\n * instance.toObject() gets called\n */\n static customProperties: string[] = [];\n\n /**\n * Returns an object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject(propertiesToInclude: any[] = []): any {\n const propertiesToSerialize = propertiesToInclude.concat(\n FabricObject.customProperties,\n (this.constructor as typeof FabricObject).customProperties || [],\n );\n let clipPathData: Partial | undefined;\n const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n const {\n clipPath,\n fill,\n stroke,\n shadow,\n strokeDashArray,\n left,\n top,\n originX,\n originY,\n width,\n height,\n strokeWidth,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit,\n scaleX,\n scaleY,\n angle,\n flipX,\n flipY,\n opacity,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX,\n skewY,\n } = this;\n if (clipPath && !clipPath.excludeFromExport) {\n clipPathData = clipPath.toObject(\n propertiesToSerialize.concat('inverted', 'absolutePositioned'),\n );\n }\n const toFixedBound = (val: number) => toFixed(val, NUM_FRACTION_DIGITS);\n const object = {\n ...pick(this, propertiesToSerialize as (keyof this)[]),\n type: (this.constructor as typeof FabricObject).type,\n version: VERSION,\n originX,\n originY,\n left: toFixedBound(left),\n top: toFixedBound(top),\n width: toFixedBound(width),\n height: toFixedBound(height),\n fill: isSerializableFiller(fill) ? fill.toObject() : fill,\n stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke,\n strokeWidth: toFixedBound(strokeWidth),\n strokeDashArray: strokeDashArray\n ? strokeDashArray.concat()\n : strokeDashArray,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit: toFixedBound(strokeMiterLimit),\n scaleX: toFixedBound(scaleX),\n scaleY: toFixedBound(scaleY),\n angle: toFixedBound(angle),\n flipX,\n flipY,\n opacity: toFixedBound(opacity),\n shadow: shadow ? shadow.toObject() : shadow,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX: toFixedBound(skewX),\n skewY: toFixedBound(skewY),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n\n return !this.includeDefaultValues\n ? this._removeDefaultValues(object)\n : object;\n }\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: any[]): any {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n }\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues(object: T): Partial {\n // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance\n // ownDefault vs prototype is swappable only if you change all the fabric objects consistently.\n const defaults = (this.constructor as typeof FabricObject).getDefaults();\n const hasStaticDefaultValues = Object.keys(defaults).length > 0;\n const baseValues = hasStaticDefaultValues\n ? defaults\n : Object.getPrototypeOf(this);\n\n return pickBy(object, (value, key) => {\n if (key === LEFT || key === TOP || key === 'type') {\n return true;\n }\n const baseValue = baseValues[key];\n return (\n value !== baseValue &&\n // basically a check for [] === []\n !(\n Array.isArray(value) &&\n Array.isArray(baseValue) &&\n value.length === 0 &&\n baseValue.length === 0\n )\n );\n });\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString() {\n return `#<${(this.constructor as typeof FabricObject).type}>`;\n }\n\n /**\n *\n * @param {Function} klass\n * @param {object} object\n * @param {object} [options]\n * @param {string} [options.extraParam] property to pass as first argument to the constructor\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static _fromObject(\n { type, ...serializedObjectOptions }: Record,\n { extraParam, ...options }: Abortable & { extraParam?: string } = {},\n ): Promise {\n return enlivenObjectEnlivables(serializedObjectOptions, options).then(\n (enlivedObjectOptions) => {\n // from the resulting enlived options, extract options.extraParam to arg0\n // to avoid accidental overrides later\n if (extraParam) {\n delete enlivedObjectOptions[extraParam];\n return new this(\n serializedObjectOptions[extraParam],\n // @ts-expect-error different signature\n enlivedObjectOptions,\n );\n } else {\n return new this(enlivedObjectOptions);\n }\n },\n ) as Promise;\n }\n\n /**\n *\n * @param {object} object\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n object: T,\n options?: Abortable,\n ) {\n return this._fromObject(object, options);\n }\n}\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n","import type {\n TModificationEvents,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\n/**\n * Wrap an action handler with firing an event if the action is performed\n * @param {TModificationEvents} eventName the event we want to fire\n * @param {TransformActionHandler} actionHandler the function to wrap\n * @param {object} extraEventInfo extra information to pas to the event handler\n * @return {TransformActionHandler} a function with an action handler signature\n */\nexport const wrapWithFireEvent = <\n T extends Transform,\n P extends object = Record,\n>(\n eventName: TModificationEvents,\n actionHandler: TransformActionHandler,\n extraEventInfo?: P,\n) => {\n return ((eventData, transform, x, y) => {\n const actionPerformed = actionHandler(eventData, transform, x, y);\n if (actionPerformed) {\n fireEvent(eventName, {\n ...commonEventInfo(eventData, transform, x, y),\n ...extraEventInfo,\n });\n }\n return actionPerformed;\n }) as TransformActionHandler;\n};\n","import type { Transform, TransformActionHandler } from '../EventTypeDefs';\n\n/**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\nexport function wrapWithFixedAnchor(\n actionHandler: TransformActionHandler,\n) {\n return ((eventData, transform, x, y) => {\n const { target, originX, originY } = transform,\n centerPoint = target.getRelativeCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, originX, originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n // flipping requires to change the transform origin, so we read from the mutated transform\n // instead of leveraging the one destructured before\n target.setPositionByOrigin(\n constraint,\n transform.originX,\n transform.originY,\n );\n return actionPerformed;\n }) as TransformActionHandler;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { CENTER, LEFT, RESIZING, RIGHT } from '../constants';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { getLocalPoint, isTransformCentered } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Action handler to change object's width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const changeObjectWidth: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const localPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // make sure the control changes width ONLY from it's side of target\n if (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) ||\n (resolveOrigin(transform.originX) === resolveOrigin(RIGHT) &&\n localPoint.x < 0) ||\n (resolveOrigin(transform.originX) === resolveOrigin(LEFT) &&\n localPoint.x > 0)\n ) {\n const { target } = transform,\n strokePadding =\n target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width,\n newWidth = Math.ceil(\n Math.abs((localPoint.x * multiplier) / target.scaleX) - strokePadding,\n );\n target.set('width', Math.max(newWidth, 0));\n // check against actual target width in case `newWidth` was rejected\n return oldWidth !== target.width;\n }\n return false;\n};\n\nexport const changeWidth = wrapWithFireEvent(\n RESIZING,\n wrapWithFixedAnchor(changeObjectWidth),\n);\n","import { FILL, STROKE, twoMathPi } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\n\nexport type ControlRenderingStyleOverride = Partial<\n Pick<\n InteractiveFabricObject,\n | 'cornerStyle'\n | 'cornerSize'\n | 'cornerColor'\n | 'cornerStrokeColor'\n | 'cornerDashArray'\n | 'transparentCorners'\n >\n>;\n\nexport type ControlRenderer<\n O extends InteractiveFabricObject = InteractiveFabricObject,\n> = (\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: O,\n) => void;\n\n/**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCircleControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n let myLeft = left,\n myTop = top,\n size;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // TODO: use proper ellipse code.\n if (xSize > ySize) {\n size = xSize;\n ctx.scale(1.0, ySize / xSize);\n myTop = (top * xSize) / ySize;\n } else if (ySize > xSize) {\n size = ySize;\n ctx.scale(xSize / ySize, 1.0);\n myLeft = (left * ySize) / xSize;\n } else {\n size = xSize;\n }\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n}\n\n/**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderSquareControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle();\n ctx.rotate(degreesToRadians(angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n ctx[`${methodName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);\n if (stroke) {\n ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n }\n ctx.restore();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type {\n ControlActionHandler,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { Intersection } from '../Intersection';\nimport { Point } from '../Point';\nimport { SCALE } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport type { TCornerPoint, TDegree, TMat2D } from '../typedefs';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { renderCircleControl, renderSquareControl } from './controlRendering';\n\nexport class Control {\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the control set.\n * @type {Boolean}\n * @default true\n */\n visible = true;\n\n /**\n * Name of the action that the control will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName = SCALE;\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle = 0;\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x = 0;\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y = 0;\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX = 0;\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY = 0;\n\n /**\n * Sets the length of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeX = 0;\n\n /**\n * Sets the height of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeY = 0;\n\n /**\n * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeX = 0;\n\n /**\n * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeY = 0;\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle = 'crosshair';\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection = false;\n\n constructor(options?: Partial) {\n Object.assign(this, options);\n }\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare actionHandler: TransformActionHandler;\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseDownHandler?: ControlActionHandler;\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseUpHandler?: ControlActionHandler;\n\n shouldActivate(\n controlKey: string,\n fabricObject: InteractiveFabricObject,\n pointer: Point,\n { tl, tr, br, bl }: TCornerPoint,\n ) {\n // TODO: locking logic can be handled here instead of in the control handler logic\n return (\n fabricObject.canvas?.getActiveObject() === fabricObject &&\n fabricObject.isControlVisible(controlKey) &&\n Intersection.isPointInPolygon(pointer, [tl, tr, br, bl])\n );\n }\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getActionHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): TransformActionHandler | undefined {\n return this.actionHandler;\n }\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseDownHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseDownHandler;\n }\n\n /**\n * Returns control mouseUp handler.\n * During actions the fabricObject or the control can be of different obj\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseUpHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseUpHandler;\n }\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.cursorStyle;\n }\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n getActionName(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.actionName;\n }\n\n /**\n * Returns controls visibility\n * @param {FabricObject} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility(fabricObject: InteractiveFabricObject, controlKey: string) {\n return fabricObject._controlsVisibility?.[controlKey] ?? this.visible;\n }\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility(\n visibility: boolean,\n name: string,\n fabricObject: InteractiveFabricObject,\n ) {\n this.visible = visibility;\n }\n\n positionHandler(\n dim: Point,\n finalMatrix: TMat2D,\n fabricObject: InteractiveFabricObject,\n currentControl: Control,\n ) {\n return new Point(\n this.x * dim.x + this.offsetX,\n this.y * dim.y + this.offsetY,\n ).transform(finalMatrix);\n }\n\n /**\n * Returns the coords for this control based on object values.\n * @param {Number} objectAngle angle from the fabric object holding the control\n * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if\n * isTouch is true)\n * @param {Number} centerX x coordinate where the control center should be\n * @param {Number} centerY y coordinate where the control center should be\n * @param {boolean} isTouch true if touch corner, false if normal corner\n */\n calcCornerCoords(\n angle: TDegree,\n objectCornerSize: number,\n centerX: number,\n centerY: number,\n isTouch: boolean,\n fabricObject: InteractiveFabricObject,\n ) {\n const t = multiplyTransformMatrixArray([\n createTranslateMatrix(centerX, centerY),\n createRotateMatrix({ angle }),\n createScaleMatrix(\n (isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize,\n (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize,\n ),\n ]);\n return {\n tl: new Point(-0.5, -0.5).transform(t),\n tr: new Point(0.5, -0.5).transform(t),\n br: new Point(0.5, 0.5).transform(t),\n bl: new Point(-0.5, 0.5).transform(t),\n };\n }\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {FabricObject} fabricObject the object where the control is about to be rendered\n */\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: InteractiveFabricObject,\n ) {\n styleOverride = styleOverride || {};\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n renderCircleControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n break;\n default:\n renderSquareControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n }\n }\n}\n","import type {\n ControlCursorCallback,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { ROTATING } from '../constants';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { isLocked, NOT_ALLOWED_CURSOR } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const rotationStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (fabricObject.lockRotation) {\n return NOT_ALLOWED_CURSOR;\n }\n return control.cursorStyle;\n};\n\n/**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\nconst rotateObjectWithSnapping: TransformActionHandler = (\n eventData,\n { target, ex, ey, theta, originX, originY },\n x,\n y,\n) => {\n const pivotPoint = target.translateToOriginPoint(\n target.getRelativeCenterPoint(),\n originX,\n originY,\n );\n\n if (isLocked(target, 'lockRotation')) {\n return false;\n }\n\n const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x);\n let angle = radiansToDegrees(curAngle - lastAngle + theta);\n\n if (target.snapAngle && target.snapAngle > 0) {\n const snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n const hasRotated = target.angle !== angle;\n // TODO: why aren't we using set?\n target.angle = angle;\n return hasRotated;\n};\n\nexport const rotationWithSnapping = wrapWithFireEvent(\n ROTATING,\n wrapWithFixedAnchor(rotateObjectWithSnapping),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxis } from '../typedefs';\nimport type { Canvas } from '../canvas/Canvas';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n invertOrigin,\n isLocked,\n isTransformCentered,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport { SCALE_X, SCALE_Y, SCALING } from '../constants';\n\ntype ScaleTransform = Transform & {\n gestureScale?: number;\n signX?: number;\n signY?: number;\n};\n\ntype ScaleBy = TAxis | 'equally' | '' | undefined;\n\n/**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\nexport function scaleIsProportional(\n eventData: TPointerEvent,\n fabricObject: FabricObject,\n): boolean {\n const canvas = fabricObject.canvas as Canvas,\n uniformIsToggled = eventData[canvas.uniScaleKey!];\n return (\n (canvas.uniformScaling && !uniformIsToggled) ||\n (!canvas.uniformScaling && uniformIsToggled)\n );\n}\n\n/**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\nexport function scalingIsForbidden(\n fabricObject: FabricObject,\n by: ScaleBy,\n scaleProportionally: boolean,\n) {\n const lockX = isLocked(fabricObject, 'lockScalingX'),\n lockY = isLocked(fabricObject, 'lockScalingY');\n if (lockX && lockY) {\n return true;\n }\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n if (lockX && by === 'x') {\n return true;\n }\n if (lockY && by === 'y') {\n return true;\n }\n // code crashes because of a division by 0 if a 0 sized object is scaled\n // forbid to prevent scaling to happen. ISSUE-9475\n const { width, height, strokeWidth } = fabricObject;\n if (width === 0 && strokeWidth === 0 && by !== 'y') {\n return true;\n }\n if (height === 0 && strokeWidth === 0 && by !== 'x') {\n return true;\n }\n return false;\n}\n\nconst scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];\n\n/**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n const scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by =\n control.x !== 0 && control.y === 0\n ? 'x'\n : control.x === 0 && control.y !== 0\n ? 'y'\n : '';\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control);\n return `${scaleMap[n]}-resize`;\n};\n\n/**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\nfunction scaleObject(\n eventData: TPointerEvent,\n transform: ScaleTransform,\n x: number,\n y: number,\n options: { by?: ScaleBy } = {},\n) {\n const target = transform.target,\n by = options.by,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally);\n let newPoint, scaleX, scaleY, dim, signX, signY;\n\n if (forbidScaling) {\n return false;\n }\n if (transform.gestureScale) {\n scaleX = transform.scaleX * transform.gestureScale;\n scaleY = transform.scaleY * transform.gestureScale;\n } else {\n newPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1;\n signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1;\n if (!transform.signX) {\n transform.signX = signX;\n }\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (\n isLocked(target, 'lockScalingFlip') &&\n (transform.signX !== signX || transform.signY !== signY)\n ) {\n return false;\n }\n\n dim = target._getTransformedDimensions();\n // missing detection of flip and logic to switch the origin\n if (scaleProportionally && !by) {\n // uniform scaling\n const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n { original } = transform,\n originalDistance =\n Math.abs((dim.x * original.scaleX) / target.scaleX) +\n Math.abs((dim.y * original.scaleY) / target.scaleY),\n scale = distance / originalDistance;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n } else {\n scaleX = Math.abs((newPoint.x * target.scaleX) / dim.x);\n scaleY = Math.abs((newPoint.y * target.scaleY) / dim.y);\n }\n // if we are scaling by center, we need to double the scale\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = invertOrigin(transform.originX);\n scaleX *= -1;\n transform.signX = signX;\n }\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = invertOrigin(transform.originY);\n scaleY *= -1;\n transform.signY = signY;\n }\n }\n // minScale is taken care of in the setter.\n const oldScaleX = target.scaleX,\n oldScaleY = target.scaleY;\n if (!by) {\n !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX);\n !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY);\n } else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set(SCALE_X, scaleX);\n by === 'y' && target.set(SCALE_Y, scaleY);\n }\n return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n}\n\n/**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scaleObjectFromCorner: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y);\n};\n\n/**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'x' });\n};\n\n/**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'y' });\n};\n\nexport const scalingEqually = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectFromCorner),\n);\n\nexport const scalingX = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectX),\n);\n\nexport const scalingY = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectY),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { TAxis, TAxisKey } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n isLocked,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport {\n CENTER,\n SCALE_X,\n SCALE_Y,\n SKEWING,\n SKEW_X,\n SKEW_Y,\n} from '../constants';\n\nexport type SkewTransform = Transform & { skewingSide: -1 | 1 };\n\nconst AXIS_KEYS: Record<\n TAxis,\n {\n counterAxis: TAxis;\n scale: TAxisKey<'scale'>;\n skew: TAxisKey<'skew'>;\n lockSkewing: TAxisKey<'lockSkewing'>;\n origin: TAxisKey<'origin'>;\n flip: TAxisKey<'flip'>;\n }\n> = {\n x: {\n counterAxis: 'y',\n scale: SCALE_X,\n skew: SKEW_X,\n lockSkewing: 'lockSkewingX',\n origin: 'originX',\n flip: 'flipX',\n },\n y: {\n counterAxis: 'x',\n scale: SCALE_Y,\n skew: SKEW_Y,\n lockSkewing: 'lockSkewingY',\n origin: 'originY',\n flip: 'flipY',\n },\n};\n\nconst skewMap = ['ns', 'nesw', 'ew', 'nwse'];\n\n/**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const skewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) {\n return NOT_ALLOWED_CURSOR;\n }\n if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control) % 4;\n return `${skewMap[n]}-resize`;\n};\n\n/**\n * Since skewing is applied before scaling, calculations are done in a scaleless plane\n * @see https://github.com/fabricjs/fabric.js/pull/8380\n */\nfunction skewObject(\n axis: TAxis,\n { target, ex, ey, skewingSide, ...transform }: SkewTransform,\n pointer: Point,\n) {\n const { skew: skewKey } = AXIS_KEYS[axis],\n offset = pointer\n .subtract(new Point(ex, ey))\n .divide(new Point(target.scaleX, target.scaleY))[axis],\n skewingBefore = target[skewKey],\n skewingStart = transform[skewKey],\n shearingStart = Math.tan(degreesToRadians(skewingStart)),\n // let a, b be the size of target\n // let a' be the value of a after applying skewing\n // then:\n // a' = a + b * skewA => skewA = (a' - a) / b\n // the value b is tricky since skewY is applied before skewX\n b =\n axis === 'y'\n ? target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n // since skewY is applied before skewX, b (=width) is not affected by skewX\n skewX: 0,\n }).x\n : target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n }).y;\n\n const shearing =\n (2 * offset * skewingSide) /\n // we max out fractions to safeguard from asymptotic behavior\n Math.max(b, 1) +\n // add starting state\n shearingStart;\n\n const skewing = radiansToDegrees(Math.atan(shearing));\n\n target.set(skewKey, skewing);\n const changed = skewingBefore !== target[skewKey];\n\n if (changed && axis === 'y') {\n // we don't want skewing to affect scaleX\n // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer\n const { skewX, scaleX } = target,\n dimBefore = target._getTransformedDimensions({ skewY: skewingBefore }),\n dimAfter = target._getTransformedDimensions(),\n compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1;\n compensationFactor !== 1 &&\n target.set(SCALE_X, compensationFactor * scaleX);\n }\n\n return changed;\n}\n\n/**\n * Wrapped Action handler for skewing on a given axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nfunction skewHandler(\n axis: TAxis,\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n) {\n const { target } = transform,\n {\n counterAxis,\n origin: originKey,\n lockSkewing: lockSkewingKey,\n skew: skewKey,\n flip: flipKey,\n } = AXIS_KEYS[axis];\n if (isLocked(target, lockSkewingKey)) {\n return false;\n }\n\n const { origin: counterOriginKey, flip: counterFlipKey } =\n AXIS_KEYS[counterAxis],\n counterOriginFactor =\n resolveOrigin(transform[counterOriginKey]) *\n (target[counterFlipKey] ? -1 : 1),\n // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively.\n // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively.\n // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer,\n // so we factor skewing direction by this value.\n skewingSide = (-Math.sign(counterOriginFactor) *\n (target[flipKey] ? -1 : 1)) as 1 | -1,\n skewingDirection =\n ((target[skewKey] === 0 &&\n // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing\n getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0) ||\n // in case target has skewing we use that as the direction\n target[skewKey] > 0\n ? 1\n : -1) * skewingSide,\n // anchor to the opposite side of the skewing direction\n // normalize value from [-1, 1] to origin value [0, 1]\n origin = -skewingDirection * 0.5 + 0.5;\n\n const finalHandler = wrapWithFireEvent(\n SKEWING,\n wrapWithFixedAnchor((eventData, transform, x, y) =>\n skewObject(axis, transform, new Point(x, y)),\n ),\n );\n\n return finalHandler(\n eventData,\n {\n ...transform,\n [originKey]: origin,\n skewingSide,\n },\n x,\n y,\n );\n}\n\n/**\n * Wrapped Action handler for skewing on the X axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('x', eventData, transform, x, y);\n};\n\n/**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('y', eventData, transform, x, y);\n};\n","import type {\n ControlCallback,\n ControlCursorCallback,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { SCALE_X, SCALE_Y, SKEW_X, SKEW_Y } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxisKey } from '../typedefs';\nimport { scaleCursorStyleHandler, scalingX, scalingY } from './scale';\nimport { skewCursorStyleHandler, skewHandlerX, skewHandlerY } from './skew';\n\nfunction isAltAction(eventData: TPointerEvent, target: FabricObject) {\n return eventData[target.canvas!.altActionKey!];\n}\n\n/**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\nexport const scaleOrSkewActionName: ControlCallback<\n TAxisKey<'skew' | 'scale'> | ''\n> = (eventData, control, fabricObject) => {\n const isAlternative = isAltAction(eventData, fabricObject);\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_X : SCALE_Y;\n }\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_Y : SCALE_X;\n }\n return '';\n};\n\n/**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleSkewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n return isAltAction(eventData, fabricObject)\n ? skewCursorStyleHandler(eventData, control, fabricObject)\n : scaleCursorStyleHandler(eventData, control, fabricObject);\n};\n/**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingXOrSkewingY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerY(eventData, transform, x, y)\n : scalingX(eventData, transform, x, y);\n};\n\n/**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingYOrSkewingX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerX(eventData, transform, x, y)\n : scalingY(eventData, transform, x, y);\n};\n","import { RESIZING, ROTATE } from '../constants';\nimport { changeWidth } from './changeWidth';\nimport { Control } from './Control';\nimport { rotationStyleHandler, rotationWithSnapping } from './rotate';\nimport { scaleCursorStyleHandler, scalingEqually } from './scale';\nimport {\n scaleOrSkewActionName,\n scaleSkewCursorStyleHandler,\n scalingXOrSkewingY,\n scalingYOrSkewingX,\n} from './scaleSkew';\n\n// use this function if you want to generate new controls for every instance\nexport const createObjectDefaultControls = () => ({\n ml: new Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mr: new Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mb: new Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n mt: new Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n tl: new Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n tr: new Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n bl: new Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n br: new Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n mtr: new Control({\n x: 0,\n y: -0.5,\n actionHandler: rotationWithSnapping,\n cursorStyleHandler: rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: ROTATE,\n }),\n});\n\nexport const createResizeControls = () => ({\n mr: new Control({\n x: 0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n ml: new Control({\n x: -0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n});\n\nexport const createTextboxDefaultControls = () => ({\n ...createObjectDefaultControls(),\n ...createResizeControls(),\n});\n","import { Point, ZERO } from '../../Point';\nimport type { TCornerPoint, TDegree } from '../../typedefs';\nimport { FabricObject } from './Object';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport type { TQrDecomposeOut } from '../../util/misc/matrix';\nimport {\n calcDimensionsMatrix,\n createRotateMatrix,\n createTranslateMatrix,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../../util/misc/matrix';\nimport type { Control } from '../../controls/Control';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { ControlRenderingStyleOverride } from '../../controls/controlRendering';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { createObjectDefaultControls } from '../../controls/commonControls';\nimport { interactiveObjectDefaultValues } from './defaultValues';\nimport { SCALE } from '../../constants';\n\nexport type TOCoord = Point & {\n corner: TCornerPoint;\n touchCorner: TCornerPoint;\n};\n\nexport type TControlSet = Record;\n\nexport type TBorderRenderingStyleOverride = Partial<\n Pick\n>;\n\nexport type TStyleOverride = ControlRenderingStyleOverride &\n TBorderRenderingStyleOverride &\n Partial<\n Pick & {\n forActiveSelection: boolean;\n }\n >;\n\nexport class InteractiveFabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n declare noScaleCache: boolean;\n\n declare snapAngle?: TDegree;\n declare snapThreshold?: TDegree;\n\n declare lockMovementX: boolean;\n declare lockMovementY: boolean;\n declare lockRotation: boolean;\n declare lockScalingX: boolean;\n declare lockScalingY: boolean;\n declare lockSkewingX: boolean;\n declare lockSkewingY: boolean;\n declare lockScalingFlip: boolean;\n\n declare cornerSize: number;\n declare touchCornerSize: number;\n declare transparentCorners: boolean;\n declare cornerColor: string;\n declare cornerStrokeColor: string;\n declare cornerStyle: 'rect' | 'circle';\n declare cornerDashArray: number[] | null;\n declare hasControls: boolean;\n\n declare borderColor: string;\n declare borderDashArray: number[] | null;\n declare borderOpacityWhenMoving: number;\n declare borderScaleFactor: number;\n declare hasBorders: boolean;\n declare selectionBackgroundColor: string;\n\n declare selectable: boolean;\n declare evented: boolean;\n declare perPixelTargetFind: boolean;\n declare activeOn: 'down' | 'up';\n\n declare hoverCursor: CSSStyleDeclaration['cursor'] | null;\n declare moveCursor: CSSStyleDeclaration['cursor'] | null;\n\n /**\n * The object's controls' position in viewport coordinates\n * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}.\n * `corner/touchCorner` describe the 4 points forming the interactive area of the corner.\n * Used to draw and locate controls.\n */\n declare oCoords: Record;\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * this isn't cleaned automatically. Non selected objects may have wrong values\n * @type [string]\n */\n declare __corner?: string;\n\n /**\n * a map of control visibility for this object.\n * this was left when controls were introduced to not break the api too much\n * this takes priority over the generic control visibility\n */\n declare _controlsVisibility: Record;\n\n /**\n * holds the controls for the object.\n * controls are added by default_controls.js\n */\n declare controls: TControlSet;\n\n /**\n * internal boolean to signal the code that the object is\n * part of the move action.\n */\n declare isMoving?: boolean;\n\n /**\n * A boolean used from the gesture module to keep tracking of a scaling\n * action when there is no scaling transform in place.\n * This is an edge case and is used twice in all codebase.\n * Probably added to keep track of some performance issues\n * @TODO use git blame to investigate why it was added\n * DON'T USE IT. WE WILL TRY TO REMOVE IT\n */\n declare _scaling?: boolean;\n\n declare canvas?: Canvas;\n\n static ownDefaults = interactiveObjectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...InteractiveFabricObject.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof InteractiveFabricObject).createControls(),\n InteractiveFabricObject.ownDefaults,\n );\n this.setOptions(options);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults\n * @param {Object} [options] Options object\n */\n static createControls(): { controls: Record } {\n return { controls: createObjectDefaultControls() };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n const transform = targetCanvas._currentTransform,\n target = transform.target,\n action = transform.action;\n if (\n this === (target as unknown as this) &&\n action &&\n action.startsWith(SCALE)\n ) {\n return false;\n }\n }\n return super._updateCacheCanvas();\n }\n\n getActiveControl() {\n const key = this.__corner;\n return key\n ? {\n key,\n control: this.controls[key],\n coord: this.oCoords[key],\n }\n : undefined;\n }\n\n /**\n * Determines which corner is under the mouse cursor, represented by `pointer`.\n * This function is return a corner only if the object is the active one.\n * This is done to avoid selecting corner of non active object and activating transformations\n * rather than drag action. The default behavior of fabricJS is that if you want to transform\n * an object, first you select it to show the control set\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found.\n */\n findControl(\n pointer: Point,\n forTouch = false,\n ): { key: string; control: Control; coord: TOCoord } | undefined {\n if (!this.hasControls || !this.canvas) {\n return undefined;\n }\n\n this.__corner = undefined;\n const cornerEntries = Object.entries(this.oCoords);\n for (let i = cornerEntries.length - 1; i >= 0; i--) {\n const [key, corner] = cornerEntries[i];\n const control = this.controls[key];\n\n if (\n control.shouldActivate(\n key,\n this,\n pointer,\n forTouch ? corner.touchCorner : corner.corner,\n )\n ) {\n // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2);\n this.__corner = key;\n\n return { key, control, coord: this.oCoords[key] };\n }\n }\n\n return undefined;\n }\n\n /**\n * Calculates the coordinates of the center of each control plus the corners of the control itself\n * This basically just delegates to each control positionHandler\n * WARNING: changing what is passed to positionHandler is a breaking change, since position handler\n * is a public api and should be done just if extremely necessary\n * @return {Record}\n */\n calcOCoords(): Record {\n const vpt = this.getViewportTransform(),\n center = this.getCenterPoint(),\n tMatrix = createTranslateMatrix(center.x, center.y),\n rMatrix = createRotateMatrix({\n angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0),\n }),\n positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix),\n startMatrix = multiplyTransformMatrices(vpt, positionMatrix),\n finalMatrix = multiplyTransformMatrices(startMatrix, [\n 1 / vpt[0],\n 0,\n 0,\n 1 / vpt[3],\n 0,\n 0,\n ]),\n transformOptions = this.group\n ? qrDecompose(this.calcTransformMatrix())\n : undefined;\n // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it\n if (transformOptions) {\n transformOptions.scaleX = Math.abs(transformOptions.scaleX);\n transformOptions.scaleY = Math.abs(transformOptions.scaleY);\n }\n const dim = this._calculateCurrentDimensions(transformOptions),\n coords: Record = {};\n\n this.forEachControl((control, key) => {\n const position = control.positionHandler(dim, finalMatrix, this, control);\n // coords[key] are sometimes used as points. Those are points to which we add\n // the property corner and touchCorner from `_calcCornerCoords`.\n // don't remove this assign for an object spread.\n coords[key] = Object.assign(\n position,\n this._calcCornerCoords(control, position),\n );\n });\n\n // debug code\n /*\n const canvas = this.canvas;\n setTimeout(function () {\n if (!canvas) return;\n canvas.contextTop.clearRect(0, 0, 700, 700);\n canvas.contextTop.fillStyle = 'green';\n Object.keys(coords).forEach(function(key) {\n const control = coords[key];\n canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n });\n } 50);\n */\n return coords;\n }\n\n /**\n * Sets the coordinates that determine the interaction area of each control\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @todo evaluate simplification of code switching to circle interaction area at runtime\n * @private\n */\n private _calcCornerCoords(control: Control, position: Point) {\n const angle = this.getTotalAngle();\n const corner = control.calcCornerCoords(\n angle,\n this.cornerSize,\n position.x,\n position.y,\n false,\n this,\n );\n const touchCorner = control.calcCornerCoords(\n angle,\n this.touchCornerSize,\n position.x,\n position.y,\n true,\n this,\n );\n return { corner, touchCorner };\n }\n\n /**\n * @override set controls' coordinates as well\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n * @return {void}\n */\n setCoords(): void {\n super.setCoords();\n this.canvas && (this.oCoords = this.calcOCoords());\n }\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the control's key and the object that is calling the iterator\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl(\n fn: (\n control: Control,\n key: string,\n fabricObject: InteractiveFabricObject,\n ) => any,\n ) {\n for (const i in this.controls) {\n fn(this.controls[i], i, this);\n }\n }\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @todo evaluate if make this disappear in favor of a pre-render hook for objects\n * this was added by Andrea Bogazzi to make possible some feature for work reasons\n * it seemed a good option, now is an edge case\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n */\n drawSelectionBackground(ctx: CanvasRenderingContext2D): void {\n if (\n !this.selectionBackgroundColor ||\n (this.canvas && (this.canvas._activeObject as unknown as this) !== this)\n ) {\n return;\n }\n ctx.save();\n const center = this.getRelativeCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.getViewportTransform();\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n }\n\n /**\n * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style.\n * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center\n * @param {Point} size the control box size used\n */\n strokeBorders(ctx: CanvasRenderingContext2D, size: Point): void {\n ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size\n * @param {TStyleOverride} styleOverride object to override the object style\n */\n _drawBorders(\n ctx: CanvasRenderingContext2D,\n size: Point,\n styleOverride: TStyleOverride = {},\n ): void {\n const options = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n borderDashArray: this.borderDashArray,\n ...styleOverride,\n };\n ctx.save();\n ctx.strokeStyle = options.borderColor;\n this._setLineDash(ctx, options.borderDashArray);\n this.strokeBorders(ctx, size);\n options.hasControls && this.drawControlsConnectingLines(ctx, size);\n ctx.restore();\n }\n\n /**\n * Renders controls and borders for the object\n * the context here is not transformed\n * @todo move to interactivity\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TStyleOverride} [styleOverride] properties to override the object style\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: TStyleOverride = {},\n ) {\n const { hasBorders, hasControls } = this;\n const styleOptions = {\n hasBorders,\n hasControls,\n ...styleOverride,\n };\n const vpt = this.getViewportTransform(),\n shouldDrawBorders = styleOptions.hasBorders,\n shouldDrawControls = styleOptions.hasControls;\n const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix());\n const options = qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n // since interactive groups have been introduced, an object could be inside a group and needing controls\n // the following equality check `this.group === this.parent` covers:\n // object without a group ( undefined === undefined )\n // object inside a group\n // excludes object inside a group but multi selected since group and parent will differ in value\n if (this.group === this.parent) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.flipX) {\n options.angle -= 180;\n }\n ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle));\n shouldDrawBorders && this.drawBorders(ctx, options, styleOverride);\n shouldDrawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {TStyleOverride} [styleOverride] object to override the object style\n */\n drawBorders(\n ctx: CanvasRenderingContext2D,\n options: TQrDecomposeOut,\n styleOverride: TStyleOverride,\n ): void {\n let size;\n if ((styleOverride && styleOverride.forActiveSelection) || this.group) {\n const bbox = sizeAfterTransform(\n this.width,\n this.height,\n calcDimensionsMatrix(options),\n ),\n stroke = !this.isStrokeAccountedForInDimensions()\n ? (this.strokeUniform\n ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1)\n : // this is extremely confusing. options comes from the upper function\n // and is the qrDecompose of a matrix that takes in account zoom too\n new Point(options.scaleX, options.scaleY)\n ).scalarMultiply(this.strokeWidth)\n : ZERO;\n size = bbox\n .add(stroke)\n .scalarAdd(this.borderScaleFactor)\n .scalarAdd(this.padding * 2);\n } else {\n size = this._calculateCurrentDimensions().scalarAdd(\n this.borderScaleFactor,\n );\n }\n this._drawBorders(ctx, size, styleOverride);\n }\n\n /**\n * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size object size x = width, y = height\n */\n drawControlsConnectingLines(\n ctx: CanvasRenderingContext2D,\n size: Point,\n ): void {\n let shouldStroke = false;\n\n ctx.beginPath();\n this.forEachControl((control, key) => {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(this, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * size.x, control.y * size.y);\n ctx.lineTo(\n control.x * size.x + control.offsetX,\n control.y * size.y + control.offsetY,\n );\n }\n });\n shouldStroke && ctx.stroke();\n }\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * Be aware that since fabric 6.0 this function does not call setCoords anymore.\n * setCoords needs to be called manually if the object of which we are rendering controls\n * is outside the standard selection and transform process.\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {ControlRenderingStyleOverride} styleOverride object to override the object style\n */\n drawControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: ControlRenderingStyleOverride = {},\n ) {\n ctx.save();\n const retinaScaling = this.getCanvasRetinaScaling();\n const { cornerStrokeColor, cornerDashArray, cornerColor } = this;\n const options = {\n cornerStrokeColor,\n cornerDashArray,\n cornerColor,\n ...styleOverride,\n };\n ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);\n ctx.strokeStyle = ctx.fillStyle = options.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = options.cornerStrokeColor;\n }\n this._setLineDash(ctx, options.cornerDashArray);\n this.forEachControl((control, key) => {\n if (control.getVisibility(this, key)) {\n const p = this.oCoords[key];\n control.render(ctx, p.x, p.y, options, this);\n }\n });\n ctx.restore();\n }\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr',\n * but since the control api allow for any control name, can be any string.\n * @returns {boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible(controlKey: string): boolean {\n return (\n this.controls[controlKey] &&\n this.controls[controlKey].getVisibility(this, controlKey)\n );\n }\n\n /**\n * Sets the visibility of the specified control.\n * please do not use.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * but since the control api allow for any control name, can be any string.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details\n */\n setControlVisible(controlKey: string, visible: boolean) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n this._controlsVisibility[controlKey] = visible;\n }\n\n /**\n * Sets the visibility state of object controls, this is just a bulk option for setControlVisible;\n * @param {Record} [options] with an optional key per control\n * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n */\n setControlsVisibility(options: Record = {}) {\n Object.entries(options).forEach(([controlKey, visibility]) =>\n this.setControlVisible(controlKey, visibility),\n );\n }\n\n /**\n * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box\n * that is in the canvas.contextContainer.\n * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object.\n * Example: blinking cursor text selection, drag effects.\n * @todo discuss swapping restoreManually with a renderCallback, but think of async issues\n * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else.\n * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed\n * with the object transformMatrix, or restored to neutral transform\n */\n clearContextTop(\n restoreManually?: boolean,\n ): CanvasRenderingContext2D | undefined {\n if (!this.canvas) {\n return;\n }\n const ctx = this.canvas.contextTop;\n if (!ctx) {\n return;\n }\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n // we add 4 pixel, to be sure to do not leave any pixel out\n const width = this.width + 4,\n height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n\n restoreManually || ctx.restore();\n return ctx;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {TPointerEvent} [options.e] event if the process is generated by an event\n * @param {FabricObject} [options.object] next object we are setting as active, and reason why\n * this is being deselected\n */\n onDeselect(_options?: {\n e?: TPointerEvent;\n object?: InteractiveFabricObject;\n }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {Event} [_options.e] event if the process is generated by an event\n */\n onSelect(_options?: { e?: TPointerEvent }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * Override to customize Drag behavior\n * Fired from {@link Canvas#_onMouseMove}\n * @returns true in order for the window to start a drag session\n */\n shouldStartDragging(_e: TPointerEvent) {\n return false;\n }\n\n /**\n * Override to customize Drag behavior\\\n * Fired once a drag session has started\n * @returns true to handle the drag event\n */\n onDragStart(_e: DragEvent) {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * @public\n * @param {DragEvent} _e\n * @returns {boolean} true if the object currently dragged can be dropped on the target\n */\n canDrop(_e: DragEvent): boolean {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the source of a drag event\n * example: render the selection status for the part of text that is being dragged from a text object\n * @public\n * @param {DragEvent} _e\n */\n renderDragSourceEffect(_e: DragEvent) {\n // for subclasses\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the target of a drag event\n * used to show that the underly object can receive a drop, or to show how the\n * object will change when dropping. example: show the cursor where the text is about to be dropped\n * @public\n * @param {DragEvent} _e\n */\n renderDropTargetEffect(_e: DragEvent) {\n // for subclasses\n }\n}\n","import type { Constructor } from '../typedefs';\n\n/***\n * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern\n */\nexport function applyMixins(\n derivedCtor: T,\n constructors: S[],\n) {\n constructors.forEach((baseCtor) => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\n name !== 'constructor' &&\n Object.defineProperty(\n derivedCtor.prototype,\n name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||\n Object.create(null),\n );\n });\n });\n return derivedCtor as T & { prototype: InstanceType };\n}\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport { FabricObjectSVGExportMixin } from './FabricObjectSVGExportMixin';\nimport { InteractiveFabricObject } from './InteractiveObject';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { classRegistry } from '../../ClassRegistry';\n\n// TODO somehow we have to make a tree-shakeable import\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FabricObject<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Props extends TFabricObjectProps = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObjectSVGExportMixin {}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class FabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends InteractiveFabricObject {}\n\napplyMixins(FabricObject, [FabricObjectSVGExportMixin]);\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n\nexport { cacheProperties } from './defaultValues';\n","/**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer\n * @return {boolean} true if transparent\n */\nexport const isTransparent = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n tolerance: number,\n): boolean => {\n tolerance = Math.round(tolerance);\n const size = tolerance * 2 + 1;\n const { data } = ctx.getImageData(x - tolerance, y - tolerance, size, size);\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (let i = 3; i < data.length; i += 4) {\n const alphaChannel = data[i];\n if (alphaChannel > 0) {\n return false;\n }\n }\n return true;\n};\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport { createVector } from '../vectors';\nimport type { TProjectStrokeOnPointsOptions, TProjection } from './types';\n\n/**\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n * @todo consider removing skewing from points before calculating stroke projection,\n * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537\n */\nexport abstract class StrokeProjectionsBase {\n declare options: TProjectStrokeOnPointsOptions;\n declare scale: Point;\n declare strokeUniformScalar: Point;\n declare strokeProjectionMagnitude: number;\n\n constructor(options: TProjectStrokeOnPointsOptions) {\n this.options = options;\n this.strokeProjectionMagnitude = this.options.strokeWidth / 2;\n this.scale = new Point(this.options.scaleX, this.options.scaleY);\n this.strokeUniformScalar = this.options.strokeUniform\n ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY)\n : new Point(1, 1);\n }\n\n /**\n * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account.\n */\n protected createSideVector(from: XY, to: XY) {\n const v = createVector(from, to);\n return this.options.strokeUniform ? v.multiply(this.scale) : v;\n }\n\n protected abstract calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude?: number,\n ): Point;\n\n protected projectOrthogonally(from: Point, to: Point, magnitude?: number) {\n return this.applySkew(\n from.add(this.calcOrthogonalProjection(from, to, magnitude)),\n );\n }\n\n protected isSkewed() {\n return this.options.skewX !== 0 || this.options.skewY !== 0;\n }\n\n protected applySkew(point: Point) {\n const p = new Point(point);\n // skewY must be applied before skewX as this distortion affects skewX calculation\n p.y += p.x * Math.tan(degreesToRadians(this.options.skewY));\n p.x += p.y * Math.tan(degreesToRadians(this.options.skewX));\n return p;\n }\n\n protected scaleUnitVector(unitVector: Point, scalar: number) {\n return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar);\n }\n\n protected abstract projectPoints(): Point[];\n\n public abstract project(): TProjection[];\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { halfPI, twoMathPi } from '../../../constants';\nimport type { TRadian } from '../../../typedefs';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport {\n calcAngleBetweenVectors,\n calcVectorRotation,\n crossProduct,\n getOrthonormalVector,\n getUnitVector,\n isBetweenVectors,\n magnitude,\n rotateVector,\n} from '../vectors';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nconst zeroVector = new Point();\n\n/**\n * class in charge of finding projections for each type of line join\n * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)}\n *\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin\n * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n *\n */\nexport class StrokeLineJoinProjections extends StrokeProjectionsBase {\n /**\n * The point being projected (the angle ∠BAC)\n */\n declare A: Point;\n /**\n * The point before A\n */\n declare B: Point;\n /**\n * The point after A\n */\n declare C: Point;\n /**\n * The AB vector\n */\n AB: Point;\n /**\n * The AC vector\n */\n AC: Point;\n /**\n * The angle of A (∠BAC)\n */\n alpha: TRadian;\n /**\n * The bisector of A (∠BAC)\n */\n bisector: Point;\n\n static getOrthogonalRotationFactor(vector1: Point, vector2?: Point) {\n const angle = vector2\n ? calcAngleBetweenVectors(vector1, vector2)\n : calcVectorRotation(vector1);\n return Math.abs(angle) < halfPI ? -1 : 1;\n }\n\n constructor(A: XY, B: XY, C: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.B = new Point(B);\n this.C = new Point(C);\n this.AB = this.createSideVector(this.A, this.B);\n this.AC = this.createSideVector(this.A, this.C);\n this.alpha = calcAngleBetweenVectors(this.AB, this.AC);\n this.bisector = getUnitVector(\n // if AC is also the zero vector nothing will be projected\n // in that case the next point will handle the projection\n rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2),\n );\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n const orthogonalProjection = getOrthonormalVector(vector);\n const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(\n orthogonalProjection,\n this.bisector,\n );\n return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide);\n }\n\n /**\n * BEVEL\n * Calculation: the projection points are formed by the vector orthogonal to the vertex.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel\n */\n projectBevel() {\n const projections: Point[] = [];\n // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C`\n (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(\n (to) => {\n projections.push(this.projectOrthogonally(this.A, to));\n projections.push(\n this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude),\n );\n },\n );\n return projections;\n }\n\n /**\n * MITER\n * Calculation: the corner is formed by extending the outer edges of the stroke\n * at the tangents of the path segments until they intersect.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter\n */\n projectMiter() {\n const projections: Point[] = [],\n alpha = Math.abs(this.alpha),\n hypotUnitScalar = 1 / Math.sin(alpha / 2),\n miterVector = this.scaleUnitVector(\n this.bisector,\n -this.strokeProjectionMagnitude * hypotUnitScalar,\n );\n\n // When two line segments meet at a sharp angle, it is possible for the join to extend,\n // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes\n // a limit on the extent of the line join.\n // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit\n // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit\n const strokeMiterLimit = this.options.strokeUniform\n ? magnitude(\n this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit),\n )\n : this.options.strokeMiterLimit;\n\n if (\n magnitude(miterVector) / this.strokeProjectionMagnitude <=\n strokeMiterLimit\n ) {\n projections.push(this.applySkew(this.A.add(miterVector)));\n }\n /* when the miter-limit is reached, the stroke line join becomes of type bevel.\n We always need two orthogonal projections which are basically bevel-type projections,\n so regardless of whether the miter-limit was reached or not, we include these projections.\n */\n projections.push(...this.projectBevel());\n\n return projections;\n }\n\n /**\n * ROUND (without skew)\n * Calculation: the projections are the two vectors parallel to X and Y axes\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew\n */\n private projectRoundNoSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [],\n // correctSide is used to only consider projecting for the outer side\n correctSide = new Point(\n StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector),\n StrokeLineJoinProjections.getOrthogonalRotationFactor(\n new Point(this.bisector.y, this.bisector.x),\n ),\n ),\n radiusOnAxisX = new Point(1, 0)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide),\n radiusOnAxisY = new Point(0, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide);\n\n [radiusOnAxisX, radiusOnAxisY].forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.A.add(vector));\n }\n });\n return projections;\n }\n\n /**\n * ROUND (with skew)\n * Calculation: the projections are the points furthest from the vertex in\n * the direction of the X and Y axes after distortion.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew\n */\n private projectRoundWithSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [];\n\n const { skewX, skewY, scaleX, scaleY, strokeUniform } = this.options,\n shearing = new Point(\n Math.tan(degreesToRadians(skewX)),\n Math.tan(degreesToRadians(skewY)),\n );\n // The points furthest from the vertex in the direction of the X and Y axes after distortion\n const circleRadius = this.strokeProjectionMagnitude,\n newY = strokeUniform\n ? circleRadius /\n scaleY /\n Math.sqrt(1 / scaleY ** 2 + (1 / scaleX ** 2) * shearing.y ** 2)\n : circleRadius / Math.sqrt(1 + shearing.y ** 2),\n furthestY = new Point(\n // Safe guard due to floating point precision. In some situations the square root\n // was returning NaN because of a negative number close to zero.\n Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)),\n newY,\n ),\n newX = strokeUniform\n ? circleRadius /\n Math.sqrt(\n 1 +\n (shearing.x ** 2 * (1 / scaleY) ** 2) /\n (1 / scaleX + (1 / scaleX) * shearing.x * shearing.y) ** 2,\n )\n : circleRadius /\n Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2),\n furthestX = new Point(\n newX,\n Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0)),\n );\n\n [\n furthestX,\n furthestX.scalarMultiply(-1),\n furthestY,\n furthestY.scalarMultiply(-1),\n ]\n // We need to skew the vector here as this information is used to check if\n // it is between the start and end of the circle segment\n .map((vector) =>\n this.applySkew(\n strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector,\n ),\n )\n .forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.applySkew(this.A).add(vector));\n }\n });\n\n return projections;\n }\n\n projectRound() {\n const projections: Point[] = [];\n /* Include the start and end points of the circle segment, so that only\n the projections contained within it are included */\n // add the orthogonal projections (start and end points of circle segment)\n projections.push(...this.projectBevel());\n // let's determines which one of the orthogonal projection is the beginning and end of the circle segment.\n // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different.\n const isStraightLine = this.alpha % twoMathPi === 0,\n // change the origin of the projections to point A\n // so that the cross product calculation is correct\n newOrigin = this.applySkew(this.A),\n proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin),\n proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin),\n // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector.\n comparisonVector = isStraightLine\n ? this.applySkew(this.AB.scalarMultiply(-1))\n : this.applySkew(\n this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1),\n ),\n // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0)\n isProj0Start = crossProduct(proj0, comparisonVector) > 0,\n startCircle = isProj0Start ? proj0 : proj1,\n endCircle = isProj0Start ? proj1 : proj0;\n if (!this.isSkewed()) {\n projections.push(...this.projectRoundNoSkew(startCircle, endCircle));\n } else {\n projections.push(...this.projectRoundWithSkew(startCircle, endCircle));\n }\n return projections;\n }\n\n /**\n * Project stroke width on points returning projections for each point as follows:\n * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel)\n * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke.\n * - `round`: same as `bevel` when it has no skew, with skew are 4 points.\n */\n protected projectPoints() {\n switch (this.options.strokeLineJoin) {\n case 'miter':\n return this.projectMiter();\n case 'round':\n return this.projectRound();\n default:\n return this.projectBevel();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n angle: this.alpha,\n bisector: this.bisector,\n }));\n }\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { getOrthonormalVector, getUnitVector } from '../vectors';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\n/**\n * class in charge of finding projections for each type of line cap for start/end of an open path\n * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)}\n *\n * Reference:\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap\n * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n */\nexport class StrokeLineCapProjections extends StrokeProjectionsBase {\n /**\n * edge point\n */\n declare A: Point;\n /**\n * point next to edge point\n */\n declare T: Point;\n\n constructor(A: XY, T: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.T = new Point(T);\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n return this.scaleUnitVector(getOrthonormalVector(vector), magnitude);\n }\n\n /**\n * OPEN PATH START/END - Line cap: Butt\n * Calculation: to find the projections, just find the points orthogonal to the stroke\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt\n */\n projectButt() {\n return [\n this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude),\n this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude),\n ];\n }\n\n /**\n * OPEN PATH START/END - Line cap: Round\n * Calculation: same as stroke line join `round`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round\n */\n projectRound() {\n const projections: Point[] = [];\n\n if (!this.isSkewed() && this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(\n this.applySkew(this.A.add(projection)),\n this.applySkew(this.A.subtract(projection)),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(\n this.A,\n this.T,\n this.T,\n this.options,\n ).projectRound(),\n );\n }\n\n return projections;\n }\n\n /**\n * OPEN PATH START/END - Line cap: Square\n * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square\n */\n projectSquare() {\n const projections: Point[] = [];\n\n if (this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(this.A.add(projection), this.A.subtract(projection));\n } else {\n const orthogonalProjection = this.calcOrthogonalProjection(\n this.A,\n this.T,\n this.strokeProjectionMagnitude,\n );\n const strokePointingOut = this.scaleUnitVector(\n getUnitVector(this.createSideVector(this.A, this.T)),\n -this.strokeProjectionMagnitude,\n );\n const projectedA = this.A.add(strokePointingOut);\n projections.push(\n projectedA.add(orthogonalProjection),\n projectedA.subtract(orthogonalProjection),\n );\n }\n\n return projections.map((p) => this.applySkew(p));\n }\n\n protected projectPoints() {\n switch (this.options.strokeLineCap) {\n case 'round':\n return this.projectRound();\n case 'square':\n return this.projectSquare();\n default:\n return this.projectButt();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n }));\n }\n}\n","import { Point, type XY } from '../../../Point';\nimport { findIndexRight } from '../../internals/findRight';\nimport { StrokeLineCapProjections } from './StrokeLineCapProjections';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nexport * from './types';\n\n/**\n *\n * Used to calculate object's bounding box\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n *\n */\nexport const projectStrokeOnPoints = (\n points: XY[],\n options: TProjectStrokeOnPointsOptions,\n openPath = false,\n): TProjection[] => {\n const projections: TProjection[] = [];\n\n if (points.length === 0) {\n return projections;\n }\n\n // first we remove duplicate neighboring points\n const reduced = points.reduce(\n (reduced, point) => {\n if (!reduced[reduced.length - 1].eq(point)) {\n reduced.push(new Point(point));\n }\n return reduced;\n },\n [new Point(points[0])],\n );\n\n if (reduced.length === 1) {\n openPath = true;\n } else if (!openPath) {\n // remove points from end in case they equal the first point\n // in order to correctly project the first point\n const start = reduced[0];\n const index = findIndexRight(reduced, (point) => !point.eq(start));\n reduced.splice(index + 1);\n }\n\n reduced.forEach((A, index, points) => {\n let B: XY, C: XY;\n if (index === 0) {\n C = points[1];\n B = openPath ? A : points[points.length - 1];\n } else if (index === points.length - 1) {\n B = points[index - 1];\n C = openPath ? A : points[0];\n } else {\n B = points[index - 1];\n C = points[index + 1];\n }\n\n if (openPath && points.length === 1) {\n projections.push(\n ...new StrokeLineCapProjections(A, A, options).project(),\n );\n } else if (openPath && (index === 0 || index === points.length - 1)) {\n projections.push(\n ...new StrokeLineCapProjections(\n A,\n index === 0 ? C : B,\n options,\n ).project(),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(A, B, C, options).project(),\n );\n }\n });\n\n return projections;\n};\n","export const findIndexRight = (\n array: T[],\n predicate: (value: T, index: number, array: T[]) => boolean,\n) => {\n for (let index = array.length - 1; index >= 0; index--) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n","import type { TextStyle } from '../../shapes/Text/StyledText';\n\nexport const cloneStyles = (style: TextStyle): TextStyle => {\n const newObj: TextStyle = {};\n Object.keys(style).forEach((key) => {\n newObj[key] = {};\n Object.keys(style[key]).forEach((keyInner) => {\n newObj[key][keyInner] = { ...style[key][keyInner] };\n });\n });\n return newObj;\n};\n","/**\n * Capitalizes a string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\nexport const capitalize = (string: string, firstLetterOnly = false): string =>\n `${string.charAt(0).toUpperCase()}${\n firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()\n }`;\n\n/**\n * Escapes XML in a string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\nexport const escapeXml = (string: string): string =>\n string\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n\n/**\n * Divide a string in the user perceived single units\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\nexport const graphemeSplit = (textstring: string): string[] => {\n const graphemes = [];\n for (let i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr as string);\n }\n return graphemes;\n};\n\n// taken from mdn in the charAt doc page.\nconst getWholeChar = (str: string, i: number): string | boolean => {\n const code = str.charCodeAt(i);\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xd800 || code > 0xdfff) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 <= code && code <= 0xdbff) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n const next = str.charCodeAt(i + 1);\n if (0xdc00 > next || next > 0xdfff) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n const prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 > prev || prev > 0xdbff) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n};\n","import { reNewline } from '../../constants';\nimport type {\n TextStyle,\n TextStyleDeclaration,\n} from '../../shapes/Text/StyledText';\nimport { cloneStyles } from '../internals/cloneStyles';\nimport { graphemeSplit } from '../lang_string';\n\nexport type TextStyleArray = {\n start: number;\n end: number;\n style: TextStyleDeclaration;\n}[];\n\n/**\n * @param {Object} prevStyle first style to compare\n * @param {Object} thisStyle second style to compare\n * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties\n * @return {boolean} true if the style changed\n */\nexport const hasStyleChanged = (\n prevStyle: TextStyleDeclaration,\n thisStyle: TextStyleDeclaration,\n forTextSpans = false,\n) =>\n prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.deltaY !== thisStyle.deltaY ||\n (forTextSpans &&\n (prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough));\n\n/**\n * Returns the array form of a text object's inline styles property with styles grouped in ranges\n * rather than per character. This format is less verbose, and is better suited for storage\n * so it is used in serialization (not during runtime).\n * @param {object} styles per character styles for a text object\n * @param {String} text the text string that the styles are applied to\n * @return {{start: number, end: number, style: object}[]}\n */\nexport const stylesToArray = (\n styles: TextStyle,\n text: string,\n): TextStyleArray => {\n const textLines = text.split('\\n'),\n stylesArray = [];\n let charIndex = -1,\n prevStyle = {};\n // clone style structure to prevent mutation\n styles = cloneStyles(styles);\n\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n if (!styles[i]) {\n //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle\n charIndex += chars.length;\n prevStyle = {};\n continue;\n }\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n const thisStyle = styles[i][c];\n //check if style exists for this character\n if (thisStyle && Object.keys(thisStyle).length > 0) {\n if (hasStyleChanged(prevStyle, thisStyle, true)) {\n stylesArray.push({\n start: charIndex,\n end: charIndex + 1,\n style: thisStyle,\n });\n } else {\n //if style is the same as previous character, increase end index\n stylesArray[stylesArray.length - 1].end++;\n }\n }\n prevStyle = thisStyle || {};\n }\n }\n return stylesArray;\n};\n\n/**\n * Returns the object form of the styles property with styles that are assigned per\n * character rather than grouped by range. This format is more verbose, and is\n * only used during runtime (not for serialization/storage)\n * @param {Array} styles the serialized form of a text object's styles\n * @param {String} text the text string that the styles are applied to\n * @return {Object}\n */\nexport const stylesFromArray = (\n styles: TextStyleArray | TextStyle,\n text: string,\n): TextStyle => {\n if (!Array.isArray(styles)) {\n // clone to prevent mutation\n return cloneStyles(styles);\n }\n const textLines = text.split(reNewline),\n stylesObject: TextStyle = {};\n let charIndex = -1,\n styleIndex = 0;\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n //check if there's a style collection that includes the current character\n if (\n styles[styleIndex] &&\n styles[styleIndex].start <= charIndex &&\n charIndex < styles[styleIndex].end\n ) {\n //create object for line index if it doesn't exist\n stylesObject[i] = stylesObject[i] || {};\n //assign a style at this character's index\n stylesObject[i][c] = { ...styles[styleIndex].style };\n //if character is at the end of the current style collection, move to the next\n if (charIndex === styles[styleIndex].end - 1) {\n styleIndex++;\n }\n }\n }\n }\n return stylesObject;\n};\n","import { FILL, STROKE } from '../constants';\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nexport const SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n FILL,\n 'fill-opacity',\n 'fill-rule',\n 'opacity',\n STROKE,\n 'stroke-dasharray',\n 'stroke-linecap',\n 'stroke-dashoffset',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke-width',\n 'id',\n 'paint-order',\n 'vector-effect',\n 'instantiated_by_use',\n 'clip-path',\n];\n","export function selectorMatches(element: HTMLElement, selector: string) {\n const nodeName = element.nodeName;\n const classNames = element.getAttribute('class');\n const id = element.getAttribute('id');\n const azAz = '(?![a-zA-Z\\\\-]+)';\n let matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n const splitClassNames = classNames.split(' ');\n for (let i = splitClassNames.length; i--; ) {\n matcher = new RegExp('\\\\.' + splitClassNames[i] + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\nimport { doesSomeParentMatch } from './doesSomeParentMatch';\n\n/**\n * @private\n */\n\nexport function elementMatchesRule(element: HTMLElement, selectors: string[]) {\n let parentMatching = true;\n // start from rightmost selector.\n const firstMatching = selectorMatches(element, selectors.pop()!);\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && selectors.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\n\nexport function doesSomeParentMatch(element: HTMLElement, selectors: string[]) {\n let selector: string,\n parentMatching = true;\n while (\n element.parentElement &&\n element.parentElement.nodeType === 1 &&\n selectors.length\n ) {\n if (parentMatching) {\n selector = selectors.pop()!;\n }\n element = element.parentElement;\n parentMatching = selectorMatches(element, selector!);\n }\n return selectors.length === 0;\n}\n","import { attributesMap } from './constants';\n\nexport const normalizeAttr = (\n attr: keyof typeof attributesMap | string,\n): string => attributesMap[attr as keyof typeof attributesMap] ?? attr;\n","import { reNum } from '../../parser/constants';\n\nconst regex = new RegExp(`(${reNum})`, 'gi');\n\nexport const cleanupSvgAttribute = (attributeValue: string) =>\n attributeValue\n .replace(regex, ' $1 ')\n // replace annoying commas and arbitrary whitespace with single spaces\n .replace(/,/gi, ' ')\n .replace(/\\s+/gi, ' ');\n","import { ROTATE, SCALE, SKEW_X, SKEW_Y, iMatrix } from '../constants';\nimport { reNum } from './constants';\nimport type { TMat2D } from '../typedefs';\nimport { cleanupSvgAttribute } from '../util/internals/cleanupSvgAttribute';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createSkewXMatrix,\n createSkewYMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\n\n// == begin transform regexp\nconst p = `(${reNum})`;\nconst skewX = String.raw`(skewX)\\(${p}\\)`;\nconst skewY = String.raw`(skewY)\\(${p}\\)`;\nconst rotate = String.raw`(rotate)\\(${p}(?: ${p} ${p})?\\)`;\nconst scale = String.raw`(scale)\\(${p}(?: ${p})?\\)`;\nconst translate = String.raw`(translate)\\(${p}(?: ${p})?\\)`;\nconst matrix = String.raw`(matrix)\\(${p} ${p} ${p} ${p} ${p} ${p}\\)`;\nconst transform = `(?:${matrix}|${translate}|${rotate}|${scale}|${skewX}|${skewY})`;\nconst transforms = `(?:${transform}*)`;\nconst transformList = String.raw`^\\s*(?:${transforms}?)\\s*$`;\n// http://www.w3.org/TR/SVG/coords.html#TransformAttribute\nconst reTransformList = new RegExp(transformList);\nconst reTransform = new RegExp(transform);\nconst reTransformAll = new RegExp(transform, 'g');\n// == end transform regexp\n\n/**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {TTransformMatrix} Array of 6 elements representing transformation matrix\n */\nexport function parseTransformAttribute(attributeValue: string): TMat2D {\n // first we clean the string\n attributeValue = cleanupSvgAttribute(attributeValue)\n // remove spaces around front parentheses\n .replace(/\\s*([()])\\s*/gi, '$1');\n\n // start with identity matrix\n const matrices: TMat2D[] = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (\n !attributeValue ||\n (attributeValue && !reTransformList.test(attributeValue))\n ) {\n return [...iMatrix];\n }\n\n for (const match of attributeValue.matchAll(reTransformAll)) {\n const transformMatch = reTransform.exec(match[0]);\n if (!transformMatch) {\n continue;\n }\n let matrix: TMat2D = iMatrix;\n const matchedParams = transformMatch.filter((m) => !!m);\n const [, operation, ...rawArgs] = matchedParams;\n const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map((arg) =>\n parseFloat(arg),\n );\n\n switch (operation) {\n case 'translate':\n matrix = createTranslateMatrix(arg0, arg1);\n break;\n case ROTATE:\n matrix = createRotateMatrix({ angle: arg0 }, { x: arg1, y: arg2 });\n break;\n case SCALE:\n matrix = createScaleMatrix(arg0, arg1);\n break;\n case SKEW_X:\n matrix = createSkewXMatrix(arg0);\n break;\n case SKEW_Y:\n matrix = createSkewYMatrix(arg0);\n break;\n case 'matrix':\n matrix = [arg0, arg1, arg2, arg3, arg4, arg5];\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix);\n }\n\n return multiplyTransformMatrixArray(matrices);\n}\n","import { multiplyTransformMatrices } from '../util/misc/matrix';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { parseTransformAttribute } from './parseTransformAttribute';\nimport { CENTER, LEFT, RIGHT, NONE, FILL, STROKE } from '../constants';\n\nexport function normalizeValue(\n attr: string,\n value: any,\n parentAttributes: Record,\n fontSize: number,\n): string | null | boolean | number[] | number {\n const isArray = Array.isArray(value);\n let parsed: number | number[];\n let ouputValue: string | null | boolean | number[] | number = value;\n if ((attr === FILL || attr === STROKE) && value === NONE) {\n ouputValue = '';\n } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === NONE) {\n ouputValue = null;\n } else {\n ouputValue = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n ouputValue = multiplyTransformMatrices(\n parentAttributes.transformMatrix,\n parseTransformAttribute(value),\n );\n } else {\n ouputValue = parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n ouputValue = value !== NONE && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n ouputValue = false;\n }\n } else if (attr === 'opacity') {\n ouputValue = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n ouputValue *= parentAttributes.opacity as number;\n }\n } else if (attr === 'textAnchor' /* text-anchor */) {\n ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER;\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = (parseUnit(value, fontSize) / fontSize) * 1000;\n } else if (attr === 'paintFirst') {\n const fillIndex = value.indexOf(FILL);\n const strokeIndex = value.indexOf(STROKE);\n ouputValue = FILL;\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n ouputValue = STROKE;\n } else if (fillIndex === -1 && strokeIndex > -1) {\n ouputValue = STROKE;\n }\n } else if (\n attr === 'href' ||\n attr === 'xlink:href' ||\n attr === 'font' ||\n attr === 'id'\n ) {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality';\n } else {\n parsed = isArray\n ? (value as string[]).map(parseUnit)\n : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed! as number) ? ouputValue : parsed!;\n}\n","import { parseUnit } from '../util/misc/svgParsing';\nimport { reFontDeclaration } from './constants';\n\n/**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\nexport function parseFontDeclaration(\n value: string,\n oStyle: Record,\n): void {\n const match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n const fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight))\n ? fontWeight\n : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n}\n","/**\n * Takes a style string and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleString(\n style: string,\n oStyle: Record,\n): void {\n style\n .replace(/;\\s*$/, '')\n .split(';')\n .forEach((chunk) => {\n if (!chunk) return;\n const [attr, value] = chunk.split(':');\n oStyle[attr.trim().toLowerCase()] = value.trim();\n });\n}\n","import { parseStyleObject } from './parseStyleObject';\nimport { parseStyleString } from './parseStyleString';\n\n/**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\nexport function parseStyleAttribute(element: HTMLElement): Record {\n const oStyle: Record = {},\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n } else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n}\n","/**\n * Takes a style object and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleObject(\n style: Record,\n oStyle: Record,\n): void {\n Object.entries(style).forEach(([prop, value]) => {\n if (value === undefined) {\n return;\n }\n oStyle[prop.toLowerCase()] = value;\n });\n}\n","import { Color } from '../color/Color';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject } from '../shapes/Object/FabricObject';\n\nconst colorAttributesMap = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity',\n};\n\n/**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\nexport function setStrokeFillOpacity(\n attributes: Record,\n): Record {\n const defaults = FabricObject.getDefaults();\n Object.entries(colorAttributesMap).forEach(([attr, colorAttr]) => {\n if (\n typeof attributes[colorAttr] === 'undefined' ||\n attributes[attr] === ''\n ) {\n return;\n }\n if (typeof attributes[attr] === 'undefined') {\n if (!defaults[attr]) {\n return;\n }\n attributes[attr] = defaults[attr];\n }\n if (attributes[attr].indexOf('url(') === 0) {\n return;\n }\n const color = new Color(attributes[attr]);\n attributes[attr] = color\n .setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2))\n .toRgba();\n });\n return attributes;\n}\n","import { DEFAULT_SVG_FONT_SIZE } from '../constants';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { cPath, fSize, svgValidParentsRegEx } from './constants';\nimport { getGlobalStylesForElement } from './getGlobalStylesForElement';\nimport { normalizeAttr } from './normalizeAttr';\nimport { normalizeValue } from './normalizeValue';\nimport { parseFontDeclaration } from './parseFontDeclaration';\nimport { parseStyleAttribute } from './parseStyleAttribute';\nimport { setStrokeFillOpacity } from './setStrokeFillOpacity';\nimport type { CSSRules } from './typedefs';\n\n/**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @param {SVGElement | HTMLElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\nexport function parseAttributes(\n element: HTMLElement | null,\n attributes: string[],\n cssRules?: CSSRules,\n): Record {\n if (!element) {\n return {};\n }\n\n let parentAttributes: Record = {},\n fontSize: number,\n parentFontSize = DEFAULT_SVG_FONT_SIZE;\n\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (\n element.parentNode &&\n svgValidParentsRegEx.test(element.parentNode.nodeName)\n ) {\n parentAttributes = parseAttributes(\n element.parentElement,\n attributes,\n cssRules,\n );\n if (parentAttributes.fontSize) {\n fontSize = parentFontSize = parseUnit(parentAttributes.fontSize);\n }\n }\n\n const ownAttributes: Record = {\n ...attributes.reduce>((memo, attr) => {\n const value = element.getAttribute(attr);\n if (value) {\n memo[attr] = value;\n }\n return memo;\n }, {}),\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ...getGlobalStylesForElement(element, cssRules),\n ...parseStyleAttribute(element),\n };\n\n if (ownAttributes[cPath]) {\n element.setAttribute(cPath, ownAttributes[cPath]);\n }\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n ownAttributes[fSize] = `${fontSize}`;\n }\n\n // this should have its own complex type\n const normalizedStyle: Record<\n string,\n string | boolean | number | number[] | null\n > = {};\n for (const attr in ownAttributes) {\n const normalizedAttr = normalizeAttr(attr);\n const normalizedValue = normalizeValue(\n normalizedAttr,\n ownAttributes[attr],\n parentAttributes,\n fontSize!,\n );\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n parseFontDeclaration(normalizedStyle.font as string, normalizedStyle);\n }\n const mergedAttrs = { ...parentAttributes, ...normalizedStyle };\n return svgValidParentsRegEx.test(element.nodeName)\n ? mergedAttrs\n : setStrokeFillOpacity(mergedAttrs);\n}\n","import { elementMatchesRule } from './elementMatchesRule';\nimport type { CSSRules } from './typedefs';\n\n/**\n * @private\n */\n\nexport function getGlobalStylesForElement(\n element: HTMLElement,\n cssRules: CSSRules = {},\n) {\n let styles: Record = {};\n for (const rule in cssRules) {\n if (elementMatchesRule(element, rule.split(' '))) {\n styles = {\n ...styles,\n ...cssRules[rule],\n };\n }\n }\n return styles;\n}\n","import { kRect } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const rectDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueRectProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedRectProps\n extends SerializedObjectProps,\n UniqueRectProps {}\n\nexport interface RectProps extends FabricObjectProps, UniqueRectProps {}\n\nconst RECT_PROPS = ['rx', 'ry'] as const;\n\nexport class Rect<\n Props extends TOptions = Partial,\n SProps extends SerializedRectProps = SerializedRectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements RectProps\n{\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Rect';\n\n static cacheProperties = [...cacheProperties, ...RECT_PROPS];\n\n static ownDefaults = rectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Rect.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Rect.ownDefaults);\n this.setOptions(options);\n this._initRxRy();\n }\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy() {\n const { rx, ry } = this;\n if (rx && !ry) {\n this.ry = rx;\n } else if (ry && !rx) {\n this.rx = ry;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const { width: w, height: h } = this;\n const x = -w / 2;\n const y = -h / 2;\n const rx = this.rx ? Math.min(this.rx, w / 2) : 0;\n const ry = this.ry ? Math.min(this.ry, h / 2) : 0;\n const isRounded = rx !== 0 || ry !== 0;\n\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded &&\n ctx.bezierCurveTo(\n x + w - kRect * rx,\n y,\n x + w,\n y + kRect * ry,\n x + w,\n y + ry,\n );\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded &&\n ctx.bezierCurveTo(\n x + w,\n y + h - kRect * ry,\n x + w - kRect * rx,\n y + h,\n x + w - rx,\n y + h,\n );\n\n ctx.lineTo(x + rx, y + h);\n isRounded &&\n ctx.bezierCurveTo(\n x + kRect * rx,\n y + h,\n x,\n y + h - kRect * ry,\n x,\n y + h - ry,\n );\n\n ctx.lineTo(x, y + ry);\n isRounded &&\n ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...RECT_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { width, height, rx, ry } = this;\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`)\n * @static\n * @memberOf Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'rx',\n 'ry',\n 'width',\n 'height',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns {@link Rect} instance from an SVG element\n * @static\n * @memberOf Rect\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n left = 0,\n top = 0,\n width = 0,\n height = 0,\n visible = true,\n ...restOfparsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n\n return new this({\n ...options,\n ...restOfparsedAttributes,\n left,\n top,\n width,\n height,\n visible: Boolean(visible && width && height),\n });\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Rect);\nclassRegistry.setSVGClass(Rect);\n","export const LAYOUT_TYPE_INITIALIZATION = 'initialization';\nexport const LAYOUT_TYPE_ADDED = 'added';\nexport const LAYOUT_TYPE_REMOVED = 'removed';\nexport const LAYOUT_TYPE_IMPERATIVE = 'imperative';\nexport const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified';\nexport const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying';\n","import { Point, ZERO } from '../../Point';\nimport type { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { multiplyTransformMatrixArray } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport {\n calcPlaneChangeMatrix,\n sendVectorToPlane,\n} from '../../util/misc/planeChange';\n\n/**\n * @returns 2 points, the tl and br corners of the non rotated bounding box of an object\n * in the {@link group} plane, taking into account objects that {@link group} is their parent\n * but also belong to the active selection.\n */\nexport const getObjectBounds = (\n destinationGroup: Group,\n object: FabricObject,\n): Point[] => {\n const {\n strokeUniform,\n strokeWidth,\n width,\n height,\n group: currentGroup,\n } = object;\n const t =\n currentGroup && currentGroup !== destinationGroup\n ? calcPlaneChangeMatrix(\n currentGroup.calcTransformMatrix(),\n destinationGroup.calcTransformMatrix(),\n )\n : null;\n const objectCenter = t\n ? object.getRelativeCenterPoint().transform(t)\n : object.getRelativeCenterPoint();\n const accountForStroke = !object['isStrokeAccountedForInDimensions']();\n const strokeUniformVector =\n strokeUniform && accountForStroke\n ? sendVectorToPlane(\n new Point(strokeWidth, strokeWidth),\n undefined,\n destinationGroup.calcTransformMatrix(),\n )\n : ZERO;\n const scalingStrokeWidth =\n !strokeUniform && accountForStroke ? strokeWidth : 0;\n const sizeVector = sizeAfterTransform(\n width + scalingStrokeWidth,\n height + scalingStrokeWidth,\n multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true),\n )\n .add(strokeUniformVector)\n .scalarDivide(2);\n return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)];\n};\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_IMPERATIVE,\n} from '../constants';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { getObjectBounds } from './utils';\n\n/**\n * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout.\n * Returning `undefined` signals the `LayoutManager` to skip the layout.\n *\n * In charge of calculating the bounding box of the passed objects.\n */\nexport abstract class LayoutStrategy {\n /**\n * override by subclass for persistence (TS does not support `static abstract`)\n */\n static type = 'strategy';\n\n /**\n * Used by the `LayoutManager` to perform layout\n * @TODO/fix: if this method is calcResult, should calc unconditionally.\n * the condition to not calc should be evaluated by the layoutManager.\n * @returns layout result **OR** `undefined` to skip layout\n */\n public calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n if (this.shouldPerformLayout(context)) {\n return this.calcBoundingBox(objects, context);\n }\n }\n\n shouldPerformLayout({ type, prevStrategy, strategy }: StrictLayoutContext) {\n return (\n type === LAYOUT_TYPE_INITIALIZATION ||\n type === LAYOUT_TYPE_IMPERATIVE ||\n (!!prevStrategy && strategy !== prevStrategy)\n );\n }\n\n shouldLayoutClipPath({ type, target: { clipPath } }: StrictLayoutContext) {\n return (\n type !== LAYOUT_TYPE_INITIALIZATION &&\n clipPath &&\n !clipPath.absolutePositioned\n );\n }\n\n getInitialSize(\n context: StrictLayoutContext & InitializationLayoutContext,\n result: Pick,\n ) {\n return result.size;\n }\n\n /**\n * Override this method to customize layout.\n */\n calcBoundingBox(\n objects: FabricObject[],\n context: StrictLayoutContext,\n ): LayoutStrategyResult | undefined {\n const { type, target } = context;\n if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) {\n return context.overrides;\n }\n if (objects.length === 0) {\n return;\n }\n const { left, top, width, height } = makeBoundingBoxFromPoints(\n objects\n .map((object) => getObjectBounds(target, object))\n .reduce((coords, curr) => coords.concat(curr), []),\n );\n const bboxSize = new Point(width, height);\n const bboxLeftTop = new Point(left, top);\n const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2));\n\n if (type === LAYOUT_TYPE_INITIALIZATION) {\n const actualSize = this.getInitialSize(context, {\n size: bboxSize,\n center: bboxCenter,\n });\n return {\n // in `initialization` we do not account for target's transformation matrix\n center: bboxCenter,\n // TODO: investigate if this is still necessary\n relativeCorrection: new Point(0, 0),\n size: actualSize,\n };\n } else {\n // we send `relativeCenter` up to group's containing plane\n const center = bboxCenter.transform(target.calcOwnMatrix());\n return {\n center,\n size: bboxSize,\n };\n }\n }\n}\n","import type { StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to fit target's objects.\n */\nexport class FitContentLayout extends LayoutStrategy {\n static readonly type = 'fit-content';\n\n /**\n * @override layout on all triggers\n * Override at will\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldPerformLayout(context: StrictLayoutContext) {\n return true;\n }\n}\n\nclassRegistry.setClass(FitContentLayout);\n","import { Point } from '../Point';\nimport {\n CENTER,\n CHANGED,\n MODIFIED,\n MODIFY_PATH,\n MODIFY_POLY,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n iMatrix,\n} from '../constants';\nimport type { Group } from '../shapes/Group';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { invertTransform } from '../util/misc/matrix';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { FitContentLayout } from './LayoutStrategies/FitContentLayout';\nimport type { LayoutStrategy } from './LayoutStrategies/LayoutStrategy';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_OBJECT_MODIFIED,\n LAYOUT_TYPE_OBJECT_MODIFYING,\n} from './constants';\nimport type {\n LayoutContext,\n LayoutResult,\n RegistrationContext,\n StrictLayoutContext,\n} from './types';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TModificationEvents } from '../EventTypeDefs';\n\nconst LAYOUT_MANAGER = 'layoutManager';\n\nexport type SerializedLayoutManager = {\n type: string;\n strategy: string;\n};\n\nexport class LayoutManager {\n private declare _prevLayoutStrategy?: LayoutStrategy;\n protected declare _subscriptions: Map;\n\n strategy: LayoutStrategy;\n\n constructor(strategy: LayoutStrategy = new FitContentLayout()) {\n this.strategy = strategy;\n this._subscriptions = new Map();\n }\n\n public performLayout(context: LayoutContext) {\n const strictContext: StrictLayoutContext = {\n bubbles: true,\n strategy: this.strategy,\n ...context,\n prevStrategy: this._prevLayoutStrategy,\n stopPropagation() {\n this.bubbles = false;\n },\n };\n\n this.onBeforeLayout(strictContext);\n\n const layoutResult = this.getLayoutResult(strictContext);\n if (layoutResult) {\n this.commitLayout(strictContext, layoutResult);\n }\n\n this.onAfterLayout(strictContext, layoutResult);\n this._prevLayoutStrategy = strictContext.strategy;\n }\n\n /**\n * Attach handlers for events that we know will invalidate the layout when\n * performed on child objects ( general transforms ).\n * Returns the disposers for later unsubscribing and cleanup\n * @param {FabricObject} object\n * @param {RegistrationContext & Partial} context\n * @returns {VoidFunction[]} disposers remove the handlers\n */\n protected attachHandlers(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ): VoidFunction[] {\n const { target } = context;\n return (\n [\n MODIFIED,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n CHANGED,\n MODIFY_POLY,\n MODIFY_PATH,\n ] as (TModificationEvents & 'modified')[]\n ).map((key) =>\n object.on(key, (e) =>\n this.performLayout(\n key === MODIFIED\n ? {\n type: LAYOUT_TYPE_OBJECT_MODIFIED,\n trigger: key,\n e,\n target,\n }\n : {\n type: LAYOUT_TYPE_OBJECT_MODIFYING,\n trigger: key,\n e,\n target,\n },\n ),\n ),\n );\n }\n\n /**\n * Subscribe an object to transform events that will trigger a layout change on the parent\n * This is important only for interactive groups.\n * @param object\n * @param context\n */\n protected subscribe(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ) {\n this.unsubscribe(object, context);\n const disposers = this.attachHandlers(object, context);\n this._subscriptions.set(object, disposers);\n }\n\n /**\n * unsubscribe object layout triggers\n */\n protected unsubscribe(\n object: FabricObject,\n _context?: RegistrationContext & Partial,\n ) {\n (this._subscriptions.get(object) || []).forEach((d) => d());\n this._subscriptions.delete(object);\n }\n\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.unsubscribe(object, context));\n }\n\n subscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.subscribe(object, context));\n }\n\n protected onBeforeLayout(context: StrictLayoutContext) {\n const { target, type } = context;\n const { canvas } = target;\n // handle layout triggers subscription\n // @TODO: gate the registration when the group is interactive\n if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) {\n this.subscribeTargets(context);\n } else if (type === LAYOUT_TYPE_REMOVED) {\n this.unsubscribeTargets(context);\n }\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:before', {\n context,\n });\n canvas &&\n canvas.fire('object:layout:before', {\n target,\n context,\n });\n\n if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) {\n const { strategy: _, ...tricklingContext } = context;\n // traverse the tree\n target.forEachObject(\n (object) =>\n (object as Group).layoutManager &&\n (object as Group).layoutManager.performLayout({\n ...tricklingContext,\n bubbles: false,\n target: object as Group,\n }),\n );\n }\n }\n\n protected getLayoutResult(\n context: StrictLayoutContext,\n ): Required | undefined {\n const { target, strategy, type } = context;\n\n const result = strategy.calcLayoutResult(context, target.getObjects());\n\n if (!result) {\n return;\n }\n\n const prevCenter =\n type === LAYOUT_TYPE_INITIALIZATION\n ? new Point()\n : target.getRelativeCenterPoint();\n\n const {\n center: nextCenter,\n correction = new Point(),\n relativeCorrection = new Point(),\n } = result;\n const offset = prevCenter\n .subtract(nextCenter)\n .add(correction)\n .transform(\n // in `initialization` we do not account for target's transformation matrix\n type === LAYOUT_TYPE_INITIALIZATION\n ? iMatrix\n : invertTransform(target.calcOwnMatrix()),\n true,\n )\n .add(relativeCorrection);\n\n return {\n result,\n prevCenter,\n nextCenter,\n offset,\n };\n }\n\n protected commitLayout(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n const {\n result: { size },\n nextCenter,\n } = layoutResult;\n // set dimensions\n target.set({ width: size.x, height: size.y });\n // layout descendants\n this.layoutObjects(context, layoutResult);\n // set position\n // in `initialization` we do not account for target's transformation matrix\n if (context.type === LAYOUT_TYPE_INITIALIZATION) {\n // TODO: what about strokeWidth?\n target.set({\n left:\n context.x ?? nextCenter.x + size.x * resolveOrigin(target.originX),\n top: context.y ?? nextCenter.y + size.y * resolveOrigin(target.originY),\n });\n } else {\n target.setPositionByOrigin(nextCenter, CENTER, CENTER);\n // invalidate\n target.setCoords();\n target.set('dirty', true);\n }\n }\n\n protected layoutObjects(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n // adjust objects to account for new center\n target.forEachObject((object) => {\n object.group === target &&\n this.layoutObject(context, layoutResult, object);\n });\n // adjust clip path to account for new center\n context.strategy.shouldLayoutClipPath(context) &&\n this.layoutObject(context, layoutResult, target.clipPath as FabricObject);\n }\n\n /**\n * @param {FabricObject} object\n * @param {Point} offset\n */\n protected layoutObject(\n context: StrictLayoutContext,\n { offset }: Required,\n object: FabricObject,\n ) {\n // TODO: this is here for cache invalidation.\n // verify if this is necessary since we have explicit\n // cache invalidation at the end of commitLayout\n object.set({\n left: object.left + offset.x,\n top: object.top + offset.y,\n });\n }\n\n protected onAfterLayout(\n context: StrictLayoutContext,\n layoutResult?: LayoutResult,\n ) {\n const {\n target,\n strategy,\n bubbles,\n prevStrategy: _,\n ...bubblingContext\n } = context;\n const { canvas } = target;\n\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:after', {\n context,\n result: layoutResult,\n });\n canvas &&\n canvas.fire('object:layout:after', {\n context,\n result: layoutResult,\n target,\n });\n\n // bubble\n const parent = target.parent;\n if (bubbles && parent?.layoutManager) {\n // add target to context#path\n (bubblingContext.path || (bubblingContext.path = [])).push(target);\n // all parents should invalidate their layout\n parent.layoutManager.performLayout({\n ...bubblingContext,\n target: parent,\n });\n }\n target.set('dirty', true);\n }\n\n dispose() {\n const { _subscriptions } = this;\n _subscriptions.forEach((disposers) => disposers.forEach((d) => d()));\n _subscriptions.clear();\n }\n\n toObject() {\n return {\n type: LAYOUT_MANAGER,\n strategy: (this.strategy.constructor as typeof LayoutStrategy).type,\n };\n }\n\n toJSON() {\n return this.toObject();\n }\n}\n\nclassRegistry.setClass(LayoutManager, LAYOUT_MANAGER);\n","import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';\nimport { createCollectionMixin } from '../Collection';\nimport type {\n TClassProperties,\n TSVGReviver,\n TOptions,\n Abortable,\n} from '../typedefs';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n} from '../util/misc/matrix';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { applyTransformToObject } from '../util/misc/objectTransforms';\nimport { FabricObject } from './Object/FabricObject';\nimport { Rect } from './Rect';\nimport { classRegistry } from '../ClassRegistry';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport { log } from '../util/internals/console';\nimport type {\n ImperativeLayoutOptions,\n LayoutBeforeEvent,\n LayoutAfterEvent,\n} from '../LayoutManager/types';\nimport { LayoutManager } from '../LayoutManager/LayoutManager';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { SerializedLayoutManager } from '../LayoutManager/LayoutManager';\nimport type { FitContentLayout } from '../LayoutManager';\n\n/**\n * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case.\n * We could have used a boolean in the constructor, as we did previously, but we think the boolean\n * would stay in the group's constructor interface and create confusion, therefore it was removed.\n * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called.\n */\nclass NoopLayoutManager extends LayoutManager {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n performLayout() {}\n}\n\nexport interface GroupEvents extends ObjectEvents, CollectionEvents {\n 'layout:before': LayoutBeforeEvent;\n 'layout:after': LayoutAfterEvent;\n}\n\nexport interface GroupOwnProps {\n subTargetCheck: boolean;\n interactive: boolean;\n}\n\nexport interface SerializedGroupProps\n extends SerializedObjectProps,\n GroupOwnProps {\n objects: SerializedObjectProps[];\n layoutManager: SerializedLayoutManager;\n}\n\nexport interface GroupProps extends FabricObjectProps, GroupOwnProps {\n layoutManager: LayoutManager;\n}\n\nexport const groupDefaultValues: Partial> = {\n strokeWidth: 0,\n subTargetCheck: false,\n interactive: false,\n};\n\n/**\n * @fires object:added\n * @fires object:removed\n * @fires layout:before\n * @fires layout:after\n */\nexport class Group\n extends createCollectionMixin(\n FabricObject,\n )\n implements GroupProps\n{\n /**\n * Used to optimize performance\n * set to `false` if you don't need contained objects to be targets of events\n * @default\n * @type boolean\n */\n declare subTargetCheck: boolean;\n\n /**\n * Used to allow targeting of object inside groups.\n * set to true if you want to select an object inside a group.\\\n * **REQUIRES** `subTargetCheck` set to true\n * This will be not removed but slowly replaced with a method setInteractive\n * that will take care of enabling subTargetCheck and necessary object events.\n * There is too much attached to group interactivity to just be evaluated by a\n * boolean in the code\n * @default\n * @deprecated\n * @type boolean\n */\n declare interactive: boolean;\n\n declare layoutManager: LayoutManager;\n\n /**\n * Used internally to optimize performance\n * Once an object is selected, instance is rendered without the selected object.\n * This way instance is cached only once for the entire interaction with the selected object.\n * @private\n */\n protected _activeObjects: FabricObject[] = [];\n\n static type = 'Group';\n\n static ownDefaults: Record = groupDefaultValues;\n private __objectSelectionTracker: (ev: ObjectEvents['selected']) => void;\n private __objectSelectionDisposer: (ev: ObjectEvents['deselected']) => void;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Group.ownDefaults,\n };\n }\n\n /**\n * Constructor\n *\n * @param {FabricObject[]} [objects] instance objects\n * @param {Object} [options] Options object\n */\n constructor(objects: FabricObject[] = [], options: Partial = {}) {\n super();\n Object.assign(this, Group.ownDefaults);\n this.setOptions(options);\n this.groupInit(objects, options);\n }\n\n /**\n * Shared code between group and active selection\n * Meant to be used by the constructor.\n */\n protected groupInit(\n objects: FabricObject[],\n options: {\n layoutManager?: LayoutManager;\n top?: number;\n left?: number;\n },\n ) {\n this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller\n\n this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(\n this,\n true,\n );\n this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(\n this,\n false,\n );\n\n this.forEachObject((object) => {\n this.enterGroup(object, false);\n });\n\n // perform initial layout\n this.layoutManager = options.layoutManager ?? new LayoutManager();\n this.layoutManager.performLayout({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: this,\n targets: [...objects],\n // @TODO remove this concept from the layout manager.\n // Layout manager will calculate the correct position,\n // group options can override it later.\n x: options.left,\n y: options.top,\n });\n }\n\n /**\n * Checks if object can enter group and logs relevant warnings\n * @private\n * @param {FabricObject} object\n * @returns\n */\n canEnterGroup(object: FabricObject) {\n if (object === this || this.isDescendantOf(object)) {\n // prevent circular object tree\n log(\n 'error',\n 'Group: circular object trees are not supported, this call has no effect',\n );\n return false;\n } else if (this._objects.indexOf(object) !== -1) {\n // is already in the objects array\n log(\n 'error',\n 'Group: duplicate objects are not supported inside group, this call has no effect',\n );\n return false;\n }\n return true;\n }\n\n /**\n * Override this method to enhance performance (for groups with a lot of objects).\n * If Overriding, be sure not pass illegal objects to group - it will break your app.\n * @private\n */\n protected _filterObjectsBeforeEnteringGroup(objects: FabricObject[]) {\n return objects.filter((object, index, array) => {\n // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates)\n return this.canEnterGroup(object) && array.indexOf(object) === index;\n });\n }\n\n /**\n * Add objects\n * @param {...FabricObject[]} objects\n */\n add(...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.add(...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {FabricObject[]} objects Object to insert\n * @param {Number} index Index to insert object at\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.insertAt(index, ...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Remove objects\n * @param {...FabricObject[]} objects\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed);\n return removed;\n }\n\n _onObjectAdded(object: FabricObject) {\n this.enterGroup(object, true);\n this.fire('object:added', { target: object });\n object.fire('added', { target: this });\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _onObjectRemoved(object: FabricObject, removeParentTransform?: boolean) {\n this.exitGroup(object, removeParentTransform);\n this.fire('object:removed', { target: object });\n object.fire('removed', { target: this });\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n this.layoutManager.performLayout({\n type,\n targets,\n target: this,\n });\n }\n\n _onStackOrderChanged() {\n this._set('dirty', true);\n }\n\n /**\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n const prev = this[key as keyof this];\n super._set(key, value);\n if (key === 'canvas' && prev !== value) {\n (this._objects || []).forEach((object) => {\n object._set(key, value);\n });\n }\n return this;\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return this.subTargetCheck;\n }\n\n /**\n * Remove all objects\n * @returns {FabricObject[]} removed objects\n */\n removeAll() {\n this._activeObjects = [];\n return this.remove(...this._objects);\n }\n\n /**\n * keeps track of the selected objects\n * @private\n */\n __objectSelectionMonitor(\n selected: T,\n {\n target: object,\n }: ObjectEvents[T extends true ? 'selected' : 'deselected'],\n ) {\n const activeObjects = this._activeObjects;\n if (selected) {\n activeObjects.push(object);\n this._set('dirty', true);\n } else if (activeObjects.length > 0) {\n const index = activeObjects.indexOf(object);\n if (index > -1) {\n activeObjects.splice(index, 1);\n this._set('dirty', true);\n }\n }\n }\n\n /**\n * @private\n * @param {boolean} watch\n * @param {FabricObject} object\n */\n _watchObject(watch: boolean, object: FabricObject) {\n // make sure we listen only once\n watch && this._watchObject(false, object);\n if (watch) {\n object.on('selected', this.__objectSelectionTracker);\n object.on('deselected', this.__objectSelectionDisposer);\n } else {\n object.off('selected', this.__objectSelectionTracker);\n object.off('deselected', this.__objectSelectionDisposer);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n object.group && object.group.remove(object);\n object._set('parent', this);\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n _enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n if (removeParentTransform) {\n // can this be converted to utils (sendObjectToPlane)?\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n invertTransform(this.calcTransformMatrix()),\n object.calcTransformMatrix(),\n ),\n );\n }\n this._shouldSetNestedCoords() && object.setCoords();\n object._set('group', this);\n object._set('canvas', this.canvas);\n this._watchObject(true, object);\n const activeObject =\n this.canvas &&\n this.canvas.getActiveObject &&\n this.canvas.getActiveObject();\n // if we are adding the activeObject in a group\n if (\n activeObject &&\n (activeObject === object || object.isDescendantOf(activeObject))\n ) {\n this._activeObjects.push(object);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n object._set('parent', undefined);\n object._set('canvas', undefined);\n }\n\n /**\n * Executes the inner fabric logic of exiting a group.\n * - Stop watching the object\n * - Remove the object from the optimization map this._activeObjects\n * - unset the group property of the object\n * @protected\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n object._set('group', undefined);\n if (!removeParentTransform) {\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n this.calcTransformMatrix(),\n object.calcTransformMatrix(),\n ),\n );\n object.setCoords();\n }\n this._watchObject(false, object);\n const index =\n this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1;\n if (index > -1) {\n this._activeObjects.splice(index, 1);\n }\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache() {\n const ownCache = FabricObject.prototype.shouldCache.call(this);\n if (ownCache) {\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n }\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow() {\n if (super.willDrawShadow()) {\n return true;\n }\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if instance or its group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache(): boolean {\n return this.ownCaching || (!!this.parent && this.parent.isOnACache());\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject(ctx: CanvasRenderingContext2D) {\n this._renderBackground(ctx);\n for (let i = 0; i < this._objects.length; i++) {\n // TODO: handle rendering edge case somehow\n if (\n this.canvas?.preserveObjectStacking &&\n this._objects[i].group !== this\n ) {\n ctx.save();\n ctx.transform(...invertTransform(this.calcTransformMatrix()));\n this._objects[i].render(ctx);\n ctx.restore();\n } else if (this._objects[i].group === this) {\n this._objects[i].render(ctx);\n }\n }\n this._drawClipPath(ctx, this.clipPath);\n }\n\n /**\n * @override\n * @return {Boolean}\n */\n setCoords() {\n super.setCoords();\n this._shouldSetNestedCoords() &&\n this.forEachObject((object) => object.setCoords());\n }\n\n triggerLayout(options: ImperativeLayoutOptions = {}) {\n this.layoutManager.performLayout({\n target: this,\n type: LAYOUT_TYPE_IMPERATIVE,\n ...options,\n });\n }\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render(ctx: CanvasRenderingContext2D) {\n this._transformDone = true;\n super.render(ctx);\n this._transformDone = false;\n }\n\n /**\n *\n * @private\n * @param {'toObject'|'toDatalessObject'} [method]\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {FabricObject[]} serialized objects\n */\n __serializeObjects(\n method: 'toObject' | 'toDatalessObject',\n propertiesToInclude?: string[],\n ) {\n const _includeDefaultValues = this.includeDefaultValues;\n return this._objects\n .filter(function (obj) {\n return !obj.excludeFromExport;\n })\n .map(function (obj) {\n const originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n const data = obj[method || 'toObject'](propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n // delete data.version;\n return data;\n });\n }\n\n /**\n * Returns object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit<\n GroupProps & TClassProperties,\n keyof SerializedGroupProps\n >,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SerializedGroupProps {\n const layoutManager = this.layoutManager.toObject();\n\n return {\n ...super.toObject([\n 'subTargetCheck',\n 'interactive',\n ...propertiesToInclude,\n ]),\n ...(layoutManager.strategy !== 'fit-content' || this.includeDefaultValues\n ? { layoutManager }\n : {}),\n objects: this.__serializeObjects(\n 'toObject',\n propertiesToInclude as string[],\n ),\n };\n }\n\n toString() {\n return `#`;\n }\n\n dispose() {\n this.layoutManager.unsubscribeTargets({\n targets: this.getObjects(),\n target: this,\n });\n this._activeObjects = [];\n this.forEachObject((object) => {\n this._watchObject(false, object);\n object.dispose();\n });\n super.dispose();\n }\n\n /**\n * @private\n */\n _createSVGBgRect(reviver?: TSVGReviver) {\n if (!this.backgroundColor) {\n return '';\n }\n const fillStroke = Rect.prototype._toSVG.call(this);\n const commons = fillStroke.indexOf('COMMON_PARTS');\n fillStroke[commons] = 'for=\"group\" ';\n const markup = fillStroke.join('');\n return reviver ? reviver(markup) : markup;\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG(reviver?: TSVGReviver) {\n const svgString = ['\\n'];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('\\n');\n return svgString;\n }\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles(): string {\n const opacity =\n typeof this.opacity !== 'undefined' && this.opacity !== 1\n ? `opacity: ${this.opacity};`\n : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].join('');\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const svgString = [];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n return this._createBaseClipPathSVGMarkup(svgString, {\n reviver,\n });\n }\n\n /**\n * @todo support loading from svg\n * @private\n * @static\n * @memberOf Group\n * @param {Object} object Object to create a group from\n * @returns {Promise}\n */\n static fromObject>(\n { type, objects = [], layoutManager, ...options }: T,\n abortable?: Abortable,\n ) {\n return Promise.all([\n enlivenObjects(objects, abortable),\n enlivenObjectEnlivables(options, abortable),\n ]).then(([objects, hydratedOptions]) => {\n const group = new this(objects, {\n ...options,\n ...hydratedOptions,\n layoutManager: new NoopLayoutManager(),\n });\n if (layoutManager) {\n const layoutClass = classRegistry.getClass(\n layoutManager.type,\n );\n const strategyClass = classRegistry.getClass(\n layoutManager.strategy,\n );\n group.layoutManager = new layoutClass(new strategyClass());\n } else {\n group.layoutManager = new LayoutManager();\n }\n group.layoutManager.subscribeTargets({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: group,\n targets: group.getObjects(),\n });\n group.setCoords();\n return group;\n });\n }\n}\n\nclassRegistry.setClass(Group);\n","import type { GroupProps } from '../../shapes/Group';\nimport { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\n\n/**\n * TODO experiment with different layout manager and svg results ( fixed fit content )\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group\n * @return {FabricObject | Group}\n */\nexport const groupSVGElements = (\n elements: FabricObject[],\n options?: Partial,\n) => {\n if (elements && elements.length === 1) {\n return elements[0];\n }\n return new Group(elements, options);\n};\n","import type { TSize } from '../../typedefs';\n\n/**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\nexport const findScaleToFit = (source: TSize, destination: TSize) =>\n Math.min(\n destination.width / source.width,\n destination.height / source.height,\n );\n\n/**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\nexport const findScaleToCover = (source: TSize, destination: TSize) =>\n Math.max(\n destination.width / source.width,\n destination.height / source.height,\n );\n","import { reNum } from '../../parser/constants';\n\nconst commaWsp = `\\\\s*,?\\\\s*`;\n\n/**\n * p for param\n * using \"bad naming\" here because it makes the regex much easier to read\n * p is a number that is preceded by an arbitary number of spaces, maybe 0,\n * a comma or not, and then possibly more spaces or not.\n */\nconst p = `${commaWsp}(${reNum})`;\n\n// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;\n\n// const reLineCommand = `(L) ?(?:${p}${p} ?)+`;\n\n// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;\n\n// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;\n\n// const reClosePathCommand = String.raw`(Z)\\s*`;\n\n// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;\n\n// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;\n\nexport const reArcCommandPoints = `${p}${p}${p}${commaWsp}([01])${commaWsp}([01])${p}${p}`;\n// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;\n\n// export const rePathCommandGroups =\n// `(?:(?:${reMoveToCommand})` +\n// `|(?:${reLineCommand})` +\n// `|(?:${reHorizontalLineCommand})` +\n// `|(?:${reVerticalLineCommand})` +\n// `|(?:${reClosePathCommand})` +\n// `|(?:${reCubicCurveCommand})` +\n// `|(?:${reCubicCurveShortcutCommand})` +\n// `|(?:${reQuadraticCurveCommand})` +\n// `|(?:${reQuadraticCurveShortcutCommand})` +\n// `|(?:${reArcCommand}))`;\n\nexport const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = >basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = >basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example Usage\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n for (let out = null; (out = regExpArcCommandPoints.exec(matchStr)); ) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n","// TODO this file needs to go away, cross browser style support is not fabricjs domain.\n\n/**\n * wrapper for setting element's style\n * @param {HTMLElement} element\n * @param {Object | string} styles\n */\nexport function setStyle(\n element: HTMLElement,\n styles: string | Record,\n) {\n const elementStyle = element.style;\n if (!elementStyle || !styles) {\n return;\n } else if (typeof styles === 'string') {\n elementStyle.cssText += ';' + styles;\n } else {\n Object.entries(styles).forEach(([property, value]) =>\n elementStyle.setProperty(property, value),\n );\n }\n}\n","import type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { sendObjectToPlane } from './planeChange';\nimport { Group } from '../../shapes/Group';\n/**\n * Merges 2 clip paths into one visually equal clip path\n *\n * **IMPORTANT**:\\\n * Does **NOT** clone the arguments, clone them proir if necessary.\n *\n * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap.\n * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible.\n *\n * In order to handle the `inverted` property we follow logic described in the following cases:\\\n * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\\\n * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\\\n * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged.\n *\n * @memberOf fabric.util\n * @param {fabric.Object} c1\n * @param {fabric.Object} c2\n * @returns {fabric.Object} merged clip path\n */\nexport const mergeClipPaths = (c1: FabricObject, c2: FabricObject) => {\n let a = c1,\n b = c2;\n if (a.inverted && !b.inverted) {\n // case (2)\n a = c2;\n b = c1;\n }\n // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane\n sendObjectToPlane(b, b.group?.calcTransformMatrix(), a.calcTransformMatrix());\n // assign the `inverted` prop to the wrapping group\n const inverted = a.inverted && b.inverted;\n if (inverted) {\n // case (1)\n a.inverted = b.inverted = false;\n }\n return new Group([a], { clipPath: b, inverted });\n};\n","/**\n * Returns random number between 2 specified ones.\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\nexport const getRandomInt = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n","import { getFabricWindow } from '../../env';\nimport { noop } from '../../constants';\nimport type { Abortable } from '../../typedefs';\nimport { SignalAbortedError } from './console';\n\ntype requestOptions = Abortable & {\n onComplete?: (xhr: XMLHttpRequest) => void;\n};\n\n/**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @deprecated this has to go away, we can use a modern browser method to do the same.\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n\nexport function request(url: string, options: requestOptions = {}) {\n const onComplete = options.onComplete || noop,\n xhr = new (getFabricWindow().XMLHttpRequest)(),\n signal = options.signal,\n abort = function () {\n xhr.abort();\n },\n removeListener = function () {\n signal && signal.removeEventListener('abort', abort);\n xhr.onerror = xhr.ontimeout = noop;\n };\n\n if (signal && signal.aborted) {\n throw new SignalAbortedError('request');\n } else if (signal) {\n signal.addEventListener('abort', abort, { once: true });\n }\n\n /** @ignore */\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4) {\n removeListener();\n onComplete(xhr);\n xhr.onreadystatechange = noop;\n }\n };\n\n xhr.onerror = xhr.ontimeout = removeListener;\n\n xhr.open('get', url, true);\n\n xhr.send();\n return xhr;\n}\n","import { CENTER, SCALE_X, SCALE_Y } from '../constants';\nimport type { FabricImage } from '../shapes/Image';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { qrDecompose } from './misc/matrix';\n\ntype FabricObjectWithTransformMatrix = FabricObject & {\n transformMatrix?: TMat2D;\n};\n\n/**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n */\nconst _assignTransformMatrixProps = (\n object: FabricObjectWithTransformMatrix,\n) => {\n if (object.transformMatrix) {\n const { scaleX, scaleY, angle, skewX } = qrDecompose(\n object.transformMatrix,\n );\n object.flipX = false;\n object.flipY = false;\n object.set(SCALE_X, scaleX);\n object.set(SCALE_Y, scaleY);\n object.angle = angle;\n object.skewX = skewX;\n object.skewY = 0;\n }\n};\n\n/**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n */\nexport const removeTransformMatrixForSvgParsing = (\n object: FabricObjectWithTransformMatrix,\n preserveAspectRatioOptions?: any,\n) => {\n let center = object._findCenterFromElement();\n if (object.transformMatrix) {\n _assignTransformMatrixProps(object);\n center = center.transform(object.transformMatrix);\n }\n delete object.transformMatrix;\n if (preserveAspectRatioOptions) {\n object.scaleX *= preserveAspectRatioOptions.scaleX;\n object.scaleY *= preserveAspectRatioOptions.scaleY;\n (object as FabricImage).cropX = preserveAspectRatioOptions.cropX;\n (object as FabricImage).cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n object.width = preserveAspectRatioOptions.width;\n object.height = preserveAspectRatioOptions.height;\n }\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n","import type { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n/**\n * Rotates `point` around `origin` with `radians`\n * @deprecated use the Point.rotate\n * @param {Point} origin The origin of the rotation\n * @param {Point} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotatePoint = (\n point: Point,\n origin: Point,\n radians: TRadian,\n): Point => point.rotate(radians, origin);\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport { createCanvasElement, setStyle } from '../../util';\nimport type { CSSDimensions } from './util';\nimport { makeElementUnselectable, setCSSDimensions } from './util';\nimport type { CanvasItem } from './StaticCanvasDOMManager';\nimport { StaticCanvasDOMManager } from './StaticCanvasDOMManager';\nimport { setCanvasDimensions } from './util';\nimport { NONE } from '../../constants';\n\nexport class CanvasDOMManager extends StaticCanvasDOMManager {\n upper: CanvasItem;\n container: HTMLDivElement;\n\n constructor(\n arg0?: string | HTMLCanvasElement,\n {\n allowTouchScrolling = false,\n containerClass = '',\n }: {\n allowTouchScrolling?: boolean;\n /**\n * @deprecated here only for backward compatibility\n */\n containerClass?: string;\n } = {},\n ) {\n super(arg0);\n const { el: lowerCanvasEl } = this.lower;\n const upperCanvasEl = this.createUpperCanvas();\n this.upper = { el: upperCanvasEl, ctx: upperCanvasEl.getContext('2d')! };\n this.applyCanvasStyle(lowerCanvasEl, {\n allowTouchScrolling,\n });\n this.applyCanvasStyle(upperCanvasEl, {\n allowTouchScrolling,\n styles: {\n position: 'absolute',\n left: '0',\n top: '0',\n },\n });\n const container = this.createContainerElement();\n container.classList.add(containerClass);\n if (lowerCanvasEl.parentNode) {\n lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl);\n }\n container.append(lowerCanvasEl, upperCanvasEl);\n this.container = container;\n }\n\n protected createUpperCanvas() {\n const { el: lowerCanvasEl } = this.lower;\n const el = createCanvasElement();\n // we assign the same classname of the lowerCanvas\n el.className = lowerCanvasEl.className;\n // but then we remove the lower-canvas specific className\n el.classList.remove('lower-canvas');\n // we add the specific upper-canvas class\n el.classList.add('upper-canvas');\n el.setAttribute('data-fabric', 'top');\n el.style.cssText = lowerCanvasEl.style.cssText;\n el.setAttribute('draggable', 'true');\n return el;\n }\n\n protected createContainerElement() {\n const container = getFabricDocument().createElement('div');\n container.setAttribute('data-fabric', 'wrapper');\n setStyle(container, {\n position: 'relative',\n });\n makeElementUnselectable(container);\n return container;\n }\n\n /**\n * @private\n * @param {HTMLCanvasElement} element canvas element to apply styles on\n */\n protected applyCanvasStyle(\n element: HTMLCanvasElement,\n options: {\n allowTouchScrolling?: boolean;\n styles?: Record;\n },\n ) {\n const { styles, allowTouchScrolling } = options;\n setStyle(element, {\n ...styles,\n 'touch-action': allowTouchScrolling ? 'manipulation' : NONE,\n });\n makeElementUnselectable(element);\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n super.setDimensions(size, retinaScaling);\n const { el, ctx } = this.upper;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial): void {\n super.setCSSDimensions(size);\n setCSSDimensions(this.upper.el, size);\n setCSSDimensions(this.container, size);\n }\n\n cleanupDOM(size: TSize) {\n const container = this.container,\n { el: lowerCanvasEl } = this.lower,\n { el: upperCanvasEl } = this.upper;\n super.cleanupDOM(size);\n container.removeChild(upperCanvasEl);\n container.removeChild(lowerCanvasEl);\n if (container.parentNode) {\n container.parentNode.replaceChild(lowerCanvasEl, container);\n }\n }\n\n dispose() {\n super.dispose();\n getEnv().dispose(this.upper.el);\n // @ts-expect-error disposing\n delete this.upper;\n // @ts-expect-error disposing\n delete this.container;\n }\n}\n","import { dragHandler } from '../controls/drag';\nimport { getActionFromCorner } from '../controls/util';\nimport { Point } from '../Point';\nimport { FabricObject } from '../shapes/Object/FabricObject';\nimport type {\n CanvasEvents,\n ModifierKey,\n TOptionalModifierKey,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport {\n addTransformToObject,\n saveObjectTransform,\n} from '../util/misc/objectTransforms';\nimport type { TCanvasSizeOptions } from './StaticCanvas';\nimport { StaticCanvas } from './StaticCanvas';\nimport { isCollection } from '../Collection';\nimport { isTransparent } from '../util/misc/isTransparent';\nimport type {\n TMat2D,\n TOriginX,\n TOriginY,\n TSize,\n TSVGReviver,\n} from '../typedefs';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { getPointer, isTouchEvent } from '../util/dom_event';\nimport type { IText } from '../shapes/IText/IText';\nimport type { BaseBrush } from '../brushes/BaseBrush';\nimport { pick } from '../util/misc/pick';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { cos, createCanvasElement, sin } from '../util';\nimport { CanvasDOMManager } from './DOMManagers/CanvasDOMManager';\nimport {\n BOTTOM,\n CENTER,\n LEFT,\n MODIFIED,\n RESIZING,\n RIGHT,\n ROTATE,\n SCALE,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CanvasOptions } from './CanvasOptions';\nimport { canvasDefaults } from './CanvasOptions';\nimport { Intersection } from '../Intersection';\nimport { isActiveSelection } from '../util/typeAssertions';\n\n/**\n * Canvas class\n * @class Canvas\n * @extends StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n *\n * @fires object:modified at the end of a transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drag:enter object drag enter\n * @fires drag:leave object drag leave\n * @fires drop:before before drop event. Prepare for the drop event (same native event).\n * @fires drop\n * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event).\n * @example\n * let a: fabric.Object, b: fabric.Object;\n * let flag = false;\n * canvas.add(a, b);\n * a.on('drop:before', opt => {\n * // we want a to accept the drop even though it's below b in the stack\n * flag = this.canDrop(opt.e);\n * });\n * b.canDrop = function(e) {\n * !flag && this.draggableTextDelegate.canDrop(e);\n * }\n * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black'));\n * a.on('drop', opt => {\n * opt.e.defaultPrevented // drop occurred\n * opt.didDrop // drop occurred on canvas\n * opt.target // drop target\n * opt.target !== a && a.set('text', 'I lost');\n * });\n * canvas.on('drop:after', opt => {\n * // inform user who won\n * if(!opt.e.defaultPrevented) {\n * // no winners\n * }\n * else if(!opt.didDrop) {\n * // my objects didn't win, some other lucky object\n * }\n * else {\n * // we have a winner it's opt.target!!\n * }\n * })\n *\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * @fires contextmenu:before\n * @fires contextmenu\n * @example\n * let handler;\n * targets.forEach(target => {\n * target.on('contextmenu:before', opt => {\n * // decide which target should handle the event before canvas hijacks it\n * if (someCaseHappens && opt.targets.includes(target)) {\n * handler = target;\n * }\n * });\n * target.on('contextmenu', opt => {\n * // do something fantastic\n * });\n * });\n * canvas.on('contextmenu', opt => {\n * if (!handler) {\n * // no one takes responsibility, it's always left to me\n * // let's show them how it's done!\n * }\n * });\n *\n */\nexport class SelectableCanvas\n extends StaticCanvas\n implements Omit\n{\n declare _objects: FabricObject[];\n\n // transform config\n declare uniformScaling: boolean;\n declare uniScaleKey: TOptionalModifierKey;\n declare centeredScaling: boolean;\n declare centeredRotation: boolean;\n declare centeredKey: TOptionalModifierKey;\n declare altActionKey: TOptionalModifierKey;\n\n // selection config\n declare selection: boolean;\n declare selectionKey: TOptionalModifierKey | ModifierKey[];\n declare altSelectionKey: TOptionalModifierKey;\n declare selectionColor: string;\n declare selectionDashArray: number[];\n declare selectionBorderColor: string;\n declare selectionLineWidth: number;\n declare selectionFullyContained: boolean;\n\n // cursors\n declare hoverCursor: CSSStyleDeclaration['cursor'];\n declare moveCursor: CSSStyleDeclaration['cursor'];\n declare defaultCursor: CSSStyleDeclaration['cursor'];\n declare freeDrawingCursor: CSSStyleDeclaration['cursor'];\n declare notAllowedCursor: CSSStyleDeclaration['cursor'];\n\n declare containerClass: string;\n\n // target find config\n declare perPixelTargetFind: boolean;\n declare targetFindTolerance: number;\n declare skipTargetFind: boolean;\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n declare isDrawingMode: boolean;\n\n declare preserveObjectStacking: boolean;\n\n // event config\n declare stopContextMenu: boolean;\n declare fireRightClick: boolean;\n declare fireMiddleClick: boolean;\n\n /**\n * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget\n * @type FabricObject[]\n */\n targets: FabricObject[] = [];\n\n /**\n * Keep track of the hovered target\n * @type FabricObject | null\n * @private\n */\n declare _hoveredTarget?: FabricObject;\n\n /**\n * hold the list of nested targets hovered\n * @type FabricObject[]\n * @private\n */\n _hoveredTargets: FabricObject[] = [];\n\n /**\n * hold the list of objects to render\n * @type FabricObject[]\n * @private\n */\n _objectsToRender?: FabricObject[];\n\n /**\n * hold a reference to a data structure that contains information\n * on the current on going transform\n * @type\n * @private\n */\n _currentTransform: Transform | null = null;\n\n /**\n * hold a reference to a data structure used to track the selection\n * box on canvas drag\n * on the current on going transform\n * x, y, deltaX and deltaY are in scene plane\n * @type\n * @private\n */\n protected _groupSelector: {\n x: number;\n y: number;\n deltaX: number;\n deltaY: number;\n } | null = null;\n\n /**\n * internal flag used to understand if the context top requires a cleanup\n * in case this is true, the contextTop will be cleared at the next render\n * @type boolean\n * @private\n */\n contextTopDirty = false;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _absolutePointer holds a reference to the pointer in fabricCanvas/design coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _absolutePointer?: Point;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _pointer holds a reference to the pointer in html coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _pointer?: Point;\n\n /**\n * During a mouse event we may need the target multiple times in multiple functions.\n * _target holds a reference to the target that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * @type {FabricObject}\n */\n protected declare _target?: FabricObject;\n\n static ownDefaults = canvasDefaults;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...SelectableCanvas.ownDefaults };\n }\n\n declare elements: CanvasDOMManager;\n get upperCanvasEl() {\n return this.elements.upper?.el;\n }\n get contextTop() {\n return this.elements.upper?.ctx;\n }\n get wrapperEl() {\n return this.elements.container;\n }\n private declare pixelFindCanvasEl: HTMLCanvasElement;\n private declare pixelFindContext: CanvasRenderingContext2D;\n\n protected declare _isCurrentlyDrawing: boolean;\n declare freeDrawingBrush?: BaseBrush;\n declare _activeObject?: FabricObject;\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new CanvasDOMManager(el, {\n allowTouchScrolling: this.allowTouchScrolling,\n containerClass: this.containerClass,\n });\n this._createCacheCanvas();\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was added\n */\n _onObjectAdded(obj: FabricObject) {\n this._objectsToRender = undefined;\n super._onObjectAdded(obj);\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was removed\n */\n _onObjectRemoved(obj: FabricObject) {\n this._objectsToRender = undefined;\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { deselected: [obj] });\n this._discardActiveObject();\n this.fire('selection:cleared', { deselected: [obj] });\n obj.fire('deselected', {\n target: obj,\n });\n }\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n super._onObjectRemoved(obj);\n }\n\n _onStackOrderChanged() {\n this._objectsToRender = undefined;\n super._onStackOrderChanged();\n }\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender(): FabricObject[] {\n const activeObject = this._activeObject;\n return !this.preserveObjectStacking && activeObject\n ? this._objects\n .filter((object) => !object.group && object !== activeObject)\n .concat(activeObject)\n : this._objects;\n }\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n this.hasLostContext = false;\n }\n !this._objectsToRender &&\n (this._objectsToRender = this._chooseObjectsToRender());\n this.renderCanvas(this.getContext(), this._objectsToRender);\n }\n\n /**\n * text selection is rendered by the active text instance during the rendering cycle\n */\n renderTopLayer(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n }\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * Does not render text selection.\n */\n renderTop() {\n const ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n // todo: how do i know if the after:render is for the top or normal contex?\n this.fire('after:render', { ctx });\n }\n\n /**\n * Set the canvas tolerance value for pixel taret find.\n * Use only integer numbers.\n * @private\n */\n setTargetFindTolerance(value: number) {\n value = Math.round(value);\n this.targetFindTolerance = value;\n const retina = this.getRetinaScaling();\n const size = Math.ceil((value * 2 + 1) * retina);\n this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size;\n this.pixelFindContext.scale(retina, retina);\n }\n\n /**\n * Returns true if object is transparent at a certain location\n * Clarification: this is `is target transparent at location X or are controls there`\n * @TODO this seems dumb that we treat controls with transparency. we can find controls\n * programmatically without painting them, the cache canvas optimization is always valid\n * @param {FabricObject} target Object to check\n * @param {Number} x Left coordinate in viewport space\n * @param {Number} y Top coordinate in viewport space\n * @return {Boolean}\n */\n isTargetTransparent(target: FabricObject, x: number, y: number): boolean {\n const tolerance = this.targetFindTolerance;\n const ctx = this.pixelFindContext;\n this.clearContext(ctx);\n ctx.save();\n ctx.translate(-x + tolerance, -y + tolerance);\n ctx.transform(...this.viewportTransform);\n const selectionBgc = target.selectionBackgroundColor;\n target.selectionBackgroundColor = '';\n target.render(ctx);\n target.selectionBackgroundColor = selectionBgc;\n ctx.restore();\n // our canvas is square, and made around tolerance.\n // so tolerance in this case also represent the center of the canvas.\n const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling());\n return isTransparent(\n ctx,\n enhancedTolerance,\n enhancedTolerance,\n enhancedTolerance,\n );\n }\n\n /**\n * takes an event and determines if selection key has been pressed\n * @private\n * @param {TPointerEvent} e Event object\n */\n _isSelectionKeyPressed(e: TPointerEvent): boolean {\n const sKey = this.selectionKey;\n if (!sKey) {\n return false;\n }\n if (Array.isArray(sKey)) {\n return !!sKey.find((key) => !!key && e[key] === true);\n } else {\n return e[sKey];\n }\n }\n\n /**\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target\n */\n _shouldClearSelection(\n e: TPointerEvent,\n target?: FabricObject,\n ): target is undefined {\n const activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return !!(\n !target ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e)) ||\n (target && !target.evented) ||\n (target && !target.selectable && activeObject && activeObject !== target)\n );\n }\n\n /**\n * This method will take in consideration a modifier key pressed and the control we are\n * about to drag, and try to guess the anchor point ( origin ) of the transormation.\n * This should be really in the realm of controls, and we should remove specific code for legacy\n * embedded actions.\n * @TODO this probably deserve discussion/rediscovery and change/refactor\n * @private\n * @deprecated\n * @param {FabricObject} target\n * @param {string} action\n * @param {boolean} altKey\n * @returns {boolean} true if the transformation should be centered\n */\n private _shouldCenterTransform(\n target: FabricObject,\n action: string,\n modifierKeyPressed: boolean,\n ) {\n if (!target) {\n return;\n }\n\n let centerTransform;\n\n if (\n action === SCALE ||\n action === SCALE_X ||\n action === SCALE_Y ||\n action === RESIZING\n ) {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === ROTATE) {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !modifierKeyPressed : modifierKeyPressed;\n }\n\n /**\n * Given the control clicked, determine the origin of the transform.\n * This is bad because controls can totally have custom names\n * should disappear before release 4.0\n * @private\n * @deprecated\n */\n _getOriginFromCorner(\n target: FabricObject,\n controlName: string,\n ): { x: TOriginX; y: TOriginY } {\n const origin = {\n x: target.originX,\n y: target.originY,\n };\n\n if (!controlName) {\n return origin;\n }\n\n // is a left control ?\n if (['ml', 'tl', 'bl'].includes(controlName)) {\n origin.x = RIGHT;\n // is a right control ?\n } else if (['mr', 'tr', 'br'].includes(controlName)) {\n origin.x = LEFT;\n }\n // is a top control ?\n if (['tl', 'mt', 'tr'].includes(controlName)) {\n origin.y = BOTTOM;\n // is a bottom control ?\n } else if (['bl', 'mb', 'br'].includes(controlName)) {\n origin.y = TOP;\n }\n return origin;\n }\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {FabricObject} target\n * @param {boolean} [alreadySelected] pass true to setup the active control\n */\n _setupCurrentTransform(\n e: TPointerEvent,\n target: FabricObject,\n alreadySelected: boolean,\n ): void {\n const pointer = target.group\n ? // transform pointer to target's containing coordinate plane\n sendPointToPlane(\n this.getScenePoint(e),\n undefined,\n target.group.calcTransformMatrix(),\n )\n : this.getScenePoint(e);\n const { key: corner = '', control } = target.getActiveControl() || {},\n actionHandler =\n alreadySelected && control\n ? control.getActionHandler(e, target, control)?.bind(control)\n : dragHandler,\n action = getActionFromCorner(alreadySelected, corner, e, target),\n altKey = e[this.centeredKey as ModifierKey],\n origin = this._shouldCenterTransform(target, action, altKey)\n ? ({ x: CENTER, y: CENTER } as const)\n : this._getOriginFromCorner(target, corner),\n /**\n * relative to target's containing coordinate plane\n * both agree on every point\n **/\n transform: Transform = {\n target: target,\n action,\n actionHandler,\n actionPerformed: false,\n corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n theta: degreesToRadians(target.angle),\n width: target.width,\n height: target.height,\n shiftKey: e.shiftKey,\n altKey,\n original: {\n ...saveObjectTransform(target),\n originX: origin.x,\n originY: origin.y,\n },\n };\n\n this._currentTransform = transform;\n\n this.fire('before:transform', {\n e,\n transform,\n });\n }\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor(value: CSSStyleDeclaration['cursor']): void {\n this.upperCanvasEl.style.cursor = value;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection(ctx: CanvasRenderingContext2D): void {\n const { x, y, deltaX, deltaY } = this._groupSelector!,\n start = new Point(x, y).transform(this.viewportTransform),\n extent = new Point(x + deltaX, y + deltaY).transform(\n this.viewportTransform,\n ),\n strokeOffset = this.selectionLineWidth / 2;\n let minX = Math.min(start.x, extent.x),\n minY = Math.min(start.y, extent.y),\n maxX = Math.max(start.x, extent.x),\n maxY = Math.max(start.y, extent.y);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n minX += strokeOffset;\n minY += strokeOffset;\n maxX -= strokeOffset;\n maxY -= strokeOffset;\n // selection border\n // @TODO: is _setLineDash still necessary on modern canvas?\n FabricObject.prototype._setLineDash.call(\n this,\n ctx,\n this.selectionDashArray,\n );\n ctx.strokeRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n /**\n * Method that determines what object we are clicking on\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @return {FabricObject | null} the target found\n */\n findTarget(e: TPointerEvent): FabricObject | undefined {\n if (this.skipTargetFind) {\n return undefined;\n }\n\n const pointer = this.getViewportPoint(e),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects();\n\n this.targets = [];\n\n if (activeObject && aObjects.length >= 1) {\n if (activeObject.findControl(pointer, isTouchEvent(e))) {\n // if we hit the corner of the active object, let's return that.\n return activeObject;\n } else if (\n aObjects.length > 1 &&\n // check pointer is over active selection and possibly perform `subTargetCheck`\n this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active selection does not select sub targets like normal groups\n return activeObject;\n } else if (\n activeObject === this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active object is not an active selection\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n const subTargets = this.targets;\n this.targets = [];\n const target = this.searchPossibleTargets(this._objects, pointer);\n if (\n e[this.altSelectionKey as ModifierKey] &&\n target &&\n target !== activeObject\n ) {\n // alt selection: select active object even though it is not the top most target\n // restore targets\n this.targets = subTargets;\n return activeObject;\n }\n return target;\n }\n }\n }\n\n return this.searchPossibleTargets(this._objects, pointer);\n }\n\n /**\n * Checks if the point is inside the object selection area including padding\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point in scene coordinates\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n private _pointIsInObjectSelectionArea(obj: FabricObject, point: Point) {\n // getCoords will already take care of group de-nesting\n let coords = obj.getCoords();\n const viewportZoom = this.getZoom();\n const padding = obj.padding / viewportZoom;\n if (padding) {\n const [tl, tr, br, bl] = coords;\n // what is the angle of the object?\n // we could use getTotalAngle, but is way easier to look at it\n // from how coords are oriented, since if something went wrong\n // at least we are consistent.\n const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x),\n cosP = cos(angleRadians) * padding,\n sinP = sin(angleRadians) * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP;\n\n coords = [\n new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP),\n new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP),\n new Point(br.x + cosPMinusSinP, br.y + cosPSinP),\n new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP),\n ];\n // in case of padding we calculate the new coords on the fly.\n // otherwise we have to maintain 2 sets of coordinates for everything.\n // we can reiterate on storing them.\n // if this is slow, for now the semplification is large and doesn't impact\n // rendering.\n // the idea behind this is that outside target check we don't need ot know\n // where those coords are\n }\n return Intersection.isPointInPolygon(point, coords);\n }\n\n /**\n * Checks point is inside the object selection condition. Either area with padding\n * or over pixels if perPixelTargetFind is enabled\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point from viewport.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget(obj: FabricObject, pointer: Point): boolean {\n if (\n obj &&\n obj.visible &&\n obj.evented &&\n this._pointIsInObjectSelectionArea(\n obj,\n sendPointToPlane(pointer, undefined, this.viewportTransform),\n )\n ) {\n if (\n (this.perPixelTargetFind || obj.perPixelTargetFind) &&\n !(obj as unknown as IText).isEditing\n ) {\n if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {FabricObject} **top most object from given `objects`** that contains pointer\n * @private\n */\n _searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n // Cache all targets where their bounding box contains point.\n let i = objects.length;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n const target = objects[i];\n if (this._checkTarget(target, pointer)) {\n if (isCollection(target) && target.subTargetCheck) {\n const subTarget = this._searchPossibleTargets(\n target._objects as FabricObject[],\n pointer,\n );\n subTarget && this.targets.push(subTarget);\n }\n return target;\n }\n }\n }\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @see {@link _searchPossibleTargets}\n * @param {FabricObject[]} [objects] objects array to look into\n * @param {Point} [pointer] coordinates from viewport to check.\n * @return {FabricObject} **top most object on screen** that contains pointer\n */\n searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n const target = this._searchPossibleTargets(objects, pointer);\n\n // if we found something in this.targets, and the group is interactive, return the innermost subTarget\n // that is still interactive\n // TODO: reverify why interactive. the target should be returned always, but selected only\n // if interactive.\n if (\n target &&\n isCollection(target) &&\n target.interactive &&\n this.targets[0]\n ) {\n /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */\n const targets = this.targets;\n for (let i = targets.length - 1; i > 0; i--) {\n const t = targets[i];\n if (!(isCollection(t) && t.interactive)) {\n // one of the subtargets was not interactive. that is the last subtarget we can return.\n // we can't dig more deep;\n return t;\n }\n }\n return targets[0];\n }\n\n return target;\n }\n\n /**\n * @returns point existing in the same plane as the {@link HTMLCanvasElement},\n * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}.\n * This means that changes to the {@link viewportTransform} do not change the values of the point\n * and it remains unchanged from the viewer's perspective.\n *\n * @example\n * const scenePoint = sendPointToPlane(\n * this.getViewportPoint(e),\n * undefined,\n * canvas.viewportTransform\n * );\n *\n */\n getViewportPoint(e: TPointerEvent) {\n if (this._pointer) {\n return this._pointer;\n }\n return this.getPointer(e, true);\n }\n\n /**\n * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in).\n * This means that changes to the {@link viewportTransform} do not change the values of the point,\n * however, from the viewer's perspective, the point is changed.\n *\n * @example\n * const viewportPoint = sendPointToPlane(\n * this.getScenePoint(e),\n * canvas.viewportTransform\n * );\n *\n */\n getScenePoint(e: TPointerEvent) {\n if (this._absolutePointer) {\n return this._absolutePointer;\n }\n return this.getPointer(e);\n }\n\n /**\n * Returns pointer relative to canvas.\n *\n * @deprecated This method is deprecated since v6 to protect you from misuse.\n * Use {@link getViewportPoint} or {@link getScenePoint} instead.\n *\n * @param {Event} e\n * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene\n * @return {Point}\n */\n getPointer(e: TPointerEvent, fromViewport = false): Point {\n const upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect();\n let pointer = getPointer(e),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0;\n\n if (!boundsWidth || !boundsHeight) {\n if (TOP in bounds && BOTTOM in bounds) {\n boundsHeight = Math.abs(bounds.top - bounds.bottom);\n }\n if (RIGHT in bounds && LEFT in bounds) {\n boundsWidth = Math.abs(bounds.right - bounds.left);\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!fromViewport) {\n pointer = sendPointToPlane(pointer, undefined, this.viewportTransform);\n }\n\n const retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n // If bounds are not available (i.e. not visible), do not apply scale.\n const cssScale =\n boundsWidth === 0 || boundsHeight === 0\n ? new Point(1, 1)\n : new Point(\n upperCanvasEl.width / boundsWidth,\n upperCanvasEl.height / boundsHeight,\n );\n\n return pointer.multiply(cssScale);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: TSize,\n options?: TCanvasSizeOptions,\n ) {\n // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract\n this._resetTransformEventData();\n super._setDimensionsImpl(dimensions, options);\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush &&\n this.freeDrawingBrush._setBrushStyles(this.contextTop);\n }\n }\n\n protected _createCacheCanvas() {\n this.pixelFindCanvasEl = createCanvasElement();\n this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', {\n willReadFrequently: true,\n })!;\n this.setTargetFindTolerance(this.targetFindTolerance);\n }\n\n /**\n * Returns context of top canvas where interactions are drawn\n * @returns {CanvasRenderingContext2D}\n */\n getTopContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns context of canvas where object selection is drawn\n * @alias\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement(): HTMLCanvasElement {\n return this.elements.upper.el;\n }\n\n /**\n * Returns currently active object\n * @return {FabricObject | null} active object\n */\n getActiveObject(): FabricObject | undefined {\n return this._activeObject;\n }\n\n /**\n * Returns an array with the current selected objects\n * @return {FabricObject[]} active objects array\n */\n getActiveObjects(): FabricObject[] {\n const active = this._activeObject;\n return isActiveSelection(active)\n ? active.getObjects()\n : active\n ? [active]\n : [];\n }\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {FabricObject[]} oldObjects old activeObject\n * @param {TPointerEvent} e mouse event triggering the selection events\n */\n _fireSelectionEvents(oldObjects: FabricObject[], e?: TPointerEvent) {\n let somethingChanged = false,\n invalidate = false;\n const objects = this.getActiveObjects(),\n added: FabricObject[] = [],\n removed: FabricObject[] = [];\n\n oldObjects.forEach((target) => {\n if (!objects.includes(target)) {\n somethingChanged = true;\n target.fire('deselected', {\n e,\n target,\n });\n removed.push(target);\n }\n });\n\n objects.forEach((target) => {\n if (!oldObjects.includes(target)) {\n somethingChanged = true;\n target.fire('selected', {\n e,\n target,\n });\n added.push(target);\n }\n });\n\n if (oldObjects.length > 0 && objects.length > 0) {\n invalidate = true;\n somethingChanged &&\n this.fire('selection:updated', {\n e,\n selected: added,\n deselected: removed,\n });\n } else if (objects.length > 0) {\n invalidate = true;\n this.fire('selection:created', {\n e,\n selected: added,\n });\n } else if (oldObjects.length > 0) {\n invalidate = true;\n this.fire('selection:cleared', {\n e,\n deselected: removed,\n });\n }\n invalidate && (this._objectsToRender = undefined);\n }\n\n /**\n * Sets given object as the only active object on canvas\n * @param {FabricObject} object Object to set as an active one\n * @param {TPointerEvent} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n setActiveObject(object: FabricObject, e?: TPointerEvent) {\n // we can't inline this, since _setActiveObject will change what getActiveObjects returns\n const currentActives = this.getActiveObjects();\n const selected = this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return selected;\n }\n\n /**\n * This is supposed to be equivalent to setActiveObject but without firing\n * any event. There is commitment to have this stay this way.\n * This is the functional part of setActiveObject.\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n _setActiveObject(object: FabricObject, e?: TPointerEvent) {\n const prevActiveObject = this._activeObject;\n if (prevActiveObject === object) {\n return false;\n }\n // after calling this._discardActiveObject, this,_activeObject could be undefined\n if (!this._discardActiveObject(e, object) && this._activeObject) {\n // refused to deselect\n return false;\n }\n if (object.onSelect({ e })) {\n return false;\n }\n\n this._activeObject = object;\n\n if (isActiveSelection(object) && prevActiveObject !== object) {\n object.set('canvas', this);\n }\n object.setCoords();\n\n return true;\n }\n\n /**\n * This is supposed to be equivalent to discardActiveObject but without firing\n * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way.\n * This is the functional part of discardActiveObject.\n * @param {Event} [e] Event (passed along when firing \"object:deselected\")\n * @param {Object} object the next object to set as active, reason why we are discarding this\n * @return {Boolean} true if the active object has been discarded\n */\n _discardActiveObject(\n e?: TPointerEvent,\n object?: FabricObject,\n ): this is { _activeObject: undefined } {\n const obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e, object })) {\n return false;\n }\n if (this._currentTransform && this._currentTransform.target === obj) {\n this.endCurrentTransform(e);\n }\n if (isActiveSelection(obj) && obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n }\n this._activeObject = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {Boolean} true if the active object has been discarded\n */\n discardActiveObject(e?: TPointerEvent): this is { _activeObject: undefined } {\n const currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n e,\n deselected: [activeObject!],\n });\n }\n const discarded = this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return discarded;\n }\n\n /**\n * End the current transform.\n * You don't usually need to call this method unless you are interrupting a user initiated transform\n * because of some other event ( a press of key combination, or something that block the user UX )\n * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event\n */\n endCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform;\n this._finalizeCurrentTransform(e);\n if (transform && transform.target) {\n // this could probably go inside _finalizeCurrentTransform\n transform.target.isMoving = false;\n }\n this._currentTransform = null;\n }\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform!,\n target = transform.target,\n options = {\n e,\n target,\n transform,\n action: transform.action,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed) {\n this.fire('object:modified', options);\n target.fire(MODIFIED, options);\n }\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n super.setViewportTransform(vpt);\n const activeObject = this._activeObject;\n if (activeObject) {\n activeObject.setCoords();\n }\n }\n\n /**\n * @override clears active selection ref and interactive canvas elements and contexts\n */\n destroy() {\n // dispose of active selection\n const activeObject = this._activeObject;\n if (isActiveSelection(activeObject)) {\n activeObject.removeAll();\n activeObject.dispose();\n }\n\n delete this._activeObject;\n\n super.destroy();\n\n // free resources\n\n // pixel find canvas\n // @ts-expect-error disposing\n this.pixelFindContext = null;\n // @ts-expect-error disposing\n this.pixelFindCanvasEl = undefined;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n // discard active object and fire events\n this.discardActiveObject();\n // make sure we clear the active object in case it refused to be discarded\n this._activeObject = undefined;\n this.clearContext(this.contextTop);\n super.clear();\n }\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls(ctx: CanvasRenderingContext2D) {\n const activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: 'toObject' | 'toDatalessObject',\n propertiesToInclude: string[],\n ): Record {\n // If the object is part of the current selection group, it should\n // be transformed appropriately\n // i.e. it should be serialised as it would appear if the selection group\n // were to be destroyed.\n const originalProperties = this._realizeGroupTransformOnObject(instance),\n object = super._toObject(instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n instance.set(originalProperties);\n return object;\n }\n\n /**\n * Realizes an object's group transformation on it\n * @private\n * @param {FabricObject} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n private _realizeGroupTransformOnObject(\n instance: FabricObject,\n ): Partial {\n const { group } = instance;\n if (group && isActiveSelection(group) && this._activeObject === group) {\n const layoutProps = [\n 'angle',\n 'flipX',\n 'flipY',\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n ] as (keyof typeof instance)[];\n const originalValues = pick(instance, layoutProps);\n addTransformToObject(instance, group.calcOwnMatrix());\n return originalValues;\n } else {\n return {};\n }\n }\n\n /**\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n // If the object is in a selection group, simulate what would happen to that\n // object when the group is deselected\n const originalProperties = this._realizeGroupTransformOnObject(instance);\n super._setSVGObject(markup, instance, reviver);\n instance.set(originalProperties);\n }\n}\n","import type { ModifierKey, TOptionalModifierKey } from '../EventTypeDefs';\nimport type { TOptions } from '../typedefs';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\n\nexport interface CanvasTransformOptions {\n /**\n * When true, objects can be transformed by one side (unproportionately)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: boolean;\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n uniScaleKey: TOptionalModifierKey;\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: boolean;\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: boolean;\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n centeredKey: TOptionalModifierKey;\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n altActionKey: TOptionalModifierKey;\n}\n\nexport interface CanvasSelectionOptions {\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: boolean;\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type ModifierKey|ModifierKey[]\n * @default\n */\n selectionKey: TOptionalModifierKey | ModifierKey[];\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|ModifierKey\n * @default\n */\n altSelectionKey: TOptionalModifierKey;\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: string;\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: number[];\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: string;\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: number;\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: boolean;\n}\n\nexport interface CanvasCursorOptions {\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n hoverCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n moveCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default default\n */\n defaultCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default crosshair\n */\n freeDrawingCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default not-allowed\n */\n notAllowedCursor: CSSStyleDeclaration['cursor'];\n}\n\nexport interface TargetFindOptions {\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: boolean;\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: number;\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: boolean;\n}\n\nexport interface CanvasEventsOptions {\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: boolean;\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: boolean;\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: boolean;\n\n /**\n * When the option is enabled, PointerEvent is used instead of TPointerEvent.\n * @type Boolean\n * @default\n */\n enablePointerEvents: boolean;\n}\n\nexport interface CanvasOptions\n extends StaticCanvasOptions,\n CanvasTransformOptions,\n CanvasSelectionOptions,\n CanvasCursorOptions,\n TargetFindOptions,\n CanvasEventsOptions {\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n * @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly\n */\n containerClass: string;\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: boolean;\n}\n\nexport type TCanvasOptions = TOptions;\n\nexport const canvasDefaults: TOptions = {\n uniformScaling: true,\n uniScaleKey: 'shiftKey',\n centeredScaling: false,\n centeredRotation: false,\n centeredKey: 'altKey',\n altActionKey: 'shiftKey',\n\n selection: true,\n selectionKey: 'shiftKey',\n selectionColor: 'rgba(100, 100, 255, 0.3)',\n selectionDashArray: [],\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n selectionLineWidth: 1,\n selectionFullyContained: false,\n\n hoverCursor: 'move',\n moveCursor: 'move',\n defaultCursor: 'default',\n freeDrawingCursor: 'crosshair',\n notAllowedCursor: 'not-allowed',\n\n perPixelTargetFind: false,\n targetFindTolerance: 0,\n skipTargetFind: false,\n\n stopContextMenu: false,\n fireRightClick: false,\n fireMiddleClick: false,\n enablePointerEvents: false,\n\n containerClass: 'canvas-container',\n\n preserveObjectStacking: false,\n};\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport type { ITextBehavior } from '../shapes/IText/ITextBehavior';\nimport { removeFromArray } from '../util/internals/removeFromArray';\nimport type { Canvas } from './Canvas';\n\n/**\n * In charge of synchronizing all interactive text instances of a canvas\n */\nexport class TextEditingManager {\n private targets: ITextBehavior[] = [];\n private declare target?: ITextBehavior;\n private __disposer: VoidFunction;\n\n constructor(canvas: Canvas) {\n const cb = () => {\n const { hiddenTextarea } =\n (canvas.getActiveObject() as ITextBehavior) || {};\n hiddenTextarea && hiddenTextarea.focus();\n };\n const el = canvas.upperCanvasEl;\n el.addEventListener('click', cb);\n this.__disposer = () => el.removeEventListener('click', cb);\n }\n\n exitTextEditing() {\n this.target = undefined;\n this.targets.forEach((target) => {\n if (target.isEditing) {\n target.exitEditing();\n }\n });\n }\n\n add(target: ITextBehavior) {\n this.targets.push(target);\n }\n\n remove(target: ITextBehavior) {\n this.unregister(target);\n removeFromArray(this.targets, target);\n }\n\n register(target: ITextBehavior) {\n this.target = target;\n }\n\n unregister(target: ITextBehavior) {\n if (target === this.target) {\n this.target = undefined;\n }\n }\n\n onMouseMove(e: TPointerEvent) {\n this.target?.isEditing && this.target.updateSelectionOnMouseMove(e);\n }\n\n clear() {\n this.targets = [];\n this.target = undefined;\n }\n\n dispose() {\n this.clear();\n this.__disposer();\n // @ts-expect-error disposing\n delete this.__disposer;\n }\n}\n","import { classRegistry } from '../ClassRegistry';\nimport { NONE } from '../constants';\nimport type {\n CanvasEvents,\n DragEventData,\n ObjectEvents,\n TPointerEvent,\n TPointerEventNames,\n Transform,\n} from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\nimport type { Group } from '../shapes/Group';\nimport type { IText } from '../shapes/IText/IText';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { isTouchEvent, stopEvent } from '../util/dom_event';\nimport { getDocumentFromElement, getWindowFromElement } from '../util/dom_misc';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { isActiveSelection } from '../util/typeAssertions';\nimport type { CanvasOptions, TCanvasOptions } from './CanvasOptions';\nimport { SelectableCanvas } from './SelectableCanvas';\nimport { TextEditingManager } from './TextEditingManager';\n\nconst addEventOptions = { passive: false } as EventListenerOptions;\n\nconst getEventPoints = (canvas: Canvas, e: TPointerEvent) => {\n const viewportPoint = canvas.getViewportPoint(e);\n const scenePoint = canvas.getScenePoint(e);\n return {\n viewportPoint,\n scenePoint,\n pointer: viewportPoint,\n absolutePointer: scenePoint,\n };\n};\n\n// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers\n// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.\n// few bytes but why give it away.\nconst addListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.addEventListener(...args);\nconst removeListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.removeEventListener(...args);\n\nconst syntheticEventConfig = {\n mouse: {\n in: 'over',\n out: 'out',\n targetIn: 'mouseover',\n targetOut: 'mouseout',\n canvasIn: 'mouse:over',\n canvasOut: 'mouse:out',\n },\n drag: {\n in: 'enter',\n out: 'leave',\n targetIn: 'dragenter',\n targetOut: 'dragleave',\n canvasIn: 'drag:enter',\n canvasOut: 'drag:leave',\n },\n} as const;\n\ntype TSyntheticEventContext = {\n mouse: { e: TPointerEvent };\n drag: DragEventData;\n};\n\nexport class Canvas extends SelectableCanvas implements CanvasOptions {\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n declare mainTouchId?: number;\n\n declare enablePointerEvents: boolean;\n\n /**\n * Holds a reference to a setTimeout timer for event synchronization\n * @type number\n * @private\n */\n private declare _willAddMouseDown: number;\n\n /**\n * Holds a reference to an object on the canvas that is receiving the drag over event.\n * @type FabricObject\n * @private\n */\n private declare _draggedoverTarget?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas from where the drag operation started\n * @type FabricObject\n * @private\n */\n private declare _dragSource?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas that is the current drop target\n * May differ from {@link _draggedoverTarget}\n * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow\n * @type FabricObject\n * @private\n */\n private declare _dropTarget: FabricObject | undefined;\n\n private _isClick: boolean;\n\n textEditingManager = new TextEditingManager(this);\n\n constructor(el?: string | HTMLCanvasElement, options: TCanvasOptions = {}) {\n super(el, options);\n // bind event handlers\n (\n [\n '_onMouseDown',\n '_onTouchStart',\n '_onMouseMove',\n '_onMouseUp',\n '_onTouchEnd',\n '_onResize',\n // '_onGesture',\n // '_onDrag',\n // '_onShake',\n // '_onLongPress',\n // '_onOrientationChange',\n '_onMouseWheel',\n '_onMouseOut',\n '_onMouseEnter',\n '_onContextMenu',\n '_onDoubleClick',\n '_onDragStart',\n '_onDragEnd',\n '_onDragProgress',\n '_onDragOver',\n '_onDragEnter',\n '_onDragLeave',\n '_onDrop',\n ] as (keyof this)[]\n ).forEach((eventHandler) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n this[eventHandler] = (this[eventHandler] as Function).bind(this);\n });\n // register event handlers\n this.addOrRemove(addListener, 'add');\n }\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n private _getEventPrefix() {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n }\n\n addOrRemove(functor: any, _eventjsFunctor: 'add' | 'remove') {\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(getWindowFromElement(canvasElement), 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove,\n addEventOptions,\n );\n functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);\n functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragstart', this._onDragStart);\n functor(canvasElement, 'dragend', this._onDragEnd);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n // eventjs[eventjsFunctor](\n // canvasElement,\n // 'orientation',\n // this._onOrientationChange\n // );\n // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n // }\n }\n\n /**\n * Removes all event listeners\n */\n removeListeners() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n private _onMouseWheel(e: MouseEvent) {\n this.__onMouseWheel(e);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onMouseOut(e: TPointerEvent) {\n const target = this._hoveredTarget;\n const shared = {\n e,\n ...getEventPoints(this, e),\n };\n this.fire('mouse:out', { ...shared, target });\n this._hoveredTarget = undefined;\n target && target.fire('mouseout', { ...shared });\n this._hoveredTargets.forEach((nestedTarget) => {\n this.fire('mouse:out', { ...shared, target: nestedTarget });\n nestedTarget && nestedTarget.fire('mouseout', { ...shared });\n });\n this._hoveredTargets = [];\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n private _onMouseEnter(e: TPointerEvent) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', {\n e,\n ...getEventPoints(this, e),\n });\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n }\n\n /**\n * supports native like text dragging\n * @private\n * @param {DragEvent} e\n */\n private _onDragStart(e: DragEvent) {\n this._isClick = false;\n const activeObject = this.getActiveObject();\n if (activeObject && activeObject.onDragStart(e)) {\n this._dragSource = activeObject;\n const options = { e, target: activeObject };\n this.fire('dragstart', options);\n activeObject.fire('dragstart', options);\n addListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n return;\n }\n stopEvent(e);\n }\n\n /**\n * First we clear top context where the effects are being rendered.\n * Then we render the effects.\n * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.\n * @private\n */\n private _renderDragEffects(\n e: DragEvent,\n source?: FabricObject,\n target?: FabricObject,\n ) {\n let dirty = false;\n // clear top context\n const dropTarget = this._dropTarget;\n if (dropTarget && dropTarget !== source && dropTarget !== target) {\n dropTarget.clearContextTop();\n dirty = true;\n }\n source?.clearContextTop();\n target !== source && target?.clearContextTop();\n // render effects\n const ctx = this.contextTop;\n ctx.save();\n ctx.transform(...this.viewportTransform);\n if (source) {\n ctx.save();\n source.transform(ctx);\n source.renderDragSourceEffect(e);\n ctx.restore();\n dirty = true;\n }\n if (target) {\n ctx.save();\n target.transform(ctx);\n target.renderDropTargetEffect(e);\n ctx.restore();\n dirty = true;\n }\n ctx.restore();\n dirty && (this.contextTopDirty = true);\n }\n\n /**\n * supports native like text dragging\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n * @private\n * @param {DragEvent} e\n */\n private _onDragEnd(e: DragEvent) {\n const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE,\n dropTarget = didDrop ? this._activeObject : undefined,\n options = {\n e,\n target: this._dragSource as FabricObject,\n subTargets: this.targets,\n dragSource: this._dragSource as FabricObject,\n didDrop,\n dropTarget: dropTarget as FabricObject,\n };\n removeListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n this.fire('dragend', options);\n this._dragSource && this._dragSource.fire('dragend', options);\n delete this._dragSource;\n // we need to call mouse up synthetically because the browser won't\n this._onMouseUp(e);\n }\n\n /**\n * fire `drag` event on canvas and drag source\n * @private\n * @param {DragEvent} e\n */\n private _onDragProgress(e: DragEvent) {\n const options = {\n e,\n target: this._dragSource as FabricObject | undefined,\n dragSource: this._dragSource as FabricObject | undefined,\n dropTarget: this._draggedoverTarget as FabricObject,\n };\n this.fire('drag', options);\n this._dragSource && this._dragSource.fire('drag', options);\n }\n\n /**\n * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.\n * Override at will\n */\n protected findDragTargets(e: DragEvent) {\n this.targets = [];\n const target = this._searchPossibleTargets(\n this._objects,\n this.getViewportPoint(e),\n );\n return {\n target,\n targets: [...this.targets],\n };\n }\n\n /**\n * prevent default to allow drop event to be fired\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets\n * @private\n * @param {DragEvent} [e] Event object fired on Event.js shake\n */\n private _onDragOver(e: DragEvent) {\n const eventType = 'dragover';\n const { target, targets } = this.findDragTargets(e);\n const dragSource = this._dragSource as FabricObject;\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource,\n canDrop: false,\n dropTarget: undefined,\n };\n let dropTarget;\n // fire on canvas\n this.fire(eventType, options);\n // make sure we fire dragenter events before dragover\n // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it\n this._fireEnterLeaveEvents(target, options);\n if (target) {\n if (target.canDrop(e)) {\n dropTarget = target;\n }\n target.fire(eventType, options);\n }\n // propagate the event to subtargets\n for (let i = 0; i < targets.length; i++) {\n const subTarget = targets[i];\n // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)\n // TODO: verify if those should loop in inverse order then?\n // what is the order of subtargets?\n if (subTarget.canDrop(e)) {\n dropTarget = subTarget;\n }\n subTarget.fire(eventType, options);\n }\n // render drag effects now that relations between source and target is clear\n this._renderDragEffects(e, dragSource, dropTarget);\n this._dropTarget = dropTarget;\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragEnter(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n };\n this.fire('dragenter', options);\n // fire dragenter on targets\n this._fireEnterLeaveEvents(target, options);\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragLeave(e: DragEvent) {\n const options = {\n e,\n target: this._draggedoverTarget,\n subTargets: this.targets,\n dragSource: this._dragSource,\n };\n this.fire('dragleave', options);\n\n // fire dragleave on targets\n this._fireEnterLeaveEvents(undefined, options);\n this._renderDragEffects(e, this._dragSource);\n this._dropTarget = undefined;\n // clear targets\n this.targets = [];\n this._hoveredTargets = [];\n }\n\n /**\n * `drop:before` is a an event that allows you to schedule logic\n * before the `drop` event. Prefer `drop` event always, but if you need\n * to run some drop-disabling logic on an event, since there is no way\n * to handle event handlers ordering, use `drop:before`\n * @private\n * @param {Event} e\n */\n private _onDrop(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = this._basicEventHandler('drop:before', {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n ...getEventPoints(this, e),\n });\n // will be set by the drop target\n options.didDrop = false;\n // will be set by the drop target, used in case options.target refuses the drop\n options.dropTarget = undefined;\n // fire `drop`\n this._basicEventHandler('drop', options);\n // inform canvas of the drop\n // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it\n // use for side effects\n this.fire('drop:after', options);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onContextMenu(e: TPointerEvent): false {\n const target = this.findTarget(e),\n subTargets = this.targets || [];\n const options = this._basicEventHandler('contextmenu:before', {\n e,\n target,\n subTargets,\n });\n // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves\n this.stopContextMenu && stopEvent(e);\n this._basicEventHandler('contextmenu', options);\n return false;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onDoubleClick(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData();\n }\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId(evt: TouchEvent | PointerEvent): number {\n const changedTouches = (evt as TouchEvent).changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return (evt as PointerEvent).pointerId;\n }\n\n return -1;\n }\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent(evt: TPointerEvent): boolean {\n if ((evt as PointerEvent).isPrimary === true) {\n return true;\n }\n if ((evt as PointerEvent).isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {\n return true;\n }\n if ((evt as TouchEvent).changedTouches) {\n return (\n (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId\n );\n }\n return true;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart(e: TouchEvent) {\n e.preventDefault();\n if (this.mainTouchId === undefined) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(canvasElement);\n addListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n addListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(\n canvasElement,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown(e: TPointerEvent) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n const doc = getDocumentFromElement(canvasElement);\n addListener(doc, `${eventTypePrefix}up`, this._onMouseUp as EventListener);\n addListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd(e: TouchEvent) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n delete this.mainTouchId;\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(() => {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(\n this.upperCanvasEl,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n this._willAddMouseDown = 0;\n }, 400) as unknown as number;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp(e: TPointerEvent) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n addListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove(e: TPointerEvent) {\n const activeObject = this.getActiveObject();\n !this.allowTouchScrolling &&\n (!activeObject ||\n // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before\n // we must not prevent the event's default behavior in order for the window to start dragging\n !activeObject.shouldStartDragging(e)) &&\n e.preventDefault &&\n e.preventDefault();\n this.__onMouseMove(e);\n }\n\n /**\n * @private\n */\n _onResize() {\n this.calcOffset();\n this._resetTransformEventData();\n }\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender(target: FabricObject | undefined) {\n const activeObject = this.getActiveObject();\n // if just one of them is available or if they are both but are different objects\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return (\n !!activeObject !== !!target ||\n (activeObject && target && activeObject !== target)\n );\n }\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'up:before');\n\n const transform = this._currentTransform;\n const isClick = this._isClick;\n const target = this._target;\n\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'up');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n let shouldRender = false;\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n if (!isClick) {\n const targetWasActive = target === this._activeObject;\n this.handleSelection(e);\n if (!shouldRender) {\n shouldRender =\n this._shouldRender(target) ||\n (!targetWasActive && target === this._activeObject);\n }\n }\n let pointer, corner;\n if (target) {\n const found = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n const { key, control } = found || {};\n corner = key;\n if (\n target.selectable &&\n target !== this._activeObject &&\n target.activeOn === 'up'\n ) {\n this.setActiveObject(target, e);\n shouldRender = true;\n } else if (control) {\n const mouseUpHandler = control.getMouseUpHandler(e, target, control);\n if (mouseUpHandler) {\n pointer = this.getScenePoint(e);\n mouseUpHandler.call(control, e, transform!, pointer.x, pointer.y);\n }\n }\n target.isMoving = false;\n }\n // if we are ending up a transform on a different control or a new object\n // fire the original mouse up from the corner that started the transform\n if (\n transform &&\n (transform.target !== target || transform.corner !== corner)\n ) {\n const originalControl =\n transform.target && transform.target.controls[transform.corner],\n originalMouseUpHandler =\n originalControl &&\n originalControl.getMouseUpHandler(\n e,\n transform.target,\n originalControl,\n );\n pointer = pointer || this.getScenePoint(e);\n originalMouseUpHandler &&\n originalMouseUpHandler.call(\n originalControl,\n e,\n transform,\n pointer.x,\n pointer.y,\n );\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up');\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = undefined);\n if (shouldRender) {\n this.requestRenderAll();\n } else if (!isClick && !(this._activeObject as IText)?.isEditing) {\n this.renderTop();\n }\n }\n\n _basicEventHandler(\n eventType: T,\n options: (CanvasEvents & ObjectEvents)[T],\n ) {\n const { target, subTargets = [] } = options as {\n target?: FabricObject;\n subTargets: FabricObject[];\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n for (let i = 0; i < subTargets.length; i++) {\n subTargets[i] !== target && subTargets[i].fire(eventType, options);\n }\n return options;\n }\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {TPointerEvent} e event from mouse\n * @param {TPointerEventNames} eventType\n */\n _handleEvent(e: TPointerEvent, eventType: T) {\n const target = this._target,\n targets = this.targets || [],\n options: CanvasEvents[`mouse:${T}`] = {\n e,\n target,\n subTargets: targets,\n ...getEventPoints(this, e),\n transform: this._currentTransform,\n ...(eventType === 'up:before' || eventType === 'up'\n ? {\n isClick: this._isClick,\n currentTarget: this.findTarget(e),\n // set by the preceding `findTarget` call\n currentSubTargets: this.targets,\n }\n : {}),\n } as CanvasEvents[`mouse:${T}`];\n this.fire(`mouse:${eventType}`, options);\n // this may be a little be more complicated of what we want to handle\n target && target.fire(`mouse${eventType}`, options);\n for (let i = 0; i < targets.length; i++) {\n targets[i] !== target && targets[i].fire(`mouse${eventType}`, options);\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode(e: TPointerEvent) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e);\n this.requestRenderAll();\n }\n // TODO: this is a scene point so it should be renamed\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });\n this._handleEvent(e, 'down');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode(e: TPointerEvent) {\n if (this._isCurrentlyDrawing) {\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseMove(pointer, {\n e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode(e: TPointerEvent) {\n const pointer = this.getScenePoint(e);\n if (this.freeDrawingBrush) {\n this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({\n e: e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n } else {\n this._isCurrentlyDrawing = false;\n }\n this._handleEvent(e, 'up');\n }\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown(e: TPointerEvent) {\n this._isClick = true;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n\n let target: FabricObject | undefined = this._target;\n\n // if right/middle click just fire events\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'down');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n let shouldRender = this._shouldRender(target);\n let grouped = false;\n if (this.handleMultiSelection(e, target)) {\n // active object might have changed while grouping\n target = this._activeObject;\n grouped = true;\n shouldRender = true;\n } else if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n // we start a group selector rectangle if\n // selection is enabled\n // and there is no target, or the following 3 conditions are satisfied:\n // target is not selectable ( otherwise we selected it )\n // target is not editing\n // target is not already selected ( otherwise we drag )\n if (\n this.selection &&\n (!target ||\n (!target.selectable &&\n !(target as IText).isEditing &&\n target !== this._activeObject))\n ) {\n const p = this.getScenePoint(e);\n this._groupSelector = {\n x: p.x,\n y: p.y,\n deltaY: 0,\n deltaX: 0,\n };\n }\n\n if (target) {\n const alreadySelected = target === this._activeObject;\n if (target.selectable && target.activeOn === 'down') {\n this.setActiveObject(target, e);\n }\n const handle = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n if (target === this._activeObject && (handle || !grouped)) {\n this._setupCurrentTransform(e, target, alreadySelected);\n const control = handle ? handle.control : undefined,\n pointer = this.getScenePoint(e),\n mouseDownHandler =\n control && control.getMouseDownHandler(e, target, control);\n mouseDownHandler &&\n mouseDownHandler.call(\n control,\n e,\n this._currentTransform!,\n pointer.x,\n pointer.y,\n );\n }\n }\n // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering\n // run before firing the `down` event to give the dev a chance to populate it themselves\n shouldRender && (this._objectsToRender = undefined);\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n shouldRender && this.requestRenderAll();\n }\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData() {\n this._target = undefined;\n this._pointer = undefined;\n this._absolutePointer = undefined;\n }\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData(e: TPointerEvent) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getViewportPoint(e);\n this._absolutePointer = sendPointToPlane(\n this._pointer,\n undefined,\n this.viewportTransform,\n );\n this._target = this._currentTransform\n ? this._currentTransform.target\n : this.findTarget(e);\n }\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove(e: TPointerEvent) {\n this._isClick = false;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'move:before');\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n const groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n const pointer = this.getScenePoint(e);\n\n groupSelector.deltaX = pointer.x - groupSelector.x;\n groupSelector.deltaY = pointer.y - groupSelector.y;\n\n this.renderTop();\n } else if (!this._currentTransform) {\n const target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(e, target);\n } else {\n this._transformObject(e);\n }\n this.textEditingManager.onMouseMove(e);\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n }\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {\n const _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target,\n oldTarget: _hoveredTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n }\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Object} data Event object fired on dragover\n * @private\n */\n _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {\n const draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target,\n oldTarget: draggedoverTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._draggedoverTarget = target;\n }\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Object} data Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents(\n type: T,\n {\n target,\n oldTarget,\n fireCanvas,\n e,\n ...data\n }: TSyntheticEventContext[T] & {\n target?: FabricObject;\n oldTarget?: FabricObject;\n fireCanvas?: boolean;\n },\n ) {\n const { targetIn, targetOut, canvasIn, canvasOut } =\n syntheticEventConfig[type];\n const targetChanged = oldTarget !== target;\n\n if (oldTarget && targetChanged) {\n const outOpt: CanvasEvents[typeof canvasOut] = {\n ...data,\n e,\n target: oldTarget,\n nextTarget: target,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasOut, outOpt);\n oldTarget.fire(targetOut, outOpt);\n }\n if (target && targetChanged) {\n const inOpt: CanvasEvents[typeof canvasIn] = {\n ...data,\n e,\n target,\n previousTarget: oldTarget,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasIn, inOpt);\n target.fire(targetIn, inOpt);\n }\n }\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n }\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject(e: TPointerEvent) {\n const scenePoint = this.getScenePoint(e),\n transform = this._currentTransform!,\n target = transform.target,\n // transform pointer to target's containing coordinate plane\n // both pointer and object should agree on every point\n localPointer = target.group\n ? sendPointToPlane(\n scenePoint,\n undefined,\n target.group.calcTransformMatrix(),\n )\n : scenePoint;\n transform.shiftKey = e.shiftKey;\n transform.altKey = !!this.centeredKey && e[this.centeredKey];\n\n this._performTransformAction(e, transform, localPointer);\n transform.actionPerformed && this.requestRenderAll();\n }\n\n /**\n * @private\n */\n _performTransformAction(\n e: TPointerEvent,\n transform: Transform,\n pointer: Point,\n ) {\n const { action, actionHandler, target } = transform;\n\n const actionPerformed =\n !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y);\n actionPerformed && target.setCoords();\n\n // this object could be created from the function in the control handlers\n if (action === 'drag' && actionPerformed) {\n transform.target.isMoving = true;\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n }\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return;\n }\n let hoverCursor = target.hoverCursor || this.hoverCursor;\n const activeSelection = isActiveSelection(this._activeObject)\n ? this._activeObject\n : null,\n // only show proper corner when group selection is not active\n corner =\n (!activeSelection || target.group !== activeSelection) &&\n // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target.findControl(this.getViewportPoint(e));\n\n if (!corner) {\n if ((target as Group).subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets\n .concat()\n .reverse()\n .map((_target) => {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n } else {\n const control = corner.control;\n this.setCursor(control.cursorStyleHandler(e, control, target));\n }\n }\n\n /**\n * ## Handles multiple selection\n * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)\n * - sets the active object in case it is not set or in case there is a single active object left under active selection.\n * ---\n * - If the active object is the active selection we add/remove `target` from it\n * - If not, add the active object and `target` to the active selection and make it the active object.\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target target of event to select/deselect\n * @returns true if grouping occurred\n */\n protected handleMultiSelection(e: TPointerEvent, target?: FabricObject) {\n const activeObject = this._activeObject;\n const isAS = isActiveSelection(activeObject);\n if (\n // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.\n !!activeObject &&\n this._isSelectionKeyPressed(e) &&\n this.selection &&\n // on top of that the user also has to hit a target that is selectable.\n !!target &&\n target.selectable &&\n // group target and active object only if they are different objects\n // else we try to find a subtarget of `ActiveSelection`\n (activeObject !== target || isAS) &&\n // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`\n // if it is then we want to remove `target` from it\n (isAS ||\n (!target.isDescendantOf(activeObject) &&\n !activeObject.isDescendantOf(target))) &&\n // target accepts selection\n !target.onSelect({ e }) &&\n // make sure we are not on top of a control\n !activeObject.getActiveControl()\n ) {\n if (isAS) {\n const prevActiveObjects = activeObject.getObjects();\n if (target === activeObject) {\n const pointer = this.getViewportPoint(e);\n target =\n // first search active objects for a target to remove\n this.searchPossibleTargets(prevActiveObjects, pointer) ||\n // if not found, search under active selection for a target to add\n // `prevActiveObjects` will be searched but we already know they will not be found\n this.searchPossibleTargets(this._objects, pointer);\n // if nothing is found bail out\n if (!target || !target.selectable) {\n return false;\n }\n }\n if (target.group === activeObject) {\n // `target` is part of active selection => remove it\n activeObject.remove(target);\n this._hoveredTarget = target;\n this._hoveredTargets = [...this.targets];\n // if after removing an object we are left with one only...\n if (activeObject.size() === 1) {\n // activate last remaining object\n // deselecting the active selection will remove the remaining object from it\n this._setActiveObject(activeObject.item(0), e);\n }\n } else {\n // `target` isn't part of active selection => add it\n activeObject.multiSelectAdd(target);\n this._hoveredTarget = activeObject;\n this._hoveredTargets = [...this.targets];\n }\n this._fireSelectionEvents(prevActiveObjects, e);\n } else {\n (activeObject as IText).exitEditing &&\n (activeObject as IText).exitEditing();\n // add the active object and the target to the active selection and set it as the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n const newActiveSelection = new klass([], {\n /**\n * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd}\n * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref\n */\n canvas: this,\n });\n newActiveSelection.multiSelectAdd(activeObject, target);\n this._hoveredTarget = newActiveSelection;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(newActiveSelection, e);\n this._fireSelectionEvents([activeObject], e);\n }\n return true;\n }\n return false;\n }\n\n /**\n * ## Handles selection\n * - selects objects that are contained in (and possibly intersecting) the selection bounding box\n * - sets the active object\n * ---\n * runs on mouse up after a mouse move\n */\n protected handleSelection(e: TPointerEvent) {\n if (!this.selection || !this._groupSelector) {\n return false;\n }\n const { x, y, deltaX, deltaY } = this._groupSelector,\n point1 = new Point(x, y),\n point2 = point1.add(new Point(deltaX, deltaY)),\n tl = point1.min(point2),\n br = point1.max(point2),\n size = br.subtract(tl);\n\n const collectedObjects = this.collectObjects(\n {\n left: tl.x,\n top: tl.y,\n width: size.x,\n height: size.y,\n },\n { includeIntersecting: !this.selectionFullyContained },\n ) as FabricObject[];\n\n const objects =\n // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down\n // should it be handled as is?\n point1.eq(point2)\n ? collectedObjects[0]\n ? [collectedObjects[0]]\n : []\n : collectedObjects.length > 1\n ? collectedObjects\n .filter((object) => !object.onSelect({ e }))\n .reverse()\n : // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case\n collectedObjects;\n\n // set active object\n if (objects.length === 1) {\n // set as active object\n this.setActiveObject(objects[0], e);\n } else if (objects.length > 1) {\n // add to active selection and make it the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n this.setActiveObject(new klass(objects, { canvas: this }), e);\n }\n\n // cleanup\n this._groupSelector = null;\n return true;\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n clear() {\n this.textEditingManager.clear();\n super.clear();\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n destroy() {\n this.removeListeners();\n this.textEditingManager.dispose();\n super.destroy();\n }\n}\n","export const linearDefaultCoords = {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n};\n\nexport const radialDefaultCoords = {\n ...linearDefaultCoords,\n r1: 0,\n r2: 0,\n};\n","/**\n *\n * @param value value to check if NaN\n * @param [valueIfNaN]\n * @returns `fallback` is `value is NaN\n */\nexport const ifNaN = (value: number, valueIfNaN?: number) => {\n return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value;\n};\n","import { ifNaN } from '../util/internals/ifNaN';\nimport { capValue } from '../util/misc/capValue';\n\nconst RE_PERCENT = /^(\\d+\\.\\d+)%|(\\d+)%$/;\n\nexport function isPercent(value: string | null) {\n return value && RE_PERCENT.test(value);\n}\n\n/**\n *\n * @param value\n * @param valueIfNaN\n * @returns ∈ [0, 1]\n */\nexport function parsePercent(\n value: string | number | null | undefined,\n valueIfNaN?: number,\n) {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string'\n ? parseFloat(value) / (isPercent(value) ? 100 : 1)\n : NaN;\n return capValue(0, ifNaN(parsed, valueIfNaN), 1);\n}\n","import { Color } from '../../color/Color';\nimport { parsePercent } from '../../parser/percent';\nimport { ifNaN } from '../../util/internals/ifNaN';\nimport type { ColorStop } from '../typedefs';\n\nconst RE_KEY_VALUE_PAIRS = /\\s*;\\s*/;\nconst RE_KEY_VALUE = /\\s*:\\s*/;\n\nfunction parseColorStop(el: SVGStopElement, multiplier: number) {\n let colorValue, opacity;\n const style = el.getAttribute('style');\n if (style) {\n const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (let i = keyValuePairs.length; i--; ) {\n const [key, value] = keyValuePairs[i]\n .split(RE_KEY_VALUE)\n .map((s) => s.trim());\n if (key === 'stop-color') {\n colorValue = value;\n } else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n const color = new Color(\n colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)',\n );\n\n return {\n offset: parsePercent(el.getAttribute('offset'), 0),\n color: color.toRgb(),\n opacity:\n ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) *\n color.getAlpha() *\n multiplier,\n };\n}\n\nexport function parseColorStops(\n el: SVGGradientElement,\n opacityAttr: string | null,\n) {\n const colorStops: ColorStop[] = [],\n colorStopEls = el.getElementsByTagName('stop'),\n multiplier = parsePercent(opacityAttr, 1);\n for (let i = colorStopEls.length; i--; ) {\n colorStops.push(parseColorStop(colorStopEls[i], multiplier));\n }\n return colorStops;\n}\n","import type { GradientType, GradientUnits } from '../typedefs';\n\nexport function parseType(el: SVGGradientElement): GradientType {\n return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT'\n ? 'linear'\n : 'radial';\n}\n\nexport function parseGradientUnits(el: SVGGradientElement): GradientUnits {\n return el.getAttribute('gradientUnits') === 'userSpaceOnUse'\n ? 'pixels'\n : 'percentage';\n}\n","import { isPercent } from '../../parser/percent';\nimport type { TSize } from '../../typedefs';\nimport type { GradientCoords, GradientType, GradientUnits } from '../typedefs';\nimport { parseGradientUnits, parseType } from './misc';\n\nfunction convertPercentUnitsToValues<\n T extends GradientType,\n K extends keyof GradientCoords,\n>(\n valuesToConvert: Record,\n { width, height, gradientUnits }: TSize & { gradientUnits: GradientUnits },\n) {\n let finalValue;\n return (Object.keys(valuesToConvert) as K[]).reduce(\n (acc, prop) => {\n const propValue = valuesToConvert[prop];\n if (propValue === 'Infinity') {\n finalValue = 1;\n } else if (propValue === '-Infinity') {\n finalValue = 0;\n } else {\n finalValue =\n typeof propValue === 'string' ? parseFloat(propValue) : propValue;\n if (typeof propValue === 'string' && isPercent(propValue)) {\n finalValue *= 0.01;\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= width;\n }\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= height;\n }\n }\n }\n }\n acc[prop] = finalValue;\n return acc;\n },\n {} as Record,\n );\n}\n\nfunction getValue(el: SVGGradientElement, key: string) {\n return el.getAttribute(key);\n}\n\nexport function parseLinearCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'x1') || 0,\n y1: getValue(el, 'y1') || 0,\n x2: getValue(el, 'x2') || '100%',\n y2: getValue(el, 'y2') || 0,\n };\n}\n\nexport function parseRadialCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%',\n y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%',\n r1: 0,\n x2: getValue(el, 'cx') || '50%',\n y2: getValue(el, 'cy') || '50%',\n r2: getValue(el, 'r') || '50%',\n };\n}\n\nexport function parseCoords(el: SVGGradientElement, size: TSize) {\n return convertPercentUnitsToValues(\n parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el),\n {\n ...size,\n gradientUnits: parseGradientUnits(el),\n },\n );\n}\n","import { Color } from '../color/Color';\nimport { iMatrix } from '../constants';\nimport { parseTransformAttribute } from '../parser/parseTransformAttribute';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { linearDefaultCoords, radialDefaultCoords } from './constants';\nimport { parseColorStops } from './parser/parseColorStops';\nimport { parseCoords } from './parser/parseCoords';\nimport { parseType, parseGradientUnits } from './parser/misc';\nimport type {\n ColorStop,\n GradientCoords,\n GradientOptions,\n GradientType,\n GradientUnits,\n SVGOptions,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { isPath } from '../util/typeAssertions';\n\n/**\n * Gradient class\n * @class Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n */\nexport class Gradient<\n S,\n T extends GradientType = S extends GradientType ? S : 'linear',\n> {\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetX: number;\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetY: number;\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n declare gradientTransform?: TMat2D;\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type GradientUnits\n * @default 'pixels'\n */\n declare gradientUnits: GradientUnits;\n\n /**\n * Gradient type linear or radial\n * @type GradientType\n * @default 'linear'\n */\n declare type: T;\n\n /**\n * Defines how the gradient is located in space and spread\n * @type GradientCoords\n */\n declare coords: GradientCoords;\n\n /**\n * Defines how many colors a gradient has and how they are located on the axis\n * defined by coords\n * @type GradientCoords\n */\n declare colorStops: ColorStop[];\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number | string\n */\n declare readonly id: string | number;\n\n static type = 'Gradient';\n\n constructor(options: GradientOptions) {\n const {\n type = 'linear' as T,\n gradientUnits = 'pixels',\n coords = {},\n colorStops = [],\n offsetX = 0,\n offsetY = 0,\n gradientTransform,\n id,\n } = options || {};\n Object.assign(this, {\n type,\n gradientUnits,\n coords: {\n ...(type === 'radial' ? radialDefaultCoords : linearDefaultCoords),\n ...coords,\n },\n colorStops,\n offsetX,\n offsetY,\n gradientTransform,\n id: id ? `${id}_${uid()}` : uid(),\n });\n }\n\n /**\n * Adds another colorStop\n * @param {Record} colorStop Object with offset and color\n * @return {Gradient} thisArg\n */\n addColorStop(colorStops: Record) {\n for (const position in colorStops) {\n const color = new Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha(),\n });\n }\n return this;\n }\n\n /**\n * Returns object representation of a gradient\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object}\n */\n toObject(propertiesToInclude?: (keyof this | string)[]) {\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: this.type,\n coords: { ...this.coords },\n colorStops: this.colorStops.map((colorStop) => ({ ...colorStop })),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform\n ? [...this.gradientTransform]\n : undefined,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {FabricObject} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG(\n object: FabricObject,\n {\n additionalTransform: preTransform,\n }: { additionalTransform?: string } = {},\n ) {\n const markup = [],\n transform = (\n this.gradientTransform\n ? this.gradientTransform.concat()\n : iMatrix.concat()\n ) as TMat2D,\n gradientUnits =\n this.gradientUnits === 'pixels'\n ? 'userSpaceOnUse'\n : 'objectBoundingBox';\n // colorStops must be sorted ascending, and guarded against deep mutations\n const colorStops = this.colorStops\n .map((colorStop) => ({ ...colorStop }))\n .sort((a, b) => {\n return a.offset - b.offset;\n });\n\n let offsetX = -this.offsetX,\n offsetY = -this.offsetY;\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n } else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n // todo what about polygon/polyline?\n if (isPath(object) && this.gradientUnits !== 'percentage') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n\n const commonAttributes = [\n `id=\"SVGID_${this.id}\"`,\n `gradientUnits=\"${gradientUnits}\"`,\n `gradientTransform=\"${\n preTransform ? preTransform + ' ' : ''\n }${matrixToSVG(transform)}\"`,\n '',\n ].join(' ');\n\n if (this.type === 'linear') {\n const { x1, y1, x2, y2 } = this.coords;\n markup.push(\n '\\n',\n );\n } else if (this.type === 'radial') {\n const { x1, y1, x2, y2, r1, r2 } = this\n .coords as GradientCoords<'radial'>;\n const needsSwap = r1 > r2;\n // svg radial gradient has just 1 radius. the biggest.\n markup.push(\n '\\n',\n );\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops.reverse(); // mutates array\n colorStops.forEach((colorStop) => {\n colorStop.offset = 1 - colorStop.offset;\n });\n }\n const minRadius = Math.min(r1, r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n const maxRadius = Math.max(r1, r2),\n percentageShift = minRadius / maxRadius;\n colorStops.forEach((colorStop) => {\n colorStop.offset += percentageShift * (1 - colorStop.offset);\n });\n }\n }\n\n colorStops.forEach(({ color, offset, opacity }) => {\n markup.push(\n '\\n',\n );\n });\n\n markup.push(\n this.type === 'linear' ? '' : '',\n '\\n',\n );\n\n return markup.join('');\n }\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasGradient {\n const { x1, y1, x2, y2, r1, r2 } = this.coords as GradientCoords<'radial'>;\n const gradient =\n this.type === 'linear'\n ? ctx.createLinearGradient(x1, y1, x2, y2)\n : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);\n\n this.colorStops.forEach(({ color, opacity, offset }) => {\n gradient.addColorStop(\n offset,\n typeof opacity !== 'undefined'\n ? new Color(color).setAlpha(opacity).toRgba()\n : color,\n );\n });\n\n return gradient;\n }\n\n static async fromObject(\n options: GradientOptions<'linear'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'radial'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'linear'> | GradientOptions<'radial'>,\n ) {\n const { colorStops, gradientTransform } = options;\n return new this({\n ...options,\n colorStops: colorStops\n ? colorStops.map((colorStop) => ({ ...colorStop }))\n : undefined,\n gradientTransform: gradientTransform ? [...gradientTransform] : undefined,\n });\n }\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link Gradient} instance from an SVG element\n * @static\n * @memberOf Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {FabricObject} instance\n * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @return {Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n *\n * @example\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n static fromElement(\n el: SVGGradientElement,\n instance: FabricObject,\n svgOptions: SVGOptions,\n ): Gradient {\n const gradientUnits = parseGradientUnits(el);\n const center = instance._findCenterFromElement();\n return new this({\n id: el.getAttribute('id') || undefined,\n type: parseType(el),\n coords: parseCoords(el, {\n width: svgOptions.viewBoxWidth || svgOptions.width,\n height: svgOptions.viewBoxHeight || svgOptions.height,\n }),\n colorStops: parseColorStops(el, svgOptions.opacity),\n gradientUnits,\n gradientTransform: parseTransformAttribute(\n el.getAttribute('gradientTransform') || '',\n ),\n ...(gradientUnits === 'pixels'\n ? {\n offsetX: instance.width / 2 - center.x,\n offsetY: instance.height / 2 - center.y,\n }\n : {\n offsetX: 0,\n offsetY: 0,\n }),\n });\n }\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Gradient, 'gradient');\nclassRegistry.setClass(Gradient, 'linear');\nclassRegistry.setClass(Gradient, 'radial');\n","import { config } from '../config';\nimport type { Abortable, TCrossOrigin, TMat2D, TSize } from '../typedefs';\nimport { ifNaN } from '../util/internals/ifNaN';\nimport { uid } from '../util/internals/uid';\nimport { loadImage } from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { toFixed } from '../util/misc/toFixed';\nimport { classRegistry } from '../ClassRegistry';\nimport type {\n PatternRepeat,\n PatternOptions,\n SerializedPatternOptions,\n} from './types';\nimport { log } from '../util/internals/console';\n\n/**\n * @see {@link http://fabricjs.com/patterns demo}\n * @see {@link http://fabricjs.com/dynamic-patterns demo}\n */\nexport class Pattern {\n static type = 'Pattern';\n\n /**\n * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern'\n * or utils like isPattern, or instance of to indentify a pattern in your code.\n * Will be removed in future versiones\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n return 'pattern';\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * @type PatternRepeat\n * @defaults\n */\n repeat: PatternRepeat = 'repeat';\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX = 0;\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY = 0;\n\n /**\n * @type TCrossOrigin\n * @default\n */\n crossOrigin: TCrossOrigin = '';\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @todo verify if using the identity matrix as default makes the rest of the code more easy\n * @type Array\n * @default\n */\n declare patternTransform?: TMat2D;\n\n /**\n * The actual pixel source of the pattern\n */\n declare source: CanvasImageSource;\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number\n */\n declare readonly id: number;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {option.source} [source] the pattern source, eventually empty or a drawable\n */\n constructor(options: PatternOptions) {\n this.id = uid();\n Object.assign(this, options);\n }\n\n /**\n * @returns true if {@link source} is an element\n */\n isImageSource(): this is { source: HTMLImageElement } {\n return (\n !!this.source && typeof (this.source as HTMLImageElement).src === 'string'\n );\n }\n\n /**\n * @returns true if {@link source} is a element\n */\n isCanvasSource(): this is { source: HTMLCanvasElement } {\n return !!this.source && !!(this.source as HTMLCanvasElement).toDataURL;\n }\n\n sourceToString(): string {\n return this.isImageSource()\n ? this.source.src\n : this.isCanvasSource()\n ? this.source.toDataURL()\n : '';\n }\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasPattern | null {\n if (\n // if the image failed to load, return, and allow rest to continue loading\n !this.source ||\n // if an image\n (this.isImageSource() &&\n (!this.source.complete ||\n this.source.naturalWidth === 0 ||\n this.source.naturalHeight === 0))\n ) {\n return null;\n }\n\n return ctx.createPattern(this.source, this.repeat)!;\n }\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object} Object representation of a pattern instance\n */\n toObject(propertiesToInclude: string[] = []): Record {\n const { repeat, crossOrigin } = this;\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: 'pattern',\n source: this.sourceToString(),\n repeat,\n crossOrigin,\n offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform\n ? [...this.patternTransform]\n : null,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n */\n toSVG({ width, height }: TSize): string {\n const { source: patternSource, repeat, id } = this,\n patternOffsetX = ifNaN(this.offsetX / width, 0),\n patternOffsetY = ifNaN(this.offsetY / height, 0),\n patternWidth =\n repeat === 'repeat-y' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetX || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).width as number) / width,\n 0,\n ),\n patternHeight =\n repeat === 'repeat-x' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetY || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).height as number) / height,\n 0,\n );\n\n return [\n ``,\n ``,\n ``,\n '',\n ].join('\\n');\n }\n /* _TO_SVG_END_ */\n\n static async fromObject(\n {\n type,\n source,\n patternTransform,\n ...otherOptions\n }: SerializedPatternOptions,\n options?: Abortable,\n ): Promise {\n const img = await loadImage(source, {\n ...options,\n crossOrigin: otherOptions.crossOrigin,\n });\n return new this({\n ...otherOptions,\n patternTransform:\n patternTransform && (patternTransform.slice(0) as TMat2D),\n source: img,\n });\n }\n}\n\nclassRegistry.setClass(Pattern);\n// kept for compatibility reason\nclassRegistry.setClass(Pattern, 'pattern');\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport type { Shadow } from '../Shadow';\nimport type { Canvas } from '../canvas/Canvas';\nimport type { TBrushEventData } from './typedefs';\n\n/**\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nexport abstract class BaseBrush {\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color = 'rgb(0, 0, 0)';\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width = 1;\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type Shadow\n * @default\n */\n shadow: Shadow | null = null;\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: CanvasLineCap = 'round';\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: CanvasLineJoin = 'round';\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit = 10;\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: number[] | null = null;\n\n /**\n * When `true`, the free drawing is limited to the whiteboard size. Default to false.\n * @type Boolean\n * @default false\n */\n\n limitedToCanvasSize = false;\n\n /**\n * @todo add type\n */\n declare canvas: Canvas;\n\n constructor(canvas: Canvas) {\n this.canvas = canvas;\n }\n\n abstract _render(): void;\n abstract onMouseDown(pointer: Point, ev: TBrushEventData): void;\n abstract onMouseMove(pointer: Point, ev: TBrushEventData): void;\n /**\n * @returns true if brush should continue blocking interaction\n */\n abstract onMouseUp(ev: TBrushEventData): boolean | void;\n\n /**\n * Sets brush styles\n * @private\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.setLineDash(this.strokeDashArray || []);\n }\n\n /**\n * Sets the transformation on given context\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @private\n */\n protected _saveAndTransform(ctx: CanvasRenderingContext2D) {\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n protected needsFullRender() {\n const color = new Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n }\n\n /**\n * Sets brush shadow styles\n * @private\n */\n protected _setShadow() {\n if (!this.shadow || !this.canvas) {\n return;\n }\n\n const canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom() * canvas.getRetinaScaling();\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n }\n\n /**\n * Removes brush shadow styles\n * @private\n */\n protected _resetShadow() {\n const ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * Check is pointer is outside canvas boundaries\n * @param {Object} pointer\n * @private\n */\n protected _isOutSideCanvas(pointer: Point) {\n return (\n pointer.x < 0 ||\n pointer.x > this.canvas.getWidth() ||\n pointer.y < 0 ||\n pointer.y > this.canvas.getHeight()\n );\n }\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { toFixed } from '../util/misc/toFixed';\nimport {\n getBoundsOfCurve,\n joinPath,\n makePathSimpler,\n parsePath,\n} from '../util/path';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type {\n TComplexPathData,\n TPathSegmentInfo,\n TSimplePathData,\n} from '../util/path/typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type {\n TBBox,\n TClassProperties,\n TSVGReviver,\n TOptions,\n} from '../typedefs';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\ninterface UniquePathProps {\n sourcePath?: string;\n path?: TSimplePathData;\n}\n\nexport interface SerializedPathProps\n extends SerializedObjectProps,\n UniquePathProps {}\n\nexport interface PathProps extends FabricObjectProps, UniquePathProps {}\n\nexport interface IPathBBox extends TBBox {\n left: number;\n top: number;\n pathOffset: Point;\n}\n\nexport class Path<\n Props extends TOptions = Partial,\n SProps extends SerializedPathProps = SerializedPathProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Array of path points\n * @type Array\n * @default\n */\n declare path: TSimplePathData;\n\n declare pathOffset: Point;\n\n declare sourcePath?: string;\n\n declare segmentsInfo?: TPathSegmentInfo[];\n\n static type = 'Path';\n\n static cacheProperties = [...cacheProperties, 'path', 'fillRule'];\n\n /**\n * Constructor\n * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Partial} [options] Options object\n * @return {Path} thisArg\n */\n constructor(\n path: TComplexPathData | string,\n // todo: evaluate this spread here\n { path: _, left, top, ...options }: Partial = {},\n ) {\n super();\n Object.assign(this, Path.ownDefaults);\n this.setOptions(options);\n this._setPath(path || [], true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box\n * @returns {Point} top left position of the bounding box, useful for complementary positioning\n */\n _setPath(path: TComplexPathData | string, adjustPosition?: boolean) {\n this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));\n this.setBoundingBox(adjustPosition);\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = this._calcBoundsFromPath();\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands(ctx: CanvasRenderingContext2D) {\n const l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (const command of this.path) {\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n ctx.lineTo(command[1] + l, command[2] + t);\n break;\n\n case 'M': // moveTo, absolute\n ctx.moveTo(command[1] + l, command[2] + t);\n break;\n\n case 'C': // bezierCurveTo, absolute\n ctx.bezierCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n command[5] + l,\n command[6] + t,\n );\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n );\n break;\n\n case 'Z':\n ctx.closePath();\n break;\n }\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render(ctx: CanvasRenderingContext2D) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns string representation of an instance\n * @return {string} string representation of an instance\n */\n toString() {\n return `#`;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n path: this.path.map((pathCmd) => pathCmd.slice()),\n };\n }\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n delete o.path;\n o.sourcePath = this.sourcePath;\n }\n return o;\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const path = joinPath(this.path, config.NUM_FRACTION_DIGITS);\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @return the path command's translate transform attribute\n */\n _getOffsetTransform() {\n const digits = config.NUM_FRACTION_DIGITS;\n return ` translate(${toFixed(-this.pathOffset.x, digits)}, ${toFixed(\n -this.pathOffset.y,\n digits,\n )})`;\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n })\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n });\n }\n\n /**\n * Returns number representation of an instance complexity\n * @return {number} complexity of this instance\n */\n complexity() {\n return this.path.length;\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { width, height, pathOffset } = this._calcDimensions();\n this.set({ width, height, pathOffset });\n // using pathOffset because it match the use case.\n // if pathOffset change here we need to use left + width/2 , top + height/2\n adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER);\n }\n\n _calcBoundsFromPath(): TBBox {\n const bounds: XY[] = [];\n let subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0; // current y\n\n for (const command of this.path) {\n // current instruction\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n x = command[1];\n y = command[2];\n bounds.push({ x: subpathStartX, y: subpathStartY }, { x, y });\n break;\n\n case 'M': // moveTo, absolute\n x = command[1];\n y = command[2];\n subpathStartX = x;\n subpathStartY = y;\n break;\n\n case 'C': // bezierCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[3],\n command[4],\n command[5],\n command[6],\n ),\n );\n x = command[5];\n y = command[6];\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[1],\n command[2],\n command[3],\n command[4],\n ),\n );\n x = command[3];\n y = command[4];\n break;\n\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n }\n return makeBoundingBoxFromPoints(bounds);\n }\n\n /**\n * @private\n */\n _calcDimensions(): IPathBBox {\n const bbox = this._calcBoundsFromPath();\n\n return {\n ...bbox,\n pathOffset: new Point(\n bbox.left + bbox.width / 2,\n bbox.top + bbox.height / 2,\n ),\n };\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`)\n * @static\n * @memberOf Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'd'];\n\n /**\n * Creates an instance of Path from an object\n * @static\n * @memberOf Path\n * @param {Object} object\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'path',\n });\n }\n\n /**\n * Creates an instance of Path from an SVG element\n * @static\n * @memberOf Path\n * @param {HTMLElement} element to parse\n * @param {Partial} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Partial,\n cssRules?: CSSRules,\n ) {\n const { d, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(d, {\n ...parsedAttributes,\n ...options,\n // we pass undefined to instruct the constructor to position the object using the bbox\n left: undefined,\n top: undefined,\n });\n }\n}\n\nclassRegistry.setClass(Path);\nclassRegistry.setSVGClass(Path);\n\n/* _FROM_SVG_START_ */\n","import type { ModifierKey, TEvent } from '../EventTypeDefs';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Path } from '../shapes/Path';\nimport { getSmoothPathFromPoints, joinPath } from '../util/path';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\n/**\n * @private\n * @param {TSimplePathData} pathData SVG path commands\n * @returns {boolean}\n */\nfunction isEmptySVGPath(pathData: TSimplePathData): boolean {\n return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0';\n}\n\nexport class PencilBrush extends BaseBrush {\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate = 0.4;\n\n /**\n * Draws a straight line between last recorded point to current pointer\n * Used for `shift` functionality\n *\n * @type boolean\n * @default false\n */\n drawStraightLine = false;\n\n /**\n * The event modifier key that makes the brush draw a straight line.\n * If `null` or 'none' or any other string that is not a modifier key the feature is disabled.\n * @type {ModifierKey | undefined | null}\n */\n straightLineKey: ModifierKey | undefined | null = 'shiftKey';\n\n private declare _points: Point[];\n private declare _hasStraightLine: boolean;\n private declare oldEnd?: Point;\n\n constructor(canvas: Canvas) {\n super(canvas);\n this._points = [];\n this._hasStraightLine = false;\n }\n\n needsFullRender() {\n return super.needsFullRender() || this._hasStraightLine;\n }\n\n static drawSegment(ctx: CanvasRenderingContext2D, p1: Point, p2: Point) {\n const midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._addPoint(pointer);\n this._render();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this._addPoint(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n } else {\n const points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = PencilBrush.drawSegment(\n ctx,\n points[length - 2],\n points[length - 1],\n );\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp({ e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return true;\n }\n this.drawStraightLine = false;\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n }\n\n /**\n * @private\n * @param {Point} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing(pointer: Point) {\n this._reset();\n this._addPoint(pointer);\n this.canvas.contextTop.moveTo(pointer.x, pointer.y);\n }\n\n /**\n * @private\n * @param {Point} point Point to be added to points array\n */\n _addPoint(point: Point) {\n if (\n this._points.length > 1 &&\n point.eq(this._points[this._points.length - 1])\n ) {\n return false;\n }\n if (this.drawStraightLine && this._points.length > 1) {\n this._hasStraightLine = true;\n this._points.pop();\n }\n this._points.push(point);\n return true;\n }\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset() {\n this._points = [];\n this._setBrushStyles(this.canvas.contextTop);\n this._setShadow();\n this._hasStraightLine = false;\n }\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n * @param {CanvasRenderingContext2D} [ctx]\n */\n _render(ctx: CanvasRenderingContext2D = this.canvas.contextTop) {\n let p1 = this._points[0],\n p2 = this._points[1];\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n const width = this.width / 1000;\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (let i = 1; i < this._points.length; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n PencilBrush.drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * Converts points to SVG path\n * @param {Point[]} points Array of points\n * @return {TSimplePathData} SVG path commands\n */\n convertPointsToSVGPath(points: Point[]): TSimplePathData {\n const correction = this.width / 1000;\n return getSmoothPathFromPoints(points, correction);\n }\n\n /**\n * Creates a Path object to add on canvas\n * @param {TSimplePathData} pathData Path data\n * @return {Path} Path to add on canvas\n */\n createPath(pathData: TSimplePathData): Path {\n const path = new Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new Shadow(this.shadow);\n }\n\n return path;\n }\n\n /**\n * Decimate points array with the decimate value\n */\n decimatePoints(points: Point[], distance: number) {\n if (points.length <= 2) {\n return points;\n }\n let lastPoint = points[0],\n cDistance;\n const zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n l = points.length - 1,\n newPoints = [lastPoint];\n for (let i = 1; i < l - 1; i++) {\n cDistance =\n Math.pow(lastPoint.x - points[i].x, 2) +\n Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n // Add the last point from the original line to the end of the array.\n // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point.\n newPoints.push(points[l]);\n return newPoints;\n }\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new Path object\n * and add it to the canvas.\n */\n _finalizeAndAddPath() {\n const ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n const pathData = this.convertPointsToSVGPath(this._points);\n if (isEmptySVGPath(pathData)) {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n const path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', { path: path });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n}\n","import type { ObjectEvents } from '../EventTypeDefs';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { cos } from '../util/misc/cos';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { sin } from '../util/misc/sin';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { CSSRules } from '../parser/typedefs';\nimport { SCALE_X, SCALE_Y } from '../constants';\n\ninterface UniqueCircleProps {\n /**\n * Radius of this circle\n * @type Number\n * @default 0\n */\n radius: number;\n\n /**\n * Angle for the start of the circle, in degrees.\n * @type TDegree 0 - 359\n * @default 0\n */\n startAngle: number;\n\n /**\n * Angle for the end of the circle, in degrees\n * @type TDegree 1 - 360\n * @default 360\n */\n endAngle: number;\n\n /**\n * Orientation for the direction of the circle.\n * Setting to true will switch the arc of the circle to traverse from startAngle to endAngle in a counter-clockwise direction.\n * Note: this will only change how the circle is drawn, and does not affect rotational transformation.\n * @default false\n */\n counterClockwise: boolean;\n}\n\nexport interface SerializedCircleProps\n extends SerializedObjectProps,\n UniqueCircleProps {}\n\nexport interface CircleProps extends FabricObjectProps, UniqueCircleProps {}\n\nconst CIRCLE_PROPS = [\n 'radius',\n 'startAngle',\n 'endAngle',\n 'counterClockwise',\n] as const;\n\nexport const circleDefaultValues: Partial> = {\n radius: 0,\n startAngle: 0,\n endAngle: 360,\n counterClockwise: false,\n};\n\nexport class Circle<\n Props extends TOptions = Partial,\n SProps extends SerializedCircleProps = SerializedCircleProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueCircleProps\n{\n declare radius: number;\n declare startAngle: number;\n declare endAngle: number;\n declare counterClockwise: boolean;\n\n static type = 'Circle';\n\n static cacheProperties = [...cacheProperties, ...CIRCLE_PROPS];\n\n static ownDefaults = circleDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Circle.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Circle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n degreesToRadians(this.startAngle),\n degreesToRadians(this.endAngle),\n this.counterClockwise,\n );\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX(): number {\n return this.get('radius') * this.get(SCALE_X);\n }\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY(): number {\n return this.get('radius') * this.get(SCALE_Y);\n }\n\n /**\n * Sets radius of an object (and updates width accordingly)\n */\n setRadius(value: number) {\n this.radius = value;\n this.set({ width: value * 2, height: value * 2 });\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]);\n }\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n const angle = (this.endAngle - this.startAngle) % 360;\n\n if (angle === 0) {\n return [\n '\\n',\n ];\n } else {\n const { radius } = this;\n const start = degreesToRadians(this.startAngle),\n end = degreesToRadians(this.endAngle),\n startX = cos(start) * radius,\n startY = sin(start) * radius,\n endX = cos(end) * radius,\n endY = sin(end) * radius,\n largeFlag = angle > 180 ? 1 : 0,\n sweepFlag = this.counterClockwise ? 0 : 1;\n return [\n `\\n',\n ];\n }\n }\n /* _TO_SVG_END_ */\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement})\n * @static\n * @memberOf Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n static ATTRIBUTE_NAMES = ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES];\n\n /**\n * Returns {@link Circle} instance from an SVG element\n * @static\n * @memberOf Circle\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Partial Circle object to default missing properties on the element.\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ): Promise {\n const {\n left = 0,\n top = 0,\n radius = 0,\n ...otherParsedAttributes\n } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n ) as Partial;\n\n // this probably requires to be fixed for default origins not being top/left.\n\n return new this({\n ...otherParsedAttributes,\n radius,\n left: left - radius,\n top: top - radius,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * @todo how do we declare this??\n */\n static fromObject>(object: T) {\n return super._fromObject(object);\n }\n}\n\nclassRegistry.setClass(Circle);\nclassRegistry.setSVGClass(Circle);\n","import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\n// @TODO this code is terrible and Line should be a special case of polyline.\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineProps {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineProps {}\n\nexport class Line<\n Props extends TOptions = Partial,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueLineProps\n{\n /**\n * x value or first line edge\n * @type number\n * @default\n */\n declare x1: number;\n\n /**\n * y value or first line edge\n * @type number\n * @default\n */\n declare y1: number;\n\n /**\n * x value or second line edge\n * @type number\n * @default\n */\n declare x2: number;\n\n /**\n * y value or second line edge\n * @type number\n * @default\n */\n declare y2: number;\n\n static type = 'Line';\n\n static cacheProperties = [...cacheProperties, ...coordProps];\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {Line} thisArg\n */\n constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) {\n super();\n Object.assign(this, Line.ownDefaults);\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight() {\n const { x1, y1, x2, y2 } = this;\n this.width = Math.abs(x2 - x1);\n this.height = Math.abs(y2 - y1);\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ]);\n const position = new Point(left + width / 2, top + height / 2);\n this.setPositionByOrigin(position, CENTER, CENTER);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineProps)) {\n // this doesn't make sense very much, since setting x1 when top or left\n // are already set, is just going to show a strange result since the\n // line will move way more than the developer expect.\n // in fabric5 it worked only when the line didn't have extra transformations,\n // in fabric6 too. With extra transform they behave bad in different ways.\n // This needs probably a good rework or a tutorial if you have to create a dynamic line\n this._setWidthHeight();\n }\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n } else {\n ctx.strokeStyle = this.stroke ?? ctx.fillStyle;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n }\n\n /**\n * Recalculates line points given width and height\n * Those points are simply placed around the center,\n * This is not useful outside internal render functions and svg output\n * Is not meant to be for the developer.\n * @private\n */\n calcLinePoints(): UniqueLineProps {\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1,\n yMult = _y1 <= _y2 ? -1 : 1,\n x1 = (xMult * width) / 2,\n y1 = (yMult * height) / 2,\n x2 = (xMult * -width) / 2,\n y2 = (yMult * -height) / 2;\n\n return {\n x1,\n x2,\n y1,\n y2,\n };\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})\n * @static\n * @memberOf Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n /**\n * Returns Line instance from an SVG element\n * @static\n * @memberOf Line\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Line instance from an object representation\n * @static\n * @memberOf Line\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>({\n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject(\n {\n ...object,\n points: [x1, y1, x2, y2],\n },\n {\n extraParam: 'points',\n },\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n","import { classRegistry } from '../ClassRegistry';\nimport { FabricObject } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { TClassProperties, TOptions } from '../typedefs';\nimport type { ObjectEvents } from '../EventTypeDefs';\n\nexport const triangleDefaultValues: Partial> = {\n width: 100,\n height: 100,\n};\n\nexport class Triangle<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n static type = 'Triangle';\n\n static ownDefaults = triangleDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...Triangle.ownDefaults };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Triangle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = `${-widthBy2} ${heightBy2},0 ${-heightBy2},${widthBy2} ${heightBy2}`;\n return [''];\n }\n}\n\nclassRegistry.setClass(Triangle);\nclassRegistry.setSVGClass(Triangle);\n","import { SCALE_X, SCALE_Y, twoMathPi } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const ellipseDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueEllipseProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedEllipseProps\n extends SerializedObjectProps,\n UniqueEllipseProps {}\n\nexport interface EllipseProps extends FabricObjectProps, UniqueEllipseProps {}\n\nconst ELLIPSE_PROPS = ['rx', 'ry'] as const;\n\nexport class Ellipse<\n Props extends TOptions = Partial,\n SProps extends SerializedEllipseProps = SerializedEllipseProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements EllipseProps\n{\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Ellipse';\n\n static cacheProperties = [...cacheProperties, ...ELLIPSE_PROPS];\n\n static ownDefaults = ellipseDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Ellipse.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Ellipse.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {Ellipse} thisArg\n */\n _set(key: string, value: any) {\n super._set(key, value);\n switch (key) {\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n }\n return this;\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx() {\n return this.get('rx') * this.get(SCALE_X);\n }\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy() {\n return this.get('ry') * this.get(SCALE_Y);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, twoMathPi, false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement})\n * @static\n * @memberOf Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry'];\n\n /**\n * Returns {@link Ellipse} instance from an SVG element\n * @static\n * @memberOf Ellipse\n * @param {HTMLElement} element Element to parse\n * @return {Ellipse}\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n return new this(parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Ellipse);\nclassRegistry.setSVGClass(Ellipse);\n","import type { XY } from '../Point';\n\n/**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\nexport function parsePointsAttribute(points: string | null): XY[] {\n // points attribute is required and must not be empty\n if (!points) {\n return [];\n }\n\n // replace commas with whitespace and remove bookending whitespace\n const pointsSplit: string[] = points.replace(/,/g, ' ').trim().split(/\\s+/);\n\n const parsedPoints = [];\n\n for (let i = 0; i < pointsSplit.length; i += 2) {\n parsedPoints.push({\n x: parseFloat(pointsSplit[i]),\n y: parseFloat(pointsSplit[i + 1]),\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n return parsedPoints;\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { parsePointsAttribute } from '../parser/parsePointsAttribute';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { calcDimensionsMatrix, transformPoint } from '../util/misc/matrix';\nimport { projectStrokeOnPoints } from '../util/misc/projectStroke';\nimport type { TProjectStrokeOnPointsOptions } from '../util/misc/projectStroke/types';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport {\n CENTER,\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const polylineDefaultValues: Partial> = {\n /**\n * @deprecated transient option soon to be removed in favor of a different design\n */\n exactBoundingBox: false,\n};\n\nexport interface SerializedPolylineProps extends SerializedObjectProps {\n points: XY[];\n}\n\nexport class Polyline<\n Props extends TOptions = Partial,\n SProps extends SerializedPolylineProps = SerializedPolylineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Points array\n * @type Array\n * @default\n */\n declare points: XY[];\n\n /**\n * WARNING: Feature in progress\n * Calculate the exact bounding box taking in account strokeWidth on acute angles\n * this will be turned to true by default on fabric 6.0\n * maybe will be left in as an optimization since calculations may be slow\n * @deprecated transient option soon to be removed in favor of a different design\n * @type Boolean\n * @default false\n */\n declare exactBoundingBox: boolean;\n\n private declare initialized: true | undefined;\n\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polyline';\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Polyline.ownDefaults,\n };\n }\n\n /**\n * A list of properties that if changed trigger a recalculation of dimensions\n * @todo check if you really need to recalculate for all cases\n */\n static layoutProperties: (keyof Polyline)[] = [\n SKEW_X,\n SKEW_Y,\n 'strokeLineCap',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'strokeWidth',\n 'strokeUniform',\n 'points',\n ];\n\n declare pathOffset: Point;\n\n declare strokeOffset: Point;\n\n static cacheProperties = [...cacheProperties, 'points'];\n\n strokeDiff: Point;\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {Polyline} thisArg\n * @example\n * var poly = new Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n constructor(points: XY[] = [], options: Props = {} as Props) {\n super();\n Object.assign(this, Polyline.ownDefaults);\n this.setOptions(options);\n this.points = points;\n const { left, top } = options;\n this.initialized = true;\n this.setBoundingBox(true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n protected isOpen() {\n return true;\n }\n\n private _projectStrokeOnPoints(options: TProjectStrokeOnPointsOptions) {\n return projectStrokeOnPoints(this.points, options, this.isOpen());\n }\n\n /**\n * Calculate the polygon bounding box\n * @private\n */\n _calcDimensions(options?: Partial) {\n options = {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeUniform: this.strokeUniform,\n strokeWidth: this.strokeWidth,\n ...(options || {}),\n };\n const points = this.exactBoundingBox\n ? this._projectStrokeOnPoints(\n options as TProjectStrokeOnPointsOptions,\n ).map((projection) => projection.projectedPoint)\n : this.points;\n if (points.length === 0) {\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n pathOffset: new Point(),\n strokeOffset: new Point(),\n strokeDiff: new Point(),\n };\n }\n const bbox = makeBoundingBoxFromPoints(points),\n // Remove scale effect, since it's applied after\n matrix = calcDimensionsMatrix({ ...options, scaleX: 1, scaleY: 1 }),\n bboxNoStroke = makeBoundingBoxFromPoints(\n this.points.map((p) => transformPoint(p, matrix, true)),\n ),\n scale = new Point(this.scaleX, this.scaleY);\n let offsetX = bbox.left + bbox.width / 2,\n offsetY = bbox.top + bbox.height / 2;\n if (this.exactBoundingBox) {\n offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX));\n // Order of those assignments is important.\n // offsetY relies on offsetX being already changed by the line above\n offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY));\n }\n\n return {\n ...bbox,\n pathOffset: new Point(offsetX, offsetY),\n strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top)\n .subtract(new Point(bbox.left, bbox.top))\n .multiply(scale),\n strokeDiff: new Point(bbox.width, bbox.height)\n .subtract(new Point(bboxNoStroke.width, bboxNoStroke.height))\n .multiply(scale),\n };\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = makeBoundingBoxFromPoints(this.points);\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { left, top, width, height, pathOffset, strokeOffset, strokeDiff } =\n this._calcDimensions();\n this.set({ width, height, pathOffset, strokeOffset, strokeDiff });\n adjustPosition &&\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER,\n );\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return this.exactBoundingBox;\n }\n\n /**\n * @override stroke is taken in account in size\n */\n _getNonTransformedDimensions() {\n return this.exactBoundingBox\n ? // TODO: fix this\n new Point(this.width, this.height)\n : super._getNonTransformedDimensions();\n }\n\n /**\n * @override stroke and skewing are taken into account when projecting stroke on points,\n * therefore we don't want the default calculation to account for skewing as well.\n * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion.\n *\n * @private\n */\n _getTransformedDimensions(options: any = {}) {\n if (this.exactBoundingBox) {\n let size: Point;\n /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because\n the stroke projections are affected.\n When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on\n projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/\n if (\n Object.keys(options).some(\n (key) =>\n this.strokeUniform ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof TProjectStrokeOnPointsOptions,\n ),\n )\n ) {\n const { width, height } = this._calcDimensions(options);\n size = new Point(options.width ?? width, options.height ?? height);\n } else {\n size = new Point(\n options.width ?? this.width,\n options.height ?? this.height,\n );\n }\n return size.multiply(\n new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY),\n );\n } else {\n return super._getTransformedDimensions(options);\n }\n }\n\n /**\n * Recalculates dimensions when changing skew and scale\n * @private\n */\n _set(key: string, value: any) {\n const changed = this.initialized && this[key as keyof this] !== value;\n const output = super._set(key, value);\n if (\n this.exactBoundingBox &&\n changed &&\n (((key === SCALE_X || key === SCALE_Y) &&\n this.strokeUniform &&\n (this.constructor as typeof Polyline).layoutProperties.includes(\n 'strokeUniform',\n )) ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof Polyline,\n ))\n ) {\n this.setDimensions();\n }\n return output;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n points: this.points.map(({ x, y }) => ({ x, y })),\n };\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const points = [],\n diffX = this.pathOffset.x,\n diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n\n for (let i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS),\n ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS),\n ' ',\n );\n }\n return [\n `<${\n (this.constructor as typeof Polyline).type.toLowerCase() as\n | 'polyline'\n | 'polygon'\n } `,\n 'COMMON_PARTS',\n `points=\"${points.join('')}\" />\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (let i = 0; i < len; i++) {\n const point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n !this.isOpen() && ctx.closePath();\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity(): number {\n return this.points.length;\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement})\n * @static\n * @memberOf Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES];\n\n /**\n * Returns Polyline instance from an SVG element\n * @static\n * @memberOf Polyline\n * @param {HTMLElement} element Element to parser\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const points = parsePointsAttribute(element.getAttribute('points')),\n // we omit left and top to instruct the constructor to position the object using the bbox\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { left, top, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(points, {\n ...parsedAttributes,\n ...options,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Polyline instance from an object representation\n * @static\n * @memberOf Polyline\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'points',\n });\n }\n}\n\nclassRegistry.setClass(Polyline);\nclassRegistry.setSVGClass(Polyline);\n","import { classRegistry } from '../ClassRegistry';\nimport { Polyline, polylineDefaultValues } from './Polyline';\n\nexport class Polygon extends Polyline {\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polygon';\n\n protected isOpen() {\n return false;\n }\n}\n\nclassRegistry.setClass(Polygon);\nclassRegistry.setSVGClass(Polygon);\n","import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { TOptions } from '../../typedefs';\nimport { FabricObject } from '../Object/FabricObject';\nimport { styleProperties } from './constants';\nimport type { StylePropertiesType } from './constants';\nimport type { FabricText } from './Text';\nimport { pick } from '../../util';\nimport { pickBy } from '../../util/misc/pick';\n\nexport type CompleteTextStyleDeclaration = Pick<\n FabricText,\n StylePropertiesType\n>;\n\nexport type TextStyleDeclaration = Partial;\n\nexport type TextStyle = {\n [line: number | string]: { [char: number | string]: TextStyleDeclaration };\n};\n\nexport abstract class StyledText<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n declare abstract styles: TextStyle;\n protected declare abstract _textLines: string[][];\n protected declare _forceClearCache: boolean;\n static _styleProperties: Readonly = styleProperties;\n abstract get2DCursorLocation(\n selectionStart: number,\n skipWrapping?: boolean,\n ): { charIndex: number; lineIndex: number };\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex?: number): boolean {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex?: number): boolean {\n if (!this.styles) {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (const p1 in obj) {\n // eslint-disable-next-line\n for (const p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return false;\n }\n const obj = this.styles;\n let stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0;\n for (const p1 in obj) {\n letterCount = 0;\n for (const p2 in obj[p1]) {\n const styleObject = obj[p1][p2] || {},\n stylePropertyHasBeenSet = styleObject[property] !== undefined;\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property as keyof this]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (let i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n // @ts-expect-error conspiracy theory of TS\n this[property as keyof this] = stylePropertyValue;\n this.removeStyle(property);\n }\n }\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return;\n }\n const obj = this.styles;\n let line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n }\n\n private _extendStyles(index: number, style: TextStyleDeclaration): void {\n const { lineIndex, charIndex } = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex);\n }\n\n const newStyle = pickBy(\n {\n // first create a new object that is a merge of existing and new\n ...this._getStyleDeclaration(lineIndex, charIndex),\n ...style,\n // use the predicate to discard undefined values\n },\n (value) => value !== undefined,\n );\n\n // finally assign to the old position the new style\n this._setStyleDeclaration(lineIndex, charIndex, newStyle);\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number,\n endIndex?: number,\n complete?: boolean,\n ): TextStyleDeclaration[] {\n const styles: TextStyleDeclaration[] = [];\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n }\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition(position: number, complete?: boolean) {\n const { lineIndex, charIndex } = this.get2DCursorLocation(position);\n return complete\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex)\n : this._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} styles Styles object\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1\n */\n setSelectionStyles(styles: object, startIndex: number, endIndex?: number) {\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n }\n\n /**\n * Get a reference, not a clone, to the style object for a given character,\n * if no style is set for a line or char, return a new empty object.\n * This is tricky and confusing because when you get an empty object you can't\n * determine if it is a reference or a new one.\n * @TODO this should always return a reference or always a clone or undefined when necessary.\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n const lineStyle = this.styles && this.styles[lineIndex];\n return lineStyle ? lineStyle[charIndex] ?? {} : {};\n }\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): CompleteTextStyleDeclaration {\n return {\n // @ts-expect-error readonly\n ...pick(this, (this.constructor as typeof StyledText)._styleProperties),\n ...this._getStyleDeclaration(lineIndex, charIndex),\n } as CompleteTextStyleDeclaration;\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n this.styles[lineIndex][charIndex] = style;\n }\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n delete this.styles[lineIndex][charIndex];\n }\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n return !!this.styles[lineIndex];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n this.styles[lineIndex] = {};\n }\n\n protected _deleteLineStyle(lineIndex: number) {\n delete this.styles[lineIndex];\n }\n}\n","import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number,\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n },\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t',\n textSpans.join(''),\n '\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number,\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height,\n ),\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number,\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex),\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `${escapeXml(char)}`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset,\n ),\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number,\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number,\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean,\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ],\n )\n .join(' ');\n }\n}\n","import { cache } from '../../cache';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, STROKE } from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type {\n CompleteTextStyleDeclaration,\n TextStyle,\n TextStyleDeclaration,\n} from './StyledText';\nimport { StyledText } from './StyledText';\nimport { SHARED_ATTRIBUTES } from '../../parser/attributes';\nimport { parseAttributes } from '../../parser/parseAttributes';\nimport type {\n Abortable,\n TCacheCanvasDimensions,\n TClassProperties,\n TFiller,\n TOptions,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { graphemeSplit } from '../../util/lang_string';\nimport { createCanvasElement } from '../../util/misc/dom';\nimport type { TextStyleArray } from '../../util/misc/textStyles';\nimport {\n hasStyleChanged,\n stylesFromArray,\n stylesToArray,\n} from '../../util/misc/textStyles';\nimport { getPathSegmentsInfo, getPointOnPath } from '../../util/path';\nimport { cacheProperties } from '../Object/FabricObject';\nimport type { Path } from '../Path';\nimport { TextSVGExportMixin } from './TextSVGExportMixin';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { StylePropertiesType } from './constants';\nimport {\n additionalProps,\n textDefaultValues,\n textLayoutProperties,\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from './constants';\nimport { CENTER, LEFT, RIGHT, TOP, BOTTOM } from '../../constants';\nimport { isFiller } from '../../util/typeAssertions';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { CSSRules } from '../../parser/typedefs';\n\nlet measuringContext: CanvasRenderingContext2D | null;\n\n/**\n * Return a context for measurement of text string.\n * if created it gets stored for reuse\n */\nfunction getMeasuringContext() {\n if (!measuringContext) {\n const canvas = createCanvasElement();\n canvas.width = canvas.height = 0;\n measuringContext = canvas.getContext('2d');\n }\n return measuringContext;\n}\n\nexport type TPathSide = 'left' | 'right';\n\nexport type TPathAlign = 'baseline' | 'center' | 'ascender' | 'descender';\n\nexport type TextLinesInfo = {\n lines: string[];\n graphemeLines: string[][];\n graphemeText: string[];\n _unwrappedLines: string[][];\n};\n\n/**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * Override to customize measuring\n */\nexport type GraphemeBBox = {\n width: number;\n height: number;\n kernedWidth: number;\n left: number;\n deltaY: number;\n renderLeft?: number;\n renderTop?: number;\n angle?: number;\n};\n\n// @TODO this is not complete\ninterface UniqueTextProps {\n charSpacing: number;\n lineHeight: number;\n fontSize: number;\n fontWeight: string | number;\n fontFamily: string;\n fontStyle: string;\n pathSide: TPathSide;\n pathAlign: TPathAlign;\n underline: boolean;\n overline: boolean;\n linethrough: boolean;\n textAlign: string;\n direction: CanvasDirection;\n path?: Path;\n}\n\nexport interface SerializedTextProps\n extends SerializedObjectProps,\n UniqueTextProps {\n styles: TextStyleArray | TextStyle;\n}\n\nexport interface TextProps extends FabricObjectProps, UniqueTextProps {\n styles: TextStyle;\n}\n\n/**\n * Text class\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n */\nexport class FabricText<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends StyledText\n implements UniqueTextProps\n{\n /**\n * Properties that requires a text layout recalculation when changed\n * @type string[]\n * @protected\n */\n static textLayoutProperties: string[] = textLayoutProperties;\n\n /**\n * @private\n */\n declare _reNewline: RegExp;\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpacesAndTabs: RegExp;\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpaceAndTab: RegExp;\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reWords: RegExp;\n\n declare text: string;\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n declare fontSize: number;\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n declare fontWeight: string | number;\n\n /**\n * Font family\n * @type String\n * @default\n */\n declare fontFamily: string;\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n declare underline: boolean;\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n declare overline: boolean;\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n declare linethrough: boolean;\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n declare textAlign: string;\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n declare fontStyle: string;\n\n /**\n * Line height\n * @type Number\n * @default\n */\n declare lineHeight: number;\n\n /**\n * Superscript schema object (minimum overlap)\n */\n declare superscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (upwards)\n * @default -0.35\n */\n baseline: number;\n };\n\n /**\n * Subscript schema object (minimum overlap)\n */\n declare subscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (downwards)\n * @default 0.11\n */\n baseline: number;\n };\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n declare textBackgroundColor: string;\n\n declare styles: TextStyle;\n\n /**\n * Path that the text should follow.\n * since 4.6.0 the path will be drawn automatically.\n * if you want to make the path visible, give it a stroke and strokeWidth or fill value\n * if you want it to be hidden, assign visible = false to the path.\n * This feature is in BETA, and SVG import/export is not yet supported.\n * @type Path\n * @example\n * const textPath = new Text('Text on a path', {\n * top: 150,\n * left: 150,\n * textAlign: 'center',\n * charSpacing: -50,\n * path: new Path('M 0 0 C 50 -100 150 -100 200 0', {\n * strokeWidth: 1,\n * visible: false\n * }),\n * pathSide: 'left',\n * pathStartOffset: 0\n * });\n * @default\n */\n declare path?: Path;\n\n /**\n * Offset amount for text path starting position\n * Only used when text has a path\n * @type Number\n * @default\n */\n declare pathStartOffset: number;\n\n /**\n * Which side of the path the text should be drawn on.\n * Only used when text has a path\n * @type {TPathSide} 'left|right'\n * @default\n */\n declare pathSide: TPathSide;\n\n /**\n * How text is aligned to the path. This property determines\n * the perpendicular position of each character relative to the path.\n * (one of \"baseline\", \"center\", \"ascender\", \"descender\")\n * This feature is in BETA, and its behavior may change\n * @type TPathAlign\n * @default\n */\n declare pathAlign: TPathAlign;\n\n /**\n * @private\n */\n declare _fontSizeFraction: number;\n\n /**\n * @private\n */\n declare offsets: { underline: number; linethrough: number; overline: number };\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n declare _fontSizeMult: number;\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n declare charSpacing: number;\n\n /**\n * Baseline shift, styles only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n declare deltaY: number;\n\n /**\n * WARNING: EXPERIMENTAL. NOT SUPPORTED YET\n * determine the direction of the text.\n * This has to be set manually together with textAlign and originX for proper\n * experience.\n * some interesting link for the future\n * https://www.w3.org/International/questions/qa-bidi-unicode-controls\n * @since 4.5.0\n * @type {CanvasDirection} 'ltr|rtl'\n * @default\n */\n declare direction: CanvasDirection;\n\n /**\n * contains characters bounding boxes\n * This variable is considered to be protected.\n * But for how mixins are implemented right now, we can't leave it private\n * @protected\n */\n __charBounds: GraphemeBBox[][] = [];\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n declare CACHE_FONT_SIZE: number;\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n declare MIN_TEXT_WIDTH: number;\n\n /**\n * contains the the text of the object, divided in lines as they are displayed\n * on screen. Wrapping will divide the text independently of line breaks\n * @type {string[]}\n * @default\n */\n declare textLines: string[];\n\n /**\n * same as textlines, but each line is an array of graphemes as split by splitByGrapheme\n * @type {string[]}\n * @default\n */\n declare _textLines: string[][];\n\n declare _unwrappedTextLines: string[][];\n declare _text: string[];\n declare cursorWidth: number;\n declare __lineHeights: number[];\n declare __lineWidths: number[];\n declare initialized?: true;\n\n static cacheProperties = [...cacheProperties, ...additionalProps];\n\n static ownDefaults = textDefaultValues;\n\n static type = 'Text';\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...FabricText.ownDefaults };\n }\n\n constructor(text: string, options?: Props) {\n super();\n Object.assign(this, FabricText.ownDefaults);\n this.setOptions(options);\n if (!this.styles) {\n this.styles = {};\n }\n this.text = text;\n this.initialized = true;\n if (this.path) {\n this.setPathInfo();\n }\n this.initDimensions();\n this.setCoords();\n }\n\n /**\n * If text has a path, it will add the extra information needed\n * for path and text calculations\n */\n setPathInfo() {\n const path = this.path;\n if (path) {\n path.segmentsInfo = getPathSegmentsInfo(path.path);\n }\n }\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText(): TextLinesInfo {\n const newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n }\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions() {\n this._splitText();\n this._clearCache();\n this.dirty = true;\n if (this.path) {\n this.width = this.path.width;\n this.height = this.path.height;\n } else {\n this.width =\n this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n this.height = this.calcTextHeight();\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n }\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces() {\n let diffSpace,\n currentLineWidth,\n numberOfSpaces,\n accumulatedSpace,\n line,\n charBound,\n spaces;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n if (\n this.textAlign !== JUSTIFY &&\n (i === len - 1 || this.isEndOfWrapping(i))\n ) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (\n currentLineWidth < this.width &&\n (spaces = this.textLines[i].match(this._reSpacesAndTabs))\n ) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (let j = 0; j <= line.length; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n } else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n return lineIndex === this._textLines.length - 1;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always 1 for text and Itext. Textbox has its own implementation\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1;\n missingNewlineOffset(_lineIndex: number): 1 {\n return 1;\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor\n * @param {Number} selectionStart\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(selectionStart: number, skipWrapping?: boolean) {\n const lines = skipWrapping ? this._unwrappedTextLines : this._textLines;\n let i: number;\n for (i = 0; i < lines.length; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart,\n };\n }\n selectionStart -=\n lines[i].length + this.missingNewlineOffset(i, skipWrapping);\n }\n return {\n lineIndex: i - 1,\n charIndex:\n lines[i - 1].length < selectionStart\n ? lines[i - 1].length\n : selectionStart,\n };\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString(): string {\n return `#`;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const dims = super._getCacheCanvasDimensions();\n const fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const path = this.path;\n path && !path.isNotVisible() && path._render(ctx);\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n }\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles(\n ctx: CanvasRenderingContext2D,\n charStyle?: any,\n forMeasuring?: boolean,\n ) {\n ctx.textBaseline = 'alphabetic';\n if (this.path) {\n switch (this.pathAlign) {\n case CENTER:\n ctx.textBaseline = 'middle';\n break;\n case 'ascender':\n ctx.textBaseline = TOP;\n break;\n case 'descender':\n ctx.textBaseline = BOTTOM;\n break;\n }\n }\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n }\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of Text object\n */\n calcTextWidth(): number {\n let maxWidth = this.getLineWidth(0);\n\n for (let i = 1, len = this._textLines.length; i < len; i++) {\n const currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n }\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: string[],\n left: number,\n top: number,\n lineIndex: number,\n ) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n }\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground(ctx: CanvasRenderingContext2D) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n const originalFill = ctx.fillStyle,\n leftOffset = this._getLeftOffset();\n let lineTopOffset = this._getTopOffset();\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (\n !this.textBackgroundColor &&\n !this.styleHas('textBackgroundColor', i)\n ) {\n lineTopOffset += heightOfLine;\n continue;\n }\n const jlen = this._textLines[i].length;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxWidth = 0;\n let boxStart = 0;\n let drawStart;\n let currentColor;\n let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < jlen; j++) {\n // at this point charbox are either standard or full with pathInfo if there is a path.\n const charBox = this.__charBounds[i][j] as Required;\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (this.path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillStyle = currentColor;\n currentColor &&\n ctx.fillRect(\n -charBox.width / 2,\n (-heightOfLine / this.lineHeight) * (1 - this._fontSizeFraction),\n charBox.width,\n heightOfLine / this.lineHeight,\n );\n ctx.restore();\n } else if (currentColor !== lastColor) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = lastColor;\n lastColor &&\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor && !this.path) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar(\n _char: string,\n charStyle: CompleteTextStyleDeclaration,\n previousChar: string | undefined,\n prevCharStyle: CompleteTextStyleDeclaration | Record,\n ) {\n const fontCache = cache.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n couple = previousChar + _char,\n stylesAreEqual =\n previousChar &&\n fontDeclaration === this._getFontDeclaration(prevCharStyle),\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE;\n let width: number | undefined,\n coupleWidth: number | undefined,\n previousWidth: number | undefined,\n kernedWidth: number | undefined;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth!;\n }\n if (\n width === undefined ||\n previousWidth === undefined ||\n coupleWidth === undefined\n ) {\n const ctx = getMeasuringContext()!;\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n // safe to use the non-null since if undefined we defined it before.\n kernedWidth = coupleWidth - previousWidth!;\n }\n }\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth! * fontMultiplier,\n };\n }\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar(line: number, _char: number): number {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n }\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n */\n measureLine(lineIndex: number) {\n const lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n }\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine(lineIndex: number) {\n let width = 0,\n prevGrapheme: string | undefined,\n graphemeInfo: GraphemeBBox | undefined;\n\n const reverse = this.pathSide === RIGHT,\n path = this.path,\n line = this._textLines[lineIndex],\n llength = line.length,\n lineBounds = new Array(llength);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (let i = 0; i < llength; i++) {\n const grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[llength] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize,\n deltaY: 0,\n } as GraphemeBBox;\n if (path && path.segmentsInfo) {\n let positionInPath = 0;\n const totalPathLength =\n path.segmentsInfo[path.segmentsInfo.length - 1].length;\n switch (this.textAlign) {\n case LEFT:\n positionInPath = reverse ? totalPathLength - width : 0;\n break;\n case CENTER:\n positionInPath = (totalPathLength - width) / 2;\n break;\n case RIGHT:\n positionInPath = reverse ? 0 : totalPathLength - width;\n break;\n //todo - add support for justify\n }\n positionInPath += this.pathStartOffset * (reverse ? -1 : 1);\n for (\n let i = reverse ? llength - 1 : 0;\n reverse ? i >= 0 : i < llength;\n reverse ? i-- : i++\n ) {\n graphemeInfo = lineBounds[i];\n if (positionInPath > totalPathLength) {\n positionInPath %= totalPathLength;\n } else if (positionInPath < 0) {\n positionInPath += totalPathLength;\n }\n // it would probably much faster to send all the grapheme position for a line\n // and calculate path position/angle at once.\n this._setGraphemeOnPath(positionInPath, graphemeInfo);\n positionInPath += graphemeInfo.kernedWidth;\n }\n }\n return { width: width, numOfSpaces: 0 };\n }\n\n /**\n * Calculate the angle and the left,top position of the char that follow a path.\n * It appends it to graphemeInfo to be reused later at rendering\n * @private\n * @param {Number} positionInPath to be measured\n * @param {GraphemeBBox} graphemeInfo current grapheme box information\n * @param {Object} startingPoint position of the point\n */\n _setGraphemeOnPath(positionInPath: number, graphemeInfo: GraphemeBBox) {\n const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,\n path = this.path!;\n\n // we are at currentPositionOnPath. we want to know what point on the path is.\n const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo)!;\n graphemeInfo.renderLeft = info.x - path.pathOffset.x;\n graphemeInfo.renderTop = info.y - path.pathOffset.y;\n graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0);\n }\n\n /**\n *\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n * @returns {GraphemeBBox} grapheme bbox\n */\n _getGraphemeBox(\n grapheme: string,\n lineIndex: number,\n charIndex: number,\n prevGrapheme?: string,\n skipLeft?: boolean,\n ): GraphemeBBox {\n const style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1)\n : {},\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle);\n let kernedWidth = info.kernedWidth,\n width = info.width,\n charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n const box: GraphemeBBox = {\n width,\n left: 0,\n height: style.fontSize,\n kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n const previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left =\n previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n }\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine(lineIndex: number): number {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n // char 0 is measured before the line cycle because it needs to char\n // emptylines\n let maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return (this.__lineHeights[lineIndex] =\n maxHeight * this.lineHeight * this._fontSizeMult);\n }\n\n /**\n * Calculate text box height\n */\n calcTextHeight() {\n let lineHeight,\n height = 0;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;\n }\n return height;\n }\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset(): number {\n return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;\n }\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset(): number {\n return -this.height / 2;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon(\n ctx: CanvasRenderingContext2D,\n method: 'fillText' | 'strokeText',\n ) {\n ctx.save();\n let lineHeights = 0;\n const left = this._getLeftOffset(),\n top = this._getTopOffset();\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i,\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill && !this.styleHas(FILL)) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke(ctx: CanvasRenderingContext2D) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n }\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: Array,\n left: number,\n top: number,\n lineIndex: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n path = this.path,\n shortCut =\n !isJustify &&\n this.charSpacing === 0 &&\n this.isEmptyStyles(lineIndex) &&\n !path,\n isLtr = this.direction === 'ltr',\n sign = this.direction === 'ltr' ? 1 : -1,\n // this was changed in the PR #7674\n // currentDirection = ctx.canvas.getAttribute('dir');\n currentDirection = ctx.direction;\n\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n drawingLeft;\n\n ctx.save();\n if (currentDirection !== this.direction) {\n ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');\n ctx.direction = isLtr ? 'ltr' : 'rtl';\n ctx.textAlign = isLtr ? LEFT : RIGHT;\n }\n top -= (lineHeight * this._fontSizeFraction) / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top);\n ctx.restore();\n return;\n }\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing || path;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i] as Required;\n if (boxWidth === 0) {\n left += sign * (charBox.kernedWidth - charBox.width);\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, false);\n }\n if (timeToRender) {\n if (path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n -boxWidth / 2,\n 0,\n );\n ctx.restore();\n } else {\n drawingLeft = left;\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n drawingLeft,\n top,\n );\n }\n charsToRender = '';\n actualStyle = nextStyle;\n left += sign * boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {TFiller} filler a fabric gradient instance\n * @return {CanvasPattern} a pattern to use as fill/stroke style\n */\n _applyPatternGradientTransformText(filler: TFiller) {\n const pCanvas = createCanvasElement(),\n // TODO: verify compatibility with strokeUniform\n width = this.width + this.strokeWidth,\n height = this.height + this.strokeWidth,\n pCtx = pCanvas.getContext('2d')!;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.fillStyle = filler.toLive(pCtx)!;\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fill();\n return pCtx.createPattern(pCanvas, 'no-repeat')!;\n }\n\n handleFiller(\n ctx: CanvasRenderingContext2D,\n property: `${T}Style`,\n filler: TFiller | string,\n ): { offsetX: number; offsetY: number } {\n let offsetX: number, offsetY: number;\n if (isFiller(filler)) {\n if (\n (filler as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n offsetX = -this.width / 2;\n offsetY = -this.height / 2;\n ctx.translate(offsetX, offsetY);\n ctx[property] = this._applyPatternGradientTransformText(filler);\n return { offsetX, offsetY };\n } else {\n // is a simple gradient or pattern\n ctx[property] = filler.toLive(ctx)!;\n return this._applyPatternGradientTransform(ctx, filler);\n }\n } else {\n // is a color\n ctx[property] = filler;\n }\n return { offsetX: 0, offsetY: 0 };\n }\n\n /**\n * This function prepare the canvas for a stroke style, and stroke and strokeWidth\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined\n * @returns\n */\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n {\n stroke,\n strokeWidth,\n }: Pick,\n ) {\n ctx.lineWidth = strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineDashOffset = this.strokeDashOffset;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n return this.handleFiller(ctx, 'strokeStyle', stroke!);\n }\n\n /**\n * This function prepare the canvas for a ill style, and fill\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with ill defined\n * @returns\n */\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n return this.handleFiller(ctx, 'fillStyle', fill!);\n }\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n lineIndex: number,\n charIndex: number,\n _char: string,\n left: number,\n top: number,\n ) {\n const decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke =\n method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n ctx.save();\n\n ctx.font = this._getFontDeclaration(fullDecl);\n\n if (decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl.deltaY) {\n top += decl.deltaY;\n }\n\n if (shouldFill) {\n const fillOffsets = this._setFillStyles(ctx, fullDecl);\n ctx.fillText(\n _char,\n left - fillOffsets.offsetX,\n top - fillOffsets.offsetY,\n );\n }\n\n if (shouldStroke) {\n const strokeOffsets = this._setStrokeStyles(ctx, fullDecl);\n ctx.strokeText(\n _char,\n left - strokeOffsets.offsetX,\n top - strokeOffsets.offsetY,\n );\n }\n\n ctx.restore();\n }\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSuperscript(start: number, end: number) {\n this._setScript(start, end, this.superscript);\n }\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSubscript(start: number, end: number) {\n this._setScript(start, end, this.subscript);\n }\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n */\n protected _setScript(\n start: number,\n end: number,\n schema: {\n size: number;\n baseline: number;\n },\n ) {\n const loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(\n loc.lineIndex,\n loc.charIndex,\n 'fontSize',\n ),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline,\n };\n this.setSelectionStyles(style, start, end);\n }\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset(lineIndex: number): number {\n const lineWidth = this.getLineWidth(lineIndex),\n lineDiff = this.width - lineWidth,\n textAlign = this.textAlign,\n direction = this.direction,\n isEndOfWrapping = this.isEndOfWrapping(lineIndex);\n let leftOffset = 0;\n if (\n textAlign === JUSTIFY ||\n (textAlign === JUSTIFY_CENTER && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_RIGHT && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_LEFT && !isEndOfWrapping)\n ) {\n return 0;\n }\n if (textAlign === CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === RIGHT) {\n leftOffset = lineDiff;\n }\n if (textAlign === JUSTIFY_CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === JUSTIFY_RIGHT) {\n leftOffset = lineDiff;\n }\n if (direction === 'rtl') {\n if (\n textAlign === RIGHT ||\n textAlign === JUSTIFY ||\n textAlign === JUSTIFY_RIGHT\n ) {\n leftOffset = 0;\n } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) {\n leftOffset = -lineDiff;\n } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) {\n leftOffset = -lineDiff / 2;\n }\n }\n return leftOffset;\n }\n\n /**\n * @private\n */\n _clearCache() {\n this._forceClearCache = false;\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n }\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth(lineIndex: number): number {\n if (this.__lineWidths[lineIndex] !== undefined) {\n return this.__lineWidths[lineIndex];\n }\n\n const { width } = this.measureLine(lineIndex);\n this.__lineWidths[lineIndex] = width;\n return width;\n }\n\n _getWidthOfCharSpacing() {\n if (this.charSpacing !== 0) {\n return (this.fontSize * this.charSpacing) / 1000;\n }\n return 0;\n }\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the character number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt(\n lineIndex: number,\n charIndex: number,\n property: T,\n ): this[T] {\n const charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n return (charStyle[property] ?? this[property]) as this[T];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration(\n ctx: CanvasRenderingContext2D,\n type: 'underline' | 'linethrough' | 'overline',\n ) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n let topOffset = this._getTopOffset();\n const leftOffset = this._getLeftOffset(),\n path = this.path,\n charSpacing = this._getWidthOfCharSpacing(),\n offsetY = this.offsets[type];\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n const line = this._textLines[i];\n const maxHeight = heightOfLine / this.lineHeight;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxStart = 0;\n let boxWidth = 0;\n let lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n let lastFill = this.getValueOfPropertyAt(i, 0, FILL);\n let currentDecoration;\n let currentFill;\n const top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n let size = this.getHeightOfChar(i, 0);\n let dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n const charBox = this.__charBounds[i][j] as Required;\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, FILL);\n const currentSize = this.getHeightOfChar(i, j);\n const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if (path && currentDecoration && currentFill) {\n ctx.save();\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillRect(\n -charBox.kernedWidth / 2,\n offsetY * currentSize + currentDy,\n charBox.kernedWidth,\n this.fontSize / 15,\n );\n ctx.restore();\n } else if (\n (currentDecoration !== lastDecoration ||\n currentFill !== lastFill ||\n currentSize !== size ||\n currentDy !== dy) &&\n boxWidth > 0\n ) {\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n if (lastDecoration && lastFill) {\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth,\n this.fontSize / 15,\n );\n }\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = currentSize;\n dy = currentDy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentFill as string;\n currentDecoration &&\n currentFill &&\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15,\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration(\n {\n fontFamily = this.fontFamily,\n fontStyle = this.fontStyle,\n fontWeight = this.fontWeight,\n fontSize = this.fontSize,\n }: Partial<\n Pick<\n TextStyleDeclaration,\n 'fontFamily' | 'fontStyle' | 'fontWeight' | 'fontSize'\n >\n > = {},\n forMeasuring?: boolean,\n ): string {\n const parsedFontFamily =\n fontFamily.includes(\"'\") ||\n fontFamily.includes('\"') ||\n fontFamily.includes(',') ||\n FabricText.genericFonts.includes(fontFamily.toLowerCase())\n ? fontFamily\n : `\"${fontFamily}\"`;\n return [\n fontStyle,\n fontWeight,\n `${forMeasuring ? this.CACHE_FONT_SIZE : fontSize}px`,\n parsedFontFamily,\n ].join(' ');\n }\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n if (!this.visible) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n if (this._forceClearCache) {\n this.initDimensions();\n }\n super.render(ctx);\n }\n\n /**\n * Override this method to customize grapheme splitting\n * @todo the util `graphemeSplit` needs to be injectable in some way.\n * is more comfortable to inject the correct util rather than having to override text\n * in the middle of the prototype chain\n * @param {string} value\n * @returns {string[]} array of graphemes\n */\n graphemeSplit(value: string): string[] {\n return graphemeSplit(value);\n }\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns Lines in the text\n */\n _splitTextIntoLines(text: string): TextLinesInfo {\n const lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'];\n let newText: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n newLines[i] = this.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines,\n };\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject([...additionalProps, ...propertiesToInclude] as K[]),\n styles: stylesToArray(this.styles, this.text),\n ...(this.path ? { path: this.path.toObject() } : {}),\n };\n }\n\n set(key: string | any, value?: any) {\n const { textLayoutProperties } = this.constructor as typeof FabricText;\n super.set(key, value);\n let needsDims = false;\n let isAddingPath = false;\n if (typeof key === 'object') {\n for (const _key in key) {\n if (_key === 'path') {\n this.setPathInfo();\n }\n needsDims = needsDims || textLayoutProperties.includes(_key);\n isAddingPath = isAddingPath || _key === 'path';\n }\n } else {\n needsDims = textLayoutProperties.includes(key);\n isAddingPath = key === 'path';\n }\n if (isAddingPath) {\n this.setPathInfo();\n }\n if (needsDims && this.initialized) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity(): number {\n return 1;\n }\n\n static genericFonts = [\n 'sans-serif',\n 'serif',\n 'cursive',\n 'fantasy',\n 'monospace',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})\n * @static\n * @memberOf Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'font-family',\n 'font-style',\n 'font-weight',\n 'font-size',\n 'letter-spacing',\n 'text-decoration',\n 'text-anchor',\n );\n\n /**\n * Returns FabricText instance from an SVG element (not yet implemented)\n * @static\n * @memberOf Text\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n FabricText.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n const {\n textAnchor = LEFT as typeof LEFT | typeof CENTER | typeof RIGHT,\n textDecoration = '',\n dx = 0,\n dy = 0,\n top = 0,\n left = 0,\n fontSize = DEFAULT_SVG_FONT_SIZE,\n strokeWidth = 1,\n ...restOfOptions\n } = { ...options, ...parsedAttributes };\n\n const textContent = (element.textContent || '')\n .replace(/^\\s+|\\s+$|\\n+/g, '')\n .replace(/\\s+/g, ' ');\n\n // this code here is probably the usual issue for SVG center find\n // this can later looked at again and probably removed.\n\n const text = new this(textContent, {\n left: left + dx,\n top: top + dy,\n underline: textDecoration.includes('underline'),\n overline: textDecoration.includes('overline'),\n linethrough: textDecoration.includes('line-through'),\n // we initialize this as 0\n strokeWidth: 0,\n fontSize,\n ...restOfOptions,\n }),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff =\n (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff;\n\n let offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (textAnchor === CENTER) {\n offX = text.getScaledWidth() / 2;\n }\n if (textAnchor === RIGHT) {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top:\n text.top -\n (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) /\n text.lineHeight,\n strokeWidth,\n });\n return text;\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns FabricText instance from an object representation\n * @param {Object} object plain js Object to create an instance from\n * @returns {Promise}\n */\n static fromObject<\n T extends TOptions,\n S extends FabricText,\n >(object: T) {\n return this._fromObject(\n {\n ...object,\n styles: stylesFromArray(object.styles || {}, object.text),\n },\n {\n extraParam: 'text',\n },\n );\n }\n}\n\napplyMixins(FabricText, [TextSVGExportMixin]);\nclassRegistry.setClass(FabricText);\nclassRegistry.setSVGClass(FabricText);\n","import type {\n DragEventData,\n DropEventData,\n TPointerEvent,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { IText } from './IText';\nimport { setStyle } from '../../util/dom_style';\nimport { cloneStyles } from '../../util/internals/cloneStyles';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, NONE } from '../../constants';\n\n/**\n * #### Dragging IText/Textbox Lifecycle\n * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection}\n * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection\n * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session\n * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur\n * - canvas fires relevant drag events that are handled by the handlers defined in this scope\n * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior\n * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown`\n */\nexport class DraggableTextDelegate {\n readonly target: IText;\n private __mouseDownInPlace = false;\n private __dragStartFired = false;\n private __isDraggingOver = false;\n private __dragStartSelection?: {\n selectionStart: number;\n selectionEnd: number;\n };\n private __dragImageDisposer?: VoidFunction;\n private _dispose?: () => void;\n\n constructor(target: IText) {\n this.target = target;\n const disposers = [\n this.target.on('dragenter', this.dragEnterHandler.bind(this)),\n this.target.on('dragover', this.dragOverHandler.bind(this)),\n this.target.on('dragleave', this.dragLeaveHandler.bind(this)),\n this.target.on('dragend', this.dragEndHandler.bind(this)),\n this.target.on('drop', this.dropHandler.bind(this)),\n ];\n this._dispose = () => {\n disposers.forEach((d) => d());\n this._dispose = undefined;\n };\n }\n\n isPointerOverSelection(e: TPointerEvent) {\n const target = this.target;\n const newSelection = target.getSelectionStartFromPointer(e);\n return (\n target.isEditing &&\n newSelection >= target.selectionStart &&\n newSelection <= target.selectionEnd &&\n target.selectionStart < target.selectionEnd\n );\n }\n\n /**\n * @public override this method to disable dragging and default to mousedown logic\n */\n start(e: TPointerEvent) {\n return (this.__mouseDownInPlace = this.isPointerOverSelection(e));\n }\n\n /**\n * @public override this method to disable dragging without discarding selection\n */\n isActive() {\n return this.__mouseDownInPlace;\n }\n\n /**\n * Ends interaction and sets cursor in case of a click\n * @returns true if was active\n */\n end(e: TPointerEvent) {\n const active = this.isActive();\n if (active && !this.__dragStartFired) {\n // mousedown has been blocked since `active` is true => cursor has not been set.\n // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection.\n // meaning this is actually a click, `active` is a false positive.\n this.target.setCursorByClick(e);\n this.target.initDelayedCursor(true);\n }\n this.__mouseDownInPlace = false;\n this.__dragStartFired = false;\n this.__isDraggingOver = false;\n return active;\n }\n\n getDragStartSelection() {\n return this.__dragStartSelection;\n }\n\n /**\n * Override to customize the drag image\n * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage\n */\n setDragImage(\n e: DragEvent,\n {\n selectionStart,\n selectionEnd,\n }: {\n selectionStart: number;\n selectionEnd: number;\n },\n ) {\n const target = this.target;\n const canvas = target.canvas!;\n const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1);\n const boundaries = target._getCursorBoundaries(selectionStart);\n const selectionPosition = new Point(\n boundaries.left + boundaries.leftOffset,\n boundaries.top + boundaries.topOffset,\n ).multiply(flipFactor);\n const pos = selectionPosition.transform(target.calcTransformMatrix());\n const pointer = canvas.getScenePoint(e);\n const diff = pointer.subtract(pos);\n const retinaScaling = target.getCanvasRetinaScaling();\n const bbox = target.getBoundingRect();\n const correction = pos.subtract(new Point(bbox.left, bbox.top));\n const vpt = canvas.viewportTransform;\n const offset = correction.add(diff).transform(vpt, true);\n // prepare instance for drag image snapshot by making all non selected text invisible\n const bgc = target.backgroundColor;\n const styles = cloneStyles(target.styles);\n target.backgroundColor = '';\n const styleOverride = {\n stroke: 'transparent',\n fill: 'transparent',\n textBackgroundColor: 'transparent',\n };\n target.setSelectionStyles(styleOverride, 0, selectionStart);\n target.setSelectionStyles(styleOverride, selectionEnd, target.text.length);\n target.dirty = true;\n const dragImage = target.toCanvasElement({\n enableRetinaScaling: canvas.enableRetinaScaling,\n viewportTransform: true,\n });\n // restore values\n target.backgroundColor = bgc;\n target.styles = styles;\n target.dirty = true;\n // position drag image offscreen\n setStyle(dragImage, {\n position: 'fixed',\n left: `${-dragImage.width}px`,\n border: NONE,\n width: `${dragImage.width / retinaScaling}px`,\n height: `${dragImage.height / retinaScaling}px`,\n });\n this.__dragImageDisposer && this.__dragImageDisposer();\n this.__dragImageDisposer = () => {\n dragImage.remove();\n };\n getDocumentFromElement(\n (e.target || this.target.hiddenTextarea)! as HTMLElement,\n ).body.appendChild(dragImage);\n e.dataTransfer?.setDragImage(dragImage, offset.x, offset.y);\n }\n\n /**\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source\n */\n onDragStart(e: DragEvent): boolean {\n this.__dragStartFired = true;\n const target = this.target;\n const active = this.isActive();\n if (active && e.dataTransfer) {\n const selection = (this.__dragStartSelection = {\n selectionStart: target.selectionStart,\n selectionEnd: target.selectionEnd,\n });\n const value = target._text\n .slice(selection.selectionStart, selection.selectionEnd)\n .join('');\n const data = { text: target.text, value, ...selection };\n e.dataTransfer.setData('text/plain', value);\n e.dataTransfer.setData(\n 'application/fabric',\n JSON.stringify({\n value: value,\n styles: target.getSelectionStyles(\n selection.selectionStart,\n selection.selectionEnd,\n true,\n ),\n }),\n );\n e.dataTransfer.effectAllowed = 'copyMove';\n this.setDragImage(e, data);\n }\n target.abortCursorAnimation();\n return active;\n }\n\n /**\n * use {@link targetCanDrop} to respect overriding\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target\n */\n canDrop(e: DragEvent): boolean {\n if (\n this.target.editable &&\n !this.target.getActiveControl() &&\n !e.defaultPrevented\n ) {\n if (this.isActive() && this.__dragStartSelection) {\n // drag source trying to drop over itself\n // allow dropping only outside of drag start selection\n const index = this.target.getSelectionStartFromPointer(e);\n const dragStartSelection = this.__dragStartSelection;\n return (\n index < dragStartSelection.selectionStart ||\n index > dragStartSelection.selectionEnd\n );\n }\n return true;\n }\n return false;\n }\n\n /**\n * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly\n */\n protected targetCanDrop(e: DragEvent) {\n return this.target.canDrop(e);\n }\n\n dragEnterHandler({ e }: DragEventData) {\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n }\n }\n\n dragOverHandler(ev: DragEventData) {\n const { e } = ev;\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n } else if (this.__isDraggingOver && !canDrop) {\n // drop state has changed\n this.__isDraggingOver = false;\n }\n if (this.__isDraggingOver) {\n // can be dropped, inform browser\n e.preventDefault();\n // inform event subscribers\n ev.canDrop = true;\n ev.dropTarget = this.target;\n }\n }\n\n dragLeaveHandler() {\n if (this.__isDraggingOver || this.isActive()) {\n this.__isDraggingOver = false;\n }\n }\n\n /**\n * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer}\n * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop\n */\n dropHandler(ev: DropEventData) {\n const { e } = ev;\n const didDrop = e.defaultPrevented;\n this.__isDraggingOver = false;\n // inform browser that the drop has been accepted\n e.preventDefault();\n let insert = e.dataTransfer?.getData('text/plain');\n if (insert && !didDrop) {\n const target = this.target;\n const canvas = target.canvas!;\n let insertAt = target.getSelectionStartFromPointer(e);\n const { styles } = (\n e.dataTransfer!.types.includes('application/fabric')\n ? JSON.parse(e.dataTransfer!.getData('application/fabric'))\n : {}\n ) as { styles: TextStyleDeclaration[] };\n const trailing = insert[Math.max(0, insert.length - 1)];\n const selectionStartOffset = 0;\n // drag and drop in same instance\n if (this.__dragStartSelection) {\n const selectionStart = this.__dragStartSelection.selectionStart;\n const selectionEnd = this.__dragStartSelection.selectionEnd;\n if (insertAt > selectionStart && insertAt <= selectionEnd) {\n insertAt = selectionStart;\n } else if (insertAt > selectionEnd) {\n insertAt -= selectionEnd - selectionStart;\n }\n target.removeChars(selectionStart, selectionEnd);\n // prevent `dragend` from handling event\n delete this.__dragStartSelection;\n }\n // remove redundant line break\n if (\n target._reNewline.test(trailing) &&\n (target._reNewline.test(target._text[insertAt]) ||\n insertAt === target._text.length)\n ) {\n insert = insert.trimEnd();\n }\n // inform subscribers\n ev.didDrop = true;\n ev.dropTarget = target;\n // finalize\n target.insertChars(insert, styles, insertAt);\n // can this part be moved in an outside event? andrea to check.\n canvas.setActiveObject(target);\n target.enterEditing(e);\n target.selectionStart = Math.min(\n insertAt + selectionStartOffset,\n target._text.length,\n );\n target.selectionEnd = Math.min(\n target.selectionStart + insert.length,\n target._text.length,\n );\n target.hiddenTextarea!.value = target.text;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n target.fire(CHANGED, {\n index: insertAt + selectionStartOffset,\n action: 'drop',\n });\n canvas.fire('text:changed', { target });\n canvas.contextTopDirty = true;\n canvas.requestRenderAll();\n }\n }\n\n /**\n * fired only on the drag source after drop (if occurred)\n * handle changes to the drag source in case of a drop on another object or a cancellation\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n */\n dragEndHandler({ e }: DragEventData) {\n if (this.isActive() && this.__dragStartFired) {\n // once the drop event finishes we check if we need to change the drag source\n // if the drag source received the drop we bail out since the drop handler has already handled logic\n if (this.__dragStartSelection) {\n const target = this.target;\n const canvas = this.target.canvas!;\n const { selectionStart, selectionEnd } = this.__dragStartSelection;\n const dropEffect = e.dataTransfer?.dropEffect || NONE;\n if (dropEffect === NONE) {\n // pointer is back over selection\n target.selectionStart = selectionStart;\n target.selectionEnd = selectionEnd;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n } else {\n target.clearContextTop();\n if (dropEffect === 'move') {\n target.removeChars(selectionStart, selectionEnd);\n target.selectionStart = target.selectionEnd = selectionStart;\n target.hiddenTextarea &&\n (target.hiddenTextarea.value = target.text);\n target._updateTextarea();\n target.fire(CHANGED, {\n index: selectionStart,\n action: 'dragend',\n });\n canvas.fire('text:changed', { target });\n canvas.requestRenderAll();\n }\n target.exitEditing();\n }\n }\n }\n\n this.__dragImageDisposer && this.__dragImageDisposer();\n delete this.__dragImageDisposer;\n delete this.__dragStartSelection;\n this.__isDraggingOver = false;\n }\n\n dispose() {\n this._dispose && this._dispose();\n }\n}\n","import type {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends FabricText {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean,\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n },\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1),\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n this.canvas.fire('text:editing:entered', {\n target: this as unknown as IText,\n e,\n });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[],\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text,\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value,\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight,\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight,\n ),\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire(MODIFIED);\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true,\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration },\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle,\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength,\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start,\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number,\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\n","import { config } from '../../config';\nimport { getFabricDocument, getEnv } from '../../env';\nimport { capValue } from '../../util/misc/capValue';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextBehavior } from './ITextBehavior';\nimport type { TKeyMapIText } from './constants';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\nimport type { IText } from './IText';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\n\nexport abstract class ITextKeyBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextBehavior {\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behavior for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the IText or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = Object.assign({}, this.keysMap);\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\n */\n declare keysMap: TKeyMapIText;\n\n declare keysMapRtl: TKeyMapIText;\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n declare ctrlKeysMapUp: TKeyMapIText;\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n declare ctrlKeysMapDown: TKeyMapIText;\n\n declare hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * DOM container to append the hiddenTextarea.\n * An alternative to attaching to the document.body.\n * Useful to reduce laggish redraw of the full document.body tree and\n * also with modals event capturing that won't let the textarea take focus.\n * @type HTMLElement\n * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare fromPaste: boolean;\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea() {\n const doc =\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument();\n const textarea = doc.createElement('textarea');\n Object.entries({\n autocapitalize: 'off',\n autocorrect: 'off',\n autocomplete: 'off',\n spellcheck: 'false',\n 'data-fabric': 'textarea',\n wrap: 'off',\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\n const { top, left, fontSize } = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\n\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\n\n Object.entries({\n blur: 'blur',\n keydown: 'onKeyDown',\n keyup: 'onKeyUp',\n input: 'onInput',\n copy: 'copy',\n cut: 'copy',\n paste: 'paste',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate',\n compositionend: 'onCompositionEnd',\n } as Record).map(([eventName, handler]) =>\n textarea.addEventListener(\n eventName,\n (this[handler] as EventListener).bind(this),\n ),\n );\n this.hiddenTextarea = textarea;\n }\n\n /**\n * Override this method to customize cursor behavior on textbox blur\n */\n blur() {\n this.abortCursorAnimation();\n }\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {KeyboardEvent} e Event object\n */\n onKeyDown(e: KeyboardEvent) {\n if (!this.isEditing) {\n return;\n }\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\n if (e.keyCode in keyMap) {\n // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n }\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {KeyboardEvent} e Event object\n */\n onKeyUp(e: KeyboardEvent) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n }\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\n const fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n const updateAndFire = () => {\n this.updateFromTextArea();\n this.fire(CHANGED);\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this as unknown as IText });\n this.canvas.requestRenderAll();\n }\n };\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n updateAndFire();\n return;\n }\n // decisions about style changes.\n const nextText = this._splitTextIntoLines(\n this.hiddenTextarea.value,\n ).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd;\n let copiedStyle: TextStyleDeclaration[] | undefined,\n removedText,\n charDiff = nextCharCount - charCount,\n removeFrom,\n removeTo;\n\n const textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value,\n );\n const backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(\n selectionStart,\n selectionStart - charDiff,\n );\n }\n }\n const insertedText = nextText.slice(\n textareaSelection.selectionEnd - charDiff,\n textareaSelection.selectionEnd,\n );\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(\n selectionStart,\n selectionStart + 1,\n false,\n );\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(\n () =>\n // this return an array of references, but that is fine since we are\n // copying the style later.\n copiedStyle![0],\n );\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differences between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n const { copyPasteData } = getEnv();\n if (\n fromPaste &&\n insertedText.join('') === copyPasteData.copiedText &&\n !config.disableStyleCopyPaste\n ) {\n copiedStyle = copyPasteData.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n updateAndFire();\n }\n\n /**\n * Composition start\n */\n onCompositionStart() {\n this.inCompositionMode = true;\n }\n\n /**\n * Composition end\n */\n onCompositionEnd() {\n this.inCompositionMode = false;\n }\n\n onCompositionUpdate({ target }: CompositionEvent) {\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\n this.compositionStart = selectionStart;\n this.compositionEnd = selectionEnd;\n this.updateTextareaPosition();\n }\n\n /**\n * Copies selected text\n */\n copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n const { copyPasteData } = getEnv();\n copyPasteData.copiedText = this.getSelectedText();\n if (!config.disableStyleCopyPaste) {\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\n this.selectionStart,\n this.selectionEnd,\n true,\n );\n } else {\n copyPasteData.copiedTextStyle = undefined;\n }\n this._copyDone = true;\n }\n\n /**\n * Pastes text\n */\n paste() {\n this.fromPaste = true;\n }\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n }\n\n /**\n * Gets start offset of a selection\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (\n lineIndex === this._textLines.length - 1 ||\n e.metaKey ||\n e.keyCode === 34\n ) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return (\n textAfterCursor.length +\n indexOnOtherLine +\n 1 +\n this.missingNewlineOffset(lineIndex)\n );\n }\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n }\n\n /**\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return (\n -this._textLines[lineIndex - 1].length +\n indexOnOtherLine -\n textBeforeCursor.length +\n (1 - missingNewlineOffset)\n );\n }\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine(lineIndex: number, width: number) {\n const line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n let widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n const leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n }\n\n /**\n * Moves cursor down\n * @param {KeyboardEvent} e Event object\n */\n moveCursorDown(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n }\n\n /**\n * Moves cursor up\n * @param {KeyboardEvent} e Event object\n */\n moveCursorUp(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n }\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\n const offset = this[`get${direction}CursorOffset`](\n e,\n this._selectionDirection === RIGHT,\n );\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n const max = this.text.length;\n this.selectionStart = capValue(0, this.selectionStart, max);\n this.selectionEnd = capValue(0, this.selectionEnd, max);\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift(offset: number) {\n const newSelection =\n this._selectionDirection === LEFT\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(\n this.selectionStart,\n this.selectionEnd,\n newSelection,\n );\n return offset !== 0;\n }\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift(offset: number) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n }\n\n /**\n * Moves cursor left\n * @param {KeyboardEvent} e Event object\n */\n moveCursorLeft(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n }\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n *\n * @todo refactor not to use method name composition\n */\n _move(\n e: KeyboardEvent,\n prop: 'selectionStart' | 'selectionEnd',\n direction: 'Left' | 'Right',\n ): boolean {\n let newValue: number | undefined;\n if (e.altKey) {\n newValue = this[`findWordBoundary${direction}`](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this[`findLineBoundary${direction}`](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n return false;\n }\n\n /**\n * @private\n */\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Left');\n }\n\n /**\n * @private\n */\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Right');\n }\n\n /**\n * Moves cursor left without keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\n let change = true;\n this._selectionDirection = LEFT;\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (\n this.selectionEnd === this.selectionStart &&\n this.selectionStart !== 0\n ) {\n change = this._moveLeft(e, 'selectionStart');\n }\n this.selectionEnd = this.selectionStart;\n return change;\n }\n\n /**\n * Moves cursor left while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === RIGHT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = LEFT;\n return this._moveLeft(e, 'selectionStart');\n }\n }\n\n /**\n * Moves cursor right\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRight(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n }\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\n const actionName = `moveCursor${direction}${\n e.shiftKey ? 'WithShift' : 'WithoutShift'\n }` as const;\n this._currentCursorOpacity = 1;\n if (this[actionName](e)) {\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor right while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorRightWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === LEFT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = RIGHT;\n return this._moveRight(e, 'selectionEnd');\n }\n }\n\n /**\n * Moves cursor right without keeping selection\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRightWithoutShift(e: KeyboardEvent) {\n let changed = true;\n this._selectionDirection = RIGHT;\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n }\n}\n","import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { stopEvent } from '../../util/dom_event';\nimport { invertTransform } from '../../util/misc/matrix';\nimport { DraggableTextDelegate } from './DraggableTextDelegate';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextKeyBehavior } from './ITextKeyBehavior';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\n\n/**\n * `LEFT_CLICK === 0`\n */\nconst notALeftClick = (e: Event) => !!(e as MouseEvent).button;\n\nexport abstract class ITextClickBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextKeyBehavior {\n private declare __lastSelected: boolean;\n private declare __lastClickTime: number;\n private declare __lastLastClickTime: number;\n private declare __lastPointer: XY | Record;\n private declare __newClickTime: number;\n\n protected draggableTextDelegate: DraggableTextDelegate;\n\n initBehavior() {\n // Initializes event handlers related to cursor or selection\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n this.on('mouseup', this.mouseUpHandler);\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n\n // Initializes \"dbclick\" event handler\n this.__lastClickTime = +new Date();\n // for triple click\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n\n // @ts-expect-error in reality it is an IText instance\n this.draggableTextDelegate = new DraggableTextDelegate(this);\n\n super.initBehavior();\n }\n\n /**\n * If this method returns true a mouse move operation over a text selection\n * will not prevent the native mouse event allowing the browser to start a drag operation.\n * shouldStartDragging can be read 'do not prevent default for mouse move event'\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns\n */\n shouldStartDragging() {\n return this.draggableTextDelegate.isActive();\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drag source,\n * @see also {@link DraggableTextDelegate#isActive}\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns {boolean} should handle event\n */\n onDragStart(e: DragEvent) {\n return this.draggableTextDelegate.onDragStart(e);\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drop target\n */\n canDrop(e: DragEvent) {\n return this.draggableTextDelegate.canDrop(e);\n }\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown(options: TPointerEventInfo) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n const newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastSelected = this.selected && !this.getActiveControl();\n }\n\n isTripleClick(newPointer: XY) {\n return (\n this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y\n );\n }\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler({ e }: TPointerEventInfo) {\n if (\n !this.canvas ||\n !this.editable ||\n notALeftClick(e) ||\n this.getActiveControl()\n ) {\n return;\n }\n\n if (this.draggableTextDelegate.start(e)) {\n return;\n }\n\n this.canvas.textEditingManager.register(this);\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore({ e }: TPointerEventInfo) {\n if (!this.canvas || !this.editable || notALeftClick(e)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n }\n\n /**\n * standard handler for mouse up, overridable\n * @private\n */\n mouseUpHandler({ e, transform }: TPointerEventInfo) {\n const didDrag = this.draggableTextDelegate.end(e);\n if (this.canvas) {\n this.canvas.textEditingManager.unregister(this);\n\n const activeObject = this.canvas._activeObject;\n if (activeObject && activeObject !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n if (\n !this.editable ||\n (this.group && !this.group.interactive) ||\n (transform && transform.actionPerformed) ||\n notALeftClick(e) ||\n didDrag\n ) {\n return;\n }\n\n if (this.__lastSelected && !this.getActiveControl()) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\n }\n } else {\n this.selected = true;\n }\n }\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {TPointerEvent} e Event object\n */\n setCursorByClick(e: TPointerEvent) {\n const newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {TPointerEvent} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer(e: TPointerEvent): number {\n const mouseOffset = this.canvas!.getScenePoint(e)\n .transform(invertTransform(this.calcTransformMatrix()))\n .add(new Point(-this._getLeftOffset(), -this._getTopOffset()));\n let height = 0,\n charIndex = 0,\n lineIndex = 0;\n\n for (let i = 0; i < this._textLines.length; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i);\n lineIndex = i;\n if (i > 0) {\n charIndex +=\n this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex));\n let width = lineLeftOffset;\n const charLength = this._textLines[lineIndex].length;\n const chars = this.__charBounds[lineIndex];\n for (let j = 0; j < charLength; j++) {\n // i removed something about flipX here, check.\n const charWidth = chars[j].kernedWidth;\n const widthAfter = width + charWidth;\n if (mouseOffset.x <= widthAfter) {\n // if the pointer is closer to the end of the char we increment charIndex\n // in order to position the cursor after the char\n if (\n Math.abs(mouseOffset.x - widthAfter) <=\n Math.abs(mouseOffset.x - width)\n ) {\n charIndex++;\n }\n break;\n }\n width = widthAfter;\n charIndex++;\n }\n\n return Math.min(\n // if object is horizontally flipped, mirror cursor location from the end\n this.flipX ? charLength - charIndex : charIndex,\n this._text.length,\n );\n }\n}\n","export type TKeyMapIText = Record<\n KeyboardEvent['keyCode'],\n CursorHandlingMethods\n>;\n\nexport type CursorHandlingMethods =\n | 'moveCursorUp'\n | 'moveCursorDown'\n | 'moveCursorLeft'\n | 'moveCursorRight'\n | 'exitEditing'\n | 'copy'\n | 'cut'\n | 'selectAll';\n\nconst MOVE_CURSOR_UP: CursorHandlingMethods = 'moveCursorUp';\nconst MOVE_CURSOR_DOWN: CursorHandlingMethods = 'moveCursorDown';\nconst MOVE_CURSOR_LEFT: CursorHandlingMethods = 'moveCursorLeft';\nconst MOVE_CURSOR_RIGHT: CursorHandlingMethods = 'moveCursorRight';\nconst EXIT_EDITING: CursorHandlingMethods = 'exitEditing';\n\n// @TODO look into import { Key } from 'ts-key-enum';\n// and transition from keyCode to Key\n// also reduce string duplication\nexport const keysMap: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_RIGHT,\n 36: MOVE_CURSOR_LEFT,\n 37: MOVE_CURSOR_LEFT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_RIGHT,\n 40: MOVE_CURSOR_DOWN,\n};\n\nexport const keysMapRtl: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_LEFT,\n 36: MOVE_CURSOR_RIGHT,\n 37: MOVE_CURSOR_RIGHT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_LEFT,\n 40: MOVE_CURSOR_DOWN,\n};\n\n/**\n * For functionalities on keyUp + ctrl || cmd\n */\nexport const ctrlKeysMapUp: TKeyMapIText = {\n 67: 'copy',\n // there was a reason this wasn't deleted. for now leave it here\n 88: 'cut',\n};\n\n/**\n * For functionalities on keyDown + ctrl || cmd\n */\nexport const ctrlKeysMapDown: TKeyMapIText = {\n 65: 'selectAll',\n};\n","import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, FILL, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions = Partial,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends ITextClickBehavior\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number,\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean,\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean,\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean,\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean,\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number,\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, FILL) as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight,\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true),\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries,\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight,\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, FILL);\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n","import type { TClassProperties, TOptions } from '../typedefs';\nimport { IText } from './IText/IText';\nimport { classRegistry } from '../ClassRegistry';\nimport { createTextboxDefaultControls } from '../controls/commonControls';\nimport { JUSTIFY } from './Text/constants';\nimport type { TextStyleDeclaration } from './Text/StyledText';\nimport type { SerializedITextProps, ITextProps } from './IText/IText';\nimport type { ITextEvents } from './IText/ITextBehavior';\nimport type { TextLinesInfo } from './Text/Text';\nimport type { Control } from '../controls/Control';\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textboxDefaultValues: Partial> = {\n minWidth: 20,\n dynamicMinWidth: 2,\n lockScalingFlip: true,\n noScaleCache: false,\n _wordJoiners: /[ \\t\\r]/,\n splitByGrapheme: false,\n};\n\nexport type GraphemeData = {\n wordsData: {\n word: string[];\n width: number;\n }[][];\n largestWordWidth: number;\n};\n\nexport type StyleMap = Record;\n\n// @TODO this is not complete\ninterface UniqueTextboxProps {\n minWidth: number;\n splitByGrapheme: boolean;\n dynamicMinWidth: number;\n _wordJoiners: RegExp;\n}\n\nexport interface SerializedTextboxProps\n extends SerializedITextProps,\n Pick {}\n\nexport interface TextboxProps extends ITextProps, UniqueTextboxProps {}\n\n/**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n */\nexport class Textbox<\n Props extends TOptions = Partial,\n SProps extends SerializedTextboxProps = SerializedTextboxProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends IText\n implements UniqueTextboxProps\n{\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n declare minWidth: number;\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n declare dynamicMinWidth: number;\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japanese\n * @type Boolean\n * @since 2.6.0\n */\n declare splitByGrapheme: boolean;\n\n declare _wordJoiners: RegExp;\n\n declare _styleMap: StyleMap;\n\n declare isWrapping: boolean;\n\n static type = 'Textbox';\n\n static textLayoutProperties = [...IText.textLayoutProperties, 'width'];\n\n static ownDefaults = textboxDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Textbox.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...Textbox.ownDefaults, ...options } as Props);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults object\n */\n static createControls(): { controls: Record } {\n return { controls: createTextboxDefaultControls() };\n }\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions() {\n if (!this.initialized) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n }\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap(textInfo: TextLinesInfo): StyleMap {\n let realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0;\n const map: StyleMap = {};\n\n for (let i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n } else if (\n !this.splitByGrapheme &&\n this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) &&\n i > 0\n ) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n }\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex: number): boolean {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return super.styleHas(property, lineIndex);\n }\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex: number): boolean {\n if (!this.styles) {\n return true;\n }\n let offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset: number,\n shouldLimit = false;\n const map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n const p2Number = parseInt(p2, 10);\n if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset!)) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n /**\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (!map) {\n return {};\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return super._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n const map = this._styleMap[lineIndex];\n super._setStyleDeclaration(map.line, map.offset + charIndex, style);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n const map = this._styleMap[lineIndex];\n super._deleteStyleDeclaration(map.line, map.offset + charIndex);\n }\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n const map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n const map = this._styleMap[lineIndex];\n super._setLineStyle(map.line);\n }\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText(lines: string[], desiredWidth: number): string[][] {\n this.isWrapping = true;\n // extract all thewords and the widths to optimally wrap lines.\n const data = this.getGraphemeDataForRender(lines);\n const wrapped: string[][] = [];\n for (let i = 0; i < data.wordsData.length; i++) {\n wrapped.push(...this._wrapLine(i, desiredWidth, data));\n }\n this.isWrapping = false;\n return wrapped;\n }\n\n /**\n * For each line of text terminated by an hard line stop,\n * measure each word width and extract the largest word from all.\n * The returned words here are the one that at the end will be rendered.\n * @param {string[]} lines the lines we need to measure\n *\n */\n getGraphemeDataForRender(lines: string[]): GraphemeData {\n const splitByGrapheme = this.splitByGrapheme,\n infix = splitByGrapheme ? '' : ' ';\n\n let largestWordWidth = 0;\n\n const data = lines.map((line, lineIndex) => {\n let offset = 0;\n const wordsOrGraphemes = splitByGrapheme\n ? this.graphemeSplit(line)\n : this.wordSplit(line);\n\n if (wordsOrGraphemes.length === 0) {\n return [{ word: [], width: 0 }];\n }\n\n return wordsOrGraphemes.map((word: string) => {\n // if using splitByGrapheme words are already in graphemes.\n const graphemeArray = splitByGrapheme\n ? [word]\n : this.graphemeSplit(word);\n const width = this._measureWord(graphemeArray, lineIndex, offset);\n largestWordWidth = Math.max(width, largestWordWidth);\n offset += graphemeArray.length + infix.length;\n return { word: graphemeArray, width };\n });\n });\n\n return {\n wordsData: data,\n largestWordWidth,\n };\n }\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * It gets called when charBounds are not available yet.\n * Override if necessary\n * Use with {@link Textbox#wordSplit}\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n */\n _measureWord(word: string[], lineIndex: number, charOffset = 0): number {\n let width = 0,\n prevGrapheme;\n const skipLeft = true;\n for (let i = 0, len = word.length; i < len; i++) {\n const box = this._getGraphemeBox(\n word[i],\n lineIndex,\n i + charOffset,\n prevGrapheme,\n skipLeft,\n );\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n }\n\n /**\n * Override this method to customize word splitting\n * Use with {@link Textbox#_measureWord}\n * @param {string} value\n * @returns {string[]} array of words\n */\n wordSplit(value: string): string[] {\n return value.split(this._wordJoiners);\n }\n\n /**\n * Wraps a line of text using the width of the Textbox as desiredWidth\n * and leveraging the known width o words from GraphemeData\n * @private\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {GraphemeData} graphemeData an object containing all the lines' words width.\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine(\n lineIndex: number,\n desiredWidth: number,\n { largestWordWidth, wordsData }: GraphemeData,\n reservedSpace = 0,\n ): string[][] {\n const additionalSpace = this._getWidthOfCharSpacing(),\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n infix = splitByGrapheme ? '' : ' ';\n\n let lineWidth = 0,\n line: string[] = [],\n // spaces in different languages?\n offset = 0,\n infixWidth = 0,\n lineJustStarted = true;\n\n desiredWidth -= reservedSpace;\n\n const maxWidth = Math.max(\n desiredWidth,\n largestWordWidth,\n this.dynamicMinWidth,\n );\n // layout words\n const data = wordsData[lineIndex];\n offset = 0;\n let i;\n for (i = 0; i < data.length; i++) {\n const { word, width: wordWidth } = data[i];\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n if (lineWidth > maxWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = splitByGrapheme\n ? 0\n : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n }\n\n i && graphemeLines.push(line);\n\n // TODO: this code is probably not necessary anymore.\n // it can be moved out of this function since largestWordWidth is now\n // known in advance\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n return graphemeLines;\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * This is important only for splitByGrapheme at the end of wrapping.\n * If we are not wrapping the offset is always 1\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1 {\n if (this.splitByGrapheme && !skipWrapping) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n }\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines(text: string) {\n const newText = super._splitTextIntoLines(text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (let i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n }\n\n getMinWidth() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n }\n\n _removeExtraneousStyles() {\n const linesToKeep = new Map();\n for (const prop in this._styleMap) {\n const propNumber = parseInt(prop, 10);\n if (this._textLines[propNumber]) {\n const lineIndex = this._styleMap[prop].line;\n linesToKeep.set(`${lineIndex}`, true);\n }\n }\n for (const prop in this.styles) {\n if (!linesToKeep.has(prop)) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([\n 'minWidth',\n 'splitByGrapheme',\n ...propertiesToInclude,\n ] as K[]) as Pick & SProps;\n }\n}\n\nclassRegistry.setClass(Textbox);\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport { sendPointToPlane } from '../../util/misc/planeChange';\nimport type { LayoutStrategyResult, StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { getObjectBounds } from './utils';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to match the clip path bounding box.\n */\nexport class ClipPathLayout extends LayoutStrategy {\n static readonly type = 'clip-path';\n\n shouldPerformLayout(context: StrictLayoutContext): boolean {\n return !!context.target.clipPath && super.shouldPerformLayout(context);\n }\n\n shouldLayoutClipPath() {\n return false;\n }\n\n calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n const { target } = context;\n const { clipPath, group } = target;\n if (!clipPath || !this.shouldPerformLayout(context)) {\n return;\n }\n // TODO: remove stroke calculation from this case\n const { width, height } = makeBoundingBoxFromPoints(\n getObjectBounds(target, clipPath as FabricObject),\n );\n const size = new Point(width, height);\n if (clipPath.absolutePositioned) {\n // we want the center point to exist in group's containing plane\n const clipPathCenter = sendPointToPlane(\n clipPath.getRelativeCenterPoint(),\n undefined,\n group ? group.calcTransformMatrix() : undefined,\n );\n return {\n center: clipPathCenter,\n size,\n };\n } else {\n // we want the center point to exist in group's containing plane, so we send it upwards\n const clipPathCenter = clipPath\n .getRelativeCenterPoint()\n .transform(target.calcOwnMatrix(), true);\n if (this.shouldPerformLayout(context)) {\n // the clip path is positioned relative to the group's center which is affected by the bbox\n // so we first calculate the bbox\n const { center = new Point(), correction = new Point() } =\n this.calcBoundingBox(objects, context) || {};\n return {\n center: center.add(clipPathCenter),\n correction: correction.subtract(clipPathCenter),\n size,\n };\n } else {\n return {\n center: target.getRelativeCenterPoint().add(clipPathCenter),\n size,\n };\n }\n }\n }\n}\n\nclassRegistry.setClass(ClipPathLayout);\n","import { Point } from '../../Point';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will keep target's initial size.\n */\nexport class FixedLayout extends LayoutStrategy {\n static readonly type = 'fixed';\n\n /**\n * @override respect target's initial size\n */\n getInitialSize(\n { target }: StrictLayoutContext & InitializationLayoutContext,\n { size }: Pick,\n ): Point {\n return new Point(target.width || size.x, target.height || size.y);\n }\n}\n\nclassRegistry.setClass(FixedLayout);\n","import { LayoutManager } from './LayoutManager';\nimport type { RegistrationContext, StrictLayoutContext } from './types';\nimport type { Group } from '../shapes/Group';\n\n/**\n * Today the LayoutManager class also takes care of subscribing event handlers\n * to update the group layout when the group is interactive and a transform is applied\n * to a child object.\n * The ActiveSelection is never interactive, but it could contain objects from\n * groups that are.\n * The standard LayoutManager would subscribe the children of the activeSelection to\n * perform layout changes to the active selection itself, what we need instead is that\n * the transformation applied to the active selection will trigger changes to the\n * original group of the children ( the one referenced under the parent property )\n * This subclass of the LayoutManager has a single duty to fill the gap of this difference.`\n */\nexport class ActiveSelectionLayoutManager extends LayoutManager {\n subscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n parent.layoutManager.subscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n\n /**\n * unsubscribe from parent only if all its children were deselected\n */\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const selectedObjects = activeSelection.getObjects();\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n !selectedObjects.some((object) => object.parent === parent) &&\n parent.layoutManager.unsubscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n}\n","import type { ControlRenderingStyleOverride } from '../controls/controlRendering';\nimport { classRegistry } from '../ClassRegistry';\nimport type { GroupProps } from './Group';\nimport { Group } from './Group';\nimport type { FabricObject } from './Object/FabricObject';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { TClassProperties } from '../typedefs';\nimport { log } from '../util/internals/console';\nimport { ActiveSelectionLayoutManager } from '../LayoutManager/ActiveSelectionLayoutManager';\n\nexport type MultiSelectionStacking = 'canvas-stacking' | 'selection-order';\n\nexport interface ActiveSelectionOptions extends GroupProps {\n multiSelectionStacking: MultiSelectionStacking;\n}\n\nconst activeSelectionDefaultValues: Partial> =\n {\n multiSelectionStacking: 'canvas-stacking',\n };\n\n/**\n * Used by Canvas to manage selection.\n *\n * @example\n * class MyActiveSelection extends ActiveSelection {\n * ...\n * }\n *\n * // override the default `ActiveSelection` class\n * classRegistry.setClass(MyActiveSelection)\n */\nexport class ActiveSelection extends Group {\n static type = 'ActiveSelection';\n\n static ownDefaults: Record = activeSelectionDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...ActiveSelection.ownDefaults };\n }\n\n /**\n * The ActiveSelection needs to use the ActiveSelectionLayoutManager\n * or selections on interactive groups may be broken\n */\n declare layoutManager: ActiveSelectionLayoutManager;\n\n /**\n * controls how selected objects are added during a multiselection event\n * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order\n * - `selection-order` adds the selected object to the top of the stack,\n * meaning that the stack is ordered by the order in which objects were selected\n * @default `canvas-stacking`\n */\n declare multiSelectionStacking: MultiSelectionStacking;\n\n constructor(\n objects: FabricObject[] = [],\n options: Partial = {},\n ) {\n super();\n Object.assign(this, ActiveSelection.ownDefaults);\n this.setOptions(options);\n const { left, top, layoutManager } = options;\n this.groupInit(objects, {\n left,\n top,\n layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(),\n });\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return true;\n }\n\n /**\n * @private\n * @override we don't want the selection monitor to be active\n */\n __objectSelectionMonitor() {\n // noop\n }\n\n /**\n * Adds objects with respect to {@link multiSelectionStacking}\n * @param targets object to add to selection\n */\n multiSelectAdd(...targets: FabricObject[]) {\n if (this.multiSelectionStacking === 'selection-order') {\n this.add(...targets);\n } else {\n // respect object stacking as it is on canvas\n // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf`\n targets.forEach((target) => {\n const index = this._objects.findIndex((obj) => obj.isInFrontOf(target));\n const insertAt =\n index === -1\n ? // `target` is in front of all other objects\n this.size()\n : index;\n this.insertAt(insertAt, target);\n });\n }\n }\n\n /**\n * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree\n */\n canEnterGroup(object: FabricObject) {\n if (\n this.getObjects().some(\n (o) => o.isDescendantOf(object) || object.isDescendantOf(o),\n )\n ) {\n // prevent circular object tree\n log(\n 'error',\n 'ActiveSelection: circular object trees are not supported, this call has no effect',\n );\n return false;\n }\n\n return super.canEnterGroup(object);\n }\n\n /**\n * Change an object so that it can be part of an active selection.\n * this method is called by multiselectAdd from canvas code.\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n // This condition check that the object has currently a group, and the group\n // is also its parent, meaning that is not in an active selection, but is\n // in a normal group.\n if (object.parent && object.parent === object.group) {\n // Disconnect the object from the group functionalities, but keep the ref parent intact\n // for later re-enter\n object.parent._exitGroup(object);\n // in this case the object is probably inside an active selection.\n } else if (object.group && object.parent !== object.group) {\n // in this case group.remove will also clear the old parent reference.\n object.group.remove(object);\n }\n // enter the active selection from a render perspective\n // the object will be in the objects array of both the ActiveSelection and the Group\n // but referenced in the group's _activeObjects so that it won't be rendered twice.\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * we want objects to retain their canvas ref when exiting instance\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n // return to parent\n object.parent && object.parent._enterGroup(object, true);\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n super._onAfterObjectsChange(type, targets);\n const groups = new Set();\n targets.forEach((object) => {\n const { parent } = object;\n parent && groups.add(parent);\n });\n if (type === LAYOUT_TYPE_REMOVED) {\n // invalidate groups' layout and mark as dirty\n groups.forEach((group) => {\n group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets);\n });\n } else {\n // mark groups as dirty\n groups.forEach((group) => {\n group._set('dirty', true);\n });\n }\n }\n\n /**\n * @override remove all objects\n */\n onDeselect() {\n this.removeAll();\n return false;\n }\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString() {\n return `#`;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache() {\n return false;\n }\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache() {\n return false;\n }\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride?: ControlRenderingStyleOverride,\n childrenOverride?: ControlRenderingStyleOverride,\n ) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n const options = {\n hasControls: false,\n ...childrenOverride,\n forActiveSelection: true,\n };\n for (let i = 0; i < this._objects.length; i++) {\n this._objects[i]._renderControls(ctx, options);\n }\n super._renderControls(ctx, styleOverride);\n ctx.restore();\n }\n}\n\nclassRegistry.setClass(ActiveSelection);\nclassRegistry.setClass(ActiveSelection, 'activeSelection');\n","/**\n * Canvas 2D filter backend.\n */\nimport type { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TPipelineResources } from './typedefs';\n\nexport class Canvas2dFilterBackend {\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters(\n filters: BaseFilter>[],\n sourceElement: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n targetCanvas: HTMLCanvasElement,\n ): T2DPipelineState | void {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const pipelineState: T2DPipelineState = {\n sourceWidth,\n sourceHeight,\n imageData,\n originalEl: sourceElement,\n originalImageData,\n canvasEl: targetCanvas,\n ctx,\n filterBackend: this,\n };\n filters.forEach((filter) => {\n filter.applyTo(pipelineState);\n });\n const { imageData: imageDataPostFilter } = pipelineState;\n if (\n imageDataPostFilter.width !== sourceWidth ||\n imageDataPostFilter.height !== sourceHeight\n ) {\n targetCanvas.width = imageDataPostFilter.width;\n targetCanvas.height = imageDataPostFilter.height;\n }\n ctx.putImageData(imageDataPostFilter, 0, 0);\n return pipelineState;\n }\n}\n","import { config } from '../config';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n TWebGLPipelineState,\n TProgramCache,\n TTextureCache,\n TPipelineResources,\n} from './typedefs';\nimport type { BaseFilter } from './BaseFilter';\n\nexport class WebGLFilterBackend {\n declare tileSize: number;\n\n /**\n * Define ...\n **/\n aPosition: Float32Array = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n\n /**\n * If GLPut data is the fastest operation, or if forced, this buffer will be used\n * to transfer the data back in the 2d logic\n **/\n declare imageBuffer?: ArrayBuffer;\n\n declare canvas: HTMLCanvasElement;\n\n /**\n * The Webgl context that will execute the operations for filtering\n **/\n declare gl: WebGLRenderingContext;\n\n /**\n * Keyed map for shader cache\n **/\n declare programCache: TProgramCache;\n\n /**\n * Keyed map for texture cache\n **/\n declare textureCache: TTextureCache;\n\n /**\n * Contains GPU info for debug\n **/\n declare gpuInfo: any;\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n constructor({ tileSize = config.textureSize } = {}) {\n this.tileSize = tileSize;\n this.setupGLContext(tileSize, tileSize);\n this.captureGPUInfo();\n }\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext(width: number, height: number): void {\n this.dispose();\n this.createWebGLCanvas(width, height);\n }\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas(width: number, height: number): void {\n const canvas = createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n const glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false,\n },\n gl = canvas.getContext('webgl', glOptions) as WebGLRenderingContext;\n\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n }\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {TexImageSource} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters(\n filters: BaseFilter>[],\n source: TexImageSource,\n width: number,\n height: number,\n targetCanvas: HTMLCanvasElement,\n cacheKey?: string,\n ): TWebGLPipelineState | undefined {\n const gl = this.gl;\n const ctx = targetCanvas.getContext('2d');\n if (!gl || !ctx) {\n return;\n }\n let cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n const pipelineState: TWebGLPipelineState = {\n originalWidth:\n (source as HTMLImageElement).width ||\n // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state?\n (source as HTMLImageElement).originalWidth ||\n 0,\n originalHeight:\n (source as HTMLImageElement).height ||\n // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state?\n (source as HTMLImageElement).originalHeight ||\n 0,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n ),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture:\n cachedTexture ||\n this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n )!,\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas,\n };\n const tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach((filter: any) => {\n filter && filter.applyTo(pipelineState);\n });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n }\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose() {\n if (this.canvas) {\n // we are disposing, we don't care about the fact\n // that the canvas shouldn't be null.\n // @ts-expect-error disposing\n this.canvas = null;\n // @ts-expect-error disposing\n this.gl = null;\n }\n this.clearWebGLCaches();\n }\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches() {\n this.programCache = {};\n this.textureCache = {};\n }\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the texture to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {number} width The width to initialize the texture at.\n * @param {number} height The height to initialize the texture.\n * @param {TexImageSource} textureImageSource A source for the texture data.\n * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture.\n * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR\n * @returns {WebGLTexture}\n */\n createTexture(\n gl: WebGLRenderingContext,\n width: number,\n height: number,\n textureImageSource?: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ) {\n const {\n NEAREST,\n TEXTURE_2D,\n RGBA,\n UNSIGNED_BYTE,\n CLAMP_TO_EDGE,\n TEXTURE_MAG_FILTER,\n TEXTURE_MIN_FILTER,\n TEXTURE_WRAP_S,\n TEXTURE_WRAP_T,\n } = gl;\n const texture = gl.createTexture();\n gl.bindTexture(TEXTURE_2D, texture);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n RGBA,\n UNSIGNED_BYTE,\n textureImageSource,\n );\n } else {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n width,\n height,\n 0,\n RGBA,\n UNSIGNED_BYTE,\n null,\n );\n }\n return texture;\n }\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture(\n uniqueId: string,\n textureImageSource: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ): WebGLTexture | null {\n const { textureCache } = this;\n if (textureCache[uniqueId]) {\n return textureCache[uniqueId];\n } else {\n const texture = this.createTexture(\n this.gl,\n (textureImageSource as HTMLImageElement).width,\n (textureImageSource as HTMLImageElement).height,\n textureImageSource,\n filter,\n );\n if (texture) {\n textureCache[uniqueId] = texture;\n }\n return texture;\n }\n }\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey(cacheKey: string) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2D(gl: WebGLRenderingContext, pipelineState: TWebGLPipelineState) {\n const glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n const sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(\n glCanvas,\n 0,\n sourceY,\n targetCanvas.width,\n targetCanvas.height,\n 0,\n 0,\n targetCanvas.width,\n targetCanvas.height,\n );\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2DPutImageData(\n this: Required,\n gl: WebGLRenderingContext,\n pipelineState: TWebGLPipelineState,\n ) {\n const targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n if (!ctx) {\n return;\n }\n const u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n const imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n }\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n const gl = this.gl,\n gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n const ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n }\n}\n\nfunction resizeCanvasIfNeeded(pipelineState: TWebGLPipelineState): void {\n const targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width,\n height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n","import { config } from '../config';\nimport { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { Canvas2dFilterBackend } from './Canvas2dFilterBackend';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\n\nexport type FilterBackend = WebGLFilterBackend | Canvas2dFilterBackend;\n\nlet filterBackend: FilterBackend;\n\n/**\n * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend\n */\nexport function initFilterBackend(): FilterBackend {\n const { WebGLProbe } = getEnv();\n WebGLProbe.queryWebGL(createCanvasElement());\n if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) {\n return new WebGLFilterBackend({ tileSize: config.textureSize });\n } else {\n return new Canvas2dFilterBackend();\n }\n}\n\n/**\n * Get the current fabricJS filter backend or initialize one if not available yet\n * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior),\n * pass `false` to get the backend ref without mutating it\n */\nexport function getFilterBackend(strict = true): FilterBackend {\n if (!filterBackend && strict) {\n filterBackend = initFilterBackend();\n }\n return filterBackend;\n}\n\nexport function setFilterBackend(backend: FilterBackend) {\n filterBackend = backend;\n}\n","import { getFabricDocument, getEnv } from '../env';\nimport type { BaseFilter } from '../filters/BaseFilter';\nimport { getFilterBackend } from '../filters/FilterBackend';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type {\n TClassProperties,\n TCrossOrigin,\n TSize,\n Abortable,\n TOptions,\n} from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { findScaleToCover, findScaleToFit } from '../util/misc/findScaleTo';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n loadImage,\n} from '../util/misc/objectEnlive';\nimport { parsePreserveAspectRatioAttribute } from '../util/misc/svgParsing';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { WebGLFilterBackend } from '../filters/WebGLFilterBackend';\nimport { FILL, NONE } from '../constants';\nimport { getDocumentFromElement } from '../util/dom_misc';\nimport type { CSSRules } from '../parser/typedefs';\nimport type { Resize } from '../filters/Resize';\nimport type { TCachedFabricObject } from './Object/Object';\nimport { log } from '../util/internals/console';\n\n// @todo Would be nice to have filtering code not imported directly.\n\nexport type ImageSource =\n | HTMLImageElement\n | HTMLVideoElement\n | HTMLCanvasElement;\n\ninterface UniqueImageProps {\n srcFromAttribute: boolean;\n minimumScaleTrigger: number;\n cropX: number;\n cropY: number;\n imageSmoothing: boolean;\n filters: BaseFilter>[];\n resizeFilter?: Resize;\n}\n\nexport const imageDefaultValues: Partial> = {\n strokeWidth: 0,\n srcFromAttribute: false,\n minimumScaleTrigger: 0.5,\n cropX: 0,\n cropY: 0,\n imageSmoothing: true,\n};\n\nexport interface SerializedImageProps extends SerializedObjectProps {\n src: string;\n crossOrigin: TCrossOrigin;\n filters: any[];\n resizeFilter?: any;\n cropX: number;\n cropY: number;\n}\n\nexport interface ImageProps extends FabricObjectProps, UniqueImageProps {}\n\nconst IMAGE_PROPS = ['cropX', 'cropY'] as const;\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n */\nexport class FabricImage<\n Props extends TOptions = Partial,\n SProps extends SerializedImageProps = SerializedImageProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements ImageProps\n{\n /**\n * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default false\n */\n declare srcFromAttribute: boolean;\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleX = 1;\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleY = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingX = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingY = 1;\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n declare minimumScaleTrigger: number;\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n declare cacheKey: string;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropX: number;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropY: number;\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n declare imageSmoothing: boolean;\n\n declare preserveAspectRatio: string;\n\n protected declare src: string;\n\n declare filters: BaseFilter>[];\n declare resizeFilter: Resize;\n\n declare _element: ImageSource;\n declare _filteredEl?: HTMLCanvasElement;\n declare _originalElement: ImageSource;\n\n static type = 'Image';\n\n static cacheProperties = [...cacheProperties, ...IMAGE_PROPS];\n\n static ownDefaults = imageDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...FabricImage.ownDefaults,\n };\n }\n /**\n * Constructor\n * Image can be initialized with any canvas drawable or a string.\n * The string should be a url and will be loaded as an image.\n * Canvas and Image element work out of the box, while videos require extra code to work.\n * Please check video element events for seeking.\n * @param {ImageSource | string} element Image element\n * @param {Object} [options] Options object\n */\n constructor(elementId: string, options?: Props);\n constructor(element: ImageSource, options?: Props);\n constructor(arg0: ImageSource | string, options?: Props) {\n super();\n this.filters = [];\n Object.assign(this, FabricImage.ownDefaults);\n this.setOptions(options);\n this.cacheKey = `texture${uid()}`;\n this.setElement(\n typeof arg0 === 'string'\n ? ((\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument()\n ).getElementById(arg0) as ImageSource)\n : arg0,\n options,\n );\n }\n\n /**\n * Returns image element which this instance if based on\n */\n getElement() {\n return this._element;\n }\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Partial} [size] Options object\n */\n setElement(element: ImageSource, size: Partial = {}) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._element = element;\n this._originalElement = element;\n this._setWidthHeight(size);\n element.classList.add(FabricImage.CSS_CANVAS);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal filters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n }\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture(key: string) {\n const backend = getFilterBackend(false);\n if (backend instanceof WebGLFilterBackend) {\n backend.evictCachesForKey(key);\n }\n }\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose() {\n super.dispose();\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._cacheContext = null;\n (\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'] as const\n ).forEach((elementKey) => {\n const el = this[elementKey];\n el && getEnv().dispose(el);\n // @ts-expect-error disposing\n this[elementKey] = undefined;\n });\n }\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin(): string | null {\n return (\n this._originalElement &&\n ((this._originalElement as any).crossOrigin || null)\n );\n }\n\n /**\n * Returns original size of an image\n */\n getOriginalSize() {\n const element = this.getElement() as any;\n if (!element) {\n return {\n width: 0,\n height: 0,\n };\n }\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height,\n };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n const w = this.width / 2,\n h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const filters: Record[] = [];\n this.filters.forEach((filterObj) => {\n filterObj && filters.push(filterObj.toObject());\n });\n return {\n ...super.toObject([...IMAGE_PROPS, ...propertiesToInclude]),\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters,\n ...(this.resizeFilter\n ? { resizeFilter: this.resizeFilter.toObject() }\n : {}),\n };\n }\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height.\n * @return {Boolean}\n */\n hasCrop() {\n return (\n !!this.cropX ||\n !!this.cropY ||\n this.width < this._element.width ||\n this.height < this._element.height\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @return {string[]} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const imageMarkup: string[] = [],\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2;\n let svgString: string[] = [],\n strokeSvg: string[] = [],\n clipPath = '',\n imageRendering = '';\n if (!element) {\n return [];\n }\n if (this.hasCrop()) {\n const clipPathId = uid();\n svgString.push(\n '\\n',\n '\\t\\n',\n '\\n',\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n if (!this.imageSmoothing) {\n imageRendering = ' image-rendering=\"optimizeSpeed\"';\n }\n imageMarkup.push(\n '\\t element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n }\" width=\"${\n element.width || (element as HTMLImageElement).naturalWidth\n }\" height=\"${\n element.height || (element as HTMLImageElement).naturalHeight\n }\"${imageRendering}${clipPath}>\\n`,\n );\n\n if (this.stroke || this.strokeDashArray) {\n const origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n `\\t\\n`,\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== FILL) {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n }\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc(filtered?: boolean): string {\n const element = filtered ? this._element : this._originalElement;\n if (element) {\n if ((element as HTMLCanvasElement).toDataURL) {\n return (element as HTMLCanvasElement).toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src') || '';\n } else {\n return (element as HTMLImageElement).src;\n }\n } else {\n return this.src || '';\n }\n }\n\n /**\n * Alias for getSrc\n * @param filtered\n * @deprecated\n */\n getSvgSrc(filtered?: boolean) {\n return this.getSrc(filtered);\n }\n\n /**\n * Loads and sets source of an image\\\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n * @param {String} src Source string (URL)\n * @param {LoadImageOptions} [options] Options object\n */\n setSrc(src: string, { crossOrigin, signal }: LoadImageOptions = {}) {\n return loadImage(src, { crossOrigin, signal }).then((img) => {\n typeof crossOrigin !== 'undefined' && this.set({ crossOrigin });\n this.setElement(img);\n });\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString() {\n return `#`;\n }\n\n applyResizeFilters() {\n const filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.x,\n scaleY = objectScale.y,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n const canvasEl = createCanvasElement(),\n sourceWidth = elementToFilter.width,\n sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n getFilterBackend().applyFilters(\n [filter],\n elementToFilter,\n sourceWidth,\n sourceHeight,\n this._element,\n );\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n }\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n */\n applyFilters(\n filters: BaseFilter>[] = this.filters || [],\n ) {\n filters = filters.filter((filter) => filter && !filter.isNeutralState());\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(`${this.cacheKey}_filtered`);\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n // this is unsafe and needs to be rethinkend\n this._filteredEl = undefined;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return;\n }\n\n const imgElement = this._originalElement,\n sourceWidth =\n (imgElement as HTMLImageElement).naturalWidth || imgElement.width,\n sourceHeight =\n (imgElement as HTMLImageElement).naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the _element a reference to _originalElement\n // we need to create a new element to host the filtered pixels\n const canvasEl = createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n } else if (this._filteredEl) {\n // if the _element is it own element,\n // and we also have a _filteredEl, then we clean up _filteredEl\n // and we assign it to _element.\n // in this way we invalidate the eventual old resize filtered element\n this._element = this._filteredEl;\n this._filteredEl\n .getContext('2d')!\n .clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n getFilterBackend().applyFilters(\n filters,\n this._originalElement,\n sourceWidth,\n sourceHeight,\n this._element as HTMLCanvasElement,\n );\n if (\n this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height\n ) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY =\n this._element.height / this._originalElement.height;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(\n this: TCachedFabricObject,\n ctx: CanvasRenderingContext2D,\n ) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n super.drawCacheOnCanvas(ctx);\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache() {\n return this.needsItsOwnCache();\n }\n\n _renderFill(ctx: CanvasRenderingContext2D) {\n const elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n const scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n // crop values cannot be lesser than 0.\n cropX = Math.max(this.cropX, 0),\n cropY = Math.max(this.cropY, 0),\n elWidth =\n (elementToDraw as HTMLImageElement).naturalWidth || elementToDraw.width,\n elHeight =\n (elementToDraw as HTMLImageElement).naturalHeight ||\n elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = Math.min(w * scaleX, elWidth - sX),\n sH = Math.min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = Math.min(w, elWidth / scaleX - cropX),\n maxDestH = Math.min(h, elHeight / scaleY - cropY);\n\n elementToDraw &&\n ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n }\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize() {\n const scale = this.getTotalObjectScaling();\n return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY;\n }\n\n /**\n * @private\n * @deprecated unused\n */\n _resetWidthHeight() {\n this.set(this.getOriginalSize());\n }\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n */\n _setWidthHeight({ width, height }: Partial = {}) {\n const size = this.getOriginalSize();\n this.width = width || size.width;\n this.height = height || size.height;\n }\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n */\n parsePreserveAspectRatioAttribute() {\n const pAR = parsePreserveAspectRatioAttribute(\n this.preserveAspectRatio || '',\n ),\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = { width: pWidth, height: pHeight };\n let rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset;\n\n if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX,\n scaleY,\n offsetLeft,\n offsetTop,\n cropX,\n cropY,\n };\n }\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n static CSS_CANVAS = 'canvas-img';\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'width',\n 'height',\n 'preserveAspectRatio',\n 'xlink:href',\n 'crossOrigin',\n 'image-rendering',\n ];\n\n /**\n * Creates an instance of FabricImage from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n { filters: f, resizeFilter: rf, src, crossOrigin, type, ...object }: T,\n options?: Abortable,\n ) {\n return Promise.all([\n loadImage(src!, { ...options, crossOrigin }),\n f && enlivenObjects>(f, options),\n // TODO: redundant - handled by enlivenObjectEnlivables\n rf && enlivenObjects>([rf], options),\n enlivenObjectEnlivables(object, options),\n ]).then(([el, filters = [], [resizeFilter] = [], hydratedProps = {}]) => {\n return new this(el, {\n ...object,\n // TODO: this creates a difference between image creation and restoring from JSON\n src,\n filters,\n resizeFilter,\n ...hydratedProps,\n });\n });\n }\n\n /**\n * Creates an instance of Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {LoadImageOptions} [options] Options object\n * @returns {Promise}\n */\n static fromURL>(\n url: string,\n { crossOrigin = null, signal }: LoadImageOptions = {},\n imageOptions?: T,\n ): Promise {\n return loadImage(url, { crossOrigin, signal }).then(\n (img) => new this(img, imageOptions),\n );\n }\n\n /**\n * Returns {@link FabricImage} instance from an SVG element\n * @static\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} callback Callback to execute when Image object is created\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable = {},\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return this.fromURL(\n parsedAttributes['xlink:href'],\n options,\n parsedAttributes,\n ).catch((err) => {\n log('log', 'Unable to parse Image', err);\n return null;\n });\n }\n}\n\nclassRegistry.setClass(FabricImage);\nclassRegistry.setSVGClass(FabricImage);\n","import { svgNS } from './constants';\nimport {\n parsePreserveAspectRatioAttribute,\n parseUnit,\n} from '../util/misc/svgParsing';\nimport { svgViewBoxElementsRegEx, reViewBoxAttrValue } from './constants';\nimport { NONE } from '../constants';\n\nexport type ParsedViewboxTransform = Partial<{\n width: number;\n height: number;\n minX: number;\n minY: number;\n viewBoxWidth: number;\n viewBoxHeight: number;\n}>;\n\n/**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\nexport function applyViewboxTransform(\n element: Element,\n): ParsedViewboxTransform {\n if (!svgViewBoxElementsRegEx.test(element.nodeName)) {\n return {};\n }\n const viewBoxAttr: string | null = element.getAttribute('viewBox');\n let scaleX = 1;\n let scaleY = 1;\n let minX = 0;\n let minY = 0;\n let matrix;\n let el;\n const widthAttr = element.getAttribute('width');\n const heightAttr = element.getAttribute('height');\n const x = element.getAttribute('x') || 0;\n const y = element.getAttribute('y') || 0;\n const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr);\n const missingViewBox = !goodViewbox;\n const missingDimAttr =\n !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%';\n\n let translateMatrix = '';\n let widthDiff = 0;\n let heightDiff = 0;\n\n if (missingViewBox) {\n if (\n (x || y) &&\n element.parentNode &&\n element.parentNode.nodeName !== '#document'\n ) {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (missingViewBox && missingDimAttr) {\n return {\n width: 0,\n height: 0,\n };\n }\n\n const parsedDim: ParsedViewboxTransform = {\n width: 0,\n height: 0,\n };\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr!);\n parsedDim.height = parseUnit(heightAttr!);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n\n const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue)!;\n minX = -parseFloat(pasedViewBox[1]);\n minY = -parseFloat(pasedViewBox[2]);\n const viewBoxWidth = parseFloat(pasedViewBox[3]);\n const viewBoxHeight = parseFloat(pasedViewBox[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n const preserveAspectRatio = parsePreserveAspectRatioAttribute(\n element.getAttribute('preserveAspectRatio') || '',\n );\n if (preserveAspectRatio.alignX !== NONE) {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY;\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (\n scaleX === 1 &&\n scaleY === 1 &&\n minX === 0 &&\n minY === 0 &&\n x === 0 &&\n y === 0\n ) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode!.nodeName !== '#document') {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n }\n\n matrix =\n translateMatrix +\n ' matrix(' +\n scaleX +\n ' 0' +\n ' 0 ' +\n scaleY +\n ' ' +\n (minX * scaleX + widthDiff) +\n ' ' +\n (minY * scaleY + heightDiff) +\n ') ';\n // seems unused.\n // parsedDim.viewboxTransform = parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n}\n","export const getTagName = (node: Element) => node.tagName.replace('svg:', '');\n","import { svgInvalidAncestors } from './constants';\nimport { getSvgRegex } from './getSvgRegex';\nimport { getTagName } from './getTagName';\n\nconst svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n\nexport function hasInvalidAncestor(element: Element) {\n let _element: Element | null = element;\n while (_element && (_element = _element.parentElement)) {\n if (\n _element &&\n _element.nodeName &&\n svgInvalidAncestorsRegEx.test(getTagName(_element)) &&\n !_element.getAttribute('instantiated_by_use')\n ) {\n return true;\n }\n }\n return false;\n}\n","export function getMultipleNodes(\n doc: Document,\n nodeNames: string[],\n): Element[] {\n let nodeName,\n nodeArray: Element[] = [],\n nodeList,\n i,\n len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagNameNS(\n 'http://www.w3.org/2000/svg',\n nodeName,\n );\n nodeArray = nodeArray.concat(Array.from(nodeList));\n }\n return nodeArray;\n}\n","const gradientsAttrs = [\n 'gradientTransform',\n 'x1',\n 'x2',\n 'y1',\n 'y2',\n 'gradientUnits',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n];\nconst xlinkAttr = 'xlink:href';\n\nexport function recursivelyParseGradientsXlink(\n doc: Document,\n gradient: Element,\n) {\n const xLink = gradient.getAttribute(xlinkAttr)?.slice(1) || '',\n referencedGradient = doc.getElementById(xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient as Element);\n }\n if (referencedGradient) {\n gradientsAttrs.forEach((attr) => {\n const value = referencedGradient.getAttribute(attr);\n if (!gradient.hasAttribute(attr) && value) {\n gradient.setAttribute(attr, value);\n }\n });\n if (!gradient.children.length) {\n const referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n }\n gradient.removeAttribute(xlinkAttr);\n}\n","import { getMultipleNodes } from './getMultipleNodes';\nimport { recursivelyParseGradientsXlink } from './recursivelyParseGradientsXlink';\n\nconst tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient',\n];\n\n/**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\nexport function getGradientDefs(\n doc: Document,\n): Record {\n const elList = getMultipleNodes(doc, tagArray);\n const gradientDefs: Record = {};\n let j = elList.length;\n while (j--) {\n const el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n const id = el.getAttribute('id');\n if (id) {\n gradientDefs[id] = el as SVGGradientElement;\n }\n }\n return gradientDefs;\n}\n","import type { CSSRules } from './typedefs';\n\n/**\n * Returns CSS rules for a given SVG document\n * @param {HTMLElement} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\nexport function getCSSRules(doc: Document) {\n const styles = doc.getElementsByTagName('style');\n let i;\n let len;\n const allRules: CSSRules = {};\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n const styleContents = (styles[i].textContent || '').replace(\n // remove comments\n /\\/\\*[\\s\\S]*?\\*\\//g,\n '',\n );\n\n if (styleContents.trim() === '') {\n continue;\n }\n // recovers all the rule in this form `body { style code... }`\n // rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n styleContents\n .split('}')\n // remove empty rules and remove everything if we didn't split in at least 2 pieces\n .filter((rule, index, array) => array.length > 1 && rule.trim())\n // at this point we have hopefully an array of rules `body { style code... `\n .forEach((rule) => {\n // if there is more than one opening bracket and the rule starts with '@', it is likely\n // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below\n // can not handle it.\n if (\n (rule.match(/{/g) || []).length > 1 &&\n rule.trim().startsWith('@')\n ) {\n return;\n }\n\n const match = rule.split('{'),\n ruleObj: Record = {},\n declaration = match[1].trim(),\n propertyValuePairs = declaration.split(';').filter(function (pair) {\n return pair.trim();\n });\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n const pair = propertyValuePairs[i].split(':'),\n property = pair[0].trim(),\n value = pair[1].trim();\n ruleObj[property] = value;\n }\n rule = match[0].trim();\n rule.split(',').forEach((_rule) => {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n allRules[_rule] = {\n ...(allRules[_rule] || {}),\n ...ruleObj,\n };\n });\n });\n }\n return allRules;\n}\n","import { Gradient } from '../gradient/Gradient';\nimport { Group } from '../shapes/Group';\nimport { FabricImage } from '../shapes/Image';\nimport { classRegistry } from '../ClassRegistry';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../util/misc/matrix';\nimport { removeTransformMatrixForSvgParsing } from '../util/transform_matrix_removal';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { Point } from '../Point';\nimport { CENTER, FILL, STROKE } from '../constants';\nimport { getGradientDefs } from './getGradientDefs';\nimport { getCSSRules } from './getCSSRules';\nimport type { LoadImageOptions } from '../util';\nimport type { CSSRules, TSvgReviverCallback } from './typedefs';\nimport type { ParsedViewboxTransform } from './applyViewboxTransform';\nimport type { SVGOptions } from '../gradient';\nimport { getTagName } from './getTagName';\nimport { parseTransformAttribute } from './parseTransformAttribute';\n\nconst findTag = (el: Element) =>\n classRegistry.getSVGClass(getTagName(el).toLowerCase());\n\ntype StorageType = {\n fill: SVGGradientElement;\n stroke: SVGGradientElement;\n clipPath: Element[];\n};\n\ntype NotParsedFabricObject = FabricObject & {\n fill: string;\n stroke: string;\n clipPath?: string;\n clipRule?: CanvasFillRule;\n};\n\nexport class ElementsParser {\n declare elements: Element[];\n declare options: LoadImageOptions & ParsedViewboxTransform;\n declare reviver?: TSvgReviverCallback;\n declare regexUrl: RegExp;\n declare doc: Document;\n declare clipPaths: Record;\n declare gradientDefs: Record;\n declare cssRules: CSSRules;\n\n constructor(\n elements: Element[],\n options: LoadImageOptions & ParsedViewboxTransform,\n reviver: TSvgReviverCallback | undefined,\n doc: Document,\n clipPaths: Record,\n ) {\n this.elements = elements;\n this.options = options;\n this.reviver = reviver;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n this.clipPaths = clipPaths;\n this.gradientDefs = getGradientDefs(doc);\n this.cssRules = getCSSRules(doc);\n }\n\n parse(): Promise> {\n return Promise.all(\n this.elements.map((element) => this.createObject(element)),\n );\n }\n\n async createObject(el: Element): Promise {\n const klass = findTag(el);\n if (klass) {\n const obj: NotParsedFabricObject = await klass.fromElement(\n el,\n this.options,\n this.cssRules,\n );\n this.resolveGradient(obj, el, FILL);\n this.resolveGradient(obj, el, STROKE);\n if (obj instanceof FabricImage && obj._originalElement) {\n removeTransformMatrixForSvgParsing(\n obj,\n obj.parsePreserveAspectRatioAttribute(),\n );\n } else {\n removeTransformMatrixForSvgParsing(obj);\n }\n await this.resolveClipPath(obj, el);\n this.reviver && this.reviver(el, obj);\n return obj;\n }\n return null;\n }\n\n extractPropertyDefinition(\n obj: NotParsedFabricObject,\n property: 'fill' | 'stroke' | 'clipPath',\n storage: Record,\n ): StorageType[typeof property] | undefined {\n const value = obj[property]!,\n regex = this.regexUrl;\n if (!regex.test(value)) {\n return undefined;\n }\n // verify: can we remove the 'g' flag? and remove lastIndex changes?\n regex.lastIndex = 0;\n // we passed the regex test, so we know is not null;\n const id = regex.exec(value)![1];\n regex.lastIndex = 0;\n // @todo fix this\n return storage[id];\n }\n\n resolveGradient(\n obj: NotParsedFabricObject,\n el: Element,\n property: 'fill' | 'stroke',\n ) {\n const gradientDef = this.extractPropertyDefinition(\n obj,\n property,\n this.gradientDefs,\n ) as SVGGradientElement;\n if (gradientDef) {\n const opacityAttr = el.getAttribute(property + '-opacity');\n const gradient = Gradient.fromElement(gradientDef, obj, {\n ...this.options,\n opacity: opacityAttr,\n } as SVGOptions);\n obj.set(property, gradient);\n }\n }\n\n // TODO: resolveClipPath could be run once per clippath with minor work per object.\n // is a refactor that i m not sure is worth on this code\n async resolveClipPath(obj: NotParsedFabricObject, usingElement: Element) {\n const clipPathElements = this.extractPropertyDefinition(\n obj,\n 'clipPath',\n this.clipPaths,\n ) as Element[];\n if (clipPathElements) {\n const objTransformInv = invertTransform(obj.calcTransformMatrix());\n const clipPathTag = clipPathElements[0].parentElement!;\n let clipPathOwner = usingElement;\n while (\n clipPathOwner.parentElement &&\n clipPathOwner.getAttribute('clip-path') !== obj.clipPath\n ) {\n clipPathOwner = clipPathOwner.parentElement;\n }\n // move the clipPath tag as sibling to the real element that is using it\n clipPathOwner.parentElement!.appendChild(clipPathTag!);\n\n // this multiplication order could be opposite.\n // but i don't have an svg to test it\n // at the first SVG that has a transform on both places and is misplaced\n // try to invert this multiplication order\n const finalTransform = parseTransformAttribute(\n `${clipPathOwner.getAttribute('transform') || ''} ${\n clipPathTag.getAttribute('originalTransform') || ''\n }`,\n );\n\n clipPathTag.setAttribute(\n 'transform',\n `matrix(${finalTransform.join(',')})`,\n );\n\n const container = await Promise.all(\n clipPathElements.map((clipPathElement) => {\n return findTag(clipPathElement)\n .fromElement(clipPathElement, this.options, this.cssRules)\n .then((enlivedClippath: NotParsedFabricObject) => {\n removeTransformMatrixForSvgParsing(enlivedClippath);\n enlivedClippath.fillRule = enlivedClippath.clipRule!;\n delete enlivedClippath.clipRule;\n return enlivedClippath;\n });\n }),\n );\n const clipPath =\n container.length === 1 ? container[0] : new Group(container);\n const gTransform = multiplyTransformMatrices(\n objTransformInv,\n clipPath.calcTransformMatrix(),\n );\n if (clipPath.clipPath) {\n await this.resolveClipPath(clipPath, clipPathOwner);\n }\n const { scaleX, scaleY, angle, skewX, translateX, translateY } =\n qrDecompose(gTransform);\n clipPath.set({\n flipX: false,\n flipY: false,\n });\n clipPath.set({\n scaleX,\n scaleY,\n angle,\n skewX,\n skewY: 0,\n });\n clipPath.setPositionByOrigin(\n new Point(translateX, translateY),\n CENTER,\n CENTER,\n );\n obj.clipPath = clipPath;\n } else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n return;\n }\n }\n}\n","import { applyViewboxTransform } from './applyViewboxTransform';\nimport { svgValidTagNamesRegEx } from './constants';\nimport { hasInvalidAncestor } from './hasInvalidAncestor';\nimport { parseUseDirectives } from './parseUseDirectives';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { ElementsParser } from './elements_parser';\nimport { log, SignalAbortedError } from '../util/internals/console';\nimport { getTagName } from './getTagName';\n\nconst isValidSvgTag = (el: Element) =>\n svgValidTagNamesRegEx.test(getTagName(el));\n\nexport const createEmptyResponse = (): SVGParsingOutput => ({\n objects: [],\n elements: [],\n options: {},\n allElements: [],\n});\n\n/**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {HTMLElement} doc SVG document to parse\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {SVGParsingOutput}\n * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n */\nexport async function parseSVGDocument(\n doc: Document,\n reviver?: TSvgReviverCallback,\n { crossOrigin, signal }: LoadImageOptions = {},\n): Promise {\n if (signal && signal.aborted) {\n log('log', new SignalAbortedError('parseSVGDocument'));\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n }\n const documentElement = doc.documentElement;\n parseUseDirectives(doc);\n\n const descendants = Array.from(documentElement.getElementsByTagName('*')),\n options = {\n ...applyViewboxTransform(documentElement),\n crossOrigin,\n signal,\n };\n\n const elements = descendants.filter((el) => {\n applyViewboxTransform(el);\n return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n if (!elements || (elements && !elements.length)) {\n return {\n ...createEmptyResponse(),\n options,\n allElements: descendants,\n };\n }\n const localClipPaths: Record = {};\n descendants\n .filter((el) => getTagName(el) === 'clipPath')\n .forEach((el) => {\n el.setAttribute('originalTransform', el.getAttribute('transform') || '');\n const id = el.getAttribute('id')!;\n localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(\n (el) => isValidSvgTag(el),\n );\n });\n\n // Precedence of rules: style > class > attribute\n const elementParser = new ElementsParser(\n elements,\n options,\n reviver,\n doc,\n localClipPaths,\n );\n\n const instances = await elementParser.parse();\n\n return {\n objects: instances,\n elements,\n options,\n allElements: descendants,\n };\n}\n","import { svgNS } from './constants';\nimport { getMultipleNodes } from './getMultipleNodes';\nimport { applyViewboxTransform } from './applyViewboxTransform';\nimport { parseStyleString } from './parseStyleString';\n\nexport function parseUseDirectives(doc: Document) {\n const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);\n const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];\n\n for (const useElement of nodelist) {\n const useAttributes: NamedNodeMap = useElement.attributes;\n\n const useAttrMap: Record = {};\n for (const attr of useAttributes) {\n attr.value && (useAttrMap[attr.name] = attr.value);\n }\n\n const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);\n\n if (xlink === '') {\n return;\n }\n const referencedElement = doc.getElementById(xlink);\n if (referencedElement === null) {\n // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink\n return;\n }\n let clonedOriginal = referencedElement.cloneNode(true) as Element;\n\n const originalAttributes: NamedNodeMap = clonedOriginal.attributes;\n\n const originalAttrMap: Record = {};\n for (const attr of originalAttributes) {\n attr.value && (originalAttrMap[attr.name] = attr.value);\n }\n\n // Transform attribute needs to be merged in a particular way\n const { x = 0, y = 0, transform = '' } = useAttrMap;\n const currentTrans = `${transform} ${\n originalAttrMap.transform || ''\n } translate(${x}, ${y})`;\n\n applyViewboxTransform(clonedOriginal);\n\n if (/^svg$/i.test(clonedOriginal.nodeName)) {\n // if is an SVG, create a group and apply all the attributes on top of it\n const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');\n Object.entries(originalAttrMap).forEach(([name, value]) =>\n el3.setAttributeNS(svgNS, name, value),\n );\n el3.append(...clonedOriginal.childNodes);\n clonedOriginal = el3;\n }\n\n for (const attr of useAttributes) {\n if (!attr) {\n continue;\n }\n const { name, value } = attr;\n if (skipAttributes.includes(name)) {\n continue;\n }\n\n if (name === 'style') {\n // when use has a style, merge the two styles, with the ref being priority (not use)\n // priority is by feature. an attribute for fill on the original element\n // will overwrite the fill in style or attribute for tha use\n const styleRecord: Record = {};\n parseStyleString(value!, styleRecord);\n // cleanup styleRecord from attributes of original\n Object.entries(originalAttrMap).forEach(([name, value]) => {\n styleRecord[name] = value;\n });\n // now we can put in the style of the original that will overwrite the original attributes\n parseStyleString(originalAttrMap.style || '', styleRecord);\n const mergedStyles = Object.entries(styleRecord)\n .map((entry) => entry.join(':'))\n .join(';');\n clonedOriginal.setAttribute(name, mergedStyles);\n } else {\n // set the attribute from use element only if the original does not have it already\n !originalAttrMap[name] && clonedOriginal.setAttribute(name, value!);\n }\n }\n\n clonedOriginal.setAttribute('transform', currentTrans);\n clonedOriginal.setAttribute('instantiated_by_use', '1');\n clonedOriginal.removeAttribute('id');\n useElement.parentNode!.replaceChild(clonedOriginal, useElement);\n }\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Polyline } from '../shapes/Polyline';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { MODIFY_POLY } from '../constants';\n\nconst ACTION_NAME: TModificationEvents = MODIFY_POLY;\n\ntype TTransformAnchor = Transform & { pointIndex: number };\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nexport const createPolyPositionHandler = (pointIndex: number) => {\n return function (dim: Point, finalMatrix: TMat2D, polyObject: Polyline) {\n const { points, pathOffset } = polyObject;\n return new Point(points[pointIndex])\n .subtract(pathOffset)\n .transform(\n multiplyTransformMatrices(\n polyObject.getViewportTransform(),\n polyObject.calcTransformMatrix(),\n ),\n );\n };\n};\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nexport const polyActionHandler = (\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) => {\n const { target, pointIndex } = transform;\n const poly = target as Polyline;\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n poly.calcOwnMatrix(),\n );\n\n poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);\n poly.setDimensions();\n\n return true;\n};\n\n/**\n * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.\n */\nexport const factoryPolyActionHandler = (\n pointIndex: number,\n fn: TransformActionHandler,\n) => {\n return function (\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n ) {\n const poly = transform.target as Polyline,\n anchorPoint = new Point(\n poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1],\n ),\n anchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix()),\n actionPerformed = fn(eventData, { ...transform, pointIndex }, x, y);\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n poly.left -= diff.x;\n poly.top -= diff.y;\n\n return actionPerformed;\n };\n};\n\nexport const createPolyActionHandler = (pointIndex: number) =>\n wrapWithFireEvent(\n ACTION_NAME,\n factoryPolyActionHandler(pointIndex, polyActionHandler),\n );\n\nexport function createPolyControls(\n poly: Polyline,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n numOfControls: number,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n arg0: number | Polyline,\n options: Partial = {},\n) {\n const controls = {} as Record;\n for (\n let idx = 0;\n idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length);\n idx++\n ) {\n controls[`p${idx}`] = new Control({\n actionName: ACTION_NAME,\n positionHandler: createPolyPositionHandler(idx),\n actionHandler: createPolyActionHandler(idx),\n ...options,\n });\n }\n return controls;\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Path } from '../shapes/Path';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport type { TSimpleParseCommandType } from '../util/path/typedefs';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\nconst ACTION_NAME: TModificationEvents = 'modifyPath' as const;\n\ntype TTransformAnchor = Transform;\n\nexport type PathPointControlStyle = {\n controlFill?: string;\n controlStroke?: string;\n connectionDashArray?: number[];\n};\n\nconst calcPathPointPosition = (\n pathObject: Path,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n const command = path[commandIndex];\n return new Point(\n (command[pointIndex] as number) - pathOffset.x,\n (command[pointIndex + 1] as number) - pathOffset.y,\n ).transform(\n multiplyTransformMatrices(\n pathObject.getViewportTransform(),\n pathObject.calcTransformMatrix(),\n ),\n );\n};\n\nconst movePathPoint = (\n pathObject: Path,\n x: number,\n y: number,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n\n const anchorCommand =\n path[(commandIndex > 0 ? commandIndex : path.length) - 1];\n const anchorPoint = new Point(\n anchorCommand[pointIndex] as number,\n anchorCommand[pointIndex + 1] as number,\n );\n\n const anchorPointInParentPlane = anchorPoint\n .subtract(pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n pathObject.calcOwnMatrix(),\n );\n\n path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;\n path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;\n pathObject.setDimensions();\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(pathObject.pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n pathObject.left -= diff.x;\n pathObject.top -= diff.y;\n pathObject.set('dirty', true);\n return true;\n};\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nfunction pathPositionHandler(\n this: PathPointControl,\n dim: Point,\n finalMatrix: TMat2D,\n pathObject: Path,\n) {\n const { commandIndex, pointIndex } = this;\n return calcPathPointPosition(pathObject, commandIndex, pointIndex);\n}\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nfunction pathActionHandler(\n this: PathPointControl,\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) {\n const { target } = transform;\n const { commandIndex, pointIndex } = this;\n const actionPerformed = movePathPoint(\n target as Path,\n x,\n y,\n commandIndex,\n pointIndex,\n );\n if (actionPerformed) {\n fireEvent(this.actionName as TModificationEvents, {\n ...commonEventInfo(eventData, transform, x, y),\n commandIndex,\n pointIndex,\n });\n }\n return actionPerformed;\n}\n\nconst indexFromPrevCommand = (previousCommandType: TSimpleParseCommandType) =>\n previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;\n\nclass PathPointControl extends Control {\n declare commandIndex: number;\n declare pointIndex: number;\n declare controlFill: string;\n declare controlStroke: string;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const overrides: ControlRenderingStyleOverride = {\n ...styleOverride,\n cornerColor: this.controlFill,\n cornerStrokeColor: this.controlStroke,\n transparentCorners: !this.controlFill,\n };\n super.render(ctx, left, top, overrides, fabricObject);\n }\n}\n\nclass PathControlPointControl extends PathPointControl {\n declare connectionDashArray?: number[];\n declare connectToCommandIndex: number;\n declare connectToPointIndex: number;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n this: PathControlPointControl,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const { path } = fabricObject;\n const {\n commandIndex,\n pointIndex,\n connectToCommandIndex,\n connectToPointIndex,\n } = this;\n ctx.save();\n ctx.strokeStyle = this.controlStroke;\n if (this.connectionDashArray) {\n ctx.setLineDash(this.connectionDashArray);\n }\n const [commandType] = path[commandIndex];\n const point = calcPathPointPosition(\n fabricObject,\n connectToCommandIndex,\n connectToPointIndex,\n );\n\n if (commandType === 'Q') {\n // one control point connects to 2 points\n const point2 = calcPathPointPosition(\n fabricObject,\n commandIndex,\n pointIndex + 2,\n );\n ctx.moveTo(point2.x, point2.y);\n ctx.lineTo(left, top);\n } else {\n ctx.moveTo(left, top);\n }\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n ctx.restore();\n\n super.render(ctx, left, top, styleOverride, fabricObject);\n }\n}\n\nconst createControl = (\n commandIndexPos: number,\n pointIndexPos: number,\n isControlPoint: boolean,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n },\n connectToCommandIndex?: number,\n connectToPointIndex?: number,\n) =>\n new (isControlPoint ? PathControlPointControl : PathPointControl)({\n commandIndex: commandIndexPos,\n pointIndex: pointIndexPos,\n actionName: ACTION_NAME,\n positionHandler: pathPositionHandler,\n actionHandler: pathActionHandler,\n connectToCommandIndex,\n connectToPointIndex,\n ...options,\n ...(isControlPoint ? options.controlPointStyle : options.pointStyle),\n } as Partial);\n\nexport function createPathControls(\n path: Path,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n } = {},\n): Record {\n const controls = {} as Record;\n let previousCommandType: TSimpleParseCommandType = 'M';\n path.path.forEach((command, commandIndex) => {\n const commandType = command[0];\n\n if (commandType !== 'Z') {\n controls[`c_${commandIndex}_${commandType}`] = createControl(\n commandIndex,\n command.length - 2,\n false,\n options,\n );\n }\n switch (commandType) {\n case 'C':\n controls[`c_${commandIndex}_C_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex - 1,\n indexFromPrevCommand(previousCommandType),\n );\n controls[`c_${commandIndex}_C_CP_2`] = createControl(\n commandIndex,\n 3,\n true,\n options,\n commandIndex,\n 5,\n );\n break;\n case 'Q':\n controls[`c_${commandIndex}_Q_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex,\n 3,\n );\n break;\n }\n previousCommandType = commandType;\n });\n return controls;\n}\n","import { getFabricWindow } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\n\nexport const isWebGLPipelineState = (\n options: TWebGLPipelineState | T2DPipelineState,\n): options is TWebGLPipelineState => {\n return (options as TWebGLPipelineState).webgl !== undefined;\n};\n\n/**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * drawImage should be faster, but is also bugged for a small combination of old hardware\n * and drivers.\n * putImageData is faster than drawImage for that specific operation.\n */\nexport const isPutImageFaster = (width: number, height: number): boolean => {\n const targetCanvas = createCanvasElement();\n const sourceCanvas = createCanvasElement();\n const gl = sourceCanvas.getContext('webgl')!;\n // eslint-disable-next-line no-undef\n const imageBuffer = new ArrayBuffer(width * height * 4);\n\n const testContext = {\n imageBuffer: imageBuffer,\n } as unknown as Required;\n const testPipelineState = {\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas,\n } as unknown as TWebGLPipelineState;\n let startTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2D.call(\n testContext,\n gl,\n testPipelineState,\n );\n const drawImageTime = getFabricWindow().performance.now() - startTime;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(\n testContext,\n gl,\n testPipelineState,\n );\n const putImageDataTime = getFabricWindow().performance.now() - startTime;\n\n return drawImageTime > putImageDataTime;\n};\n","export const highPsourceCode = `precision highp float`;\n\nexport const identityFragmentShader = `\n ${highPsourceCode};\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }`;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }`;\n","import { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n T2DPipelineState,\n TWebGLAttributeLocationMap,\n TWebGLPipelineState,\n TWebGLProgramCacheItem,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport {\n highPsourceCode,\n identityFragmentShader,\n vertexSource,\n} from './shaders/baseFilter';\nimport type { Abortable } from '../typedefs';\nimport { FabricError } from '../util/internals/console';\n\nconst regex = new RegExp(highPsourceCode, 'g');\n\nexport class BaseFilter<\n Name extends string,\n OwnProps extends Record = object,\n> {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n get type(): Name {\n return (this.constructor as typeof BaseFilter).type as Name;\n }\n\n /**\n * The class type. Used to identify which class this is.\n * This is used for serialization purposes and internally it can be used\n * to identify classes. As a developer you could use `instance of Class`\n * but to avoid importing all the code and blocking tree shaking we try\n * to avoid doing that.\n */\n static type = 'BaseFilter';\n\n /**\n * Contains the uniform locations for the fragment shader.\n * uStepW and uStepH are handled by the BaseFilter, each filter class\n * needs to specify all the one that are needed\n */\n static uniformLocations: string[] = [];\n\n declare static defaults: Record;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor({\n type,\n ...options\n }: { type?: never } & Partial & Record = {}) {\n Object.assign(\n this,\n (this.constructor as typeof BaseFilter).defaults,\n options,\n );\n }\n\n protected getFragmentSource(): string {\n return identityFragmentShader;\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram(\n gl: WebGLRenderingContext,\n fragmentSource: string = this.getFragmentSource(),\n vertexSource: string = this.getVertexSource(),\n ) {\n const {\n WebGLProbe: { GLPrecision = 'highp' },\n } = getEnv();\n if (GLPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(\n regex,\n highPsourceCode.replace('highp', GLPrecision),\n );\n }\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n const program = gl.createProgram();\n\n if (!vertexShader || !fragmentShader || !program) {\n throw new FabricError(\n 'Vertex, fragment shader or program creation error',\n );\n }\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n vertexShader,\n )}`,\n );\n }\n\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n fragmentShader,\n )}`,\n );\n }\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new FabricError(\n `Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}`,\n );\n }\n\n const uniformLocations = this.getUniformLocations(gl, program) || {};\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n\n return {\n program,\n attributeLocations: this.getAttributeLocations(gl, program),\n uniformLocations,\n };\n }\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLAttributeLocationMap {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n }\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLUniformLocationMap {\n const locations = (this.constructor as unknown as typeof BaseFilter)\n .uniformLocations;\n\n const uniformLocations: Record = {};\n for (let i = 0; i < locations.length; i++) {\n uniformLocations[locations[i]] = gl.getUniformLocation(\n program,\n locations[i],\n );\n }\n return uniformLocations;\n }\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData(\n gl: WebGLRenderingContext,\n attributeLocations: Record,\n aPositionData: Float32Array,\n ) {\n const attributeLocation = attributeLocations.aPosition;\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n }\n\n _setupFrameBuffer(options: TWebGLPipelineState) {\n const gl = options.context;\n if (options.passes > 1) {\n const width = options.destinationWidth;\n const height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(\n gl,\n width,\n height,\n );\n }\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n options.targetTexture,\n 0,\n );\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n }\n\n _swapTextures(options: TWebGLPipelineState) {\n options.passes--;\n options.pass++;\n const temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n }\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isNeutralState(options?: any): boolean {\n return false;\n }\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(_options: T2DPipelineState): void {\n // override by subclass\n }\n\n /**\n * Returns a string that represent the current selected shader code for the filter.\n * Used to force recompilation when parameters change or to retrieve the shader from cache\n * @type string\n **/\n getCacheKey(): string {\n return this.type;\n }\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n * @return {WebGLProgram} the compiled program shader\n */\n retrieveShader(options: TWebGLPipelineState): TWebGLProgramCacheItem {\n const key = this.getCacheKey();\n if (!options.programCache[key]) {\n options.programCache[key] = this.createProgram(options.context);\n }\n return options.programCache[key];\n }\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context;\n const shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n bindAdditionalTexture(\n gl: WebGLRenderingContext,\n texture: WebGLTexture,\n textureUnit: number,\n ) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n }\n\n unbindAdditionalTexture(gl: WebGLRenderingContext, textureUnit: number) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n }\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program.\n * @param {Object} _uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData(\n _gl: WebGLRenderingContext,\n _uniformLocations: TWebGLUniformLocationMap,\n ): void {\n // override by subclass\n }\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer(options: T2DPipelineState) {\n if (!options.helpLayer) {\n const helpLayer = createCanvasElement();\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n }\n\n /**\n * Returns object representation of an instance\n * It will automatically export the default values of a filter,\n * stored in the static defaults property.\n * @return {Object} Object representation of an instance\n */\n toObject(): { type: Name } & OwnProps {\n const defaultKeys = Object.keys(\n (this.constructor as typeof BaseFilter).defaults || {},\n ) as (keyof OwnProps)[];\n\n return {\n type: this.type,\n ...defaultKeys.reduce((acc, key) => {\n acc[key] = this[\n key as keyof this\n ] as unknown as (typeof acc)[typeof key];\n return acc;\n }, {} as OwnProps),\n };\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n static async fromObject(\n { type, ...filterOptions }: Record,\n _options: Abortable,\n ): Promise> {\n return new this(filterOptions);\n }\n}\n","export const blendColorFragmentSource = {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen:\n 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion:\n 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: `\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n `,\n tint: `\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n `,\n} as const;\n","import { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { blendColorFragmentSource } from './shaders/blendColor';\n\nexport type TBlendMode =\n | 'multiply'\n | 'add'\n | 'difference'\n | 'screen'\n | 'subtract'\n | 'darken'\n | 'lighten'\n | 'overlay'\n | 'exclusion'\n | 'tint';\n\ntype BlendColorOwnProps = {\n color: string;\n mode: TBlendMode;\n alpha: number;\n};\n\nexport const blendColorDefaultValues: BlendColorOwnProps = {\n color: '#F95C63',\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Color Blend filter class\n * @example\n * const filter = new BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendColor extends BaseFilter<'BlendColor', BlendColorOwnProps> {\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n * @type String\n * @default\n **/\n declare color: BlendColorOwnProps['color'];\n\n /**\n * Blend mode for the filter: one of multiply, add, difference, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n * @type String\n * @default\n **/\n declare mode: BlendColorOwnProps['mode'];\n /**\n * alpha value. represent the strength of the blend color operation.\n * @type Number\n * @default\n **/\n declare alpha: BlendColorOwnProps['alpha'];\n\n static defaults = blendColorDefaultValues;\n\n static type = 'BlendColor';\n\n static uniformLocations = ['uColor'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n protected getFragmentSource(): string {\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ${blendColorFragmentSource[this.mode]}\n }\n }\n `;\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const source = new Color(this.color).getSource();\n const tr = source[0] * this.alpha;\n const tg = source[1] * this.alpha;\n const tb = source[2] * this.alpha;\n const alpha1 = 1 - this.alpha;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n break;\n case 'screen':\n data[i] = 255 - ((255 - r) * (255 - tr)) / 255;\n data[i + 1] = 255 - ((255 - g) * (255 - tg)) / 255;\n data[i + 2] = 255 - ((255 - b) * (255 - tb)) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] =\n tr < 128\n ? (2 * r * tr) / 255\n : 255 - (2 * (255 - r) * (255 - tr)) / 255;\n data[i + 1] =\n tg < 128\n ? (2 * g * tg) / 255\n : 255 - (2 * (255 - g) * (255 - tg)) / 255;\n data[i + 2] =\n tb < 128\n ? (2 * b * tb) / 255\n : 255 - (2 * (255 - b) * (255 - tb)) / 255;\n break;\n case 'exclusion':\n data[i] = tr + r - (2 * tr * r) / 255;\n data[i + 1] = tg + g - (2 * tg * g) / 255;\n data[i + 2] = tb + b - (2 * tb * b) / 255;\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource();\n source[0] = (this.alpha * source[0]) / 255;\n source[1] = (this.alpha * source[1]) / 255;\n source[2] = (this.alpha * source[2]) / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n }\n}\n\nclassRegistry.setClass(BlendColor);\n","import type { TBlendImageMode } from '../BlendImage';\n\nexport const fragmentSource: Record = {\n multiply: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n `,\n mask: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n `,\n} as const;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n ` as const;\n","import { FabricImage } from '../shapes/Image';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport type { WebGLFilterBackend } from './WebGLFilterBackend';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource, vertexSource } from './shaders/blendImage';\n\nexport type TBlendImageMode = 'multiply' | 'mask';\n\ntype BlendImageOwnProps = {\n mode: TBlendImageMode;\n alpha: number;\n};\n\nexport const blendImageDefaultValues: BlendImageOwnProps = {\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Image Blend filter class\n * @example\n * const filter = new filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendImage extends BaseFilter<'BlendImage', BlendImageOwnProps> {\n /**\n * Image to make the blend operation with.\n **/\n declare image: FabricImage;\n\n /**\n * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will\n * multiply the values of each channel (R, G, B, and A) of the filter image by\n * their corresponding values in the base image. 'mask' will only look at the\n * alpha channel of the filter image, and apply those values to the base\n * image's alpha channel.\n * @type String\n * @default\n **/\n declare mode: BlendImageOwnProps['mode'];\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n declare alpha: BlendImageOwnProps['alpha'];\n\n static type = 'BlendImage';\n\n static defaults = blendImageDefaultValues;\n\n static uniformLocations = ['uTransformMatrix', 'uImage'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource(): string {\n return fragmentSource[this.mode];\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture!, gl.TEXTURE1);\n super.applyToWebGL(options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n }\n\n createTexture(backend: WebGLFilterBackend, image: FabricImage) {\n return backend.getCachedTexture(image.cacheKey, image.getElement());\n }\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix() {\n const image = this.image,\n { width, height } = image.getElement();\n return [\n 1 / image.scaleX,\n 0,\n 0,\n 0,\n 1 / image.scaleY,\n 0,\n -image.left / width,\n -image.top / height,\n 1,\n ];\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({\n imageData: { data, width, height },\n filterBackend: { resources },\n }: T2DPipelineState) {\n const image = this.image;\n if (!resources.blendImage) {\n resources.blendImage = createCanvasElement();\n }\n const canvas1 = resources.blendImage;\n const context = canvas1.getContext('2d')!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(\n image.scaleX,\n 0,\n 0,\n image.scaleY,\n image.left,\n image.top,\n );\n context.drawImage(image.getElement(), 0, 0, width, height);\n const blendData = context.getImageData(0, 0, width, height).data;\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n const tr = blendData[i];\n const tg = blendData[i + 1];\n const tb = blendData[i + 2];\n const ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n data[i + 3] = (a * ta) / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n }\n\n /**\n * Returns object representation of an instance\n * TODO: Handle the possibility of missing image better.\n * As of now a BlendImage filter without image can't be used with fromObject\n * @return {Object} Object representation of an instance\n */\n toObject(): {\n type: 'BlendImage';\n image: ReturnType;\n } & BlendImageOwnProps {\n return {\n ...super.toObject(),\n image: this.image && this.image.toObject(),\n };\n }\n\n /**\n * Create filter instance from an object representation\n * @static\n * @param {object} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static async fromObject(\n { type, image, ...filterOptions }: Record,\n options: { signal: AbortSignal },\n ): Promise> {\n return FabricImage.fromObject(image, options).then(\n (enlivedImage) =>\n new this({ ...filterOptions, image: enlivedImage }) as BlendImage,\n );\n }\n}\n\nclassRegistry.setClass(BlendImage);\n","import { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n TWebGLPipelineState,\n T2DPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/blur';\n\ntype BlurOwnProps = {\n blur: number;\n};\n\nexport const blurDefaultValues: BlurOwnProps = {\n blur: 0,\n};\n\n/**\n * Blur filter class\n * @example\n * const filter = new Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Blur extends BaseFilter<'Blur', BlurOwnProps> {\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range between 0 and 1.\n * @type Number\n * @default\n */\n declare blur: BlurOwnProps['blur'];\n\n declare horizontal: boolean;\n declare aspectRatio: number;\n\n static type = 'Blur';\n\n static defaults = blurDefaultValues;\n\n static uniformLocations = ['uDelta'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(options: T2DPipelineState) {\n options.imageData = this.simpleBlur(options);\n }\n\n simpleBlur({\n ctx,\n imageData,\n filterBackend: { resources },\n }: T2DPipelineState) {\n const { width, height } = imageData;\n if (!resources.blurLayer1) {\n resources.blurLayer1 = createCanvasElement();\n resources.blurLayer2 = createCanvasElement();\n }\n const canvas1 = resources.blurLayer1!;\n const canvas2 = resources.blurLayer2!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n const ctx1 = canvas1.getContext('2d')!,\n ctx2 = canvas2.getContext('2d')!,\n nSamples = 15,\n blur = this.blur * 0.06 * 0.5;\n let random, percent, j, i;\n\n // load first canvas\n ctx1.putImageData(imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n ctx.drawImage(canvas1, 0, 0);\n const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.uDelta, delta);\n }\n\n isNeutralState() {\n return this.blur === 0;\n }\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta() {\n let blurScale = 1;\n const delta = [0, 0];\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n const blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n return delta;\n }\n}\n\nclassRegistry.setClass(Blur);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n ` as const;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/brightness';\n\ntype BrightnessOwnProps = {\n brightness: number;\n};\n\nexport const brightnessDefaultValues: BrightnessOwnProps = {\n brightness: 0,\n};\n\n/**\n * Brightness filter class\n * @example\n * const filter = new Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Brightness extends BaseFilter<'Brightness', BrightnessOwnProps> {\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n declare brightness: BrightnessOwnProps['brightness'];\n\n static type = 'Brightness';\n\n static defaults = brightnessDefaultValues;\n\n static uniformLocations = ['uBrightness'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const brightness = Math.round(this.brightness * 255);\n for (let i = 0; i < data.length; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n }\n\n isNeutralState() {\n return this.brightness === 0;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n }\n}\n\nclassRegistry.setClass(Brightness);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TMatColorMatrix,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/colorMatrix';\n\ntype ColorMatrixOwnProps = {\n matrix: TMatColorMatrix;\n colorsOnly: boolean;\n};\n\nexport const colorMatrixDefaultValues: ColorMatrixOwnProps = {\n matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\n colorsOnly: true,\n};\n\n/**\n * Color Matrix filter class\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo}\n * @example Kodachrome filter\n * const filter = new ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class ColorMatrix<\n Name extends string = 'ColorMatrix',\n OwnProps extends object = ColorMatrixOwnProps,\n> extends BaseFilter {\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n declare matrix: ColorMatrixOwnProps['matrix'];\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario\n * to save some calculation\n * @type Boolean\n * @default true\n */\n declare colorsOnly: ColorMatrixOwnProps['colorsOnly'];\n\n static type = 'ColorMatrix';\n\n static defaults = colorMatrixDefaultValues;\n\n static uniformLocations = ['uColorMatrix', 'uConstants'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n m = this.matrix,\n colorsOnly = this.colorsOnly;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n } else {\n const a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] =\n r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] =\n r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const m = this.matrix,\n matrix = [\n m[0],\n m[1],\n m[2],\n m[3],\n m[5],\n m[6],\n m[7],\n m[8],\n m[10],\n m[11],\n m[12],\n m[13],\n m[15],\n m[16],\n m[17],\n m[18],\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n }\n\n toObject() {\n return {\n ...super.toObject(),\n matrix: [...this.matrix] as TMatColorMatrix,\n };\n }\n}\n\nclassRegistry.setClass(ColorMatrix);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }`;\n","import { ColorMatrix } from './ColorMatrix';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TMatColorMatrix } from './typedefs';\n\ntype FixedFiltersOwnProps = {\n colorsOnly: boolean;\n};\n\nexport function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) {\n const newClass = class extends ColorMatrix {\n static type = key;\n\n static defaults = {\n colorsOnly: false,\n matrix,\n };\n\n //@ts-expect-error TS wants matrix to be exported.\n toObject(): { type: string } & FixedFiltersOwnProps {\n return { type: this.type, colorsOnly: this.colorsOnly };\n }\n };\n classRegistry.setClass(newClass, key);\n return newClass as typeof ColorMatrix;\n}\n\nexport const Brownie = createColorMatrixFilter(\n 'Brownie',\n [\n 0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449,\n 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Vintage = createColorMatrixFilter(\n 'Vintage',\n [\n 0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0,\n 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Kodachrome = createColorMatrixFilter(\n 'Kodachrome',\n [\n 1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0,\n 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Technicolor = createColorMatrixFilter(\n 'Technicolor',\n [\n 1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0,\n -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Polaroid = createColorMatrixFilter(\n 'Polaroid',\n [\n 1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016,\n 1.483, 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Sepia = createColorMatrixFilter(\n 'Sepia',\n [\n 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131,\n 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const BlackWhite = createColorMatrixFilter(\n 'BlackWhite',\n [\n 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0,\n 1, 0,\n ],\n);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLPipelineState } from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\n\ntype ComposedOwnProps = {\n subFilters: BaseFilter[];\n};\n\n/**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\nexport class Composed extends BaseFilter<'Composed', ComposedOwnProps> {\n /**\n * A non sparse array of filters to apply\n */\n declare subFilters: ComposedOwnProps['subFilters'];\n\n static type = 'Composed';\n\n constructor(\n options: { subFilters?: BaseFilter[] } & Record<\n string,\n any\n > = {},\n ) {\n super(options);\n this.subFilters = options.subFilters || [];\n }\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n options.passes += this.subFilters.length - 1;\n }\n this.subFilters.forEach((filter) => {\n filter.applyTo(options);\n });\n }\n\n /**\n * Serialize this filter into JSON.\n * @returns {Object} A JSON representation of this filter.\n */\n //@ts-expect-error TS doesn't like this toObject\n toObject(): {\n type: 'Composed';\n subFilters: ReturnType['toObject']>[];\n } {\n return {\n type: this.type,\n subFilters: this.subFilters.map((filter) => filter.toObject()),\n };\n }\n\n isNeutralState() {\n return !this.subFilters.some((filter) => !filter.isNeutralState());\n }\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n * @static\n * @param {oject} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject(\n object: Record,\n options: { signal: AbortSignal },\n ): Promise {\n return Promise.all(\n ((object.subFilters || []) as BaseFilter[]).map(\n (filter) =>\n classRegistry\n .getClass(filter.type)\n .fromObject(filter, options),\n ),\n ).then(\n (enlivedFilters) => new this({ subFilters: enlivedFilters }) as Composed,\n );\n }\n}\n\nclassRegistry.setClass(Composed);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/constrast';\n\ntype ContrastOwnProps = {\n contrast: number;\n};\n\nexport const contrastDefaultValues: ContrastOwnProps = {\n contrast: 0,\n};\n\n/**\n * Contrast filter class\n * @example\n * const filter = new Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Contrast extends BaseFilter<'Contrast', ContrastOwnProps> {\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n declare contrast: ContrastOwnProps['contrast'];\n\n static type = 'Contrast';\n\n static defaults = contrastDefaultValues;\n\n static uniformLocations = ['uContrast'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n isNeutralState() {\n return this.contrast === 0;\n }\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const contrast = Math.floor(this.contrast * 255),\n contrastF = (259 * (contrast + 255)) / (255 * (259 - contrast));\n\n for (let i = 0; i < data.length; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n }\n}\n\nclassRegistry.setClass(Contrast);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }`;\n","export const fragmentSource = {\n Convolute_3_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_3_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_5_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_5_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_7_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_7_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_9_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_9_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/convolute';\n\nexport type ConvoluteOwnProps = {\n opaque: boolean;\n matrix: number[];\n};\n\nexport const convoluteDefaultValues: ConvoluteOwnProps = {\n opaque: false,\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n};\n\n/**\n * Adapted from html5rocks article\n * @example Sharpen filter\n * const filter = new Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Blur filter\n * const filter = new Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter\n * const filter = new Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter with opaqueness\n * const filter = new Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Convolute extends BaseFilter<'Convolute', ConvoluteOwnProps> {\n /*\n * Opaque value (true/false)\n */\n declare opaque: ConvoluteOwnProps['opaque'];\n\n /*\n * matrix for the filter, max 9x9\n */\n declare matrix: ConvoluteOwnProps['matrix'];\n\n static type = 'Convolute';\n\n static defaults = convoluteDefaultValues;\n\n static uniformLocations = ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize'];\n\n getCacheKey() {\n return `${this.type}_${Math.sqrt(this.matrix.length)}_${\n this.opaque ? 1 : 0\n }` as keyof typeof fragmentSource;\n }\n\n getFragmentSource() {\n return fragmentSource[this.getCacheKey()];\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0;\n let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n }\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject() {\n return {\n ...super.toObject(),\n opaque: this.opaque,\n matrix: [...this.matrix],\n };\n }\n}\n\nclassRegistry.setClass(Convolute);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/gamma';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nconst GAMMA = 'Gamma' as const;\n\nexport type GammaInput = [number, number, number];\n\nexport type GammaOwnProps = {\n gamma: GammaInput;\n};\n\nexport const gammaDefaultValues: GammaOwnProps = {\n gamma: [1, 1, 1],\n};\n\n/**\n * Gamma filter class\n * @example\n * const filter = new Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Gamma extends BaseFilter {\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n declare gamma: GammaOwnProps['gamma'];\n declare rgbValues?: {\n r: Uint8Array;\n g: Uint8Array;\n b: Uint8Array;\n };\n\n static type = GAMMA;\n\n static defaults = gammaDefaultValues;\n\n static uniformLocations = ['uGamma'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n constructor(options: { gamma?: GammaInput } = {}) {\n super(options);\n this.gamma =\n options.gamma ||\n ((\n this.constructor as typeof Gamma\n ).defaults.gamma.concat() as GammaInput);\n }\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const gamma = this.gamma,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2];\n\n if (!this.rgbValues) {\n this.rgbValues = {\n r: new Uint8Array(256),\n g: new Uint8Array(256),\n b: new Uint8Array(256),\n };\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n const rgb = this.rgbValues;\n for (let i = 0; i < 256; i++) {\n rgb.r[i] = Math.pow(i / 255, rInv) * 255;\n rgb.g[i] = Math.pow(i / 255, gInv) * 255;\n rgb.b[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (let i = 0; i < data.length; i += 4) {\n data[i] = rgb.r[data[i]];\n data[i + 1] = rgb.g[data[i + 1]];\n data[i + 2] = rgb.b[data[i + 2]];\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n }\n\n isNeutralState() {\n const { gamma } = this;\n return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1;\n }\n\n toObject(): { type: typeof GAMMA; gamma: GammaInput } {\n return {\n type: GAMMA,\n gamma: this.gamma.concat() as GammaInput,\n };\n }\n}\n\nclassRegistry.setClass(Gamma);\n","import type { TGrayscaleMode } from '../Grayscale';\n\nexport const fragmentSource: Record = {\n average: `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n `,\n lightness: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n luminosity: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/grayscale';\n\nexport type TGrayscaleMode = 'average' | 'lightness' | 'luminosity';\n\ntype GrayscaleOwnProps = {\n mode: TGrayscaleMode;\n};\n\nexport const grayscaleDefaultValues: GrayscaleOwnProps = {\n mode: 'average',\n};\n\n/**\n * Grayscale image filter class\n * @example\n * const filter = new Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Grayscale extends BaseFilter<'Grayscale', GrayscaleOwnProps> {\n declare mode: TGrayscaleMode;\n\n static type = 'Grayscale';\n\n static defaults = grayscaleDefaultValues;\n\n static uniformLocations = ['uMode'];\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0, value: number; i < data.length; i += 4) {\n switch (this.mode) {\n case 'average':\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n break;\n case 'lightness':\n value =\n (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) /\n 2;\n break;\n case 'luminosity':\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n break;\n }\n\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n }\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource() {\n return fragmentSource[this.mode];\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n }\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState() {\n return false;\n }\n}\n\nclassRegistry.setClass(Grayscale);\n","import { cos } from '../util/misc/cos';\nimport { sin } from '../util/misc/sin';\nimport { ColorMatrix } from './ColorMatrix';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\n\nexport type HueRotationOwnProps = {\n rotation: number;\n};\n\nexport const hueRotationDefaultValues: HueRotationOwnProps = {\n rotation: 0,\n};\n\n/**\n * HueRotation filter class\n * @example\n * const filter = new HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class HueRotation extends ColorMatrix<\n 'HueRotation',\n HueRotationOwnProps\n> {\n /**\n * HueRotation value, from -1 to 1.\n */\n declare rotation: HueRotationOwnProps['rotation'];\n\n static type = 'HueRotation';\n\n static defaults = hueRotationDefaultValues;\n\n calculateMatrix() {\n const rad = this.rotation * Math.PI,\n cosine = cos(rad),\n sine = sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sine,\n OneMinusCos = 1 - cosine;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\n this.matrix[0] = cosine + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cosine + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cosine + aThird * OneMinusCos;\n }\n\n isNeutralState() {\n return this.rotation === 0;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n this.calculateMatrix();\n super.applyTo(options);\n }\n\n //@ts-expect-error TS and classes with different methods\n toObject(): { type: 'HueRotation'; rotation: number } {\n return {\n type: this.type,\n rotation: this.rotation,\n };\n }\n}\n\nclassRegistry.setClass(HueRotation);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/invert';\n\nexport type InvertOwnProps = {\n alpha: boolean;\n invert: boolean;\n};\n\nexport const invertDefaultValues: InvertOwnProps = {\n alpha: false,\n invert: true,\n};\n\n/**\n * @example\n * const filter = new Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Invert extends BaseFilter<'Invert', InvertOwnProps> {\n /**\n * Invert also alpha.\n * @param {Boolean} alpha\n * @default\n **/\n declare alpha: InvertOwnProps['alpha'];\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n declare invert: InvertOwnProps['invert'];\n\n static type = 'Invert';\n\n static defaults = invertDefaultValues;\n\n static uniformLocations = ['uInvert', 'uAlpha'];\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0; i < data.length; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n\n if (this.alpha) {\n data[i + 3] = 255 - data[i + 3];\n }\n }\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState() {\n return !this.invert;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1i(uniformLocations.uInvert, Number(this.invert));\n gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha));\n }\n}\n\nclassRegistry.setClass(Invert);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/noise';\n\nexport type NoiseOwnProps = {\n noise: number;\n};\n\nexport const noiseDefaultValues: NoiseOwnProps = {\n noise: 0,\n};\n\n/**\n * Noise filter class\n * @example\n * const filter = new Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Noise extends BaseFilter<'Noise', NoiseOwnProps> {\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n declare noise: NoiseOwnProps['noise'];\n\n static type = 'Noise';\n\n static defaults = noiseDefaultValues;\n\n static uniformLocations = ['uNoise', 'uSeed'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const noise = this.noise;\n for (let i = 0; i < data.length; i += 4) {\n const rand = (0.5 - Math.random()) * noise;\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n }\n\n isNeutralState() {\n return this.noise === 0;\n }\n}\n\nclassRegistry.setClass(Noise);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/pixelate';\n\nexport type PixelateOwnProps = {\n blocksize: number;\n};\n\nexport const pixelateDefaultValues: PixelateOwnProps = {\n blocksize: 4,\n};\n\n/**\n * Pixelate filter class\n * @example\n * const filter = new Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Pixelate extends BaseFilter<'Pixelate', PixelateOwnProps> {\n declare blocksize: PixelateOwnProps['blocksize'];\n\n static type = 'Pixelate';\n\n static defaults = pixelateDefaultValues;\n\n static uniformLocations = ['uBlocksize'];\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data, width, height } }: T2DPipelineState) {\n for (let i = 0; i < height; i += this.blocksize) {\n for (let j = 0; j < width; j += this.blocksize) {\n const index = i * 4 * width + j * 4;\n const r = data[index];\n const g = data[index + 1];\n const b = data[index + 2];\n const a = data[index + 3];\n\n for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) {\n for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) {\n const index = _i * 4 * width + _j * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n }\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState() {\n return this.blocksize === 1;\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n }\n}\n\nclassRegistry.setClass(Pixelate);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n`;\n","import { classRegistry } from '../ClassRegistry';\nimport { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport { fragmentShader } from './shaders/removeColor';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nexport type RemoveColorOwnProps = {\n color: string;\n distance: number;\n useAlpha: boolean;\n};\n\nexport const removeColorDefaultValues: RemoveColorOwnProps = {\n color: '#FFFFFF',\n distance: 0.02,\n useAlpha: false,\n};\n\n/**\n * Remove white filter class\n * @example\n * const filter = new RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class RemoveColor extends BaseFilter<\n 'RemoveColor',\n RemoveColorOwnProps\n> {\n /**\n * Color to remove, in any format understood by {@link Color}.\n * @param {String} type\n * @default\n */\n declare color: RemoveColorOwnProps['color'];\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n declare distance: RemoveColorOwnProps['distance'];\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n declare useAlpha: RemoveColorOwnProps['useAlpha'];\n\n static type = 'RemoveColor';\n\n static defaults = removeColorDefaultValues;\n\n static uniformLocations = ['uLow', 'uHigh'];\n\n getFragmentSource() {\n return fragmentShader;\n }\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const distance = this.distance * 255,\n source = new Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n if (\n r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]\n ) {\n data[i + 3] = 0;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource(),\n distance = this.distance,\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1,\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1,\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n }\n}\n\nclassRegistry.setClass(RemoveColor);\n","export const fragmentShader = `\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { XY } from '../Point';\n\nexport type TResizeType = 'bilinear' | 'hermite' | 'sliceHack' | 'lanczos';\n\nexport type ResizeOwnProps = {\n resizeType: TResizeType;\n scaleX: number;\n scaleY: number;\n lanczosLobes: number;\n};\n\nexport const resizeDefaultValues: ResizeOwnProps = {\n resizeType: 'hermite',\n scaleX: 1,\n scaleY: 1,\n lanczosLobes: 3,\n};\n\ntype ResizeDuring2DResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n};\n\ntype ResizeDuringWEBGLResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n horizontal: boolean;\n width: number;\n height: number;\n taps: number[];\n tempScale: number;\n dH: number;\n dW: number;\n};\n\n/**\n * Resize image filter class\n * @example\n * const filter = new Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Resize extends BaseFilter<'Resize', ResizeOwnProps> {\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @default\n */\n declare resizeType: ResizeOwnProps['resizeType'];\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n declare scaleX: ResizeOwnProps['scaleX'];\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n declare scaleY: ResizeOwnProps['scaleY'];\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n declare lanczosLobes: ResizeOwnProps['lanczosLobes'];\n\n static type = 'Resize';\n\n static defaults = resizeDefaultValues;\n\n static uniformLocations = ['uDelta', 'uTaps'];\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n this: ResizeDuringWEBGLResize,\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform2fv(\n uniformLocations.uDelta,\n this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height],\n );\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n }\n\n getFilterWindow(this: ResizeDuringWEBGLResize) {\n const scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n }\n\n getCacheKey(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return `${this.type}_${filterWindow}`;\n }\n\n getFragmentSource(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return this.generateShader(filterWindow);\n }\n\n getTaps(this: ResizeDuringWEBGLResize) {\n const lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n }\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader(filterWindow: number) {\n const offsets = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = `${i}.0 * uDelta`;\n }\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[${filterWindow}];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ${offsets\n .map(\n (offset, i) => `\n color += texture2D(uTexture, vTexCoord + ${offset}) * uTaps[${i}] + texture2D(uTexture, vTexCoord - ${offset}) * uTaps[${i}];\n sum += 2.0 * uTaps[${i}];\n `,\n )\n .join('\\n')}\n gl_FragColor = color / sum;\n }\n `;\n }\n\n applyToForWebgl(this: ResizeDuringWEBGLResize, options: TWebGLPipelineState) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n super.applyTo(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n super.applyTo(options);\n options.sourceHeight = options.destinationHeight;\n }\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n (this as unknown as ResizeDuringWEBGLResize).applyToForWebgl(options);\n } else {\n (this as unknown as ResizeDuring2DResize).applyTo2d(options);\n }\n }\n\n isNeutralState() {\n return this.scaleX === 1 && this.scaleY === 1;\n }\n\n lanczosCreate(lobes: number) {\n return (x: number) => {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.1920929e-7 && x > -1.1920929e-7) {\n return 1.0;\n }\n x *= Math.PI;\n const xx = x / lobes;\n return ((Math.sin(x) / x) * Math.sin(xx)) / xx;\n };\n }\n\n applyTo2d(this: ResizeDuring2DResize, options: T2DPipelineState) {\n const imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n const oW = imageData.width;\n const oH = imageData.height;\n const dW = Math.round(oW * scaleX);\n const dH = Math.round(oH * scaleY);\n let newData: ImageData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n } else {\n // this should never trigger, is here just for safety net.\n newData = new ImageData(dW, dH);\n }\n options.imageData = newData;\n }\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo(\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const imageData = options.imageData;\n const mult = 0.5;\n let doneW = false;\n let doneH = false;\n let stepW = oW * mult;\n let stepH = oH * mult;\n const resources = options.filterBackend.resources;\n let sX = 0;\n let sY = 0;\n const dX = oW;\n let dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = createCanvasElement();\n }\n const tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n const ctx = tmpCanvas.getContext('2d')!;\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = Math.floor(dW);\n dH = Math.floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < Math.floor(stepW * mult)) {\n stepW = Math.floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n if (dH < Math.floor(stepH * mult)) {\n stepH = Math.floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n }\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ): ImageData {\n function process(u: number): ImageData {\n let v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = Math.floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = Math.floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = Math.floor(1000 * Math.abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = Math.floor(1000 * Math.abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(\n Math.sqrt(\n Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2),\n ) / 1000,\n );\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n } else {\n return destImg;\n }\n }\n\n const srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = Math.ceil((ratioX * this.lanczosLobes) / 2),\n range2Y = Math.ceil((ratioY * this.lanczosLobes) / 2),\n cacheLanc: Record> = {},\n center: XY = { x: 0, y: 0 },\n icenter: XY = { x: 0, y: 0 };\n\n return process(0);\n }\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n let a;\n let b;\n let c;\n let d;\n let x;\n let y;\n let i;\n let j;\n let xDiff;\n let yDiff;\n let chnl;\n let color;\n let offset = 0;\n let origPix;\n const ratioX = this.rcpScaleX;\n const ratioY = this.rcpScaleY;\n const w4 = 4 * (oW - 1);\n const img = options.imageData;\n const pixels = img.data;\n const destImage = options.ctx.createImageData(dW, dH);\n const destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = Math.floor(ratioX * j);\n y = Math.floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color =\n a * (1 - xDiff) * (1 - yDiff) +\n b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) +\n d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n }\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = Math.ceil(ratioW / 2),\n ratioHHalf = Math.ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n for (let j = 0; j < dH; j++) {\n for (let i = 0; i < dW; i++) {\n const x2 = (i + j * dW) * 4;\n let weight = 0;\n let weights = 0;\n let weightsAlpha = 0;\n let gxR = 0;\n let gxG = 0;\n let gxB = 0;\n let gxA = 0;\n const centerY = (j + 0.5) * ratioH;\n for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW,\n w0 = dy * dy;\n for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf;\n const w = Math.sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = (weight * data[dx + 3]) / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n }\n}\n\nclassRegistry.setClass(Resize);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/saturation';\n\nexport type SaturationOwnProps = {\n saturation: number;\n};\n\nexport const saturationDefaultValues: SaturationOwnProps = {\n saturation: 0,\n};\n\n/**\n * Saturate filter class\n * @example\n * const filter = new Saturation({\n * saturation: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Saturation extends BaseFilter<'Saturation', SaturationOwnProps> {\n /**\n * Saturation value, from -1 to 1.\n * Increases/decreases the color saturation.\n * A value of 0 has no effect.\n *\n * @param {Number} saturation\n * @default\n */\n declare saturation: SaturationOwnProps['saturation'];\n\n static type = 'Saturation';\n\n static defaults = saturationDefaultValues;\n\n static uniformLocations = ['uSaturation'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.saturation;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n }\n\n isNeutralState() {\n return this.saturation === 0;\n }\n}\n\nclassRegistry.setClass(Saturation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/vibrance';\n\nexport type VibranceOwnProps = {\n vibrance: number;\n};\n\nexport const vibranceDefaultValues: VibranceOwnProps = {\n vibrance: 0,\n};\n\n/**\n * Vibrance filter class\n * @example\n * const filter = new Vibrance({\n * vibrance: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Vibrance extends BaseFilter<'Vibrance', VibranceOwnProps> {\n /**\n * Vibrance value, from -1 to 1.\n * Increases/decreases the saturation of more muted colors with less effect on saturated colors.\n * A value of 0 has no effect.\n *\n * @param {Number} vibrance\n * @default\n */\n declare vibrance: VibranceOwnProps['vibrance'];\n\n static type = 'Vibrance';\n\n static defaults = vibranceDefaultValues;\n\n static uniformLocations = ['uVibrance'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.vibrance;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;\n const amt = ((Math.abs(max - avg) * 2) / 255) * adjust;\n data[i] += max !== data[i] ? (max - data[i]) * amt : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uVibrance, -this.vibrance);\n }\n\n isNeutralState() {\n return this.vibrance === 0;\n }\n}\n\nclassRegistry.setClass(Vibrance);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Circle } from '../shapes/Circle';\nimport { Group } from '../shapes/Group';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { CircleBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\nexport class CircleBrush extends BaseBrush {\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width = 10;\n\n declare points: CircleBrushPoint[];\n\n constructor(canvas: Canvas) {\n super(canvas);\n this.points = [];\n }\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Point} pointer\n */\n drawDot(pointer: Point) {\n const point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n }\n\n dot(ctx: CanvasRenderingContext2D, point: CircleBrushPoint) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Invoked on mouse down\n */\n onMouseDown(pointer: Point) {\n this.points = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n }\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render() {\n const ctx = this.canvas.contextTop,\n points = this.points;\n this._saveAndTransform(ctx);\n for (let i = 0; i < points.length; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n } else {\n this.drawDot(pointer);\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const circles: Circle[] = [];\n\n for (let i = 0; i < this.points.length; i++) {\n const point = this.points[i],\n circle = new Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: CENTER,\n originY: CENTER,\n fill: point.fill,\n });\n\n this.shadow && (circle.shadow = new Shadow(this.shadow));\n\n circles.push(circle);\n }\n const group = new Group(circles, { canvas: this.canvas });\n\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n /**\n * @param {Object} pointer\n * @return {Point} Just added pointer point\n */\n addPoint({ x, y }: Point) {\n const pointerPoint: CircleBrushPoint = {\n x,\n y,\n radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba(),\n };\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n}\n","import { Pattern } from '../Pattern';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { Canvas } from '../canvas/Canvas';\nimport { PencilBrush } from './PencilBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\nexport class PatternBrush extends PencilBrush {\n declare source?: CanvasImageSource;\n\n constructor(canvas: Canvas) {\n super(canvas);\n }\n\n getPatternSrc() {\n const dotWidth = 20,\n dotDistance = 5,\n patternCanvas = createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n if (patternCtx) {\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(\n dotWidth / 2,\n dotWidth / 2,\n dotWidth / 2,\n 0,\n Math.PI * 2,\n false,\n );\n patternCtx.closePath();\n patternCtx.fill();\n }\n return patternCanvas;\n }\n\n /**\n * Creates \"pattern\" instance property\n * @param {CanvasRenderingContext2D} ctx\n */\n getPattern(ctx: CanvasRenderingContext2D) {\n return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat');\n }\n\n /**\n * Sets brush styles\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n super._setBrushStyles(ctx);\n const pattern = this.getPattern(ctx);\n pattern && (ctx.strokeStyle = pattern);\n }\n\n /**\n * Creates path\n */\n createPath(pathData: TSimplePathData) {\n const path = super.createPath(pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new Pattern({\n source: this.source || this.getPatternSrc(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y,\n });\n return path;\n }\n}\n","import type { Point } from '../Point';\nimport { Group } from '../shapes/Group';\nimport { Shadow } from '../Shadow';\nimport { Rect } from '../shapes/Rect';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { SprayBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\n/**\n *\n * @param rects\n * @returns\n */\nfunction getUniqueRects(rects: Rect[]) {\n const uniqueRects: Record = {};\n const uniqueRectsArray: Rect[] = [];\n\n for (let i = 0, key: string; i < rects.length; i++) {\n key = `${rects[i].left}${rects[i].top}`;\n if (!uniqueRects[key]) {\n uniqueRects[key] = true;\n uniqueRectsArray.push(rects[i]);\n }\n }\n\n return uniqueRectsArray;\n}\n\nexport class SprayBrush extends BaseBrush {\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width = 10;\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density = 20;\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth = 1;\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance = 1;\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity = false;\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping = true;\n\n private declare sprayChunks: SprayBrushPoint[][];\n\n private declare sprayChunk: SprayBrushPoint[];\n\n /**\n * Constructor\n * @param {Canvas} canvas\n * @return {SprayBrush} Instance of a spray brush\n */\n constructor(canvas: Canvas) {\n super(canvas);\n this.sprayChunks = [];\n this.sprayChunk = [];\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point) {\n this.sprayChunks = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const rects: Rect[] = [];\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n const sprayChunk = this.sprayChunks[i];\n for (let j = 0; j < sprayChunk.length; j++) {\n const chunck = sprayChunk[j];\n const rect = new Rect({\n width: chunck.width,\n height: chunck.width,\n left: chunck.x + 1,\n top: chunck.y + 1,\n originX: CENTER,\n originY: CENTER,\n fill: this.color,\n });\n rects.push(rect);\n }\n }\n\n const group = new Group(\n this.optimizeOverlapping ? getUniqueRects(rects) : rects,\n {\n objectCaching: true,\n subTargetCheck: false,\n interactive: false,\n },\n );\n this.shadow && group.set('shadow', new Shadow(this.shadow));\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n renderChunck(sprayChunck: SprayBrushPoint[]) {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < sprayChunck.length; i++) {\n const point = sprayChunck[i];\n ctx.globalAlpha = point.opacity;\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n }\n\n /**\n * Render all spray chunks\n */\n _render() {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n this.renderChunck(this.sprayChunks[i]);\n }\n ctx.restore();\n }\n\n /**\n * @param {Point} pointer\n */\n addSprayChunk(pointer: Point) {\n this.sprayChunk = [];\n const radius = this.width / 2;\n\n for (let i = 0; i < this.density; i++) {\n this.sprayChunk.push({\n x: getRandomInt(pointer.x - radius, pointer.x + radius),\n y: getRandomInt(pointer.y - radius, pointer.y + radius),\n width: this.dotWidthVariance\n ? getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance,\n )\n : this.dotWidth,\n opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1,\n });\n }\n\n this.sprayChunks.push(this.sprayChunk);\n }\n}\n","import { getFabricWindow } from '../env';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { parseSVGDocument } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\n\n/**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string representing the svg\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromString(\n string: string,\n reviver?: TSvgReviverCallback,\n options?: LoadImageOptions,\n): Promise {\n const parser = new (getFabricWindow().DOMParser)(),\n // should we use `image/svg+xml` here?\n doc = parser.parseFromString(string.trim(), 'text/xml');\n return parseSVGDocument(doc, reviver, options);\n}\n","import { request } from '../util/internals/dom_request';\nimport { parseSVGDocument, createEmptyResponse } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\n\n/**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {string} url where the SVG is\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromURL(\n url: string,\n reviver?: TSvgReviverCallback,\n options: LoadImageOptions = {},\n): Promise {\n // need to handle error properly\n return new Promise((resolve, reject) => {\n const onComplete = (r: XMLHttpRequest) => {\n const xml = r.responseXML;\n if (xml) {\n resolve(xml);\n }\n reject();\n };\n\n request(url.replace(/^\\n\\s*/, '').trim(), {\n onComplete,\n signal: options.signal,\n });\n })\n .then((parsedDoc) => parseSVGDocument(parsedDoc, reviver, options))\n .catch(() => {\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n });\n}\n"],"names":["BaseConfiguration","constructor","_defineProperty","this","window","devicePixelRatio","config","super","configure","arguments","length","undefined","Object","assign","addFonts","paths","fontPaths","_objectSpread","removeFonts","forEach","fontFamily","clearFonts","restoreDefaults","keys","defaults","reduce","acc","key","log","severity","_len","optionalParams","Array","_key","console","FabricError","Error","message","options","concat","SignalAbortedError","context","GLProbe","WebGLProbe","testPrecision","gl","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","queryWebGL","canvas","getContext","maxTextureSize","getParameter","MAX_TEXTURE_SIZE","GLPrecision","find","getExtension","loseContext","isSupported","textureSize","copyPasteData","env","setEnv","getEnv","document","isTouchSupported","navigator","maxTouchPoints","dispose","getFabricDocument","getFabricWindow","getDevicePixelRatio","_config$devicePixelRa","Math","max","cache","getFontCache","_ref","fontStyle","fontWeight","toLowerCase","charWidthsCache","fontCache","cacheKey","clearFontCache","limitDimsByArea","ar","perfLimitSizeTotal","roughWidth","sqrt","floor","VERSION","noop","halfPI","PI","twoMathPi","PiBy180","iMatrix","freeze","DEFAULT_SVG_FONT_SIZE","kRect","CENTER","LEFT","TOP","BOTTOM","RIGHT","NONE","reNewline","MOVING","SCALING","ROTATING","ROTATE","SKEWING","RESIZING","MODIFY_POLY","MODIFY_PATH","CHANGED","SCALE","SCALE_X","SCALE_Y","SKEW_X","SKEW_Y","FILL","STROKE","MODIFIED","JSON","SVG","classRegistry","Map","has","classType","getClass","get","setClass","classConstructor","set","type","getSVGClass","SVGTagName","setSVGClass","runningAnimations","remove","index","indexOf","splice","cancelAll","animations","animation","abort","cancelByCanvas","filter","_animation$target","target","cancelByTarget","Observable","on","arg0","handler","__eventListeners","entries","eventName","off","push","once","disposers","_ref2","d","disposer","args","call","_removeEventListener","eventListener","_ref3","fire","_this$__eventListener","listenersForEvent","i","removeFromArray","array","value","idx","cos","angle","abs","sin","angleSlice","sign","Point","y","x","add","that","addEquals","scalarAdd","scalar","scalarAddEquals","subtract","subtractEquals","scalarSubtract","scalarSubtractEquals","multiply","scalarMultiply","scalarMultiplyEquals","divide","scalarDivide","scalarDivideEquals","eq","lt","lte","gt","gte","lerp","t","min","distanceFrom","dx","dy","midPointFrom","toString","setXY","setX","setY","setFromPoint","swap","clone","rotate","radians","origin","ZERO","sinus","cosinus","p","transform","ignoreOffset","isCollection","fabricObject","isArray","_objects","createCollectionMixin","Base","Collection","_onObjectAdded","object","_onObjectRemoved","_onStackOrderChanged","objects","size","insertAt","_len2","_key2","removed","_len3","_key3","forEachObject","callback","getObjects","_len4","types","_key4","o","isType","item","isEmpty","contains","deep","includes","some","obj","complexity","memo","current","sendObjectToBack","unshift","bringObjectToFront","sendObjectBackwards","intersecting","newIdx","findNewLowerIndex","bringObjectForward","findNewUpperIndex","moveObjectTo","isOverlapping","collectObjects","left","top","width","height","includeIntersecting","tl","br","selectable","visible","intersectsWithRect","isContainedWithinRect","containsPoint","CommonMethods","_setOptions","prop","_setObject","_set","toggle","property","requestAnimFrame","requestAnimationFrame","cancelAnimFrame","handle","cancelAnimationFrame","id","uid","createCanvasElement","element","createElement","createImage","toDataURL","canvasEl","format","quality","degreesToRadians","degrees","radiansToDegrees","isIdentityMatrix","mat","every","transformPoint","invertTransform","a","r","multiplyTransformMatrices","b","is2x2","multiplyTransformMatrixArray","matrices","reduceRight","product","curr","calcPlaneRotation","atan2","qrDecompose","denom","pow","scaleX","scaleY","skewX","skewY","translateX","translateY","createTranslateMatrix","createRotateMatrix","angleRadiant","cosValue","sinValue","createScaleMatrix","angleToSkew","tan","createSkewXMatrix","skewValue","createSkewYMatrix","calcDimensionsMatrix","flipX","flipY","matrix","composeMatrix","scaleMatrix","loadImage","url","signal","crossOrigin","Promise","resolve","reject","aborted","img","err","src","addEventListener","done","onload","onerror","removeEventListener","enlivenObjects","reviver","instances","all","map","fromObject","then","fabricInstance","catch","error","instance","finally","enlivenObjectEnlivables","serializedObject","promises","values","enlived","pick","source","pickBy","predicate","ColorNameMap","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","hue2rgb","q","rgb2Hsl","g","maxValue","minValue","h","s","l","round","fromAlphaToFloat","parseFloat","endsWith","hexify","toUpperCase","padStart","greyAverage","avg","Color","color","setSource","_source","_tryParsingColor","sourceFromHex","sourceFromRgb","sourceFromHsl","isUnrecognised","getSource","toRgb","toRgba","join","toHsl","toHsla","toHex","toHexa","slice","getAlpha","setAlpha","alpha","toGrayscale","toBlackWhite","threshold","average","bOrW","overlayWith","otherColor","otherSource","R","G","B","fromRgb","fromRgba","match","parsedValue","fromHsl","fromHsla","parseAngletoDegrees","fromHex","expandedValue","split","hex","hexCouple","parseInt","lowercase","numeric","toFixed","number","fractionDigits","Number","parseUnit","fontSize","unit","exec","dpi","DPI","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","alignX","alignY","align","meetOrSlice","matrixToSVG","NUM_FRACTION_DIGITS","colorPropToSVG","colorValue","opacityValue","inlineStyle","toLive","opacity","isFiller","filler","isSerializableFiller","toObject","isPattern","offsetX","isTextObject","_renderText","isActiveSelection","getScrollLeftTop","doc","getDocumentFromElement","elementLoop","docElement","documentElement","body","scrollLeft","scrollTop","parentNode","host","nodeType","style","position","el","ownerDocument","getWindowFromElement","_el$ownerDocument","defaultView","setCanvasDimensions","ctx","retinaScaling","setAttribute","scale","setCSSDimensions","makeElementUnselectable","onselectstart","userSelect","StaticCanvasDOMManager","createLowerCanvas","lower","getElementById","hasAttribute","_originalCanvasStyle","cssText","classList","cleanupDOM","removeAttribute","setDimensions","calcOffset","_getWindowFromElement","offset","elemStyle","getComputedStyle","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","box","docElem","getBoundingClientRect","scrollLeftTop","clientLeft","clientTop","getElementOffset","staticCanvasDefaults","backgroundVpt","backgroundColor","overlayVpt","overlayColor","includeDefaultValues","svgViewportTransformation","renderOnAddRemove","skipOffscreen","enableRetinaScaling","imageSmoothingEnabled","controlsAboveOverlay","allowTouchScrolling","viewportTransform","StaticCanvas","lowerCanvasEl","_this$elements$lower","elements","contextContainer","_this$elements$lower2","getDefaults","ownDefaults","initElements","_setDimensionsImpl","skipControlsDrawing","calcViewportBoundaries","requestRenderAll","setCoords","getRetinaScaling","_offset","getWidth","getHeight","setWidth","setHeight","dimensions","cssOnly","backstoreOnly","hasLostContext","getZoom","setViewportTransform","vpt","zoomToPoint","point","before","newPoint","after","setZoom","absolutePan","relativePan","getElement","clearContext","clearRect","clear","backgroundImage","overlayImage","renderAll","cancelRequestedRender","destroyed","renderCanvas","renderAndReset","nextRenderHandle","disposed","iVpt","vptCoords","tr","bl","drawControls","_ctx","v","path","clipPath","patternQuality","_renderBackground","save","_renderObjects","restore","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","__cleanupTask","globalCompositeOperation","zoomX","zoomY","drawImage","_cacheCanvas","cacheTranslationX","cacheTranslationY","len","render","_renderBackgroundOrOverlay","fill","needsVpt","isAFiller","beginPath","moveTo","lineTo","closePath","fillStyle","offsetY","m","gradientTransform","patternTransform","getCenter","getCenterPoint","centerObjectH","_centerObject","centerObjectV","centerObject","viewportCenterObject","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","center","toDatalessJSON","propertiesToInclude","toDatalessObject","_toObjectMethod","toJSON","methodName","clipPathData","excludeFromExport","_toObject","version","__serializeBgOverlay","originalValue","data","bgImage","bgColor","background","overlay","toSVG","markup","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","optViewBox","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","additionalTransform","fontList","styles","styleRow","fontListMarkup","_setSVGObject","bgOrOverlay","repeat","finalWidth","finalHeight","loadFromJSON","json","serialized","parse","enlivedMap","properties","cloneWithoutData","multiplier","finalMultiplier","toCanvasElement","scaledWidth","scaledHeight","zoom","originalWidth","originalHeight","originalSkipControlsDrawing","newZoom","vp","newVp","originalRetina","objectsToRender","task","destroy","kill","touchEvents","getPointer","event","scroll","_evt","touchProp","changedTouches","getTouchInfo","clientX","clientY","isTouchEvent","pointerType","stopEvent","e","preventDefault","stopPropagation","makeBoundingBoxFromPoints","points","addTransformToObject","applyTransformToObject","calcOwnMatrix","_qrDecompose","otherOptions","_objectWithoutProperties","_excluded","setPositionByOrigin","resetObjectTransform","saveObjectTransform","sizeAfterTransform","dimX","dimY","bbox","calcPlaneChangeMatrix","from","sendPointToPlane","to","sendVectorToPlane","sendObjectToPlane","fireEvent","_target$canvas","originOffset","bottom","right","resolveOrigin","originValue","NOT_ALLOWED_CURSOR","isTransformCentered","originX","originY","invertOrigin","isLocked","lockingKey","commonEventInfo","eventData","pointer","findCornerQuadrant","control","cornerAngle","getTotalAngle","getLocalPoint","corner","controls","padding","localPoint","getRelativeCenterPoint","translateToGivenOrigin","normalizePoint","dragHandler","newLeft","newTop","moveX","moveY","FabricObjectSVGExportMixin","getSvgStyles","skipShadow","fillRule","strokeWidth","strokeDashArray","strokeDashOffset","strokeLineCap","strokeLineJoin","strokeMiterLimit","visibility","getSvgFilter","stroke","shadow","getSvgCommons","getSvgTransform","full","calcTransformMatrix","svgTransform","_toSVG","_reviver","_createBaseSVGMarkup","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","withShadow","styleInfo","shadowInfo","vectorEffect","strokeUniform","absoluteClipPath","absolutePositioned","clipPathMarkup","addPaintOrder","paintFirst","getSvgRegex","arr","RegExp","reNum","String","raw","_templateObject","_taggedTemplateLiteral","svgNS","reFontDeclaration","attributesMap","cx","cy","display","fSize","cPath","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgValidParentsRegEx","reViewBoxAttrValue","unitVectorX","zero","rotateVector","vector","createVector","magnitude","calcAngleBetweenVectors","crossProduct","dotProduct","calcVectorRotation","getUnitVector","getOrthonormalVector","counterClockwise","isBetweenVectors","AxB","AxT","BxT","shadowOffsetRegex","reOffsetsAndBlur","Shadow","parseShadow","shadowStr","blur","replace","fBoxX","fBoxY","affectStroke","nonScaling","capValue","stateProperties","cacheProperties","fabricObjectDefaultValues","minScaleLimit","objectCaching","inverted","centeredRotation","centeredScaling","dirty","normalize","c","asin","elastic","defaultEasing","easeOutBounce","easeInBounce","easeInCirc","easeInCubic","easeInElastic","normA","normS","normP","easeInExpo","easeInOutBounce","easeInOutCirc","easeInOutCubic","easeInOutElastic","normC","easeInOutExpo","easeInOutQuad","easeInOutQuart","easeInOutQuint","easeInOutSine","easeInQuad","easeInQuart","easeInQuint","easeInSine","easeOutCirc","easeOutCubic","easeOutElastic","easeOutExpo","easeOutQuad","easeOutQuart","easeOutQuint","easeOutSine","defaultAbort","AnimationBase","startValue","byValue","duration","delay","easing","onStart","onChange","onComplete","tick","bind","_onStart","_onChange","_onComplete","_abort","endValue","calculate","state","_state","isDone","start","firstTick","timestamp","startTime","Date","register","setTimeout","durationMs","boundDurationMs","durationProgress","valueProgress","unregister","ValueAnimation","timeElapsed","ArrayAnimation","defaultColorEasing","wrapColorCallback","rgba","ColorAnimation","startColor","endColor","animate","isArrayAnimation","animateColor","Intersection","status","append","isPointContained","T","A","infinite","AB","isPointInPolygon","other","hits","inter","intersectSegmentSegment","intersectLineLine","a1","a2","b1","b2","aInfinite","bInfinite","a2xa1x","a2ya1y","b2xb1x","b2yb1y","a1xb1x","a1yb1y","uaT","ubT","uB","ua","ub","segmentsCoincide","intersectSegmentLine","s1","s2","l1","l2","intersectLinePolygon","result","intersectSegmentPolygon","intersectPolygonPolygon","points1","points2","coincidences","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","ObjectGeometry","getX","getXY","getY","getRelativeX","setRelativeX","getRelativeY","setRelativeY","relativePosition","getRelativeXY","group","setRelativeXY","isStrokeAccountedForInDimensions","getCoords","aCoords","calcACoords","coords","intersectsWithObject","intersection","isContainedWithinObject","getBoundingRect","isOnScreen","isPartiallyOnScreen","getScaledWidth","_getTransformedDimensions","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","getCanvasRetinaScaling","_this$canvas","getViewportTransform","_this$canvas2","rotateMatrix","tMatrix","finalMatrix","dim","w","transformMatrixKey","skipGroup","prefix","matrixCache","ownMatrixCache","_getNonTransformedDimensions","_calculateCurrentDimensions","dimOptions","preScalingStrokeValue","postScalingStrokeValue","finalDimensions","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","translateToOriginPoint","relCenter","getPointByOrigin","pos","_getLeftTopCoords","FabricObject","name","setOptions","_createCacheCanvas","_cacheContext","_updateCacheCanvas","_limitCacheSize","dims","maxCacheSideLimit","minCacheSideLimit","limX","limY","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","minCacheSize","dimensionsChanged","zoomChanged","drawingWidth","drawingHeight","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","getHeightOfLine","ceil","setTransform","translate","needFullTransform","contextTop","getObjectScaling","retina","getObjectOpacity","_constrainScale","isChanged","parent","isNotVisible","_setupCompositeOperation","drawSelectionBackground","_setOpacity","_setShadow","drawCacheOnCanvas","_removeCacheCanvas","drawObject","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","isOnACache","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_render","_drawClipPath","skipCanvas","fillRect","_removeShadow","globalAlpha","_setStrokeStyles","decl","lineWidth","lineCap","lineDashOffset","lineJoin","miterLimit","gradientUnits","_applyPatternForTransformedGradient","strokeStyle","_applyPatternGradientTransform","_setFillStyles","_setLineDash","dashArray","setLineDash","sx","sy","multX","multY","scaling","shadowColor","shadowBlur","browserShadowBlurConstant","shadowOffsetX","shadowOffsetY","_renderPaintInOrder","_renderStroke","_renderFill","_pCtx$createPattern","pCanvas","pCtx","createPattern","_findCenterFromElement","objectForm","cloneAsImage","origParams","originalGroup","originalShadow","canvasProvider","withoutTransform","withoutShadow","boundingRect","shadowOffset","originalCanvas","setOnGroup","animatable","_animate","propIsColor","colorProperties","animationOptions","isDescendantOf","getAncestors","ancestors","findCommonAncestors","fork","otherFork","common","otherAncestors","ancestor","j","hasCommonAncestors","commonAncestors","isInFrontOf","ancestorData","firstCommonAncestor","headOfFork","pop","headOfOtherFork","thisIndex","otherIndex","propertiesToSerialize","customProperties","toFixedBound","val","_removeDefaultValues","baseValues","getPrototypeOf","baseValue","_fromObject","serializedObjectOptions","_ref4","extraParam","_excluded2","enlivedObjectOptions","wrapWithFireEvent","actionHandler","extraEventInfo","actionPerformed","wrapWithFixedAnchor","centerPoint","constraint","changeWidth","changeObjectWidth","strokePadding","oldWidth","newWidth","renderCircleControl","styleOverride","xSize","sizeX","cornerSize","ySize","sizeY","transparentCorners","cornerStrokeColor","myLeft","myTop","cornerColor","arc","renderSquareControl","xSizeBy2","ySizeBy2","strokeRect","Control","shouldActivate","controlKey","_fabricObject$canvas","getActiveObject","isControlVisible","getActionHandler","getMouseDownHandler","mouseDownHandler","getMouseUpHandler","mouseUpHandler","cursorStyleHandler","cursorStyle","getActionName","actionName","getVisibility","_fabricObject$_contro","_fabricObject$_contro2","_controlsVisibility","setVisibility","positionHandler","currentControl","calcCornerCoords","objectCornerSize","centerX","centerY","isTouch","touchSizeX","touchSizeY","cornerStyle","rotationStyleHandler","lockRotation","rotationWithSnapping","rotateObjectWithSnapping","ex","ey","theta","pivotPoint","lastAngle","curAngle","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","hasRotated","scaleIsProportional","uniformIsToggled","uniScaleKey","uniformScaling","scalingIsForbidden","by","scaleProportionally","lockX","lockY","scaleMap","scaleCursorStyleHandler","n","scaleObject","signX","signY","gestureScale","distance","original","oldScaleX","oldScaleY","scalingEqually","scaleObjectFromCorner","scalingX","scaleObjectX","scalingY","scaleObjectY","AXIS_KEYS","counterAxis","skew","lockSkewing","flip","skewMap","skewCursorStyleHandler","skewHandler","axis","originKey","lockSkewingKey","skewKey","flipKey","counterOriginKey","counterFlipKey","counterOriginFactor","skewingSide","finalHandler","skewingBefore","skewingStart","shearingStart","shearing","skewing","atan","changed","dimBefore","dimAfter","compensationFactor","skewObject","skewHandlerX","skewHandlerY","isAltAction","altActionKey","scaleOrSkewActionName","isAlternative","scaleSkewCursorStyleHandler","scalingXOrSkewingY","scalingYOrSkewingX","createObjectDefaultControls","ml","mr","mb","mt","mtr","withConnection","createResizeControls","createTextboxDefaultControls","InteractiveFabricObject","createControls","targetCanvas","noScaleCache","_currentTransform","action","startsWith","getActiveControl","__corner","coord","oCoords","findControl","forTouch","hasControls","cornerEntries","touchCorner","calcOCoords","rMatrix","positionMatrix","startMatrix","transformOptions","forEachControl","_calcCornerCoords","touchCornerSize","fn","selectionBackgroundColor","_activeObject","wh","strokeBorders","_drawBorders","borderColor","borderDashArray","drawControlsConnectingLines","_renderControls","hasBorders","styleOptions","shouldDrawBorders","shouldDrawControls","borderScaleFactor","isMoving","borderOpacityWhenMoving","drawBorders","forActiveSelection","shouldStroke","cornerDashArray","setControlVisible","setControlsVisibility","clearContextTop","restoreManually","onDeselect","_options","onSelect","shouldStartDragging","_e","onDragStart","canDrop","renderDragSourceEffect","renderDropTargetEffect","applyMixins","derivedCtor","constructors","baseCtor","getOwnPropertyNames","prototype","defineProperty","getOwnPropertyDescriptor","create","lockMovementX","lockMovementY","lockScalingX","lockScalingY","lockSkewingX","lockSkewingY","lockScalingFlip","evented","perPixelTargetFind","activeOn","hoverCursor","moveCursor","isTransparent","tolerance","getImageData","StrokeProjectionsBase","strokeProjectionMagnitude","strokeUniformScalar","createSideVector","projectOrthogonally","applySkew","calcOrthogonalProjection","isSkewed","scaleUnitVector","unitVector","zeroVector","StrokeLineJoinProjections","getOrthogonalRotationFactor","vector1","vector2","C","AC","bisector","orthogonalProjection","correctSide","projectBevel","projections","projectMiter","hypotUnitScalar","miterVector","projectRoundNoSkew","startCircle","endCircle","projectRoundWithSkew","circleRadius","newY","furthestY","newX","furthestX","projectRound","isStraightLine","newOrigin","proj0","proj1","comparisonVector","isProj0Start","projectPoints","project","originPoint","projectedPoint","StrokeLineCapProjections","projectButt","projection","projectSquare","strokePointingOut","projectedA","projectStrokeOnPoints","openPath","reduced","findIndexRight","cloneStyles","newObj","keyInner","escapeXml","string","graphemeSplit","textstring","graphemes","chr","getWholeChar","str","code","charCodeAt","isNaN","charAt","next","prev","firstLetterOnly","hasStyleChanged","prevStyle","thisStyle","forTextSpans","textBackgroundColor","deltaY","overline","underline","linethrough","stylesToArray","text","textLines","stylesArray","charIndex","chars","end","stylesFromArray","stylesObject","styleIndex","SHARED_ATTRIBUTES","selectorMatches","selector","nodeName","classNames","getAttribute","azAz","matcher","splitClassNames","elementMatchesRule","selectors","parentMatching","firstMatching","parentElement","doesSomeParentMatch","normalizeAttr","attr","_attributesMap","regex","cleanupSvgAttribute","attributeValue","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_templateObject6","transforms","transformList","_templateObject7","reTransformList","reTransform","reTransformAll","parseTransformAttribute","test","matchAll","transformMatch","matchedParams","operation","rawArgs","arg1","arg2","arg3","arg4","arg5","arg","normalizeValue","parentAttributes","parsed","ouputValue","transformMatrix","fillIndex","strokeIndex","parseFontDeclaration","oStyle","lineHeight","parseStyleString","chunk","parseStyleAttribute","parseStyleObject","colorAttributesMap","parseAttributes","attributes","cssRules","parentFontSize","ownAttributes","rule","getGlobalStylesForElement","normalizedStyle","normalizedAttr","normalizedValue","font","mergedAttrs","colorAttr","setStrokeFillOpacity","RECT_PROPS","Rect","_initRxRy","rx","ry","isRounded","bezierCurveTo","fromElement","_parseAttributes","ATTRIBUTE_NAMES","restOfparsedAttributes","Boolean","LAYOUT_TYPE_INITIALIZATION","LAYOUT_TYPE_ADDED","LAYOUT_TYPE_REMOVED","LAYOUT_TYPE_IMPERATIVE","getObjectBounds","destinationGroup","currentGroup","objectCenter","accountForStroke","strokeUniformVector","scalingStrokeWidth","sizeVector","LayoutStrategy","calcLayoutResult","shouldPerformLayout","calcBoundingBox","prevStrategy","strategy","shouldLayoutClipPath","getInitialSize","overrides","bboxSize","bboxCenter","actualSize","relativeCorrection","FitContentLayout","LAYOUT_MANAGER","LayoutManager","_subscriptions","performLayout","strictContext","bubbles","_prevLayoutStrategy","onBeforeLayout","layoutResult","getLayoutResult","commitLayout","onAfterLayout","attachHandlers","trigger","subscribe","unsubscribe","_context","delete","unsubscribeTargets","targets","subscribeTargets","tricklingContext","layoutManager","prevCenter","nextCenter","correction","_context$x","_context$y","layoutObjects","layoutObject","_","bubblingContext","NoopLayoutManager","Group","groupInit","_options$layoutManage","__objectSelectionTracker","__objectSelectionMonitor","__objectSelectionDisposer","enterGroup","canEnterGroup","_filterObjectsBeforeEnteringGroup","allowedObjects","_onAfterObjectsChange","removeParentTransform","exitGroup","_shouldSetNestedCoords","subTargetCheck","removeAll","_activeObjects","selected","activeObjects","_watchObject","watch","_enterGroup","activeObject","_exitGroup","ownCache","preserveObjectStacking","triggerLayout","__serializeObjects","method","_includeDefaultValues","originalDefaults","_createSVGBgRect","fillStroke","commons","svgString","bg","abortable","hydratedOptions","layoutClass","strategyClass","interactive","findScaleToFit","destination","findScaleToCover","commaWsp","reArcCommandPoints","repeatedCommands","M","segmentToBezier","theta1","theta2","cosTh","sinTh","cx1","cy1","mT","fromX","fromY","costh1","sinth1","costh2","sinth2","toX","toY","calcVectorAngle","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","begx","begy","cp1x","cp1y","cp2x","cp2y","endx","endy","argsString","cachesBoundsOfCurve","boundsOfCurveCache","tvalues","bounds","b2ac","sqrtb2ac","t1","t2","jlen","iterator","getPointOnCubicBezierIterator","fromArcToBeziers","fx","fy","rot","large","sweep","tx","ty","segsNorm","arcToSegments","rotateX","root","sinTheta","px","py","rx2","ry2","py2","px2","pl","_rx","_ry","mTheta","dtheta","segments","mDelta","th3","makePathSimpler","x1","y1","destinationPath","previous","controlX","controlY","parsedCommand","converted","calcLineLength","x2","y2","pct","c1","c2","CB2","c3","CB3","c4","CB4","QB1","QB2","QB3","getTangentCubicIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","qb1","qb2","qb3","tangentX","tangentY","getPointOnQuadraticBezierIterator","getTangentQuadraticIterator","invT","pathIterator","tempP","tmpLen","perc","findPercentageForDistance","segInfo","nextLen","nextStep","lastPerc","angleFinder","getPathSegmentsInfo","tempInfo","totalLength","info","basicInfo","command","destX","destY","getPointOnPath","infos","segPercent","segment","rePathCmdAll","regExpArcCommandPoints","reMyNum","commandLengths","parsePath","pathString","_pathString$match","chain","matchStr","commandLetter","commandLength","paramArr","lastIndex","out","newCommand","transformedCommand","getSmoothPathFromPoints","p1","p2","multSignX","multSignY","manyPoints","midPoint","joinPath","pathData","setStyle","elementStyle","setProperty","getRandomInt","random","request","xhr","removeListener","ontimeout","onreadystatechange","readyState","open","send","removeTransformMatrixForSvgParsing","preserveAspectRatioOptions","_assignTransformMatrixProps","cropX","cropY","offsetLeft","offsetTop","_newCanvas$getContext","newCanvas","getRegularPolygonPath","numVertexes","radius","interiorAngle","rotationAdjustment","rad","commonAttributes","groupSVGElements","mergeClipPaths","_b$group","removeTransformFromObject","finalTransform","rotatePoint","transformPath","pathOffset","pathSegment","newSegment","CanvasDOMManager","containerClass","upperCanvasEl","createUpperCanvas","upper","applyCanvasStyle","container","createContainerElement","replaceChild","className","removeChild","SelectableCanvas","_this$elements$upper","_this$elements$upper2","wrapperEl","_objectsToRender","deselected","_discardActiveObject","_hoveredTarget","_hoveredTargets","_chooseObjectsToRender","contextTopDirty","_groupSelector","isDrawingMode","renderTopLayer","_isCurrentlyDrawing","freeDrawingBrush","selection","_drawSelection","renderTop","setTargetFindTolerance","targetFindTolerance","pixelFindCanvasEl","pixelFindContext","isTargetTransparent","selectionBgc","enhancedTolerance","_isSelectionKeyPressed","sKey","selectionKey","_shouldClearSelection","getActiveObjects","_shouldCenterTransform","modifierKeyPressed","centerTransform","_getOriginFromCorner","controlName","_setupCurrentTransform","alreadySelected","_control$getActionHan","getScenePoint","getActionFromCorner","altKey","centeredKey","lastX","lastY","shiftKey","setCursor","cursor","deltaX","extent","strokeOffset","selectionLineWidth","minX","minY","maxX","maxY","selectionColor","selectionBorderColor","selectionDashArray","findTarget","skipTargetFind","getViewportPoint","aObjects","searchPossibleTargets","subTargets","altSelectionKey","_pointIsInObjectSelectionArea","viewportZoom","angleRadians","cosP","sinP","cosPSinP","cosPMinusSinP","_checkTarget","isEditing","_searchPossibleTargets","subTarget","_pointer","_absolutePointer","fromViewport","boundsWidth","boundsHeight","cssScale","_resetTransformEventData","_setBrushStyles","willReadFrequently","getTopContext","getSelectionContext","getSelectionElement","active","_fireSelectionEvents","oldObjects","somethingChanged","invalidate","added","setActiveObject","currentActives","_setActiveObject","prevActiveObject","endCurrentTransform","discardActiveObject","discarded","_finalizeCurrentTransform","_scaling","originalProperties","_realizeGroupTransformOnObject","originalValues","selectionFullyContained","defaultCursor","freeDrawingCursor","notAllowedCursor","stopContextMenu","fireRightClick","fireMiddleClick","enablePointerEvents","TextEditingManager","cb","hiddenTextarea","focus","__disposer","exitTextEditing","exitEditing","onMouseMove","_this$target","updateSelectionOnMouseMove","addEventOptions","passive","getEventPoints","viewportPoint","scenePoint","absolutePointer","addListener","syntheticEventConfig","mouse","in","targetIn","targetOut","canvasIn","canvasOut","drag","Canvas","eventHandler","addOrRemove","_getEventPrefix","functor","_eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","removeListeners","_onMouseUp","_onTouchEnd","__onMouseWheel","shared","nestedTarget","_isClick","_dragSource","_onDragProgress","_renderDragEffects","dropTarget","_dropTarget","didDrop","dataTransfer","dropEffect","dragSource","_draggedoverTarget","findDragTargets","eventType","_fireEnterLeaveEvents","_basicEventHandler","_cacheTransformEventData","_handleEvent","getPointerId","evt","identifier","pointerId","_isMainEvent","isPrimary","touches","mainTouchId","__onMouseDown","__onMouseUp","_willAddMouseDown","clearTimeout","__onMouseMove","_shouldRender","_this$_activeObject","isClick","_target","button","_onMouseUpInDrawingMode","shouldRender","targetWasActive","handleSelection","found","originalControl","originalMouseUpHandler","_setCursorFromEvent","currentTarget","currentSubTargets","_onMouseDownInDrawingMode","onMouseDown","_onMouseMoveInDrawingMode","onMouseUp","grouped","handleMultiSelection","groupSelector","_transformObject","_fireOverOutEvents","textEditingManager","fireSyntheticInOutEvents","oldTarget","fireCanvas","draggedoverTarget","targetChanged","outOpt","nextTarget","inOpt","previousTarget","localPointer","_performTransformAction","activeSelection","reverse","isAS","prevActiveObjects","multiSelectAdd","newActiveSelection","point1","point2","collectedObjects","klass","linearDefaultCoords","radialDefaultCoords","ifNaN","valueIfNaN","RE_PERCENT","isPercent","parsePercent","NaN","RE_KEY_VALUE_PAIRS","RE_KEY_VALUE","parseColorStop","keyValuePairs","parseColorStops","opacityAttr","colorStops","colorStopEls","getElementsByTagName","parseType","parseGradientUnits","getValue","parseCoords","valuesToConvert","finalValue","propValue","convertPercentUnitsToValues","parseLinearCoords","parseRadialCoords","Gradient","addColorStop","colorStop","preTransform","sort","_renderPathCommands","needsSwap","minRadius","percentageShift","gradient","createLinearGradient","createRadialGradient","svgOptions","viewBoxWidth","viewBoxHeight","Pattern","isImageSource","isCanvasSource","sourceToString","complete","naturalWidth","naturalHeight","patternSource","patternOffsetX","patternOffsetY","patternWidth","patternHeight","BaseBrush","_saveAndTransform","needsFullRender","_resetShadow","_isOutSideCanvas","Path","_setPath","adjustPosition","setBoundingBox","_calcBoundsFromPath","quadraticCurveTo","pathCmd","sourcePath","_getOffsetTransform","digits","_calcDimensions","subpathStartX","subpathStartY","parsedAttributes","PencilBrush","_points","_hasStraightLine","drawSegment","drawStraightLine","straightLineKey","_prepareForDrawing","_addPoint","limitedToCanvasSize","oldEnd","_finalizeAndAddPath","_reset","convertPointsToSVGPath","createPath","decimatePoints","cDistance","lastPoint","adjustedDistance","newPoints","decimate","isEmptySVGPath","CIRCLE_PROPS","Circle","setRadius","startAngle","endAngle","getRadiusX","getRadiusY","startX","startY","endX","endY","largeFlag","sweepFlag","coordProps","Line","_setWidthHeight","calcLinePoints","origStrokeStyle","_this$stroke","_x1","_x2","_y1","_y2","xMult","yMult","Triangle","widthBy2","heightBy2","ELLIPSE_PROPS","Ellipse","getRx","getRy","parsePointsAttribute","pointsSplit","parsedPoints","polylineDefaultValues","exactBoundingBox","Polyline","initialized","isOpen","_projectStrokeOnPoints","strokeDiff","bboxNoStroke","layoutProperties","_options$width","_options$height","_options$width2","_options$height2","output","diffX","diffY","Polygon","fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","textDefaultValues","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER","StyledText","isEmptyStyles","lineIndex","line","p3","styleHas","cleanStyle","letterCount","stylePropertyValue","stylesCount","allStyleObjectPropertiesMatch","graphemeCount","styleObject","_textLines","removeStyle","lineNum","charNum","_extendStyles","get2DCursorLocation","_getLineStyle","_setLineStyle","newStyle","_getStyleDeclaration","_setStyleDeclaration","getSelectionStyles","startIndex","endIndex","getStyleAtPosition","getCompleteStyleDeclaration","setSelectionStyles","_forceClearCache","_lineStyle$charIndex","lineStyle","_styleProperties","_deleteStyleDeclaration","_deleteLineStyle","multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","svgColor","createSVGRect","measuringContext","FabricText","setPathInfo","initDimensions","segmentsInfo","_splitText","newLines","_splitTextIntoLines","lines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","calcTextHeight","enlargeSpaces","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","charBound","spaces","isEndOfWrapping","getLineWidth","__charBounds","kernedWidth","missingNewlineOffset","_lineIndex","selectionStart","skipWrapping","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","leftOffset","_getLeftOffset","lineTopOffset","_getTopOffset","heightOfLine","lineLeftOffset","_getLineLeftOffset","drawStart","currentColor","boxWidth","boxStart","lastColor","getValueOfPropertyAt","charBox","renderLeft","_measureChar","_char","previousChar","prevCharStyle","fontDeclaration","couple","stylesAreEqual","fontMultiplier","coupleWidth","previousWidth","getMeasuringContext","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","prevGrapheme","graphemeInfo","llength","lineBounds","grapheme","_getGraphemeBox","positionInPath","totalPathLength","_setGraphemeOnPath","numOfSpaces","centerPosition","skipLeft","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isJustify","shortCut","isLtr","currentDirection","actualStyle","nextStyle","timeToRender","drawingLeft","charsToRender","_renderChar","_applyPatternGradientTransformText","handleFiller","fullDecl","shouldFill","fillOffsets","fillText","strokeOffsets","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","lineDiff","__lineWidths","_charStyle$property","topOffset","currentDecoration","currentFill","lastDecoration","lastFill","currentSize","currentDy","parsedFontFamily","genericFonts","newLine","newText","needsDims","isAddingPath","_options$parsedAttrib","textAnchor","textDecoration","restOfOptions","textContent","textHeightScaleFactor","scaledDiff","textHeight","offX","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textBgRects","textSpans","getSvgTextDecoration","textTopOffset","textLeftOffset","lineOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","fillStyles","dySpan","_getSVGLineTopOffset","lastHeight","useWhiteSpace","decoration","DraggableTextDelegate","dragEnterHandler","dragOverHandler","dragLeaveHandler","dragEndHandler","dropHandler","_dispose","isPointerOverSelection","newSelection","getSelectionStartFromPointer","selectionEnd","__mouseDownInPlace","isActive","__dragStartFired","setCursorByClick","initDelayedCursor","__isDraggingOver","getDragStartSelection","__dragStartSelection","setDragImage","_e$dataTransfer","flipFactor","boundaries","_getCursorBoundaries","diff","bgc","dragImage","border","__dragImageDisposer","appendChild","setData","stringify","effectAllowed","abortCursorAnimation","editable","defaultPrevented","dragStartSelection","targetCanDrop","ev","_e$dataTransfer2","insert","getData","trailing","selectionStartOffset","removeChars","trimEnd","insertChars","enterEditing","_updateTextarea","_e$dataTransfer3","reNonWord","ITextBehavior","initBehavior","_tick","_onTickComplete","_animateCursor","toValue","_currentCursorOpacity","renderCursorOrSelection","_currentTickState","cursorDuration","_this$_currentTickCom","_currentTickCompleteState","restart","cursorDelay","shouldClear","cursorAnimation","restartCursorIfNeeded","selectAll","_fireSelectionChanged","getSelectedText","findWordBoundaryLeft","startFrom","_reSpace","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","selectWord","newSelectionStart","newSelectionEnd","selectLine","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","activeElement","currentStart","currentEnd","__selectionStartOnMouseDown","editingBorderColor","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","fromGraphemeToStringSelection","cursorOffsetCache","inCompositionMode","updateTextareaPosition","updateFromTextArea","textarea","_calcTextareaPosition","desiredPosition","compositionStart","cursorLocation","charHeight","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","_exitEditing","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","styleObj","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","_selectionDirection","ITextKeyBehavior","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","hiddenTextareaContainer","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","onKeyDown","keyMap","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","updateAndFire","nextText","charCount","nextCharCount","removedText","removeFrom","removeTo","charDiff","textareaSelection","backDelete","copiedText","disableStyleCopyPaste","copiedTextStyle","onCompositionStart","onCompositionEnd","onCompositionUpdate","compositionEnd","_getWidthBeforeCursor","bound","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","getUpCursorOffset","textBeforeCursor","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","newValue","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","moveCursorRightWithShift","moveCursorRightWithoutShift","notALeftClick","ITextClickBehavior","_mouseDownHandler","_mouseDownHandlerBefore","doubleClickHandler","tripleClickHandler","__lastClickTime","__lastLastClickTime","__lastPointer","draggableTextDelegate","__newClickTime","newPointer","isTripleClick","__lastSelected","didDrag","mouseOffset","charLength","widthAfter","MOVE_CURSOR_UP","MOVE_CURSOR_DOWN","MOVE_CURSOR_LEFT","MOVE_CURSOR_RIGHT","EXIT_EDITING","iTextDefaultValues","cursorColor","caching","IText","setSelectionStart","_updateAndFire","setSelectionEnd","renderCursor","renderSelection","skipCaching","_getCursorBoundariesOffsets","__getCursorBoundariesOffsets","renderCursorAt","_renderCursor","_renderSelection","dragSelection","startLine","endLine","startChar","endChar","realLineHeight","boxEnd","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","cursorPosition","Textbox","dynamicMinWidth","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","splitByGrapheme","isWrapping","nextOffset","nextLineIndex","shouldLimit","mapNextLine","p2Number","_wrapText","desiredWidth","getGraphemeDataForRender","wrapped","wordsData","_wrapLine","infix","largestWordWidth","wordsOrGraphemes","wordSplit","word","graphemeArray","_measureWord","charOffset","_wordJoiners","reservedSpace","additionalSpace","infixWidth","lineJustStarted","wordWidth","getMinWidth","minWidth","linesToKeep","propNumber","ClipPathLayout","clipPathCenter","FixedLayout","ActiveSelectionLayoutManager","parents","Set","selectedObjects","ActiveSelection","multiSelectionStacking","findIndex","groups","childrenOverride","Canvas2dFilterBackend","applyFilters","filters","sourceElement","sourceWidth","sourceHeight","pipelineState","imageData","originalEl","originalImageData","filterBackend","applyTo","imageDataPostFilter","putImageData","WebGLFilterBackend","tileSize","Float32Array","setupGLContext","captureGPUInfo","createWebGLCanvas","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","destinationWidth","destinationHeight","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","aPosition","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","dWidth","dHeight","resizeCanvasIfNeeded","copyGLTo2D","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","NEAREST","RGBA","UNSIGNED_BYTE","CLAMP_TO_EDGE","TEXTURE_MAG_FILTER","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","texture","texParameteri","texImage2D","uniqueId","evictCachesForKey","glCanvas","sourceY","copyGLTo2DPutImageData","numBytes","u8","Uint8Array","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","imgData","ImageData","gpuInfo","renderer","vendor","ext","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","initFilterBackend","enableGLFiltering","getFilterBackend","IMAGE_PROPS","FabricImage","setElement","_element","removeTexture","_originalElement","CSS_CANVAS","resizeFilter","applyResizeFilters","backend","elementKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","imageMarkup","strokeSvg","imageRendering","imageSmoothing","getSvgSrc","origFill","filtered","srcFromAttribute","setSrc","minimumScale","minimumScaleTrigger","elementToFilter","_filteredEl","_filterScalingX","_filterScalingY","_lastScaleX","_lastScaleY","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","pAR","preserveAspectRatio","pWidth","pHeight","rWidth","rHeight","f","rf","hydratedProps","fromURL","imageOptions","applyViewboxTransform","viewBoxAttr","widthAttr","heightAttr","missingViewBox","missingDimAttr","translateMatrix","widthDiff","heightDiff","parsedDim","pasedViewBox","createElementNS","firstChild","getTagName","node","tagName","svgInvalidAncestorsRegEx","getMultipleNodes","nodeNames","nodeList","nodeArray","getElementsByTagNameNS","gradientsAttrs","xlinkAttr","recursivelyParseGradientsXlink","_gradient$getAttribut","xLink","referencedGradient","children","referenceClone","cloneNode","tagArray","getCSSRules","allRules","styleContents","ruleObj","propertyValuePairs","pair","_rule","findTag","ElementsParser","clipPaths","regexUrl","gradientDefs","elList","getGradientDefs","createObject","resolveGradient","resolveClipPath","extractPropertyDefinition","storage","gradientDef","usingElement","clipPathElements","objTransformInv","clipPathTag","clipPathOwner","clipPathElement","enlivedClippath","clipRule","gTransform","isValidSvgTag","createEmptyResponse","allElements","async","parseSVGDocument","nodelist","skipAttributes","useElement","useAttributes","useAttrMap","xlink","href","referencedElement","clonedOriginal","originalAttributes","originalAttrMap","currentTrans","el3","setAttributeNS","childNodes","styleRecord","mergedStyles","entry","parseUseDirectives","descendants","hasInvalidAncestor","localClipPaths","elementParser","ACTION_NAME","createPolyPositionHandler","pointIndex","polyObject","polyActionHandler","poly","mouseLocalPosition","factoryPolyActionHandler","anchorPoint","anchorPointInParentPlane","createPolyActionHandler","calcPathPointPosition","pathObject","commandIndex","pathPositionHandler","pathActionHandler","movePathPoint","anchorCommand","PathPointControl","controlFill","controlStroke","PathControlPointControl","connectToCommandIndex","connectToPointIndex","connectionDashArray","commandType","createControl","commandIndexPos","pointIndexPos","isControlPoint","controlPointStyle","pointStyle","previousCommandType","indexFromPrevCommand","isWebGLPipelineState","highPsourceCode","identityFragmentShader","BaseFilter","getFragmentSource","getVertexSource","createProgram","vertexSource","vertexShader","VERTEX_SHADER","program","getShaderInfoLog","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","attributeLocations","getAttributeLocations","getAttribLocation","locations","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","finish","_swapTextures","temp","applyToWebGL","applyTo2d","getCacheKey","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","_gl","_uniformLocations","createHelpLayer","helpLayer","defaultKeys","blendColorFragmentSource","screen","difference","lighten","darken","exclusion","tint","BlendColor","mode","tg","alpha1","uniform4fv","uColor","mask","BlendImage","image","TEXTURE1","calculateMatrix","resources","blendImage","canvas1","blendData","uniform1i","uImage","uniformMatrix3fv","uTransformMatrix","filterOptions","enlivedImage","Blur","aspectRatio","horizontal","simpleBlur","blurLayer1","blurLayer2","canvas2","ctx1","ctx2","nSamples","percent","newImageData","delta","chooseRightDelta","uniform2fv","uDelta","blurScale","Brightness","brightness","uBrightness","ColorMatrix","colorsOnly","constants","uniformMatrix4fv","uColorMatrix","uConstants","createColorMatrixFilter","_Class","newClass","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","Composed","subFilters","enlivedFilters","Contrast","contrast","contrastF","uContrast","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","Convolute","opaque","weights","side","halfSide","sw","sh","createImageData","dst","alphaFac","dstOff","scx","scy","srcOff","wt","uniform1fv","uMatrix","GAMMA","Gamma","gamma","rInv","gInv","bInv","rgbValues","rgb","uniform3fv","uGamma","lightness","luminosity","Grayscale","uMode","HueRotation","rotation","cosine","sine","aThird","aThirdSqtSin","OneMinusCos","Invert","invert","uInvert","uAlpha","Noise","noise","rand","uNoise","uSeed","Pixelate","blocksize","_i","_j","uBlocksize","RemoveColor","lowC","highC","uLow","uHigh","useAlpha","Resize","uTaps","taps","getFilterWindow","tempScale","lanczosLobes","filterWindow","generateShader","getTaps","lobeFunction","lanczosCreate","applyToForWebgl","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","oW","oH","newData","resizeType","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","mult","doneW","doneH","stepW","stepH","dX","dY","tmpCanvas","srcData","destImg","destData","lanczos","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","process","u","weight","fX","fY","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","yy","w0","Saturation","adjust","saturation","uSaturation","Vibrance","vibrance","amt","uVibrance","drawDot","addPoint","dot","originalRenderOnAddRemove","circles","circle","pointerPoint","getPatternSrc","patternCanvas","patternCtx","dotWidth","getPattern","pattern","topLeft","sprayChunks","sprayChunk","addSprayChunk","renderChunck","rects","chunck","rect","optimizeOverlapping","uniqueRects","uniqueRectsArray","getUniqueRects","sprayChunck","density","dotWidthVariance","randomOpacity","isPutImageFaster","testContext","ArrayBuffer","testPipelineState","performance","now","drawImageTime","parseFromString","xml","responseXML","parsedDoc"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.min.mjs b/dist/index.min.mjs new file mode 100644 index 00000000000..c310ac00a30 --- /dev/null +++ b/dist/index.min.mjs @@ -0,0 +1,2 @@ +function t(t,e,s){return(e=function(t){var e=function(t,e){if("object"!=typeof t||!t)return t;var s=t[Symbol.toPrimitive];if(void 0!==s){var i=s.call(t,e||"default");if("object"!=typeof i)return i;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==typeof e?e:e+""}(e))in t?Object.defineProperty(t,e,{value:s,enumerable:!0,configurable:!0,writable:!0}):t[e]=s,t}function e(t,e){var s=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),s.push.apply(s,i)}return s}function s(s){for(var i=1;i=0)continue;s[i]=t[i]}return s}(t,e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);for(i=0;i=0||{}.propertyIsEnumerable.call(t,s)&&(r[s]=t[s])}return r}function r(t,e){return e||(e=t.slice(0)),Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))}class n{constructor(){t(this,"browserShadowBlurConstant",1),t(this,"DPI",96),t(this,"devicePixelRatio","undefined"!=typeof window?window.devicePixelRatio:1),t(this,"perfLimitSizeTotal",2097152),t(this,"maxCacheSideLimit",4096),t(this,"minCacheSideLimit",256),t(this,"disableStyleCopyPaste",!1),t(this,"enableGLFiltering",!0),t(this,"textureSize",4096),t(this,"forceGLPutImageData",!1),t(this,"cachesBoundsOfCurve",!1),t(this,"fontPaths",{}),t(this,"NUM_FRACTION_DIGITS",4)}}const o=new class extends n{constructor(t){super(),this.configure(t)}configure(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Object.assign(this,t)}addFonts(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.fontPaths=s(s({},this.fontPaths),t)}removeFonts(){(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).forEach((t=>{delete this.fontPaths[t]}))}clearFonts(){this.fontPaths={}}restoreDefaults(t){const e=new n,s=(null==t?void 0:t.reduce(((t,s)=>(t[s]=e[s],t)),{}))||e;this.configure(s)}},a=function(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;ithis.testPrecision(e,t))),e.getExtension("WEBGL_lose_context").loseContext(),a("log","WebGL: max texture size ".concat(this.maxTextureSize)))}isSupported(t){return!!this.maxTextureSize&&this.maxTextureSize>=t}}const d={};let g;const f=t=>{g=t},p=()=>g||(g={document:document,window:window,isTouchSupported:"ontouchstart"in window||"ontouchstart"in document||window&&window.navigator&&window.navigator.maxTouchPoints>0,WebGLProbe:new u,dispose(){},copyPasteData:d}),m=()=>p().document,v=()=>p().window,y=()=>{var t;return Math.max(null!==(t=o.devicePixelRatio)&&void 0!==t?t:v().devicePixelRatio,1)};const _=new class{constructor(){t(this,"charWidthsCache",{}),t(this,"boundsOfCurveCache",{})}getFontCache(t){let{fontFamily:e,fontStyle:s,fontWeight:i}=t;e=e.toLowerCase(),this.charWidthsCache[e]||(this.charWidthsCache[e]={});const r=this.charWidthsCache[e],n="".concat(s.toLowerCase(),"_").concat((i+"").toLowerCase());return r[n]||(r[n]={}),r[n]}clearFontCache(t){(t=(t||"").toLowerCase())?this.charWidthsCache[t]&&delete this.charWidthsCache[t]:this.charWidthsCache={}}limitDimsByArea(t){const{perfLimitSizeTotal:e}=o,s=Math.sqrt(e*t);return[Math.floor(s),Math.floor(e/s)]}};const x="6.4.2";function C(){}const b=Math.PI/2,w=2*Math.PI,S=Math.PI/180,T=Object.freeze([1,0,0,1,0,0]),O=16,k=.4477152502,D="center",M="left",P="top",E="bottom",A="right",j="none",F=/\r?\n/,L="moving",R="scaling",I="rotating",B="rotate",X="skewing",W="resizing",Y="modifyPoly",V="modifyPath",H="changed",z="scale",G="scaleX",N="scaleY",U="skewX",q="skewY",K="fill",J="stroke",Q="modified",Z="json",$="svg";const tt=new class{constructor(){this[Z]=new Map,this[$]=new Map}has(t){return this[Z].has(t)}getClass(t){const e=this[Z].get(t);if(!e)throw new h("No class registered for ".concat(t));return e}setClass(t,e){e?this[Z].set(e,t):(this[Z].set(t.type,t),this[Z].set(t.type.toLowerCase(),t))}getSVGClass(t){return this[$].get(t)}setSVGClass(t,e){this[$].set(null!=e?e:t.type.toLowerCase(),t)}};const et=new class extends Array{remove(t){const e=this.indexOf(t);e>-1&&this.splice(e,1)}cancelAll(){const t=this.splice(0);return t.forEach((t=>t.abort())),t}cancelByCanvas(t){if(!t)return[];const e=this.filter((e=>{var s;return e.target===t||"object"==typeof e.target&&(null===(s=e.target)||void 0===s?void 0:s.canvas)===t}));return e.forEach((t=>t.abort())),e}cancelByTarget(t){if(!t)return[];const e=this.filter((e=>e.target===t));return e.forEach((t=>t.abort())),e}};class st{constructor(){t(this,"__eventListeners",{})}on(t,e){if(this.__eventListeners||(this.__eventListeners={}),"object"==typeof t)return Object.entries(t).forEach((t=>{let[e,s]=t;this.on(e,s)})),()=>this.off(t);if(e){const s=t;return this.__eventListeners[s]||(this.__eventListeners[s]=[]),this.__eventListeners[s].push(e),()=>this.off(s,e)}return()=>!1}once(t,e){if("object"==typeof t){const e=[];return Object.entries(t).forEach((t=>{let[s,i]=t;e.push(this.once(s,i))})),()=>e.forEach((t=>t()))}if(e){const s=this.on(t,(function(){for(var t=arguments.length,i=new Array(t),r=0;r!1}_removeEventListener(t,e){if(this.__eventListeners[t])if(e){const s=this.__eventListeners[t],i=s.indexOf(e);i>-1&&s.splice(i,1)}else this.__eventListeners[t]=[]}off(t,e){if(this.__eventListeners)if(void 0===t)for(const t in this.__eventListeners)this._removeEventListener(t);else"object"==typeof t?Object.entries(t).forEach((t=>{let[e,s]=t;this._removeEventListener(e,s)})):this._removeEventListener(t,e)}fire(t,e){var s;if(!this.__eventListeners)return;const i=null===(s=this.__eventListeners[t])||void 0===s?void 0:s.concat();if(i)for(let t=0;t{const s=t.indexOf(e);return-1!==s&&t.splice(s,1),t},rt=t=>{if(0===t)return 1;switch(Math.abs(t)/b){case 1:case 3:return 0;case 2:return-1}return Math.cos(t)},nt=t=>{if(0===t)return 0;const e=t/b,s=Math.sign(t);switch(e){case 1:return s;case 2:return 0;case 3:return-s}return Math.sin(t)};class ot{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;"object"==typeof t?(this.x=t.x,this.y=t.y):(this.x=t,this.y=e)}add(t){return new ot(this.x+t.x,this.y+t.y)}addEquals(t){return this.x+=t.x,this.y+=t.y,this}scalarAdd(t){return new ot(this.x+t,this.y+t)}scalarAddEquals(t){return this.x+=t,this.y+=t,this}subtract(t){return new ot(this.x-t.x,this.y-t.y)}subtractEquals(t){return this.x-=t.x,this.y-=t.y,this}scalarSubtract(t){return new ot(this.x-t,this.y-t)}scalarSubtractEquals(t){return this.x-=t,this.y-=t,this}multiply(t){return new ot(this.x*t.x,this.y*t.y)}scalarMultiply(t){return new ot(this.x*t,this.y*t)}scalarMultiplyEquals(t){return this.x*=t,this.y*=t,this}divide(t){return new ot(this.x/t.x,this.y/t.y)}scalarDivide(t){return new ot(this.x/t,this.y/t)}scalarDivideEquals(t){return this.x/=t,this.y/=t,this}eq(t){return this.x===t.x&&this.y===t.y}lt(t){return this.xt.x&&this.y>t.y}gte(t){return this.x>=t.x&&this.y>=t.y}lerp(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:.5;return e=Math.max(Math.min(1,e),0),new ot(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)}distanceFrom(t){const e=this.x-t.x,s=this.y-t.y;return Math.sqrt(e*e+s*s)}midPointFrom(t){return this.lerp(t)}min(t){return new ot(Math.min(this.x,t.x),Math.min(this.y,t.y))}max(t){return new ot(Math.max(this.x,t.x),Math.max(this.y,t.y))}toString(){return"".concat(this.x,",").concat(this.y)}setXY(t,e){return this.x=t,this.y=e,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setFromPoint(t){return this.x=t.x,this.y=t.y,this}swap(t){const e=this.x,s=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=s}clone(){return new ot(this.x,this.y)}rotate(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:at;const s=nt(t),i=rt(t),r=this.subtract(e);return new ot(r.x*i-r.y*s,r.x*s+r.y*i).add(e)}transform(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return new ot(t[0]*this.x+t[2]*this.y+(e?0:t[4]),t[1]*this.x+t[3]*this.y+(e?0:t[5]))}}const at=new ot(0,0),ht=t=>!!t&&Array.isArray(t._objects);function ct(e){class s extends e{constructor(){super(...arguments),t(this,"_objects",[])}_onObjectAdded(t){}_onObjectRemoved(t){}_onStackOrderChanged(t){}add(){for(var t=arguments.length,e=new Array(t),s=0;sthis._onObjectAdded(t))),i}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;ithis._onObjectAdded(t))),this._objects.length}remove(){const t=this._objects,e=[];for(var s=arguments.length,i=new Array(s),r=0;r{const i=t.indexOf(s);-1!==i&&(t.splice(i,1),e.push(s),this._onObjectRemoved(s))})),e}forEachObject(t){this.getObjects().forEach(((e,s,i)=>t(e,s,i)))}getObjects(){for(var t=arguments.length,e=new Array(t),s=0;st.isType(...e)))}item(t){return this._objects[t]}isEmpty(){return 0===this._objects.length}size(){return this._objects.length}contains(t,e){return!!this._objects.includes(t)||!!e&&this._objects.some((e=>e instanceof s&&e.contains(t,!0)))}complexity(){return this._objects.reduce(((t,e)=>t+=e.complexity?e.complexity():0),0)}sendObjectToBack(t){return!(!t||t===this._objects[0])&&(it(this._objects,t),this._objects.unshift(t),this._onStackOrderChanged(t),!0)}bringObjectToFront(t){return!(!t||t===this._objects[this._objects.length-1])&&(it(this._objects,t),this._objects.push(t),this._onStackOrderChanged(t),!0)}sendObjectBackwards(t,e){if(!t)return!1;const s=this._objects.indexOf(t);if(0!==s){const i=this.findNewLowerIndex(t,s,e);return it(this._objects,t),this._objects.splice(i,0,t),this._onStackOrderChanged(t),!0}return!1}bringObjectForward(t,e){if(!t)return!1;const s=this._objects.indexOf(t);if(s!==this._objects.length-1){const i=this.findNewUpperIndex(t,s,e);return it(this._objects,t),this._objects.splice(i,0,t),this._onStackOrderChanged(t),!0}return!1}moveObjectTo(t,e){return t!==this._objects[e]&&(it(this._objects,t),this._objects.splice(e,0,t),this._onStackOrderChanged(t),!0)}findNewLowerIndex(t,e,s){let i;if(s){i=e;for(let s=e-1;s>=0;--s)if(t.isOverlapping(this._objects[s])){i=s;break}}else i=e-1;return i}findNewUpperIndex(t,e,s){let i;if(s){i=e;for(let s=e+1;s1&&void 0!==arguments[1]?arguments[1]:{};const o=[],a=new ot(e,s),h=a.add(new ot(i,r));for(let t=this._objects.length-1;t>=0;t--){const e=this._objects[t];e.selectable&&e.visible&&(n&&e.intersectsWithRect(a,h)||e.isContainedWithinRect(a,h)||n&&e.containsPoint(a)||n&&e.containsPoint(h))&&o.push(e)}return o}}return s}class lt extends st{_setOptions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};for(const e in t)this.set(e,t[e])}_setObject(t){for(const e in t)this._set(e,t[e])}set(t,e){return"object"==typeof t?this._setObject(t):this._set(t,e),this}_set(t,e){this[t]=e}toggle(t){const e=this.get(t);return"boolean"==typeof e&&this.set(t,!e),this}get(t){return this[t]}}function ut(t){return v().requestAnimationFrame(t)}function dt(t){return v().cancelAnimationFrame(t)}let gt=0;const ft=()=>gt++,pt=()=>{const t=m().createElement("canvas");if(!t||void 0===t.getContext)throw new h("Failed to create `canvas` element");return t},mt=()=>m().createElement("img"),vt=(t,e,s)=>t.toDataURL("image/".concat(e),s),yt=t=>t*S,_t=t=>t/S,xt=t=>t.every(((t,e)=>t===T[e])),Ct=(t,e,s)=>new ot(t).transform(e,s),bt=t=>{const e=1/(t[0]*t[3]-t[1]*t[2]),s=[e*t[3],-e*t[1],-e*t[2],e*t[0],0,0],{x:i,y:r}=new ot(t[4],t[5]).transform(s,!0);return s[4]=-i,s[5]=-r,s},wt=(t,e,s)=>[t[0]*e[0]+t[2]*e[1],t[1]*e[0]+t[3]*e[1],t[0]*e[2]+t[2]*e[3],t[1]*e[2]+t[3]*e[3],s?0:t[0]*e[4]+t[2]*e[5]+t[4],s?0:t[1]*e[4]+t[3]*e[5]+t[5]],St=(t,e)=>t.reduceRight(((t,s)=>s&&t?wt(s,t,e):s||t),void 0)||T.concat(),Tt=t=>{let[e,s]=t;return Math.atan2(s,e)},Ot=t=>{const e=Tt(t),s=Math.pow(t[0],2)+Math.pow(t[1],2),i=Math.sqrt(s),r=(t[0]*t[3]-t[2]*t[1])/i,n=Math.atan2(t[0]*t[2]+t[1]*t[3],s);return{angle:_t(e),scaleX:i,scaleY:r,skewX:_t(n),skewY:0,translateX:t[4]||0,translateY:t[5]||0}},kt=function(t){return[1,0,0,1,t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:0]};function Dt(){let{angle:t=0}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{x:e=0,y:s=0}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=yt(t),r=rt(i),n=nt(i);return[r,n,-n,r,e?e-(r*e-n*s):0,s?s-(n*e+r*s):0]}const Mt=function(t){return[t,0,0,arguments.length>1&&void 0!==arguments[1]?arguments[1]:t,0,0]},Pt=t=>Math.tan(yt(t)),Et=t=>[1,0,Pt(t),1,0,0],At=t=>[1,Pt(t),0,1,0,0],jt=t=>{let{scaleX:e=1,scaleY:s=1,flipX:i=!1,flipY:r=!1,skewX:n=0,skewY:o=0}=t,a=Mt(i?-e:e,r?-s:s);return n&&(a=wt(a,Et(n),!0)),o&&(a=wt(a,At(o),!0)),a},Ft=t=>{const{translateX:e=0,translateY:s=0,angle:i=0}=t;let r=kt(e,s);i&&(r=wt(r,Dt({angle:i})));const n=jt(t);return xt(n)||(r=wt(r,n)),r},Lt=function(t){let{signal:e,crossOrigin:s=null}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise((function(i,r){if(e&&e.aborted)return r(new c("loadImage"));const n=mt();let o;e&&(o=function(t){n.src="",r(t)},e.addEventListener("abort",o,{once:!0}));const a=function(){n.onload=n.onerror=null,o&&(null==e||e.removeEventListener("abort",o)),i(n)};t?(n.onload=a,n.onerror=function(){o&&(null==e||e.removeEventListener("abort",o)),r(new h("Error loading ".concat(n.src)))},s&&(n.crossOrigin=s),n.src=t):a()}))},Rt=function(t){let{signal:e,reviver:s=C}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((i,r)=>{const n=[];e&&e.addEventListener("abort",r,{once:!0}),Promise.all(t.map((t=>tt.getClass(t.type).fromObject(t,{signal:e}).then((e=>(s(t,e),n.push(e),e)))))).then(i).catch((t=>{n.forEach((t=>{t.dispose&&t.dispose()})),r(t)})).finally((()=>{e&&e.removeEventListener("abort",r)}))}))},It=function(t){let{signal:e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return new Promise(((s,i)=>{const r=[];e&&e.addEventListener("abort",i,{once:!0});const n=Object.values(t).map((t=>t&&t.type&&tt.has(t.type)?Rt([t],{signal:e}).then((t=>{let[e]=t;return r.push(e),e})):t)),o=Object.keys(t);Promise.all(n).then((t=>t.reduce(((t,e,s)=>(t[o[s]]=e,t)),{}))).then(s).catch((t=>{r.forEach((t=>{t.dispose&&t.dispose()})),i(t)})).finally((()=>{e&&e.removeEventListener("abort",i)}))}))},Bt=function(t){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:[]).reduce(((e,s)=>(s in t&&(e[s]=t[s]),e)),{})},Xt=(t,e)=>Object.keys(t).reduce(((s,i)=>(e(t[i],i,t)&&(s[i]=t[i]),s)),{}),Wt={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#0FF",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000",blanchedalmond:"#FFEBCD",blue:"#00F",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#0FF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgrey:"#A9A9A9",darkgreen:"#006400",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#F0F",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgray:"#D3D3D3",lightgrey:"#D3D3D3",lightgreen:"#90EE90",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#789",lightslategrey:"#789",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",lime:"#0F0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#F0F",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",rebeccapurple:"#639",red:"#F00",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFF",whitesmoke:"#F5F5F5",yellow:"#FF0",yellowgreen:"#9ACD32"},Yt=(t,e,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(e-t)*s:s<.5?e:s<2/3?t+(e-t)*(2/3-s)*6:t),Vt=(t,e,s,i)=>{t/=255,e/=255,s/=255;const r=Math.max(t,e,s),n=Math.min(t,e,s);let o,a;const h=(r+n)/2;if(r===n)o=a=0;else{const i=r-n;switch(a=h>.5?i/(2-r-n):i/(r+n),r){case t:o=(e-s)/i+(e0&&void 0!==arguments[0]?arguments[0]:"1";return parseFloat(t)/(t.endsWith("%")?100:1)},zt=t=>Math.min(Math.round(t),255).toString(16).toUpperCase().padStart(2,"0"),Gt=t=>{let[e,s,i,r=1]=t;const n=Math.round(.3*e+.59*s+.11*i);return[n,n,n,r]};class Nt{constructor(e){if(t(this,"isUnrecognised",!1),e)if(e instanceof Nt)this.setSource([...e._source]);else if(Array.isArray(e)){const[t,s,i,r=1]=e;this.setSource([t,s,i,r])}else this.setSource(this._tryParsingColor(e));else this.setSource([0,0,0,1])}_tryParsingColor(t){return t in Wt&&(t=Wt[t]),"transparent"===t?[255,255,255,0]:Nt.sourceFromHex(t)||Nt.sourceFromRgb(t)||Nt.sourceFromHsl(t)||(this.isUnrecognised=!0)&&[0,0,0,1]}getSource(){return this._source}setSource(t){this._source=t}toRgb(){const[t,e,s]=this.getSource();return"rgb(".concat(t,",").concat(e,",").concat(s,")")}toRgba(){return"rgba(".concat(this.getSource().join(","),")")}toHsl(){const[t,e,s]=Vt(...this.getSource());return"hsl(".concat(t,",").concat(e,"%,").concat(s,"%)")}toHsla(){const[t,e,s,i]=Vt(...this.getSource());return"hsla(".concat(t,",").concat(e,"%,").concat(s,"%,").concat(i,")")}toHex(){return this.toHexa().slice(0,6)}toHexa(){const[t,e,s,i]=this.getSource();return"".concat(zt(t)).concat(zt(e)).concat(zt(s)).concat(zt(Math.round(255*i)))}getAlpha(){return this.getSource()[3]}setAlpha(t){return this._source[3]=t,this}toGrayscale(){return this.setSource(Gt(this.getSource())),this}toBlackWhite(t){const[e,,,s]=Gt(this.getSource()),i=e<(t||127)?0:255;return this.setSource([i,i,i,s]),this}overlayWith(t){t instanceof Nt||(t=new Nt(t));const e=this.getSource(),s=t.getSource(),[i,r,n]=e.map(((t,e)=>Math.round(.5*t+.5*s[e])));return this.setSource([i,r,n,e[3]]),this}static fromRgb(t){return Nt.fromRgba(t)}static fromRgba(t){return new Nt(Nt.sourceFromRgb(t))}static sourceFromRgb(t){const e=t.match(/^rgba?\(\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d{0,3}(?:\.\d+)?%?)\s*)?\)$/i);if(e){const[t,s,i]=e.slice(1,4).map((t=>{const e=parseFloat(t);return t.endsWith("%")?Math.round(2.55*e):e}));return[t,s,i,Ht(e[4])]}}static fromHsl(t){return Nt.fromHsla(t)}static fromHsla(t){return new Nt(Nt.sourceFromHsl(t))}static sourceFromHsl(t){const e=t.match(/^hsla?\(\s*([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d*(?:\.\d+)?%?)\s*)?\)$/i);if(!e)return;const s=(Nt.parseAngletoDegrees(e[1])%360+360)%360/360,i=parseFloat(e[2])/100,r=parseFloat(e[3])/100;let n,o,a;if(0===i)n=o=a=r;else{const t=r<=.5?r*(i+1):r+i-r*i,e=2*r-t;n=Yt(e,t,s+1/3),o=Yt(e,t,s),a=Yt(e,t,s-1/3)}return[Math.round(255*n),Math.round(255*o),Math.round(255*a),Ht(e[4])]}static fromHex(t){return new Nt(Nt.sourceFromHex(t))}static sourceFromHex(t){if(t.match(/^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i)){const e=t.slice(t.indexOf("#")+1);let s;s=e.length<=4?e.split("").map((t=>t+t)):e.match(/.{2}/g);const[i,r,n,o=255]=s.map((t=>parseInt(t,16)));return[i,r,n,o/255]}}static parseAngletoDegrees(t){const e=t.toLowerCase(),s=parseFloat(e);return e.includes("rad")?_t(s):e.includes("turn")?360*s:s}}const Ut=(t,e)=>parseFloat(Number(t).toFixed(e)),qt=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:O;const s=/\D{0,2}$/.exec(t),i=parseFloat(t),r=o.DPI;switch(null==s?void 0:s[0]){case"mm":return i*r/25.4;case"cm":return i*r/2.54;case"in":return i*r;case"pt":return i*r/72;case"pc":return i*r/72*12;case"em":return i*e;default:return i}},Kt=t=>{const[e,s]=t.trim().split(" "),[i,r]=(n=e)&&n!==j?[n.slice(1,4),n.slice(5,8)]:n===j?[n,n]:["Mid","Mid"];var n;return{meetOrSlice:s||"meet",alignX:i,alignY:r}},Jt=t=>"matrix("+t.map((t=>Ut(t,o.NUM_FRACTION_DIGITS))).join(" ")+")",Qt=function(t,e){let s,i,r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(e)if(e.toLive)s="url(#SVGID_".concat(e.id,")");else{const t=new Nt(e),r=t.getAlpha();s=t.toRgb(),1!==r&&(i=r.toString())}else s="none";return r?"".concat(t,": ").concat(s,"; ").concat(i?"".concat(t,"-opacity: ").concat(i,"; "):""):"".concat(t,'="').concat(s,'" ').concat(i?"".concat(t,'-opacity="').concat(i,'" '):"")},Zt=t=>!!t&&void 0!==t.toLive,$t=t=>!!t&&"function"==typeof t.toObject,te=t=>!!t&&void 0!==t.offsetX&&"source"in t,ee=t=>!!t&&"function"==typeof t._renderText,se=t=>!!t&&"multiSelectionStacking"in t;function ie(t){const e=t&&re(t);let s=0,i=0;if(!t||!e)return{left:s,top:i};let r=t;const n=e.documentElement,o=e.body||{scrollLeft:0,scrollTop:0};for(;r&&(r.parentNode||r.host)&&(r=r.parentNode||r.host,r===e?(s=o.scrollLeft||n.scrollLeft||0,i=o.scrollTop||n.scrollTop||0):(s+=r.scrollLeft||0,i+=r.scrollTop||0),1!==r.nodeType||"fixed"!==r.style.position););return{left:s,top:i}}const re=t=>t.ownerDocument||null,ne=t=>{var e;return(null===(e=t.ownerDocument)||void 0===e?void 0:e.defaultView)||null},oe=function(t,e,s){let{width:i,height:r}=s,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1;t.width=i,t.height=r,n>1&&(t.setAttribute("width",(i*n).toString()),t.setAttribute("height",(r*n).toString()),e.scale(n,n))},ae=(t,e)=>{let{width:s,height:i}=e;s&&(t.style.width="number"==typeof s?"".concat(s,"px"):s),i&&(t.style.height="number"==typeof i?"".concat(i,"px"):i)};function he(t){return void 0!==t.onselectstart&&(t.onselectstart=()=>!1),t.style.userSelect=j,t}class ce{constructor(e){t(this,"_originalCanvasStyle",void 0),t(this,"lower",void 0);const s=this.createLowerCanvas(e);this.lower={el:s,ctx:s.getContext("2d")}}createLowerCanvas(t){const e=(s=t)&&void 0!==s.getContext?t:t&&m().getElementById(t)||pt();var s;if(e.hasAttribute("data-fabric"))throw new h("Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?");return this._originalCanvasStyle=e.style.cssText,e.setAttribute("data-fabric","main"),e.classList.add("lower-canvas"),e}cleanupDOM(t){let{width:e,height:s}=t;const{el:i}=this.lower;i.classList.remove("lower-canvas"),i.removeAttribute("data-fabric"),i.setAttribute("width","".concat(e)),i.setAttribute("height","".concat(s)),i.style.cssText=this._originalCanvasStyle||"",this._originalCanvasStyle=void 0}setDimensions(t,e){const{el:s,ctx:i}=this.lower;oe(s,i,t,e)}setCSSDimensions(t){ae(this.lower.el,t)}calcOffset(){return function(t){var e;const s=t&&re(t),i={left:0,top:0};if(!s)return i;const r=(null===(e=ne(t))||void 0===e?void 0:e.getComputedStyle(t,null))||{};i.left+=parseInt(r.borderLeftWidth,10)||0,i.top+=parseInt(r.borderTopWidth,10)||0,i.left+=parseInt(r.paddingLeft,10)||0,i.top+=parseInt(r.paddingTop,10)||0;let n={left:0,top:0};const o=s.documentElement;void 0!==t.getBoundingClientRect&&(n=t.getBoundingClientRect());const a=ie(t);return{left:n.left+a.left-(o.clientLeft||0)+i.left,top:n.top+a.top-(o.clientTop||0)+i.top}}(this.lower.el)}dispose(){p().dispose(this.lower.el),delete this.lower}}const le={backgroundVpt:!0,backgroundColor:"",overlayVpt:!0,overlayColor:"",includeDefaultValues:!0,svgViewportTransformation:!0,renderOnAddRemove:!0,skipOffscreen:!0,enableRetinaScaling:!0,imageSmoothingEnabled:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,viewportTransform:[...T]};class ue extends(ct(lt)){get lowerCanvasEl(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.el}get contextContainer(){var t;return null===(t=this.elements.lower)||void 0===t?void 0:t.ctx}static getDefaults(){return ue.ownDefaults}constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,this.constructor.getDefaults()),this.set(e),this.initElements(t),this._setDimensionsImpl({width:this.width||this.elements.lower.el.width||0,height:this.height||this.elements.lower.el.height||0}),this.skipControlsDrawing=!1,this.viewportTransform=[...this.viewportTransform],this.calcViewportBoundaries()}initElements(t){this.elements=new ce(t)}add(){const t=super.add(...arguments);return arguments.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i0&&this.renderOnAddRemove&&this.requestRenderAll(),r}remove(){const t=super.remove(...arguments);return t.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}_onObjectAdded(t){t.canvas&&t.canvas!==this&&(a("warn","Canvas is trying to add an object that belongs to a different canvas.\nResulting to default behavior: removing object from previous canvas and adding to new canvas"),t.canvas.remove(t)),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added",{target:this})}_onObjectRemoved(t){t._set("canvas",void 0),this.fire("object:removed",{target:t}),t.fire("removed",{target:this})}_onStackOrderChanged(){this.renderOnAddRemove&&this.requestRenderAll()}getRetinaScaling(){return this.enableRetinaScaling?y():1}calcOffset(){return this._offset=this.elements.calcOffset()}getWidth(){return this.width}getHeight(){return this.height}setWidth(t,e){return this.setDimensions({width:t},e)}setHeight(t,e){return this.setDimensions({height:t},e)}_setDimensionsImpl(t){let{cssOnly:e=!1,backstoreOnly:i=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!e){const e=s({width:this.width,height:this.height},t);this.elements.setDimensions(e,this.getRetinaScaling()),this.hasLostContext=!0,this.width=e.width,this.height=e.height}i||this.elements.setCSSDimensions(t),this.calcOffset()}setDimensions(t,e){this._setDimensionsImpl(t,e),e&&e.cssOnly||this.requestRenderAll()}getZoom(){return this.viewportTransform[0]}setViewportTransform(t){this.viewportTransform=t,this.calcViewportBoundaries(),this.renderOnAddRemove&&this.requestRenderAll()}zoomToPoint(t,e){const s=t,i=[...this.viewportTransform],r=Ct(t,bt(i));i[0]=e,i[3]=e;const n=Ct(r,i);i[4]+=s.x-n.x,i[5]+=s.y-n.y,this.setViewportTransform(i)}setZoom(t){this.zoomToPoint(new ot(0,0),t)}absolutePan(t){const e=[...this.viewportTransform];return e[4]=-t.x,e[5]=-t.y,this.setViewportTransform(e)}relativePan(t){return this.absolutePan(new ot(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))}getElement(){return this.elements.lower.el}clearContext(t){t.clearRect(0,0,this.width,this.height)}getContext(){return this.elements.lower.ctx}clear(){this.remove(...this.getObjects()),this.backgroundImage=void 0,this.overlayImage=void 0,this.backgroundColor="",this.overlayColor="",this.clearContext(this.getContext()),this.fire("canvas:cleared"),this.renderOnAddRemove&&this.requestRenderAll()}renderAll(){this.cancelRequestedRender(),this.destroyed||this.renderCanvas(this.getContext(),this._objects)}renderAndReset(){this.nextRenderHandle=0,this.renderAll()}requestRenderAll(){this.nextRenderHandle||this.disposed||this.destroyed||(this.nextRenderHandle=ut((()=>this.renderAndReset())))}calcViewportBoundaries(){const t=this.width,e=this.height,s=bt(this.viewportTransform),i=Ct({x:0,y:0},s),r=Ct({x:t,y:e},s),n=i.min(r),o=i.max(r);return this.vptCoords={tl:n,tr:new ot(o.x,n.y),bl:new ot(n.x,o.y),br:o}}cancelRequestedRender(){this.nextRenderHandle&&(dt(this.nextRenderHandle),this.nextRenderHandle=0)}drawControls(t){}renderCanvas(t,e){if(this.destroyed)return;const s=this.viewportTransform,i=this.clipPath;this.calcViewportBoundaries(),this.clearContext(t),t.imageSmoothingEnabled=this.imageSmoothingEnabled,t.patternQuality="best",this.fire("before:render",{ctx:t}),this._renderBackground(t),t.save(),t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this._renderObjects(t,e),t.restore(),this.controlsAboveOverlay||this.skipControlsDrawing||this.drawControls(t),i&&(i._set("canvas",this),i.shouldCache(),i._transformDone=!0,i.renderCache({forClipping:!0}),this.drawClipPathOnCanvas(t,i)),this._renderOverlay(t),this.controlsAboveOverlay&&!this.skipControlsDrawing&&this.drawControls(t),this.fire("after:render",{ctx:t}),this.__cleanupTask&&(this.__cleanupTask(),this.__cleanupTask=void 0)}drawClipPathOnCanvas(t,e){const s=this.viewportTransform;t.save(),t.transform(...s),t.globalCompositeOperation="destination-in",e.transform(t),t.scale(1/e.zoomX,1/e.zoomY),t.drawImage(e._cacheCanvas,-e.cacheTranslationX,-e.cacheTranslationY),t.restore()}_renderObjects(t,e){for(let s=0,i=e.length;s!t.excludeFromExport)).map((s=>this._toObject(s,t,e)))},this.__serializeBgOverlay(t,e)),r?{clipPath:r}:null)}_toObject(t,e,s){let i;this.includeDefaultValues||(i=t.includeDefaultValues,t.includeDefaultValues=!1);const r=t[e](s);return this.includeDefaultValues||(t.includeDefaultValues=!!i),r}__serializeBgOverlay(t,e){const s={},i=this.backgroundImage,r=this.overlayImage,n=this.backgroundColor,o=this.overlayColor;return Zt(n)?n.excludeFromExport||(s.background=n.toObject(e)):n&&(s.background=n),Zt(o)?o.excludeFromExport||(s.overlay=o.toObject(e)):o&&(s.overlay=o),i&&!i.excludeFromExport&&(s.backgroundImage=this._toObject(i,t,e)),r&&!r.excludeFromExport&&(s.overlayImage=this._toObject(r,t,e)),s}toSVG(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0;t.reviver=e;const s=[];return this._setSVGPreamble(s,t),this._setSVGHeader(s,t),this.clipPath&&s.push('\n')),this._setSVGBgOverlayColor(s,"background"),this._setSVGBgOverlayImage(s,"backgroundImage",e),this._setSVGObjects(s,e),this.clipPath&&s.push("\n"),this._setSVGBgOverlayColor(s,"overlay"),this._setSVGBgOverlayImage(s,"overlayImage",e),s.push(""),s.join("")}_setSVGPreamble(t,e){e.suppressPreamble||t.push('\n','\n')}_setSVGHeader(t,e){const s=e.width||"".concat(this.width),i=e.height||"".concat(this.height),r=o.NUM_FRACTION_DIGITS,n=e.viewBox;let a;if(n)a='viewBox="'.concat(n.x," ").concat(n.y," ").concat(n.width," ").concat(n.height,'" ');else if(this.svgViewportTransformation){const t=this.viewportTransform;a='viewBox="'.concat(Ut(-t[4]/t[0],r)," ").concat(Ut(-t[5]/t[3],r)," ").concat(Ut(this.width/t[0],r)," ").concat(Ut(this.height/t[3],r),'" ')}else a='viewBox="0 0 '.concat(this.width," ").concat(this.height,'" ');t.push("\n',"Created with Fabric.js ",x,"\n","\n",this.createSVGFontFacesMarkup(),this.createSVGRefElementsMarkup(),this.createSVGClipPathMarkup(e),"\n")}createSVGClipPathMarkup(t){const e=this.clipPath;return e?(e.clipPathId="CLIPPATH_".concat(ft()),'\n').concat(e.toClipPathSVG(t.reviver),"\n")):""}createSVGRefElementsMarkup(){return["background","overlay"].map((t=>{const e=this["".concat(t,"Color")];if(Zt(e)){const s=this["".concat(t,"Vpt")],i=this.viewportTransform,r={isType:()=>!1,width:this.width/(s?i[0]:1),height:this.height/(s?i[3]:1)};return e.toSVG(r,{additionalTransform:s?Jt(i):""})}})).join("")}createSVGFontFacesMarkup(){const t=[],e={},s=o.fontPaths;this._objects.forEach((function e(s){t.push(s),ht(s)&&s._objects.forEach(e)})),t.forEach((t=>{if(!ee(t))return;const{styles:i,fontFamily:r}=t;!e[r]&&s[r]&&(e[r]=!0,i&&Object.values(i).forEach((t=>{Object.values(t).forEach((t=>{let{fontFamily:i=""}=t;!e[i]&&s[i]&&(e[i]=!0)}))})))}));const i=Object.keys(e).map((t=>"\t\t@font-face {\n\t\t\tfont-family: '".concat(t,"';\n\t\t\tsrc: url('").concat(s[t],"');\n\t\t}\n"))).join("");return i?'\t\n"):""}_setSVGObjects(t,e){this.forEachObject((s=>{s.excludeFromExport||this._setSVGObject(t,s,e)}))}_setSVGObject(t,e,s){t.push(e.toSVG(s))}_setSVGBgOverlayImage(t,e,s){const i=this[e];i&&!i.excludeFromExport&&i.toSVG&&t.push(i.toSVG(s))}_setSVGBgOverlayColor(t,e){const s=this["".concat(e,"Color")];if(s)if(Zt(s)){const i=s.repeat||"",r=this.width,n=this.height,o=this["".concat(e,"Vpt")]?Jt(bt(this.viewportTransform)):"";t.push('\n'))}else t.push('\n")}loadFromJSON(t,e){let{signal:s}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(!t)return Promise.reject(new h("`json` is undefined"));const i="string"==typeof t?JSON.parse(t):t,{objects:r=[],backgroundImage:n,background:o,overlayImage:a,overlay:c,clipPath:l}=i,u=this.renderOnAddRemove;return this.renderOnAddRemove=!1,Promise.all([Rt(r,{reviver:e,signal:s}),It({backgroundImage:n,backgroundColor:o,overlayImage:a,overlayColor:c,clipPath:l},{signal:s})]).then((t=>{let[e,s]=t;return this.clear(),this.add(...e),this.set(i),this.set(s),this.renderOnAddRemove=u,this}))}clone(t){const e=this.toObject(t);return this.cloneWithoutData().loadFromJSON(e)}cloneWithoutData(){const t=pt();return t.width=this.width,t.height=this.height,new this.constructor(t)}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{format:e="png",quality:s=1,multiplier:i=1,enableRetinaScaling:r=!1}=t,n=i*(r?this.getRetinaScaling():1);return vt(this.toCanvasElement(n,t),e,s)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,{width:e,height:s,left:i,top:r,filter:n}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=(e||this.width)*t,a=(s||this.height)*t,h=this.getZoom(),c=this.width,l=this.height,u=this.skipControlsDrawing,d=h*t,g=this.viewportTransform,f=[d,0,0,d,(g[4]-(i||0))*t,(g[5]-(r||0))*t],p=this.enableRetinaScaling,m=pt(),v=n?this._objects.filter((t=>n(t))):this._objects;return m.width=o,m.height=a,this.enableRetinaScaling=!1,this.viewportTransform=f,this.width=o,this.height=a,this.skipControlsDrawing=!0,this.calcViewportBoundaries(),this.renderCanvas(m.getContext("2d"),v),this.viewportTransform=g,this.width=c,this.height=l,this.calcViewportBoundaries(),this.enableRetinaScaling=p,this.skipControlsDrawing=u,m}dispose(){return!this.disposed&&this.elements.cleanupDOM({width:this.width,height:this.height}),et.cancelByCanvas(this),this.disposed=!0,new Promise(((t,e)=>{const s=()=>{this.destroy(),t(!0)};s.kill=e,this.__cleanupTask&&this.__cleanupTask.kill("aborted"),this.destroyed?t(!1):this.nextRenderHandle?this.__cleanupTask=s:s()}))}destroy(){this.destroyed=!0,this.cancelRequestedRender(),this.forEachObject((t=>t.dispose())),this._objects=[],this.backgroundImage&&this.backgroundImage.dispose(),this.backgroundImage=void 0,this.overlayImage&&this.overlayImage.dispose(),this.overlayImage=void 0,this.elements.dispose()}toString(){return"#")}}t(ue,"ownDefaults",le);const de=["touchstart","touchmove","touchend"];const ge=t=>{const e=ie(t.target),s=function(t){const e=t.changedTouches;return e&&e[0]?e[0]:t}(t);return new ot(s.clientX+e.left,s.clientY+e.top)},fe=t=>de.includes(t.type)||"touch"===t.pointerType,pe=t=>{t.preventDefault(),t.stopPropagation()},me=t=>{let e=0,s=0,i=0,r=0;for(let n=0,o=t.length;ni||!n)&&(i=o),(or||!n)&&(r=a),(a_e(t,wt(e,t.calcOwnMatrix())),_e=(t,e)=>{const s=Ot(e),{translateX:r,translateY:n,scaleX:o,scaleY:a}=s,h=i(s,ve),c=new ot(r,n);t.flipX=!1,t.flipY=!1,Object.assign(t,h),t.set({scaleX:o,scaleY:a}),t.setPositionByOrigin(c,D,D)},xe=t=>{t.scaleX=1,t.scaleY=1,t.skewX=0,t.skewY=0,t.flipX=!1,t.flipY=!1,t.rotate(0)},Ce=t=>({scaleX:t.scaleX,scaleY:t.scaleY,skewX:t.skewX,skewY:t.skewY,angle:t.angle,left:t.left,flipX:t.flipX,flipY:t.flipY,top:t.top}),be=(t,e,s)=>{const i=t/2,r=e/2,n=[new ot(-i,-r),new ot(i,-r),new ot(-i,r),new ot(i,r)].map((t=>t.transform(s))),o=me(n);return new ot(o.width,o.height)},we=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:T;return wt(bt(arguments.length>1&&void 0!==arguments[1]?arguments[1]:T),t)},Se=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:T,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:T;return t.transform(we(e,s))},Te=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:T,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:T;return t.transform(we(e,s),!0)},Oe=(t,e,s)=>{const i=we(e,s);return _e(t,wt(i,t.calcOwnMatrix())),i},ke=(t,e)=>{var i;const{transform:{target:r}}=e;null===(i=r.canvas)||void 0===i||i.fire("object:".concat(t),s(s({},e),{},{target:r})),r.fire(t,e)},De={left:-.5,top:-.5,center:0,bottom:.5,right:.5},Me=t=>"string"==typeof t?De[t]:t-.5,Pe="not-allowed";function Ee(t){return Me(t.originX)===Me(D)&&Me(t.originY)===Me(D)}function Ae(t){return.5-Me(t)}const je=(t,e)=>t[e],Fe=(t,e,s,i)=>({e:t,transform:e,pointer:new ot(s,i)});function Le(t,e){const s=t.getTotalAngle()+_t(Math.atan2(e.y,e.x))+360;return Math.round(s%360/45)}function Re(t,e,s,i,r){var n;let{target:o,corner:a}=t;const h=o.controls[a],c=(null===(n=o.canvas)||void 0===n?void 0:n.getZoom())||1,l=o.padding/c,u=function(t,e,s,i){const r=t.getRelativeCenterPoint(),n=void 0!==s&&void 0!==i?t.translateToGivenOrigin(r,D,D,s,i):new ot(t.left,t.top);return(t.angle?e.rotate(-yt(t.angle),r):e).subtract(n)}(o,new ot(i,r),e,s);return u.x>=l&&(u.x-=l),u.x<=-l&&(u.x+=l),u.y>=l&&(u.y-=l),u.y<=l&&(u.y+=l),u.x-=h.offsetX,u.y-=h.offsetY,u}const Ie=(t,e,s,i)=>{const{target:r,offsetX:n,offsetY:o}=e,a=s-n,h=i-o,c=!je(r,"lockMovementX")&&r.left!==a,l=!je(r,"lockMovementY")&&r.top!==h;return c&&r.set(M,a),l&&r.set(P,h),(c||l)&&ke(L,Fe(t,e,s,i)),c||l};class Be{getSvgStyles(t){const e=this.fillRule?this.fillRule:"nonzero",s=this.strokeWidth?this.strokeWidth:"0",i=this.strokeDashArray?this.strokeDashArray.join(" "):j,r=this.strokeDashOffset?this.strokeDashOffset:"0",n=this.strokeLineCap?this.strokeLineCap:"butt",o=this.strokeLineJoin?this.strokeLineJoin:"miter",a=this.strokeMiterLimit?this.strokeMiterLimit:"4",h=void 0!==this.opacity?this.opacity:"1",c=this.visible?"":" visibility: hidden;",l=t?"":this.getSvgFilter(),u=Qt(K,this.fill);return[Qt(J,this.stroke),"stroke-width: ",s,"; ","stroke-dasharray: ",i,"; ","stroke-linecap: ",n,"; ","stroke-dashoffset: ",r,"; ","stroke-linejoin: ",o,"; ","stroke-miterlimit: ",a,"; ",u,"fill-rule: ",e,"; ","opacity: ",h,";",l,c].join("")}getSvgFilter(){return this.shadow?"filter: url(#SVGID_".concat(this.shadow.id,");"):""}getSvgCommons(){return[this.id?'id="'.concat(this.id,'" '):"",this.clipPath?'clip-path="url(#'.concat(this.clipPath.clipPathId,')" '):""].join("")}getSvgTransform(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const s=t?this.calcTransformMatrix():this.calcOwnMatrix(),i='transform="'.concat(Jt(s));return"".concat(i).concat(e,'" ')}_toSVG(t){return[""]}toSVG(t){return this._createBaseSVGMarkup(this._toSVG(t),{reviver:t})}toClipPathSVG(t){return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(t),{reviver:t})}_createBaseClipPathSVGMarkup(t){let{reviver:e,additionalTransform:s=""}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=[this.getSvgTransform(!0,s),this.getSvgCommons()].join(""),r=t.indexOf("COMMON_PARTS");return t[r]=i,e?e(t.join("")):t.join("")}_createBaseSVGMarkup(t){let{noStyle:e,reviver:s,withShadow:i,additionalTransform:r}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=e?"":'style="'.concat(this.getSvgStyles(),'" '),o=i?'style="'.concat(this.getSvgFilter(),'" '):"",a=this.clipPath,h=this.strokeUniform?'vector-effect="non-scaling-stroke" ':"",c=a&&a.absolutePositioned,l=this.stroke,u=this.fill,d=this.shadow,g=[],f=t.indexOf("COMMON_PARTS");let p;a&&(a.clipPathId="CLIPPATH_".concat(ft()),p='\n').concat(a.toClipPathSVG(s),"\n")),c&&g.push("\n"),g.push("\n");const m=[n,h,e?"":this.addPaintOrder()," ",r?'transform="'.concat(r,'" '):""].join("");return t[f]=m,Zt(u)&&g.push(u.toSVG(this)),Zt(l)&&g.push(l.toSVG(this)),d&&g.push(d.toSVG(this)),a&&g.push(p),g.push(t.join("")),g.push("\n"),c&&g.push("\n"),s?s(g.join("")):g.join("")}addPaintOrder(){return this.paintFirst!==K?' paint-order="'.concat(this.paintFirst,'" '):""}}function Xe(t){return new RegExp("^("+t.join("|")+")\\b","i")}var We;const Ye=String.raw(We||(We=r(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"],["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"]))),Ve="http://www.w3.org/2000/svg",He=new RegExp("(normal|italic)?\\s*(normal|small-caps)?\\s*(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*("+Ye+"(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|"+Ye+"))?\\s+(.*)"),ze={cx:M,x:M,r:"radius",cy:P,y:P,display:"visible",visibility:"visible",transform:"transformMatrix","fill-opacity":"fillOpacity","fill-rule":"fillRule","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","letter-spacing":"charSpacing","paint-order":"paintFirst","stroke-dasharray":"strokeDashArray","stroke-dashoffset":"strokeDashOffset","stroke-linecap":"strokeLineCap","stroke-linejoin":"strokeLineJoin","stroke-miterlimit":"strokeMiterLimit","stroke-opacity":"strokeOpacity","stroke-width":"strokeWidth","text-decoration":"textDecoration","text-anchor":"textAnchor",opacity:"opacity","clip-path":"clipPath","clip-rule":"clipRule","vector-effect":"strokeUniform","image-rendering":"imageSmoothing"},Ge="font-size",Ne="clip-path",Ue=Xe(["path","circle","polygon","polyline","ellipse","rect","line","image","text"]),qe=Xe(["symbol","image","marker","pattern","view","svg"]),Ke=Xe(["symbol","g","a","svg","clipPath","defs"]),Je=new RegExp("^\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*,?\\s*("+Ye+"+)\\s*$"),Qe=new ot(1,0),Ze=new ot,$e=(t,e)=>t.rotate(e),ts=(t,e)=>new ot(e).subtract(t),es=t=>t.distanceFrom(Ze),ss=(t,e)=>Math.atan2(os(t,e),as(t,e)),is=t=>ss(Qe,t),rs=t=>t.eq(Ze)?t:t.scalarDivide(es(t)),ns=function(t){let e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return rs(new ot(-t.y,t.x).scalarMultiply(e?1:-1))},os=(t,e)=>t.x*e.y-t.y*e.x,as=(t,e)=>t.x*e.x+t.y*e.y,hs=(t,e,s)=>{if(t.eq(e)||t.eq(s))return!0;const i=os(e,s),r=os(e,t),n=os(s,t);return i>=0?r>=0&&n<=0:!(r<=0&&n>=0)},cs="(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?",ls=new RegExp("(?:\\s|^)"+cs+cs+"("+Ye+"?(?:px)?)?(?:\\s?|$)(?:$|\\s)");class us{constructor(t){const e="string"==typeof t?us.parseShadow(t):t;Object.assign(this,us.ownDefaults,e),this.id=ft()}static parseShadow(t){const e=t.trim(),[,s=0,i=0,r=0]=(ls.exec(e)||[]).map((t=>parseFloat(t)||0));return{color:(e.replace(ls,"")||"rgb(0,0,0)").trim(),offsetX:s,offsetY:i,blur:r}}toString(){return[this.offsetX,this.offsetY,this.blur,this.color].join("px ")}toSVG(t){const e=$e(new ot(this.offsetX,this.offsetY),yt(-t.angle)),s=new Nt(this.color);let i=40,r=40;return t.width&&t.height&&(i=100*Ut((Math.abs(e.x)+this.blur)/t.width,o.NUM_FRACTION_DIGITS)+20,r=100*Ut((Math.abs(e.y)+this.blur)/t.height,o.NUM_FRACTION_DIGITS)+20),t.flipX&&(e.x*=-1),t.flipY&&(e.y*=-1),'\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n')}toObject(){const t={color:this.color,blur:this.blur,offsetX:this.offsetX,offsetY:this.offsetY,affectStroke:this.affectStroke,nonScaling:this.nonScaling,type:this.constructor.type},e=us.ownDefaults;return this.includeDefaultValues?t:Xt(t,((t,s)=>t!==e[s]))}static async fromObject(t){return new this(t)}}t(us,"ownDefaults",{color:"rgb(0,0,0)",blur:0,offsetX:0,offsetY:0,affectStroke:!1,includeDefaultValues:!0,nonScaling:!1}),t(us,"type","shadow"),tt.setClass(us,"shadow");const ds=(t,e,s)=>Math.max(t,Math.min(e,s)),gs=[P,M,G,N,"flipX","flipY","originX","originY","angle","opacity","globalCompositeOperation","shadow","visible",U,q],fs=[K,J,"strokeWidth","strokeDashArray","width","height","paintFirst","strokeUniform","strokeLineCap","strokeDashOffset","strokeLineJoin","strokeMiterLimit","backgroundColor","clipPath"],ps={top:0,left:0,width:0,height:0,angle:0,flipX:!1,flipY:!1,scaleX:1,scaleY:1,minScaleLimit:0,skewX:0,skewY:0,originX:M,originY:P,strokeWidth:1,strokeUniform:!1,padding:0,opacity:1,paintFirst:K,fill:"rgb(0,0,0)",fillRule:"nonzero",stroke:null,strokeDashArray:null,strokeDashOffset:0,strokeLineCap:"butt",strokeLineJoin:"miter",strokeMiterLimit:4,globalCompositeOperation:"source-over",backgroundColor:"",shadow:null,visible:!0,includeDefaultValues:!0,excludeFromExport:!1,objectCaching:!0,clipPath:void 0,inverted:!1,absolutePositioned:!1,centeredRotation:!0,centeredScaling:!1,dirty:!0},ms=(t,e,s,i)=>(tt*Math.pow(2,10*(i-=1))*Math.sin((i*r-e)*w/s),ys=(t,e,s,i)=>-s*Math.cos(t/i*b)+s+e,_s=(t,e,s,i)=>(t/=i)<1/2.75?s*(7.5625*t*t)+e:t<2/2.75?s*(7.5625*(t-=1.5/2.75)*t+.75)+e:t<2.5/2.75?s*(7.5625*(t-=2.25/2.75)*t+.9375)+e:s*(7.5625*(t-=2.625/2.75)*t+.984375)+e,xs=(t,e,s,i)=>s-_s(i-t,0,s,i)+e;var Cs=Object.freeze({__proto__:null,defaultEasing:ys,easeInBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return s*(t/=i)*t*((r+1)*t-r)+e},easeInBounce:xs,easeInCirc:(t,e,s,i)=>-s*(Math.sqrt(1-(t/=i)*t)-1)+e,easeInCubic:(t,e,s,i)=>s*(t/i)**3+e,easeInElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(1===(t/=i))return e+s;n||(n=.3*i);const{a:o,s:a,p:h}=ms(r,s,n,1.70158);return-vs(o,a,h,t,i)+e},easeInExpo:(t,e,s,i)=>0===t?e:s*2**(10*(t/i-1))+e,easeInOutBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return(t/=i/2)<1?s/2*(t*t*((1+(r*=1.525))*t-r))+e:s/2*((t-=2)*t*((1+(r*=1.525))*t+r)+2)+e},easeInOutBounce:(t,e,s,i)=>t(t/=i/2)<1?-s/2*(Math.sqrt(1-t**2)-1)+e:s/2*(Math.sqrt(1-(t-=2)*t)+1)+e,easeInOutCubic:(t,e,s,i)=>(t/=i/2)<1?s/2*t**3+e:s/2*((t-2)**3+2)+e,easeInOutElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(2===(t/=i/2))return e+s;n||(n=i*(.3*1.5));const{a:o,s:a,p:h,c:c}=ms(r,s,n,1.70158);return t<1?-.5*vs(o,a,h,t,i)+e:o*Math.pow(2,-10*(t-=1))*Math.sin((t*i-a)*w/h)*.5+c+e},easeInOutExpo:(t,e,s,i)=>0===t?e:t===i?e+s:(t/=i/2)<1?s/2*2**(10*(t-1))+e:s/2*-(2**(-10*--t)+2)+e,easeInOutQuad:(t,e,s,i)=>(t/=i/2)<1?s/2*t**2+e:-s/2*(--t*(t-2)-1)+e,easeInOutQuart:(t,e,s,i)=>(t/=i/2)<1?s/2*t**4+e:-s/2*((t-=2)*t**3-2)+e,easeInOutQuint:(t,e,s,i)=>(t/=i/2)<1?s/2*t**5+e:s/2*((t-2)**5+2)+e,easeInOutSine:(t,e,s,i)=>-s/2*(Math.cos(Math.PI*t/i)-1)+e,easeInQuad:(t,e,s,i)=>s*(t/=i)*t+e,easeInQuart:(t,e,s,i)=>s*(t/=i)*t**3+e,easeInQuint:(t,e,s,i)=>s*(t/i)**5+e,easeInSine:(t,e,s,i)=>-s*Math.cos(t/i*b)+s+e,easeOutBack:function(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1.70158;return s*((t=t/i-1)*t*((r+1)*t+r)+1)+e},easeOutBounce:_s,easeOutCirc:(t,e,s,i)=>s*Math.sqrt(1-(t=t/i-1)*t)+e,easeOutCubic:(t,e,s,i)=>s*((t/i-1)**3+1)+e,easeOutElastic:(t,e,s,i)=>{const r=s;let n=0;if(0===t)return e;if(1===(t/=i))return e+s;n||(n=.3*i);const{a:o,s:a,p:h,c:c}=ms(r,s,n,1.70158);return o*2**(-10*t)*Math.sin((t*i-a)*w/h)+c+e},easeOutExpo:(t,e,s,i)=>t===i?e+s:s*-(2**(-10*t/i)+1)+e,easeOutQuad:(t,e,s,i)=>-s*(t/=i)*(t-2)+e,easeOutQuart:(t,e,s,i)=>-s*((t=t/i-1)*t**3-1)+e,easeOutQuint:(t,e,s,i)=>s*((t/i-1)**5+1)+e,easeOutSine:(t,e,s,i)=>s*Math.sin(t/i*b)+e});const bs=()=>!1;class ws{constructor(e){let{startValue:s,byValue:i,duration:r=500,delay:n=0,easing:o=ys,onStart:a=C,onChange:h=C,onComplete:c=C,abort:l=bs,target:u}=e;t(this,"_state","pending"),t(this,"durationProgress",0),t(this,"valueProgress",0),this.tick=this.tick.bind(this),this.duration=r,this.delay=n,this.easing=o,this._onStart=a,this._onChange=h,this._onComplete=c,this._abort=l,this.target=u,this.startValue=s,this.byValue=i,this.value=this.startValue,this.endValue=Object.freeze(this.calculate(this.duration).value)}get state(){return this._state}isDone(){return"aborted"===this._state||"completed"===this._state}start(){const t=t=>{"pending"===this._state&&(this.startTime=t||+new Date,this._state="running",this._onStart(),this.tick(this.startTime))};this.register(),this.delay>0?setTimeout((()=>ut(t)),this.delay):ut(t)}tick(t){const e=(t||+new Date)-this.startTime,s=Math.min(e,this.duration);this.durationProgress=s/this.duration;const{value:i,valueProgress:r}=this.calculate(s);this.value=Object.freeze(i),this.valueProgress=r,"aborted"!==this._state&&(this._abort(this.value,this.valueProgress,this.durationProgress)?(this._state="aborted",this.unregister()):e>=this.duration?(this.durationProgress=this.valueProgress=1,this._onChange(this.endValue,this.valueProgress,this.durationProgress),this._state="completed",this._onComplete(this.endValue,this.valueProgress,this.durationProgress),this.unregister()):(this._onChange(this.value,this.valueProgress,this.durationProgress),ut(this.tick)))}register(){et.push(this)}unregister(){et.remove(this)}abort(){this._state="aborted",this.unregister()}}const Ss=["startValue","endValue"];class Ts extends ws{constructor(t){let{startValue:e=0,endValue:r=100}=t;super(s(s({},i(t,Ss)),{},{startValue:e,byValue:r-e}))}calculate(t){const e=this.easing(t,this.startValue,this.byValue,this.duration);return{value:e,valueProgress:Math.abs((e-this.startValue)/this.byValue)}}}const Os=["startValue","endValue"];class ks extends ws{constructor(t){let{startValue:e=[0],endValue:r=[100]}=t;super(s(s({},i(t,Os)),{},{startValue:e,byValue:r.map(((t,s)=>t-e[s]))}))}calculate(t){const e=this.startValue.map(((e,s)=>this.easing(t,e,this.byValue[s],this.duration,s)));return{value:e,valueProgress:Math.abs((e[0]-this.startValue[0])/this.byValue[0])}}}const Ds=["startValue","endValue","easing","onChange","onComplete","abort"],Ms=(t,e,s,i)=>e+s*(1-Math.cos(t/i*b)),Ps=t=>t&&((e,s,i)=>t(new Nt(e).toRgba(),s,i));class Es extends ws{constructor(t){let{startValue:e,endValue:r,easing:n=Ms,onChange:o,onComplete:a,abort:h}=t,c=i(t,Ds);const l=new Nt(e).getSource(),u=new Nt(r).getSource();super(s(s({},c),{},{startValue:l,byValue:u.map(((t,e)=>t-l[e])),easing:n,onChange:Ps(o),onComplete:Ps(a),abort:Ps(h)}))}calculate(t){const[e,s,i,r]=this.startValue.map(((e,s)=>this.easing(t,e,this.byValue[s],this.duration,s))),n=[...[e,s,i].map(Math.round),ds(0,r,1)];return{value:n,valueProgress:n.map(((t,e)=>0!==this.byValue[e]?Math.abs((t-this.startValue[e])/this.byValue[e]):0)).find((t=>0!==t))||0}}}function As(t){const e=(t=>Array.isArray(t.startValue)||Array.isArray(t.endValue))(t)?new ks(t):new Ts(t);return e.start(),e}function js(t){const e=new Es(t);return e.start(),e}class Fs{constructor(t){this.status=t,this.points=[]}includes(t){return this.points.some((e=>e.eq(t)))}append(){for(var t=arguments.length,e=new Array(t),s=0;s!this.includes(t)))),this}static isPointContained(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(e.eq(s))return t.eq(e);if(e.x===s.x)return t.x===e.x&&(i||t.y>=Math.min(e.y,s.y)&&t.y<=Math.max(e.y,s.y));if(e.y===s.y)return t.y===e.y&&(i||t.x>=Math.min(e.x,s.x)&&t.x<=Math.max(e.x,s.x));{const r=ts(e,s),n=ts(e,t).divide(r);return i?Math.abs(n.x)===Math.abs(n.y):n.x===n.y&&n.x>=0&&n.x<=1}}static isPointInPolygon(t,e){const s=new ot(t).setX(Math.min(t.x-1,...e.map((t=>t.x))));let i=0;for(let r=0;r4&&void 0!==arguments[4])||arguments[4],n=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];const o=e.x-t.x,a=e.y-t.y,h=i.x-s.x,c=i.y-s.y,l=t.x-s.x,u=t.y-s.y,d=h*u-c*l,g=o*u-a*l,f=c*o-h*a;if(0!==f){const e=d/f,s=g/f;return(r||0<=e&&e<=1)&&(n||0<=s&&s<=1)?new Fs("Intersection").append(new ot(t.x+e*o,t.y+e*a)):new Fs}if(0===d||0===g){const o=r||n||Fs.isPointContained(t,s,i)||Fs.isPointContained(e,s,i)||Fs.isPointContained(s,t,e)||Fs.isPointContained(i,t,e);return new Fs(o?"Coincident":void 0)}return new Fs("Parallel")}static intersectSegmentLine(t,e,s,i){return Fs.intersectLineLine(t,e,s,i,!1,!0)}static intersectSegmentSegment(t,e,s,i){return Fs.intersectLineLine(t,e,s,i,!1,!1)}static intersectLinePolygon(t,e,s){let i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];const r=new Fs,n=s.length;for(let o,a,h,c=0;c0&&(r.status="Intersection"),r}static intersectSegmentPolygon(t,e,s){return Fs.intersectLinePolygon(t,e,s,!1)}static intersectPolygonPolygon(t,e){const s=new Fs,i=t.length,r=[];for(let n=0;n0&&r.length===t.length?new Fs("Coincident"):(s.points.length>0&&(s.status="Intersection"),s)}static intersectPolygonRectangle(t,e,s){const i=e.min(s),r=e.max(s),n=new ot(r.x,i.y),o=new ot(i.x,r.y);return Fs.intersectPolygonPolygon(t,[i,n,r,o])}}class Ls extends lt{getX(){return this.getXY().x}setX(t){this.setXY(this.getXY().setX(t))}getY(){return this.getXY().y}setY(t){this.setXY(this.getXY().setY(t))}getRelativeX(){return this.left}setRelativeX(t){this.left=t}getRelativeY(){return this.top}setRelativeY(t){this.top=t}getXY(){const t=this.getRelativeXY();return this.group?Ct(t,this.group.calcTransformMatrix()):t}setXY(t,e,s){this.group&&(t=Ct(t,bt(this.group.calcTransformMatrix()))),this.setRelativeXY(t,e,s)}getRelativeXY(){return new ot(this.left,this.top)}setRelativeXY(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.originX,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.originY;this.setPositionByOrigin(t,e,s)}isStrokeAccountedForInDimensions(){return!1}getCoords(){const{tl:t,tr:e,br:s,bl:i}=this.aCoords||(this.aCoords=this.calcACoords()),r=[t,e,s,i];if(this.group){const t=this.group.calcTransformMatrix();return r.map((e=>Ct(e,t)))}return r}intersectsWithRect(t,e){return"Intersection"===Fs.intersectPolygonRectangle(this.getCoords(),t,e).status}intersectsWithObject(t){const e=Fs.intersectPolygonPolygon(this.getCoords(),t.getCoords());return"Intersection"===e.status||"Coincident"===e.status||t.isContainedWithinObject(this)||this.isContainedWithinObject(t)}isContainedWithinObject(t){return this.getCoords().every((e=>t.containsPoint(e)))}isContainedWithinRect(t,e){const{left:s,top:i,width:r,height:n}=this.getBoundingRect();return s>=t.x&&s+r<=e.x&&i>=t.y&&i+n<=e.y}isOverlapping(t){return this.intersectsWithObject(t)||this.isContainedWithinObject(t)||t.isContainedWithinObject(this)}containsPoint(t){return Fs.isPointInPolygon(t,this.getCoords())}isOnScreen(){if(!this.canvas)return!1;const{tl:t,br:e}=this.canvas.vptCoords;return!!this.getCoords().some((s=>s.x<=e.x&&s.x>=t.x&&s.y<=e.y&&s.y>=t.y))||(!!this.intersectsWithRect(t,e)||this.containsPoint(t.midPointFrom(e)))}isPartiallyOnScreen(){if(!this.canvas)return!1;const{tl:t,br:e}=this.canvas.vptCoords;if(this.intersectsWithRect(t,e))return!0;return this.getCoords().every((s=>(s.x>=e.x||s.x<=t.x)&&(s.y>=e.y||s.y<=t.y)))&&this.containsPoint(t.midPointFrom(e))}getBoundingRect(){return me(this.getCoords())}getScaledWidth(){return this._getTransformedDimensions().x}getScaledHeight(){return this._getTransformedDimensions().y}scale(t){this._set(G,t),this._set(N,t),this.setCoords()}scaleToWidth(t){const e=this.getBoundingRect().width/this.getScaledWidth();return this.scale(t/this.width/e)}scaleToHeight(t){const e=this.getBoundingRect().height/this.getScaledHeight();return this.scale(t/this.height/e)}getCanvasRetinaScaling(){var t;return(null===(t=this.canvas)||void 0===t?void 0:t.getRetinaScaling())||1}getTotalAngle(){return this.group?_t(Tt(this.calcTransformMatrix())):this.angle}getViewportTransform(){var t;return(null===(t=this.canvas)||void 0===t?void 0:t.viewportTransform)||T.concat()}calcACoords(){const t=Dt({angle:this.angle}),{x:e,y:s}=this.getRelativeCenterPoint(),i=kt(e,s),r=wt(i,t),n=this._getTransformedDimensions(),o=n.x/2,a=n.y/2;return{tl:Ct({x:-o,y:-a},r),tr:Ct({x:o,y:-a},r),bl:Ct({x:-o,y:a},r),br:Ct({x:o,y:a},r)}}setCoords(){this.aCoords=this.calcACoords()}transformMatrixKey(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=[];return!t&&this.group&&(e=this.group.transformMatrixKey(t)),e.push(this.top,this.left,this.width,this.height,this.scaleX,this.scaleY,this.angle,this.strokeWidth,this.skewX,this.skewY,+this.flipX,+this.flipY,Me(this.originX),Me(this.originY)),e}calcTransformMatrix(){let t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],e=this.calcOwnMatrix();if(t||!this.group)return e;const s=this.transformMatrixKey(t),i=this.matrixCache;return i&&i.key.every(((t,e)=>t===s[e]))?i.value:(this.group&&(e=wt(this.group.calcTransformMatrix(!1),e)),this.matrixCache={key:s,value:e},e)}calcOwnMatrix(){const t=this.transformMatrixKey(!0),e=this.ownMatrixCache;if(e&&e.key===t)return e.value;const s=this.getRelativeCenterPoint(),i={angle:this.angle,translateX:s.x,translateY:s.y,scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,flipX:this.flipX,flipY:this.flipY},r=Ft(i);return this.ownMatrixCache={key:t,value:r},r}_getNonTransformedDimensions(){return new ot(this.width,this.height).scalarAdd(this.strokeWidth)}_calculateCurrentDimensions(t){return this._getTransformedDimensions(t).transform(this.getViewportTransform(),!0).scalarAdd(2*this.padding)}_getTransformedDimensions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const e=s({scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,width:this.width,height:this.height,strokeWidth:this.strokeWidth},t),i=e.strokeWidth;let r=i,n=0;this.strokeUniform&&(r=0,n=i);const o=e.width+r,a=e.height+r;let h;return h=0===e.skewX&&0===e.skewY?new ot(o*e.scaleX,a*e.scaleY):be(o,a,jt(e)),h.scalarAdd(n)}translateToGivenOrigin(t,e,s,i,r){let n=t.x,o=t.y;const a=Me(i)-Me(e),h=Me(r)-Me(s);if(a||h){const t=this._getTransformedDimensions();n+=a*t.x,o+=h*t.y}return new ot(n,o)}translateToCenterPoint(t,e,s){if(e===D&&s===D)return t;const i=this.translateToGivenOrigin(t,e,s,D,D);return this.angle?i.rotate(yt(this.angle),t):i}translateToOriginPoint(t,e,s){const i=this.translateToGivenOrigin(t,D,D,e,s);return this.angle?i.rotate(yt(this.angle),t):i}getCenterPoint(){const t=this.getRelativeCenterPoint();return this.group?Ct(t,this.group.calcTransformMatrix()):t}getRelativeCenterPoint(){return this.translateToCenterPoint(new ot(this.left,this.top),this.originX,this.originY)}getPointByOrigin(t,e){return this.translateToOriginPoint(this.getRelativeCenterPoint(),t,e)}setPositionByOrigin(t,e,s){const i=this.translateToCenterPoint(t,e,s),r=this.translateToOriginPoint(i,this.originX,this.originY);this.set({left:r.x,top:r.y})}_getLeftTopCoords(){return this.translateToOriginPoint(this.getRelativeCenterPoint(),M,P)}}const Rs=["type"],Is=["extraParam"];let Bs=class e extends Ls{static getDefaults(){return e.ownDefaults}get type(){const t=this.constructor.type;return"FabricObject"===t?"object":t.toLowerCase()}set type(t){a("warn","Setting type has no effect",t)}constructor(s){super(),t(this,"_cacheContext",null),Object.assign(this,e.ownDefaults),this.setOptions(s)}_createCacheCanvas(){this._cacheCanvas=pt(),this._cacheContext=this._cacheCanvas.getContext("2d"),this._updateCacheCanvas(),this.dirty=!0}_limitCacheSize(t){const e=t.width,s=t.height,i=o.maxCacheSideLimit,r=o.minCacheSideLimit;if(e<=i&&s<=i&&e*s<=o.perfLimitSizeTotal)return ec&&(t.zoomX/=e/c,t.width=c,t.capped=!0),s>l&&(t.zoomY/=s/l,t.height=l,t.capped=!0),t}_getCacheCanvasDimensions(){const t=this.getTotalObjectScaling(),e=this._getTransformedDimensions({skewX:0,skewY:0}),s=e.x*t.x/this.scaleX,i=e.y*t.y/this.scaleY;return{width:s+2,height:i+2,zoomX:t.x,zoomY:t.y,x:s,y:i}}_updateCacheCanvas(){const t=this._cacheCanvas,e=this._cacheContext,s=this._limitCacheSize(this._getCacheCanvasDimensions()),i=o.minCacheSideLimit,r=s.width,n=s.height,a=s.zoomX,h=s.zoomY,c=r!==t.width||n!==t.height,l=this.zoomX!==a||this.zoomY!==h;if(!t||!e)return!1;let u,d,g=c||l,f=0,p=0,m=!1;if(c){const t=this._cacheCanvas.width,e=this._cacheCanvas.height,o=r>t||n>e;m=o||(r<.9*t||n<.9*e)&&t>i&&e>i,o&&!s.capped&&(r>i||n>i)&&(f=.1*r,p=.1*n)}return ee(this)&&this.path&&(g=!0,m=!0,f+=this.getHeightOfLine(0)*this.zoomX,p+=this.getHeightOfLine(0)*this.zoomY),!!g&&(m?(t.width=Math.ceil(r+f),t.height=Math.ceil(n+p)):(e.setTransform(1,0,0,1,0,0),e.clearRect(0,0,t.width,t.height)),u=s.x/2,d=s.y/2,this.cacheTranslationX=Math.round(t.width/2-u)+u,this.cacheTranslationY=Math.round(t.height/2-d)+d,e.translate(this.cacheTranslationX,this.cacheTranslationY),e.scale(a,h),this.zoomX=a,this.zoomY=h,!0)}setOptions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this._setOptions(t)}transform(t){const e=this.group&&!this.group._transformDone||this.group&&this.canvas&&t===this.canvas.contextTop,s=this.calcTransformMatrix(!e);t.transform(s[0],s[1],s[2],s[3],s[4],s[5])}getObjectScaling(){if(!this.group)return new ot(Math.abs(this.scaleX),Math.abs(this.scaleY));const t=Ot(this.calcTransformMatrix());return new ot(Math.abs(t.scaleX),Math.abs(t.scaleY))}getTotalObjectScaling(){const t=this.getObjectScaling();if(this.canvas){const e=this.canvas.getZoom(),s=this.getCanvasRetinaScaling();return t.scalarMultiply(e*s)}return t}getObjectOpacity(){let t=this.opacity;return this.group&&(t*=this.group.getObjectOpacity()),t}_constrainScale(t){return Math.abs(t)0&&void 0!==arguments[0]&&arguments[0];if(this.isNotVisible())return!1;const e=this._cacheCanvas,s=this._cacheContext;return!(!e||!s||t||!this._updateCacheCanvas())||!!(this.dirty||this.clipPath&&this.clipPath.absolutePositioned)&&(e&&s&&!t&&(s.save(),s.setTransform(1,0,0,1,0,0),s.clearRect(0,0,e.width,e.height),s.restore()),!0)}_renderBackground(t){if(!this.backgroundColor)return;const e=this._getNonTransformedDimensions();t.fillStyle=this.backgroundColor,t.fillRect(-e.x/2,-e.y/2,e.x,e.y),this._removeShadow(t)}_setOpacity(t){this.group&&!this.group._transformDone?t.globalAlpha=this.getObjectOpacity():t.globalAlpha*=this.opacity}_setStrokeStyles(t,e){const s=e.stroke;s&&(t.lineWidth=e.strokeWidth,t.lineCap=e.strokeLineCap,t.lineDashOffset=e.strokeDashOffset,t.lineJoin=e.strokeLineJoin,t.miterLimit=e.strokeMiterLimit,Zt(s)?"percentage"===s.gradientUnits||s.gradientTransform||s.patternTransform?this._applyPatternForTransformedGradient(t,s):(t.strokeStyle=s.toLive(t),this._applyPatternGradientTransform(t,s)):t.strokeStyle=e.stroke)}_setFillStyles(t,e){let{fill:s}=e;s&&(Zt(s)?(t.fillStyle=s.toLive(t),this._applyPatternGradientTransform(t,s)):t.fillStyle=s)}_setClippingProperties(t){t.globalAlpha=1,t.strokeStyle="transparent",t.fillStyle="#000000"}_setLineDash(t,e){e&&0!==e.length&&(1&e.length&&e.push(...e),t.setLineDash(e))}_setShadow(t){if(!this.shadow)return;const e=this.shadow,s=this.canvas,i=this.getCanvasRetinaScaling(),[r,,,n]=(null==s?void 0:s.viewportTransform)||T,a=r*i,h=n*i,c=e.nonScaling?new ot(1,1):this.getObjectScaling();t.shadowColor=e.color,t.shadowBlur=e.blur*o.browserShadowBlurConstant*(a+h)*(c.x+c.y)/4,t.shadowOffsetX=e.offsetX*a*c.x,t.shadowOffsetY=e.offsetY*h*c.y}_removeShadow(t){this.shadow&&(t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0)}_applyPatternGradientTransform(t,e){if(!Zt(e))return{offsetX:0,offsetY:0};const s=e.gradientTransform||e.patternTransform,i=-this.width/2+e.offsetX||0,r=-this.height/2+e.offsetY||0;return"percentage"===e.gradientUnits?t.transform(this.width,0,0,this.height,i,r):t.transform(1,0,0,1,i,r),s&&t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),{offsetX:i,offsetY:r}}_renderPaintInOrder(t){this.paintFirst===J?(this._renderStroke(t),this._renderFill(t)):(this._renderFill(t),this._renderStroke(t))}_render(t){}_renderFill(t){this.fill&&(t.save(),this._setFillStyles(t,this),"evenodd"===this.fillRule?t.fill("evenodd"):t.fill(),t.restore())}_renderStroke(t){if(this.stroke&&0!==this.strokeWidth){if(this.shadow&&!this.shadow.affectStroke&&this._removeShadow(t),t.save(),this.strokeUniform){const e=this.getObjectScaling();t.scale(1/e.x,1/e.y)}this._setLineDash(t,this.strokeDashArray),this._setStrokeStyles(t,this),t.stroke(),t.restore()}}_applyPatternForTransformedGradient(t,e){var s;const i=this._limitCacheSize(this._getCacheCanvasDimensions()),r=pt(),n=this.getCanvasRetinaScaling(),o=i.x/this.scaleX/n,a=i.y/this.scaleY/n;r.width=Math.ceil(o),r.height=Math.ceil(a);const h=r.getContext("2d");h&&(h.beginPath(),h.moveTo(0,0),h.lineTo(o,0),h.lineTo(o,a),h.lineTo(0,a),h.closePath(),h.translate(o/2,a/2),h.scale(i.zoomX/this.scaleX/n,i.zoomY/this.scaleY/n),this._applyPatternGradientTransform(h,e),h.fillStyle=e.toLive(t),h.fill(),t.translate(-this.width/2-this.strokeWidth/2,-this.height/2-this.strokeWidth/2),t.scale(n*this.scaleX/i.zoomX,n*this.scaleY/i.zoomY),t.strokeStyle=null!==(s=h.createPattern(r,"no-repeat"))&&void 0!==s?s:"")}_findCenterFromElement(){return new ot(this.left+this.width/2,this.top+this.height/2)}clone(t){const e=this.toObject(t);return this.constructor.fromObject(e)}cloneAsImage(t){const e=this.toCanvasElement(t);return new(tt.getClass("image"))(e)}toCanvasElement(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const e=Ce(this),s=this.group,i=this.shadow,r=Math.abs,n=t.enableRetinaScaling?y():1,o=(t.multiplier||1)*n,a=t.canvasProvider||(t=>new ue(t,{enableRetinaScaling:!1,renderOnAddRemove:!1,skipOffscreen:!1}));delete this.group,t.withoutTransform&&xe(this),t.withoutShadow&&(this.shadow=null),t.viewportTransform&&Oe(this,this.getViewportTransform()),this.setCoords();const h=pt(),c=this.getBoundingRect(),l=this.shadow,u=new ot;if(l){const t=l.blur,e=l.nonScaling?new ot(1,1):this.getObjectScaling();u.x=2*Math.round(r(l.offsetX)+t)*r(e.x),u.y=2*Math.round(r(l.offsetY)+t)*r(e.y)}const d=c.width+u.x,g=c.height+u.y;h.width=Math.ceil(d),h.height=Math.ceil(g);const f=a(h);"jpeg"===t.format&&(f.backgroundColor="#fff"),this.setPositionByOrigin(new ot(f.width/2,f.height/2),D,D);const p=this.canvas;f._objects=[this],this.set("canvas",f),this.setCoords();const m=f.toCanvasElement(o||1,t);return this.set("canvas",p),this.shadow=i,s&&(this.group=s),this.set(e),this.setCoords(),f._objects=[],f.destroy(),m}toDataURL(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return vt(this.toCanvasElement(t),t.format||"png",t.quality||1)}isType(){for(var t=arguments.length,e=new Array(t),s=0;s{let[i,r]=s;return t[i]=this._animate(i,r,e),t}),{})}_animate(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=t.split("."),n=this.constructor.colorProperties.includes(r[r.length-1]),{abort:o,startValue:a,onChange:h,onComplete:c}=i,l=s(s({},i),{},{target:this,startValue:null!=a?a:r.reduce(((t,e)=>t[e]),this),endValue:e,abort:null==o?void 0:o.bind(this),onChange:(t,e,s)=>{r.reduce(((e,s,i)=>(i===r.length-1&&(e[s]=t),e[s])),this),h&&h(t,e,s)},onComplete:(t,e,s)=>{this.setCoords(),c&&c(t,e,s)}});return n?js(l):As(l)}isDescendantOf(t){const{parent:e,group:s}=this;return e===t||s===t||!!e&&e.isDescendantOf(t)||!!s&&s!==e&&s.isDescendantOf(t)}getAncestors(){const t=[];let e=this;do{e=e.parent,e&&t.push(e)}while(e);return t}findCommonAncestors(t){if(this===t)return{fork:[],otherFork:[],common:[this,...this.getAncestors()]};const e=this.getAncestors(),s=t.getAncestors();if(0===e.length&&s.length>0&&this===s[s.length-1])return{fork:[],otherFork:[t,...s.slice(0,s.length-1)],common:[this]};for(let i,r=0;r-1&&n>o}toObject(){const t=(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).concat(e.customProperties,this.constructor.customProperties||[]);let i;const r=o.NUM_FRACTION_DIGITS,{clipPath:n,fill:a,stroke:h,shadow:c,strokeDashArray:l,left:u,top:d,originX:g,originY:f,width:p,height:m,strokeWidth:v,strokeLineCap:y,strokeDashOffset:_,strokeLineJoin:C,strokeUniform:b,strokeMiterLimit:w,scaleX:S,scaleY:T,angle:O,flipX:k,flipY:D,opacity:M,visible:P,backgroundColor:E,fillRule:A,paintFirst:j,globalCompositeOperation:F,skewX:L,skewY:R}=this;n&&!n.excludeFromExport&&(i=n.toObject(t.concat("inverted","absolutePositioned")));const I=t=>Ut(t,r),B=s(s({},Bt(this,t)),{},{type:this.constructor.type,version:x,originX:g,originY:f,left:I(u),top:I(d),width:I(p),height:I(m),fill:$t(a)?a.toObject():a,stroke:$t(h)?h.toObject():h,strokeWidth:I(v),strokeDashArray:l?l.concat():l,strokeLineCap:y,strokeDashOffset:_,strokeLineJoin:C,strokeUniform:b,strokeMiterLimit:I(w),scaleX:I(S),scaleY:I(T),angle:I(O),flipX:k,flipY:D,opacity:I(M),shadow:c?c.toObject():c,visible:P,backgroundColor:E,fillRule:A,paintFirst:j,globalCompositeOperation:F,skewX:I(L),skewY:I(R)},i?{clipPath:i}:null);return this.includeDefaultValues?B:this._removeDefaultValues(B)}toDatalessObject(t){return this.toObject(t)}_removeDefaultValues(t){const e=this.constructor.getDefaults(),s=Object.keys(e).length>0?e:Object.getPrototypeOf(this);return Xt(t,((t,e)=>{if(e===M||e===P||"type"===e)return!0;const i=s[e];return t!==i&&!(Array.isArray(t)&&Array.isArray(i)&&0===t.length&&0===i.length)}))}toString(){return"#<".concat(this.constructor.type,">")}static _fromObject(t){let e=i(t,Rs),s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{extraParam:r}=s,n=i(s,Is);return It(e,n).then((t=>r?(delete t[r],new this(e[r],t)):new this(t)))}static fromObject(t,e){return this._fromObject(t,e)}};t(Bs,"stateProperties",gs),t(Bs,"cacheProperties",fs),t(Bs,"ownDefaults",ps),t(Bs,"type","FabricObject"),t(Bs,"colorProperties",[K,J,"backgroundColor"]),t(Bs,"customProperties",[]),tt.setClass(Bs),tt.setClass(Bs,"object");const Xs=(t,e,i)=>(r,n,o,a)=>{const h=e(r,n,o,a);return h&&ke(t,s(s({},Fe(r,n,o,a)),i)),h};function Ws(t){return(e,s,i,r)=>{const{target:n,originX:o,originY:a}=s,h=n.getRelativeCenterPoint(),c=n.translateToOriginPoint(h,o,a),l=t(e,s,i,r);return n.setPositionByOrigin(c,s.originX,s.originY),l}}const Ys=Xs(W,Ws(((t,e,s,i)=>{const r=Re(e,e.originX,e.originY,s,i);if(Me(e.originX)===Me(D)||Me(e.originX)===Me(A)&&r.x<0||Me(e.originX)===Me(M)&&r.x>0){const{target:t}=e,s=t.strokeWidth/(t.strokeUniform?t.scaleX:1),i=Ee(e)?2:1,n=t.width,o=Math.ceil(Math.abs(r.x*i/t.scaleX)-s);return t.set("width",Math.max(o,0)),n!==t.width}return!1})));function Vs(t,e,s,i,r){i=i||{};const n=this.sizeX||i.cornerSize||r.cornerSize,o=this.sizeY||i.cornerSize||r.cornerSize,a=void 0!==i.transparentCorners?i.transparentCorners:r.transparentCorners,h=a?J:K,c=!a&&(i.cornerStrokeColor||r.cornerStrokeColor);let l,u=e,d=s;t.save(),t.fillStyle=i.cornerColor||r.cornerColor||"",t.strokeStyle=i.cornerStrokeColor||r.cornerStrokeColor||"",n>o?(l=n,t.scale(1,o/n),d=s*n/o):o>n?(l=o,t.scale(n/o,1),u=e*o/n):l=n,t.lineWidth=1,t.beginPath(),t.arc(u,d,l/2,0,w,!1),t[h](),c&&t.stroke(),t.restore()}function Hs(t,e,s,i,r){i=i||{};const n=this.sizeX||i.cornerSize||r.cornerSize,o=this.sizeY||i.cornerSize||r.cornerSize,a=void 0!==i.transparentCorners?i.transparentCorners:r.transparentCorners,h=a?J:K,c=!a&&(i.cornerStrokeColor||r.cornerStrokeColor),l=n/2,u=o/2;t.save(),t.fillStyle=i.cornerColor||r.cornerColor||"",t.strokeStyle=i.cornerStrokeColor||r.cornerStrokeColor||"",t.lineWidth=1,t.translate(e,s);const d=r.getTotalAngle();t.rotate(yt(d)),t["".concat(h,"Rect")](-l,-u,n,o),c&&t.strokeRect(-l,-u,n,o),t.restore()}class zs{constructor(e){t(this,"visible",!0),t(this,"actionName",z),t(this,"angle",0),t(this,"x",0),t(this,"y",0),t(this,"offsetX",0),t(this,"offsetY",0),t(this,"sizeX",0),t(this,"sizeY",0),t(this,"touchSizeX",0),t(this,"touchSizeY",0),t(this,"cursorStyle","crosshair"),t(this,"withConnection",!1),Object.assign(this,e)}shouldActivate(t,e,s,i){var r;let{tl:n,tr:o,br:a,bl:h}=i;return(null===(r=e.canvas)||void 0===r?void 0:r.getActiveObject())===e&&e.isControlVisible(t)&&Fs.isPointInPolygon(s,[n,o,a,h])}getActionHandler(t,e,s){return this.actionHandler}getMouseDownHandler(t,e,s){return this.mouseDownHandler}getMouseUpHandler(t,e,s){return this.mouseUpHandler}cursorStyleHandler(t,e,s){return e.cursorStyle}getActionName(t,e,s){return e.actionName}getVisibility(t,e){var s,i;return null!==(s=null===(i=t._controlsVisibility)||void 0===i?void 0:i[e])&&void 0!==s?s:this.visible}setVisibility(t,e,s){this.visible=t}positionHandler(t,e,s,i){return new ot(this.x*t.x+this.offsetX,this.y*t.y+this.offsetY).transform(e)}calcCornerCoords(t,e,s,i,r,n){const o=St([kt(s,i),Dt({angle:t}),Mt((r?this.touchSizeX:this.sizeX)||e,(r?this.touchSizeY:this.sizeY)||e)]);return{tl:new ot(-.5,-.5).transform(o),tr:new ot(.5,-.5).transform(o),br:new ot(.5,.5).transform(o),bl:new ot(-.5,.5).transform(o)}}render(t,e,s,i,r){if("circle"===((i=i||{}).cornerStyle||r.cornerStyle))Vs.call(this,t,e,s,i,r);else Hs.call(this,t,e,s,i,r)}}const Gs=(t,e,s)=>s.lockRotation?Pe:e.cursorStyle,Ns=Xs(I,Ws(((t,e,s,i)=>{let{target:r,ex:n,ey:o,theta:a,originX:h,originY:c}=e;const l=r.translateToOriginPoint(r.getRelativeCenterPoint(),h,c);if(je(r,"lockRotation"))return!1;const u=Math.atan2(o-l.y,n-l.x),d=Math.atan2(i-l.y,s-l.x);let g=_t(d-u+a);if(r.snapAngle&&r.snapAngle>0){const t=r.snapAngle,e=r.snapThreshold||t,s=Math.ceil(g/t)*t,i=Math.floor(g/t)*t;Math.abs(g-i){const i=Us(t,s);if(qs(s,0!==e.x&&0===e.y?"x":0===e.x&&0!==e.y?"y":"",i))return Pe;const r=Le(s,e);return"".concat(Ks[r],"-resize")};function Qs(t,e,s,i){let r=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};const n=e.target,o=r.by,a=Us(t,n);let h,c,l,u,d,g;if(qs(n,o,a))return!1;if(e.gestureScale)c=e.scaleX*e.gestureScale,l=e.scaleY*e.gestureScale;else{if(h=Re(e,e.originX,e.originY,s,i),d="y"!==o?Math.sign(h.x||e.signX||1):1,g="x"!==o?Math.sign(h.y||e.signY||1):1,e.signX||(e.signX=d),e.signY||(e.signY=g),je(n,"lockScalingFlip")&&(e.signX!==d||e.signY!==g))return!1;if(u=n._getTransformedDimensions(),a&&!o){const t=Math.abs(h.x)+Math.abs(h.y),{original:s}=e,i=t/(Math.abs(u.x*s.scaleX/n.scaleX)+Math.abs(u.y*s.scaleY/n.scaleY));c=s.scaleX*i,l=s.scaleY*i}else c=Math.abs(h.x*n.scaleX/u.x),l=Math.abs(h.y*n.scaleY/u.y);Ee(e)&&(c*=2,l*=2),e.signX!==d&&"y"!==o&&(e.originX=Ae(e.originX),c*=-1,e.signX=d),e.signY!==g&&"x"!==o&&(e.originY=Ae(e.originY),l*=-1,e.signY=g)}const f=n.scaleX,p=n.scaleY;return o?("x"===o&&n.set(G,c),"y"===o&&n.set(N,l)):(!je(n,"lockScalingX")&&n.set(G,c),!je(n,"lockScalingY")&&n.set(N,l)),f!==n.scaleX||p!==n.scaleY}const Zs=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i)))),$s=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i,{by:"x"})))),ti=Xs(R,Ws(((t,e,s,i)=>Qs(t,e,s,i,{by:"y"})))),ei=["target","ex","ey","skewingSide"],si={x:{counterAxis:"y",scale:G,skew:U,lockSkewing:"lockSkewingX",origin:"originX",flip:"flipX"},y:{counterAxis:"x",scale:N,skew:q,lockSkewing:"lockSkewingY",origin:"originY",flip:"flipY"}},ii=["ns","nesw","ew","nwse"],ri=(t,e,s)=>{if(0!==e.x&&je(s,"lockSkewingY"))return Pe;if(0!==e.y&&je(s,"lockSkewingX"))return Pe;const i=Le(s,e)%4;return"".concat(ii[i],"-resize")};function ni(t,e,r,n,o){const{target:a}=r,{counterAxis:h,origin:c,lockSkewing:l,skew:u,flip:d}=si[t];if(je(a,l))return!1;const{origin:g,flip:f}=si[h],p=Me(r[g])*(a[f]?-1:1),m=-Math.sign(p)*(a[d]?-1:1),v=.5*-((0===a[u]&&Re(r,D,D,n,o)[t]>0||a[u]>0?1:-1)*m)+.5,y=Xs(X,Ws(((e,s,r,n)=>function(t,e,s){let{target:r,ex:n,ey:o,skewingSide:a}=e,h=i(e,ei);const{skew:c}=si[t],l=s.subtract(new ot(n,o)).divide(new ot(r.scaleX,r.scaleY))[t],u=r[c],d=h[c],g=Math.tan(yt(d)),f="y"===t?r._getTransformedDimensions({scaleX:1,scaleY:1,skewX:0}).x:r._getTransformedDimensions({scaleX:1,scaleY:1}).y,p=2*l*a/Math.max(f,1)+g,m=_t(Math.atan(p));r.set(c,m);const v=u!==r[c];if(v&&"y"===t){const{skewX:t,scaleX:e}=r,s=r._getTransformedDimensions({skewY:u}),i=r._getTransformedDimensions(),n=0!==t?s.x/i.x:1;1!==n&&r.set(G,n*e)}return v}(t,s,new ot(r,n)))));return y(e,s(s({},r),{},{[c]:v,skewingSide:m}),n,o)}const oi=(t,e,s,i)=>ni("x",t,e,s,i),ai=(t,e,s,i)=>ni("y",t,e,s,i);function hi(t,e){return t[e.canvas.altActionKey]}const ci=(t,e,s)=>{const i=hi(t,s);return 0===e.x?i?U:N:0===e.y?i?q:G:""},li=(t,e,s)=>hi(t,s)?ri(0,e,s):Js(t,e,s),ui=(t,e,s,i)=>hi(t,e.target)?ai(t,e,s,i):$s(t,e,s,i),di=(t,e,s,i)=>hi(t,e.target)?oi(t,e,s,i):ti(t,e,s,i),gi=()=>({ml:new zs({x:-.5,y:0,cursorStyleHandler:li,actionHandler:ui,getActionName:ci}),mr:new zs({x:.5,y:0,cursorStyleHandler:li,actionHandler:ui,getActionName:ci}),mb:new zs({x:0,y:.5,cursorStyleHandler:li,actionHandler:di,getActionName:ci}),mt:new zs({x:0,y:-.5,cursorStyleHandler:li,actionHandler:di,getActionName:ci}),tl:new zs({x:-.5,y:-.5,cursorStyleHandler:Js,actionHandler:Zs}),tr:new zs({x:.5,y:-.5,cursorStyleHandler:Js,actionHandler:Zs}),bl:new zs({x:-.5,y:.5,cursorStyleHandler:Js,actionHandler:Zs}),br:new zs({x:.5,y:.5,cursorStyleHandler:Js,actionHandler:Zs}),mtr:new zs({x:0,y:-.5,actionHandler:Ns,cursorStyleHandler:Gs,offsetY:-40,withConnection:!0,actionName:B})}),fi=()=>({mr:new zs({x:.5,y:0,actionHandler:Ys,cursorStyleHandler:li,actionName:W}),ml:new zs({x:-.5,y:0,actionHandler:Ys,cursorStyleHandler:li,actionName:W})}),pi=()=>s(s({},gi()),fi());class mi extends Bs{static getDefaults(){return s(s({},super.getDefaults()),mi.ownDefaults)}constructor(t){super(),Object.assign(this,this.constructor.createControls(),mi.ownDefaults),this.setOptions(t)}static createControls(){return{controls:gi()}}_updateCacheCanvas(){const t=this.canvas;if(this.noScaleCache&&t&&t._currentTransform){const e=t._currentTransform,s=e.target,i=e.action;if(this===s&&i&&i.startsWith(z))return!1}return super._updateCacheCanvas()}getActiveControl(){const t=this.__corner;return t?{key:t,control:this.controls[t],coord:this.oCoords[t]}:void 0}findControl(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(!this.hasControls||!this.canvas)return;this.__corner=void 0;const s=Object.entries(this.oCoords);for(let i=s.length-1;i>=0;i--){const[r,n]=s[i],o=this.controls[r];if(o.shouldActivate(r,this,t,e?n.touchCorner:n.corner))return this.__corner=r,{key:r,control:o,coord:this.oCoords[r]}}}calcOCoords(){const t=this.getViewportTransform(),e=this.getCenterPoint(),s=kt(e.x,e.y),i=Dt({angle:this.getTotalAngle()-(this.group&&this.flipX?180:0)}),r=wt(s,i),n=wt(t,r),o=wt(n,[1/t[0],0,0,1/t[3],0,0]),a=this.group?Ot(this.calcTransformMatrix()):void 0;a&&(a.scaleX=Math.abs(a.scaleX),a.scaleY=Math.abs(a.scaleY));const h=this._calculateCurrentDimensions(a),c={};return this.forEachControl(((t,e)=>{const s=t.positionHandler(h,o,this,t);c[e]=Object.assign(s,this._calcCornerCoords(t,s))})),c}_calcCornerCoords(t,e){const s=this.getTotalAngle();return{corner:t.calcCornerCoords(s,this.cornerSize,e.x,e.y,!1,this),touchCorner:t.calcCornerCoords(s,this.touchCornerSize,e.x,e.y,!0,this)}}setCoords(){super.setCoords(),this.canvas&&(this.oCoords=this.calcOCoords())}forEachControl(t){for(const e in this.controls)t(this.controls[e],e,this)}drawSelectionBackground(t){if(!this.selectionBackgroundColor||this.canvas&&this.canvas._activeObject!==this)return;t.save();const e=this.getRelativeCenterPoint(),s=this._calculateCurrentDimensions(),i=this.getViewportTransform();t.translate(e.x,e.y),t.scale(1/i[0],1/i[3]),t.rotate(yt(this.angle)),t.fillStyle=this.selectionBackgroundColor,t.fillRect(-s.x/2,-s.y/2,s.x,s.y),t.restore()}strokeBorders(t,e){t.strokeRect(-e.x/2,-e.y/2,e.x,e.y)}_drawBorders(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r=s({hasControls:this.hasControls,borderColor:this.borderColor,borderDashArray:this.borderDashArray},i);t.save(),t.strokeStyle=r.borderColor,this._setLineDash(t,r.borderDashArray),this.strokeBorders(t,e),r.hasControls&&this.drawControlsConnectingLines(t,e),t.restore()}_renderControls(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{hasBorders:i,hasControls:r}=this,n=s({hasBorders:i,hasControls:r},e),o=this.getViewportTransform(),a=n.hasBorders,h=n.hasControls,c=wt(o,this.calcTransformMatrix()),l=Ot(c);t.save(),t.translate(l.translateX,l.translateY),t.lineWidth=1*this.borderScaleFactor,this.group===this.parent&&(t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1),this.flipX&&(l.angle-=180),t.rotate(yt(this.group?l.angle:this.angle)),a&&this.drawBorders(t,l,e),h&&this.drawControls(t,e),t.restore()}drawBorders(t,e,s){let i;if(s&&s.forActiveSelection||this.group){const t=be(this.width,this.height,jt(e)),s=this.isStrokeAccountedForInDimensions()?at:(this.strokeUniform?(new ot).scalarAdd(this.canvas?this.canvas.getZoom():1):new ot(e.scaleX,e.scaleY)).scalarMultiply(this.strokeWidth);i=t.add(s).scalarAdd(this.borderScaleFactor).scalarAdd(2*this.padding)}else i=this._calculateCurrentDimensions().scalarAdd(this.borderScaleFactor);this._drawBorders(t,i,s)}drawControlsConnectingLines(t,e){let s=!1;t.beginPath(),this.forEachControl(((i,r)=>{i.withConnection&&i.getVisibility(this,r)&&(s=!0,t.moveTo(i.x*e.x,i.y*e.y),t.lineTo(i.x*e.x+i.offsetX,i.y*e.y+i.offsetY))})),s&&t.stroke()}drawControls(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.save();const i=this.getCanvasRetinaScaling(),{cornerStrokeColor:r,cornerDashArray:n,cornerColor:o}=this,a=s({cornerStrokeColor:r,cornerDashArray:n,cornerColor:o},e);t.setTransform(i,0,0,i,0,0),t.strokeStyle=t.fillStyle=a.cornerColor,this.transparentCorners||(t.strokeStyle=a.cornerStrokeColor),this._setLineDash(t,a.cornerDashArray),this.forEachControl(((e,s)=>{if(e.getVisibility(this,s)){const i=this.oCoords[s];e.render(t,i.x,i.y,a,this)}})),t.restore()}isControlVisible(t){return this.controls[t]&&this.controls[t].getVisibility(this,t)}setControlVisible(t,e){this._controlsVisibility||(this._controlsVisibility={}),this._controlsVisibility[t]=e}setControlsVisibility(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};Object.entries(t).forEach((t=>{let[e,s]=t;return this.setControlVisible(e,s)}))}clearContextTop(t){if(!this.canvas)return;const e=this.canvas.contextTop;if(!e)return;const s=this.canvas.viewportTransform;e.save(),e.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this.transform(e);const i=this.width+4,r=this.height+4;return e.clearRect(-i/2,-r/2,i,r),t||e.restore(),e}onDeselect(t){return!1}onSelect(t){return!1}shouldStartDragging(t){return!1}onDragStart(t){return!1}canDrop(t){return!1}renderDragSourceEffect(t){}renderDropTargetEffect(t){}}function vi(t,e){return e.forEach((e=>{Object.getOwnPropertyNames(e.prototype).forEach((s=>{"constructor"!==s&&Object.defineProperty(t.prototype,s,Object.getOwnPropertyDescriptor(e.prototype,s)||Object.create(null))}))})),t}t(mi,"ownDefaults",{noScaleCache:!0,lockMovementX:!1,lockMovementY:!1,lockRotation:!1,lockScalingX:!1,lockScalingY:!1,lockSkewingX:!1,lockSkewingY:!1,lockScalingFlip:!1,cornerSize:13,touchCornerSize:24,transparentCorners:!0,cornerColor:"rgb(178,204,255)",cornerStrokeColor:"",cornerStyle:"rect",cornerDashArray:null,hasControls:!0,borderColor:"rgb(178,204,255)",borderDashArray:null,borderOpacityWhenMoving:.4,borderScaleFactor:1,hasBorders:!0,selectionBackgroundColor:"",selectable:!0,evented:!0,perPixelTargetFind:!1,activeOn:"down",hoverCursor:null,moveCursor:null});class yi extends mi{}vi(yi,[Be]),tt.setClass(yi),tt.setClass(yi,"object");const _i=(t,e,s,i)=>{const r=2*(i=Math.round(i))+1,{data:n}=t.getImageData(e-i,s-i,r,r);for(let t=3;t0)return!1}return!0};class xi{constructor(t){this.options=t,this.strokeProjectionMagnitude=this.options.strokeWidth/2,this.scale=new ot(this.options.scaleX,this.options.scaleY),this.strokeUniformScalar=this.options.strokeUniform?new ot(1/this.options.scaleX,1/this.options.scaleY):new ot(1,1)}createSideVector(t,e){const s=ts(t,e);return this.options.strokeUniform?s.multiply(this.scale):s}projectOrthogonally(t,e,s){return this.applySkew(t.add(this.calcOrthogonalProjection(t,e,s)))}isSkewed(){return 0!==this.options.skewX||0!==this.options.skewY}applySkew(t){const e=new ot(t);return e.y+=e.x*Math.tan(yt(this.options.skewY)),e.x+=e.y*Math.tan(yt(this.options.skewX)),e}scaleUnitVector(t,e){return t.multiply(this.strokeUniformScalar).scalarMultiply(e)}}const Ci=new ot;class bi extends xi{static getOrthogonalRotationFactor(t,e){const s=e?ss(t,e):is(t);return Math.abs(s)2&&void 0!==arguments[2]?arguments[2]:this.strokeProjectionMagnitude;const i=this.createSideVector(t,e),r=ns(i),n=bi.getOrthogonalRotationFactor(r,this.bisector);return this.scaleUnitVector(r,s*n)}projectBevel(){const t=[];return(this.alpha%w==0?[this.B]:[this.B,this.C]).forEach((e=>{t.push(this.projectOrthogonally(this.A,e)),t.push(this.projectOrthogonally(this.A,e,-this.strokeProjectionMagnitude))})),t}projectMiter(){const t=[],e=Math.abs(this.alpha),s=1/Math.sin(e/2),i=this.scaleUnitVector(this.bisector,-this.strokeProjectionMagnitude*s),r=this.options.strokeUniform?es(this.scaleUnitVector(this.bisector,this.options.strokeMiterLimit)):this.options.strokeMiterLimit;return es(i)/this.strokeProjectionMagnitude<=r&&t.push(this.applySkew(this.A.add(i))),t.push(...this.projectBevel()),t}projectRoundNoSkew(t,e){const s=[],i=new ot(bi.getOrthogonalRotationFactor(this.bisector),bi.getOrthogonalRotationFactor(new ot(this.bisector.y,this.bisector.x)));return[new ot(1,0).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(i),new ot(0,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(i)].forEach((i=>{hs(i,t,e)&&s.push(this.A.add(i))})),s}projectRoundWithSkew(t,e){const s=[],{skewX:i,skewY:r,scaleX:n,scaleY:o,strokeUniform:a}=this.options,h=new ot(Math.tan(yt(i)),Math.tan(yt(r))),c=this.strokeProjectionMagnitude,l=a?c/o/Math.sqrt(1/o**2+1/n**2*h.y**2):c/Math.sqrt(1+h.y**2),u=new ot(Math.sqrt(Math.max(c**2-l**2,0)),l),d=a?c/Math.sqrt(1+h.x**2*(1/o)**2/(1/n+1/n*h.x*h.y)**2):c/Math.sqrt(1+h.x**2/(1+h.x*h.y)**2),g=new ot(d,Math.sqrt(Math.max(c**2-d**2,0)));return[g,g.scalarMultiply(-1),u,u.scalarMultiply(-1)].map((t=>this.applySkew(a?t.multiply(this.strokeUniformScalar):t))).forEach((i=>{hs(i,t,e)&&s.push(this.applySkew(this.A).add(i))})),s}projectRound(){const t=[];t.push(...this.projectBevel());const e=this.alpha%w==0,s=this.applySkew(this.A),i=t[e?0:2].subtract(s),r=t[e?1:0].subtract(s),n=e?this.applySkew(this.AB.scalarMultiply(-1)):this.applySkew(this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1)),o=os(i,n)>0,a=o?i:r,h=o?r:i;return this.isSkewed()?t.push(...this.projectRoundWithSkew(a,h)):t.push(...this.projectRoundNoSkew(a,h)),t}projectPoints(){switch(this.options.strokeLineJoin){case"miter":return this.projectMiter();case"round":return this.projectRound();default:return this.projectBevel()}}project(){return this.projectPoints().map((t=>({originPoint:this.A,projectedPoint:t,angle:this.alpha,bisector:this.bisector})))}}class wi extends xi{constructor(t,e,s){super(s),this.A=new ot(t),this.T=new ot(e)}calcOrthogonalProjection(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.strokeProjectionMagnitude;const i=this.createSideVector(t,e);return this.scaleUnitVector(ns(i),s)}projectButt(){return[this.projectOrthogonally(this.A,this.T,this.strokeProjectionMagnitude),this.projectOrthogonally(this.A,this.T,-this.strokeProjectionMagnitude)]}projectRound(){const t=[];if(!this.isSkewed()&&this.A.eq(this.T)){const e=new ot(1,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar);t.push(this.applySkew(this.A.add(e)),this.applySkew(this.A.subtract(e)))}else t.push(...new bi(this.A,this.T,this.T,this.options).projectRound());return t}projectSquare(){const t=[];if(this.A.eq(this.T)){const e=new ot(1,1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar);t.push(this.A.add(e),this.A.subtract(e))}else{const e=this.calcOrthogonalProjection(this.A,this.T,this.strokeProjectionMagnitude),s=this.scaleUnitVector(rs(this.createSideVector(this.A,this.T)),-this.strokeProjectionMagnitude),i=this.A.add(s);t.push(i.add(e),i.subtract(e))}return t.map((t=>this.applySkew(t)))}projectPoints(){switch(this.options.strokeLineCap){case"round":return this.projectRound();case"square":return this.projectSquare();default:return this.projectButt()}}project(){return this.projectPoints().map((t=>({originPoint:this.A,projectedPoint:t})))}}const Si=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const i=[];if(0===t.length)return i;const r=t.reduce(((t,e)=>(t[t.length-1].eq(e)||t.push(new ot(e)),t)),[new ot(t[0])]);if(1===r.length)s=!0;else if(!s){const t=r[0],e=((t,e)=>{for(let s=t.length-1;s>=0;s--)if(e(t[s],s,t))return s;return-1})(r,(e=>!e.eq(t)));r.splice(e+1)}return r.forEach(((t,r,n)=>{let o,a;0===r?(a=n[1],o=s?t:n[n.length-1]):r===n.length-1?(o=n[r-1],a=s?t:n[0]):(o=n[r-1],a=n[r+1]),s&&1===n.length?i.push(...new wi(t,t,e).project()):!s||0!==r&&r!==n.length-1?i.push(...new bi(t,o,a,e).project()):i.push(...new wi(t,0===r?a:o,e).project())})),i},Ti=t=>{const e={};return Object.keys(t).forEach((i=>{e[i]={},Object.keys(t[i]).forEach((r=>{e[i][r]=s({},t[i][r])}))})),e},Oi=t=>t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">"),ki=t=>{const e=[];for(let s,i=0;i{const s=t.charCodeAt(e);if(isNaN(s))return"";if(s<55296||s>57343)return t.charAt(e);if(55296<=s&&s<=56319){if(t.length<=e+1)throw"High surrogate without following low surrogate";const s=t.charCodeAt(e+1);if(56320>s||s>57343)throw"High surrogate without following low surrogate";return t.charAt(e)+t.charAt(e+1)}if(0===e)throw"Low surrogate without preceding high surrogate";const i=t.charCodeAt(e-1);if(55296>i||i>56319)throw"Low surrogate without preceding high surrogate";return!1};var Mi=Object.freeze({__proto__:null,capitalize:function(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return"".concat(t.charAt(0).toUpperCase()).concat(e?t.slice(1):t.slice(1).toLowerCase())},escapeXml:Oi,graphemeSplit:ki});const Pi=function(t,e){let s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];return t.fill!==e.fill||t.stroke!==e.stroke||t.strokeWidth!==e.strokeWidth||t.fontSize!==e.fontSize||t.fontFamily!==e.fontFamily||t.fontWeight!==e.fontWeight||t.fontStyle!==e.fontStyle||t.textBackgroundColor!==e.textBackgroundColor||t.deltaY!==e.deltaY||s&&(t.overline!==e.overline||t.underline!==e.underline||t.linethrough!==e.linethrough)},Ei=(t,e)=>{const s=e.split("\n"),i=[];let r=-1,n={};t=Ti(t);for(let e=0;e0&&(Pi(n,o,!0)?i.push({start:r,end:r+1,style:o}):i[i.length-1].end++),n=o||{}}else r+=o.length,n={}}return i},Ai=(t,e)=>{if(!Array.isArray(t))return Ti(t);const i=e.split(F),r={};let n=-1,o=0;for(let e=0;e{var e;return null!==(e=ze[t])&&void 0!==e?e:t},Ii=new RegExp("(".concat(Ye,")"),"gi"),Bi=t=>t.replace(Ii," $1 ").replace(/,/gi," ").replace(/\s+/gi," ");var Xi,Wi,Yi,Vi,Hi,zi,Gi;const Ni="(".concat(Ye,")"),Ui=String.raw(Xi||(Xi=r(["(skewX)(",")"],["(skewX)\\(","\\)"])),Ni),qi=String.raw(Wi||(Wi=r(["(skewY)(",")"],["(skewY)\\(","\\)"])),Ni),Ki=String.raw(Yi||(Yi=r(["(rotate)(","(?: "," ",")?)"],["(rotate)\\(","(?: "," ",")?\\)"])),Ni,Ni,Ni),Ji=String.raw(Vi||(Vi=r(["(scale)(","(?: ",")?)"],["(scale)\\(","(?: ",")?\\)"])),Ni,Ni),Qi=String.raw(Hi||(Hi=r(["(translate)(","(?: ",")?)"],["(translate)\\(","(?: ",")?\\)"])),Ni,Ni),Zi=String.raw(zi||(zi=r(["(matrix)("," "," "," "," "," ",")"],["(matrix)\\("," "," "," "," "," ","\\)"])),Ni,Ni,Ni,Ni,Ni,Ni),$i="(?:".concat(Zi,"|").concat(Qi,"|").concat(Ki,"|").concat(Ji,"|").concat(Ui,"|").concat(qi,")"),tr="(?:".concat($i,"*)"),er=String.raw(Gi||(Gi=r(["^s*(?:","?)s*$"],["^\\s*(?:","?)\\s*$"])),tr),sr=new RegExp(er),ir=new RegExp($i),rr=new RegExp($i,"g");function nr(t){const e=[];if(!(t=Bi(t).replace(/\s*([()])\s*/gi,"$1"))||t&&!sr.test(t))return[...T];for(const s of t.matchAll(rr)){const t=ir.exec(s[0]);if(!t)continue;let i=T;const r=t.filter((t=>!!t)),[,n,...o]=r,[a,h,c,l,u,d]=o.map((t=>parseFloat(t)));switch(n){case"translate":i=kt(a,h);break;case B:i=Dt({angle:a},{x:h,y:c});break;case z:i=Mt(a,h);break;case U:i=Et(a);break;case q:i=At(a);break;case"matrix":i=[a,h,c,l,u,d]}e.push(i)}return St(e)}function or(t,e,s,i){const r=Array.isArray(e);let n,o=e;if(t!==K&&t!==J||e!==j){if("strokeUniform"===t)return"non-scaling-stroke"===e;if("strokeDashArray"===t)o=e===j?null:e.replace(/,/g," ").split(/\s+/).map(parseFloat);else if("transformMatrix"===t)o=s&&s.transformMatrix?wt(s.transformMatrix,nr(e)):nr(e);else if("visible"===t)o=e!==j&&"hidden"!==e,s&&!1===s.visible&&(o=!1);else if("opacity"===t)o=parseFloat(e),s&&void 0!==s.opacity&&(o*=s.opacity);else if("textAnchor"===t)o="start"===e?M:"end"===e?A:D;else if("charSpacing"===t)n=qt(e,i)/i*1e3;else if("paintFirst"===t){const t=e.indexOf(K),s=e.indexOf(J);o=K,(t>-1&&s>-1&&s-1)&&(o=J)}else{if("href"===t||"xlink:href"===t||"font"===t||"id"===t)return e;if("imageSmoothing"===t)return"optimizeQuality"===e;n=r?e.map(qt):qt(e,i)}}else o="";return!r&&isNaN(n)?o:n}function ar(t,e){const s=t.match(He);if(!s)return;const i=s[1],r=s[3],n=s[4],o=s[5],a=s[6];i&&(e.fontStyle=i),r&&(e.fontWeight=isNaN(parseFloat(r))?r:parseFloat(r)),n&&(e.fontSize=qt(n)),a&&(e.fontFamily=a),o&&(e.lineHeight="normal"===o?1:o)}function hr(t,e){t.replace(/;\s*$/,"").split(";").forEach((t=>{if(!t)return;const[s,i]=t.split(":");e[s.trim().toLowerCase()]=i.trim()}))}function cr(t){const e={},s=t.getAttribute("style");return s?("string"==typeof s?hr(s,e):function(t,e){Object.entries(t).forEach((t=>{let[s,i]=t;void 0!==i&&(e[s.toLowerCase()]=i)}))}(s,e),e):e}const lr={stroke:"strokeOpacity",fill:"fillOpacity"};function ur(t,e,i){if(!t)return{};let r,n={},o=O;t.parentNode&&Ke.test(t.parentNode.nodeName)&&(n=ur(t.parentElement,e,i),n.fontSize&&(r=o=qt(n.fontSize)));const a=s(s(s({},e.reduce(((e,s)=>{const i=t.getAttribute(s);return i&&(e[s]=i),e}),{})),function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i={};for(const r in e)Li(t,r.split(" "))&&(i=s(s({},i),e[r]));return i}(t,i)),cr(t));a[Ne]&&t.setAttribute(Ne,a[Ne]),a[Ge]&&(r=qt(a[Ge],o),a[Ge]="".concat(r));const h={};for(const t in a){const e=Ri(t),s=or(e,a[t],n,r);h[e]=s}h&&h.font&&ar(h.font,h);const c=s(s({},n),h);return Ke.test(t.nodeName)?c:function(t){const e=yi.getDefaults();return Object.entries(lr).forEach((s=>{let[i,r]=s;if(void 0===t[r]||""===t[i])return;if(void 0===t[i]){if(!e[i])return;t[i]=e[i]}if(0===t[i].indexOf("url("))return;const n=new Nt(t[i]);t[i]=n.setAlpha(Ut(n.getAlpha()*t[r],2)).toRgba()})),t}(c)}const dr=["left","top","width","height","visible"],gr=["rx","ry"];class fr extends yi{static getDefaults(){return s(s({},super.getDefaults()),fr.ownDefaults)}constructor(t){super(),Object.assign(this,fr.ownDefaults),this.setOptions(t),this._initRxRy()}_initRxRy(){const{rx:t,ry:e}=this;t&&!e?this.ry=t:e&&!t&&(this.rx=e)}_render(t){const{width:e,height:s}=this,i=-e/2,r=-s/2,n=this.rx?Math.min(this.rx,e/2):0,o=this.ry?Math.min(this.ry,s/2):0,a=0!==n||0!==o;t.beginPath(),t.moveTo(i+n,r),t.lineTo(i+e-n,r),a&&t.bezierCurveTo(i+e-k*n,r,i+e,r+k*o,i+e,r+o),t.lineTo(i+e,r+s-o),a&&t.bezierCurveTo(i+e,r+s-k*o,i+e-k*n,r+s,i+e-n,r+s),t.lineTo(i+n,r+s),a&&t.bezierCurveTo(i+k*n,r+s,i,r+s-k*o,i,r+s-o),t.lineTo(i,r+o),a&&t.bezierCurveTo(i,r+k*o,i+k*n,r,i+n,r),t.closePath(),this._renderPaintInOrder(t)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...gr,...t])}_toSVG(){const{width:t,height:e,rx:s,ry:i}=this;return["\n')]}static async fromElement(t,e,r){const n=ur(t,this.ATTRIBUTE_NAMES,r),{left:o=0,top:a=0,width:h=0,height:c=0,visible:l=!0}=n,u=i(n,dr);return new this(s(s(s({},e),u),{},{left:o,top:a,width:h,height:c,visible:Boolean(l&&h&&c)}))}}t(fr,"type","Rect"),t(fr,"cacheProperties",[...fs,...gr]),t(fr,"ownDefaults",{rx:0,ry:0}),t(fr,"ATTRIBUTE_NAMES",[...ji,"x","y","rx","ry","width","height"]),tt.setClass(fr),tt.setSVGClass(fr);const pr="initialization",mr="added",vr="removed",yr="imperative",_r=(t,e)=>{const{strokeUniform:s,strokeWidth:i,width:r,height:n,group:o}=e,a=o&&o!==t?we(o.calcTransformMatrix(),t.calcTransformMatrix()):null,h=a?e.getRelativeCenterPoint().transform(a):e.getRelativeCenterPoint(),c=!e.isStrokeAccountedForInDimensions(),l=s&&c?Te(new ot(i,i),void 0,t.calcTransformMatrix()):at,u=!s&&c?i:0,d=be(r+u,n+u,St([a,e.calcOwnMatrix()],!0)).add(l).scalarDivide(2);return[h.subtract(d),h.add(d)]};class xr{calcLayoutResult(t,e){if(this.shouldPerformLayout(t))return this.calcBoundingBox(e,t)}shouldPerformLayout(t){let{type:e,prevStrategy:s,strategy:i}=t;return e===pr||e===yr||!!s&&i!==s}shouldLayoutClipPath(t){let{type:e,target:{clipPath:s}}=t;return e!==pr&&s&&!s.absolutePositioned}getInitialSize(t,e){return e.size}calcBoundingBox(t,e){const{type:s,target:i}=e;if(s===yr&&e.overrides)return e.overrides;if(0===t.length)return;const{left:r,top:n,width:o,height:a}=me(t.map((t=>_r(i,t))).reduce(((t,e)=>t.concat(e)),[])),h=new ot(o,a),c=new ot(r,n).add(h.scalarDivide(2));if(s===pr){const t=this.getInitialSize(e,{size:h,center:c});return{center:c,relativeCorrection:new ot(0,0),size:t}}return{center:c.transform(i.calcOwnMatrix()),size:h}}}t(xr,"type","strategy");class Cr extends xr{shouldPerformLayout(t){return!0}}t(Cr,"type","fit-content"),tt.setClass(Cr);const br=["strategy"],wr=["target","strategy","bubbles","prevStrategy"],Sr="layoutManager";class Tr{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new Cr;t(this,"strategy",void 0),this.strategy=e,this._subscriptions=new Map}performLayout(t){const e=s(s({bubbles:!0,strategy:this.strategy},t),{},{prevStrategy:this._prevLayoutStrategy,stopPropagation(){this.bubbles=!1}});this.onBeforeLayout(e);const i=this.getLayoutResult(e);i&&this.commitLayout(e,i),this.onAfterLayout(e,i),this._prevLayoutStrategy=e.strategy}attachHandlers(t,e){const{target:s}=e;return[Q,L,W,I,R,X,H,Y,V].map((e=>t.on(e,(t=>this.performLayout(e===Q?{type:"object_modified",trigger:e,e:t,target:s}:{type:"object_modifying",trigger:e,e:t,target:s})))))}subscribe(t,e){this.unsubscribe(t,e);const s=this.attachHandlers(t,e);this._subscriptions.set(t,s)}unsubscribe(t,e){(this._subscriptions.get(t)||[]).forEach((t=>t())),this._subscriptions.delete(t)}unsubscribeTargets(t){t.targets.forEach((e=>this.unsubscribe(e,t)))}subscribeTargets(t){t.targets.forEach((e=>this.subscribe(e,t)))}onBeforeLayout(t){const{target:e,type:r}=t,{canvas:n}=e;if(r===pr||r===mr?this.subscribeTargets(t):r===vr&&this.unsubscribeTargets(t),e.fire("layout:before",{context:t}),n&&n.fire("object:layout:before",{target:e,context:t}),r===yr&&t.deep){const r=i(t,br);e.forEachObject((t=>t.layoutManager&&t.layoutManager.performLayout(s(s({},r),{},{bubbles:!1,target:t}))))}}getLayoutResult(t){const{target:e,strategy:s,type:i}=t,r=s.calcLayoutResult(t,e.getObjects());if(!r)return;const n=i===pr?new ot:e.getRelativeCenterPoint(),{center:o,correction:a=new ot,relativeCorrection:h=new ot}=r,c=n.subtract(o).add(a).transform(i===pr?T:bt(e.calcOwnMatrix()),!0).add(h);return{result:r,prevCenter:n,nextCenter:o,offset:c}}commitLayout(t,e){const{target:s}=t,{result:{size:i},nextCenter:r}=e;var n,o;(s.set({width:i.x,height:i.y}),this.layoutObjects(t,e),t.type===pr)?s.set({left:null!==(n=t.x)&&void 0!==n?n:r.x+i.x*Me(s.originX),top:null!==(o=t.y)&&void 0!==o?o:r.y+i.y*Me(s.originY)}):(s.setPositionByOrigin(r,D,D),s.setCoords(),s.set("dirty",!0))}layoutObjects(t,e){const{target:s}=t;s.forEachObject((i=>{i.group===s&&this.layoutObject(t,e,i)})),t.strategy.shouldLayoutClipPath(t)&&this.layoutObject(t,e,s.clipPath)}layoutObject(t,e,s){let{offset:i}=e;s.set({left:s.left+i.x,top:s.top+i.y})}onAfterLayout(t,e){const{target:r,strategy:n,bubbles:o,prevStrategy:a}=t,h=i(t,wr),{canvas:c}=r;r.fire("layout:after",{context:t,result:e}),c&&c.fire("object:layout:after",{context:t,result:e,target:r});const l=r.parent;o&&null!=l&&l.layoutManager&&((h.path||(h.path=[])).push(r),l.layoutManager.performLayout(s(s({},h),{},{target:l}))),r.set("dirty",!0)}dispose(){const{_subscriptions:t}=this;t.forEach((t=>t.forEach((t=>t())))),t.clear()}toObject(){return{type:Sr,strategy:this.strategy.constructor.type}}toJSON(){return this.toObject()}}tt.setClass(Tr,Sr);const Or=["type","objects","layoutManager"];class kr extends Tr{performLayout(){}}class Dr extends(ct(yi)){static getDefaults(){return s(s({},super.getDefaults()),Dr.ownDefaults)}constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"_activeObjects",[]),t(this,"__objectSelectionTracker",void 0),t(this,"__objectSelectionDisposer",void 0),Object.assign(this,Dr.ownDefaults),this.setOptions(s),this.groupInit(e,s)}groupInit(t,e){var s;this._objects=[...t],this.__objectSelectionTracker=this.__objectSelectionMonitor.bind(this,!0),this.__objectSelectionDisposer=this.__objectSelectionMonitor.bind(this,!1),this.forEachObject((t=>{this.enterGroup(t,!1)})),this.layoutManager=null!==(s=e.layoutManager)&&void 0!==s?s:new Tr,this.layoutManager.performLayout({type:pr,target:this,targets:[...t],x:e.left,y:e.top})}canEnterGroup(t){return t===this||this.isDescendantOf(t)?(a("error","Group: circular object trees are not supported, this call has no effect"),!1):-1===this._objects.indexOf(t)||(a("error","Group: duplicate objects are not supported inside group, this call has no effect"),!1)}_filterObjectsBeforeEnteringGroup(t){return t.filter(((t,e,s)=>this.canEnterGroup(t)&&s.indexOf(t)===e))}add(){for(var t=arguments.length,e=new Array(t),s=0;s1?e-1:0),i=1;i{s._set(t,e)})),this}_shouldSetNestedCoords(){return this.subTargetCheck}removeAll(){return this._activeObjects=[],this.remove(...this._objects)}__objectSelectionMonitor(t,e){let{target:s}=e;const i=this._activeObjects;if(t)i.push(s),this._set("dirty",!0);else if(i.length>0){const t=i.indexOf(s);t>-1&&(i.splice(t,1),this._set("dirty",!0))}}_watchObject(t,e){t&&this._watchObject(!1,e),t?(e.on("selected",this.__objectSelectionTracker),e.on("deselected",this.__objectSelectionDisposer)):(e.off("selected",this.__objectSelectionTracker),e.off("deselected",this.__objectSelectionDisposer))}enterGroup(t,e){t.group&&t.group.remove(t),t._set("parent",this),this._enterGroup(t,e)}_enterGroup(t,e){e&&_e(t,wt(bt(this.calcTransformMatrix()),t.calcTransformMatrix())),this._shouldSetNestedCoords()&&t.setCoords(),t._set("group",this),t._set("canvas",this.canvas),this._watchObject(!0,t);const s=this.canvas&&this.canvas.getActiveObject&&this.canvas.getActiveObject();s&&(s===t||t.isDescendantOf(s))&&this._activeObjects.push(t)}exitGroup(t,e){this._exitGroup(t,e),t._set("parent",void 0),t._set("canvas",void 0)}_exitGroup(t,e){t._set("group",void 0),e||(_e(t,wt(this.calcTransformMatrix(),t.calcTransformMatrix())),t.setCoords()),this._watchObject(!1,t);const s=this._activeObjects.length>0?this._activeObjects.indexOf(t):-1;s>-1&&this._activeObjects.splice(s,1)}shouldCache(){const t=yi.prototype.shouldCache.call(this);if(t)for(let t=0;tt.setCoords()))}triggerLayout(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.layoutManager.performLayout(s({target:this,type:yr},t))}render(t){this._transformDone=!0,super.render(t),this._transformDone=!1}__serializeObjects(t,e){const s=this.includeDefaultValues;return this._objects.filter((function(t){return!t.excludeFromExport})).map((function(i){const r=i.includeDefaultValues;i.includeDefaultValues=s;const n=i[t||"toObject"](e);return i.includeDefaultValues=r,n}))}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=this.layoutManager.toObject();return s(s(s({},super.toObject(["subTargetCheck","interactive",...t])),"fit-content"!==e.strategy||this.includeDefaultValues?{layoutManager:e}:{}),{},{objects:this.__serializeObjects("toObject",t)})}toString(){return"#")}dispose(){this.layoutManager.unsubscribeTargets({targets:this.getObjects(),target:this}),this._activeObjects=[],this.forEachObject((t=>{this._watchObject(!1,t),t.dispose()})),super.dispose()}_createSVGBgRect(t){if(!this.backgroundColor)return"";const e=fr.prototype._toSVG.call(this),s=e.indexOf("COMMON_PARTS");e[s]='for="group" ';const i=e.join("");return t?t(i):i}_toSVG(t){const e=["\n"],s=this._createSVGBgRect(t);s&&e.push("\t\t",s);for(let s=0;s\n"),e}getSvgStyles(){const t=void 0!==this.opacity&&1!==this.opacity?"opacity: ".concat(this.opacity,";"):"",e=this.visible?"":" visibility: hidden;";return[t,this.getSvgFilter(),e].join("")}toClipPathSVG(t){const e=[],s=this._createSVGBgRect(t);s&&e.push("\t",s);for(let s=0;s{let[e,i]=t;const r=new this(e,s(s(s({},a),i),{},{layoutManager:new kr}));if(o){const t=tt.getClass(o.type),e=tt.getClass(o.strategy);r.layoutManager=new t(new e)}else r.layoutManager=new Tr;return r.layoutManager.subscribeTargets({type:pr,target:r,targets:r.getObjects()}),r.setCoords(),r}))}}t(Dr,"type","Group"),t(Dr,"ownDefaults",{strokeWidth:0,subTargetCheck:!1,interactive:!1}),tt.setClass(Dr);const Mr=(t,e)=>Math.min(e.width/t.width,e.height/t.height),Pr=(t,e)=>Math.max(e.width/t.width,e.height/t.height),Er="\\s*,?\\s*",Ar="".concat(Er,"(").concat(Ye,")"),jr="".concat(Ar).concat(Ar).concat(Ar).concat(Er,"([01])").concat(Er,"([01])").concat(Ar).concat(Ar),Fr={m:"l",M:"L"},Lr=(t,e,s,i,r,n,o,a,h,c,l)=>{const u=rt(t),d=nt(t),g=rt(e),f=nt(e),p=s*r*g-i*n*f+o,m=i*r*g+s*n*f+a;return["C",c+h*(-s*r*d-i*n*u),l+h*(-i*r*d+s*n*u),p+h*(s*r*f+i*n*g),m+h*(i*r*f-s*n*g),p,m]},Rr=(t,e,s,i)=>{const r=Math.atan2(e,t),n=Math.atan2(i,s);return n>=r?n-r:2*Math.PI-(r-n)};function Ir(t,e,s,i,r,n,a,h){let c;if(o.cachesBoundsOfCurve&&(c=[...arguments].join(),_.boundsOfCurveCache[c]))return _.boundsOfCurveCache[c];const l=Math.sqrt,u=Math.abs,d=[],g=[[0,0],[0,0]];let f=6*t-12*s+6*r,p=-3*t+9*s-9*r+3*a,m=3*s-3*t;for(let t=0;t<2;++t){if(t>0&&(f=6*e-12*i+6*n,p=-3*e+9*i-9*n+3*h,m=3*i-3*e),u(p)<1e-12){if(u(f)<1e-12)continue;const t=-m/f;0{let[i,r,n,o,a,h,c,l]=s;const u=((t,e,s,i,r,n,o)=>{if(0===s||0===i)return[];let a=0,h=0,c=0;const l=Math.PI,u=o*S,d=nt(u),g=rt(u),f=.5*(-g*t-d*e),p=.5*(-g*e+d*t),m=s**2,v=i**2,y=p**2,_=f**2,x=m*v-m*y-v*_;let C=Math.abs(s),b=Math.abs(i);if(x<0){const t=Math.sqrt(1-x/(m*v));C*=t,b*=t}else c=(r===n?-1:1)*Math.sqrt(x/(m*y+v*_));const w=c*C*p/b,T=-c*b*f/C,O=g*w-d*T+.5*t,k=d*w+g*T+.5*e;let D=Rr(1,0,(f-w)/C,(p-T)/b),M=Rr((f-w)/C,(p-T)/b,(-f-w)/C,(-p-T)/b);0===n&&M>0?M-=2*l:1===n&&M<0&&(M+=2*l);const P=Math.ceil(Math.abs(M/l*2)),E=[],A=M/P,j=8/3*Math.sin(A/4)*Math.sin(A/4)/Math.sin(A/2);let F=D+A;for(let t=0;t{let e=0,s=0,i=0,r=0;const n=[];let o,a=0,h=0;for(const c of t){const t=[...c];let l;switch(t[0]){case"l":t[1]+=e,t[2]+=s;case"L":e=t[1],s=t[2],l=["L",e,s];break;case"h":t[1]+=e;case"H":e=t[1],l=["L",e,s];break;case"v":t[1]+=s;case"V":s=t[1],l=["L",e,s];break;case"m":t[1]+=e,t[2]+=s;case"M":e=t[1],s=t[2],i=t[1],r=t[2],l=["M",e,s];break;case"c":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s,t[5]+=e,t[6]+=s;case"C":a=t[3],h=t[4],e=t[5],s=t[6],l=["C",t[1],t[2],a,h,e,s];break;case"s":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s;case"S":"C"===o?(a=2*e-a,h=2*s-h):(a=e,h=s),e=t[3],s=t[4],l=["C",a,h,t[1],t[2],e,s],a=l[3],h=l[4];break;case"q":t[1]+=e,t[2]+=s,t[3]+=e,t[4]+=s;case"Q":a=t[1],h=t[2],e=t[3],s=t[4],l=["Q",a,h,e,s];break;case"t":t[1]+=e,t[2]+=s;case"T":"Q"===o?(a=2*e-a,h=2*s-h):(a=e,h=s),e=t[1],s=t[2],l=["Q",a,h,e,s];break;case"a":t[6]+=e,t[7]+=s;case"A":Br(e,s,t).forEach((t=>n.push(t))),e=t[6],s=t[7];break;case"z":case"Z":e=i,s=r,l=["Z"]}l?(n.push(l),o=l[0]):o=""}return n},Wr=(t,e,s,i)=>Math.sqrt((s-t)**2+(i-e)**2),Yr=(t,e,s,i,r,n,o,a)=>h=>{const c=h**3,l=(t=>3*t**2*(1-t))(h),u=(t=>3*t*(1-t)**2)(h),d=(t=>(1-t)**3)(h);return new ot(o*c+r*l+s*u+t*d,a*c+n*l+i*u+e*d)},Vr=t=>t**2,Hr=t=>2*t*(1-t),zr=t=>(1-t)**2,Gr=(t,e,s,i,r,n,o,a)=>h=>{const c=Vr(h),l=Hr(h),u=zr(h),d=3*(u*(s-t)+l*(r-s)+c*(o-r)),g=3*(u*(i-e)+l*(n-i)+c*(a-n));return Math.atan2(g,d)},Nr=(t,e,s,i,r,n)=>o=>{const a=Vr(o),h=Hr(o),c=zr(o);return new ot(r*a+s*h+t*c,n*a+i*h+e*c)},Ur=(t,e,s,i,r,n)=>o=>{const a=1-o,h=2*(a*(s-t)+o*(r-s)),c=2*(a*(i-e)+o*(n-i));return Math.atan2(c,h)},qr=(t,e,s)=>{let i=new ot(e,s),r=0;for(let e=1;e<=100;e+=1){const s=t(e/100);r+=Wr(i.x,i.y,s.x,s.y),i=s}return r},Kr=(t,e)=>{let i,r=0,n=0,o={x:t.x,y:t.y},a=s({},o),h=.01,c=0;const l=t.iterator,u=t.angleFinder;for(;n1e-4;)a=l(r),c=r,i=Wr(o.x,o.y,a.x,a.y),i+n>e?(r-=h,h/=2):(o=a,r+=h,n+=i);return s(s({},a),{},{angle:u(c)})},Jr=t=>{let e,s,i=0,r=0,n=0,o=0,a=0;const h=[];for(const c of t){const t={x:r,y:n,command:c[0],length:0};switch(c[0]){case"M":s=t,s.x=o=r=c[1],s.y=a=n=c[2];break;case"L":s=t,s.length=Wr(r,n,c[1],c[2]),r=c[1],n=c[2];break;case"C":e=Yr(r,n,c[1],c[2],c[3],c[4],c[5],c[6]),s=t,s.iterator=e,s.angleFinder=Gr(r,n,c[1],c[2],c[3],c[4],c[5],c[6]),s.length=qr(e,r,n),r=c[5],n=c[6];break;case"Q":e=Nr(r,n,c[1],c[2],c[3],c[4]),s=t,s.iterator=e,s.angleFinder=Ur(r,n,c[1],c[2],c[3],c[4]),s.length=qr(e,r,n),r=c[3],n=c[4];break;case"Z":s=t,s.destX=o,s.destY=a,s.length=Wr(r,n,o,a),r=o,n=a}i+=s.length,h.push(s)}return h.push({length:i,x:r,y:n}),h},Qr=function(t,e){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:Jr(t),r=0;for(;e-i[r].length>0&&r{var e;const s=[],i=null!==(e=t.match(Zr))&&void 0!==e?e:[];for(const t of i){const e=t[0];if("z"===e||"Z"===e){s.push([e]);continue}const i=en[e.toLowerCase()];let r=[];if("a"===e||"A"===e){$r.lastIndex=0;for(let e=null;e=$r.exec(t);)r.push(...e.slice(1))}else r=t.match(tn)||[];for(let t=0;t0&&o?o:e;for(let e=0;e1&&void 0!==arguments[1]?arguments[1]:0,s=new ot(t[0]),i=new ot(t[1]),r=1,n=0;const o=[],a=t.length,h=a>2;let c;for(h&&(r=t[2].xt[c-2].x?1:s.x===t[c-2].x?0:-1,n=s.y>t[c-2].y?1:s.y===t[c-2].y?0:-1),o.push(["L",s.x+r*e,s.y+n*e]),o},nn=(t,e)=>t.map((t=>t.map(((t,s)=>0===s||void 0===e?t:Ut(t,e))).join(" "))).join(" ");function on(t,e){const s=t.style;s&&e&&("string"==typeof e?s.cssText+=";"+e:Object.entries(e).forEach((t=>{let[e,i]=t;return s.setProperty(e,i)})))}const an=(t,e)=>Math.floor(Math.random()*(e-t+1))+t;function hn(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=e.onComplete||C,i=new(v().XMLHttpRequest),r=e.signal,n=function(){i.abort()},o=function(){r&&r.removeEventListener("abort",n),i.onerror=i.ontimeout=C};if(r&&r.aborted)throw new c("request");return r&&r.addEventListener("abort",n,{once:!0}),i.onreadystatechange=function(){4===i.readyState&&(o(),s(i),i.onreadystatechange=C)},i.onerror=i.ontimeout=o,i.open("get",t,!0),i.send(),i}const cn=(t,e)=>{let s=t._findCenterFromElement();t.transformMatrix&&((t=>{if(t.transformMatrix){const{scaleX:e,scaleY:s,angle:i,skewX:r}=Ot(t.transformMatrix);t.flipX=!1,t.flipY=!1,t.set(G,e),t.set(N,s),t.angle=i,t.skewX=r,t.skewY=0}})(t),s=s.transform(t.transformMatrix)),delete t.transformMatrix,e&&(t.scaleX*=e.scaleX,t.scaleY*=e.scaleY,t.cropX=e.cropX,t.cropY=e.cropY,s.x+=e.offsetLeft,s.y+=e.offsetTop,t.width=e.width,t.height=e.height),t.setPositionByOrigin(s,D,D)};var ln=Object.freeze({__proto__:null,addTransformToObject:ye,animate:As,animateColor:js,applyTransformToObject:_e,calcAngleBetweenVectors:ss,calcDimensionsMatrix:jt,calcPlaneChangeMatrix:we,calcVectorRotation:is,cancelAnimFrame:dt,capValue:ds,composeMatrix:Ft,copyCanvasElement:t=>{var e;const s=pt();return s.width=t.width,s.height=t.height,null===(e=s.getContext("2d"))||void 0===e||e.drawImage(t,0,0),s},cos:rt,createCanvasElement:pt,createImage:mt,createRotateMatrix:Dt,createScaleMatrix:Mt,createSkewXMatrix:Et,createSkewYMatrix:At,createTranslateMatrix:kt,createVector:ts,crossProduct:os,degreesToRadians:yt,dotProduct:as,ease:Cs,enlivenObjectEnlivables:It,enlivenObjects:Rt,findScaleToCover:Pr,findScaleToFit:Mr,getBoundsOfCurve:Ir,getOrthonormalVector:ns,getPathSegmentsInfo:Jr,getPointOnPath:Qr,getPointer:ge,getRandomInt:an,getRegularPolygonPath:(t,e)=>{const s=2*Math.PI/t;let i=-b;t%2==0&&(i+=s/2);const r=new Array(t+1);for(let n=0;n{const e=["instantiated_by_use","style","id","class"];switch(t){case"linearGradient":return e.concat(["x1","y1","x2","y2","gradientUnits","gradientTransform"]);case"radialGradient":return e.concat(["gradientUnits","gradientTransform","cx","cy","r","fx","fy","fr"]);case"stop":return e.concat(["offset","stop-color","stop-opacity"])}return e},getUnitVector:rs,groupSVGElements:(t,e)=>t&&1===t.length?t[0]:new Dr(t,e),hasStyleChanged:Pi,invertTransform:bt,isBetweenVectors:hs,isIdentityMatrix:xt,isTouchEvent:fe,isTransparent:_i,joinPath:nn,loadImage:Lt,magnitude:es,makeBoundingBoxFromPoints:me,makePathSimpler:Xr,matrixToSVG:Jt,mergeClipPaths:(t,e)=>{var s;let i=t,r=e;i.inverted&&!r.inverted&&(i=e,r=t),Oe(r,null===(s=r.group)||void 0===s?void 0:s.calcTransformMatrix(),i.calcTransformMatrix());const n=i.inverted&&r.inverted;return n&&(i.inverted=r.inverted=!1),new Dr([i],{clipPath:r,inverted:n})},multiplyTransformMatrices:wt,multiplyTransformMatrixArray:St,parsePath:sn,parsePreserveAspectRatioAttribute:Kt,parseUnit:qt,pick:Bt,projectStrokeOnPoints:Si,qrDecompose:Ot,radiansToDegrees:_t,removeFromArray:it,removeTransformFromObject:(t,e)=>{const s=bt(e),i=wt(s,t.calcOwnMatrix());_e(t,i)},removeTransformMatrixForSvgParsing:cn,request:hn,requestAnimFrame:ut,resetObjectTransform:xe,rotatePoint:(t,e,s)=>t.rotate(s,e),rotateVector:$e,saveObjectTransform:Ce,sendObjectToPlane:Oe,sendPointToPlane:Se,sendVectorToPlane:Te,setStyle:on,sin:nt,sizeAfterTransform:be,string:Mi,stylesFromArray:Ai,stylesToArray:Ei,toDataURL:vt,toFixed:Ut,transformPath:(t,e,s)=>(s&&(e=wt(e,[1,0,0,1,-s.x,-s.y])),t.map((t=>{const s=[...t];for(let i=1;i1&&void 0!==arguments[1]?arguments[1]:{};super(e),t(this,"upper",void 0),t(this,"container",void 0);const{el:r}=this.lower,n=this.createUpperCanvas();this.upper={el:n,ctx:n.getContext("2d")},this.applyCanvasStyle(r,{allowTouchScrolling:s}),this.applyCanvasStyle(n,{allowTouchScrolling:s,styles:{position:"absolute",left:"0",top:"0"}});const o=this.createContainerElement();o.classList.add(i),r.parentNode&&r.parentNode.replaceChild(o,r),o.append(r,n),this.container=o}createUpperCanvas(){const{el:t}=this.lower,e=pt();return e.className=t.className,e.classList.remove("lower-canvas"),e.classList.add("upper-canvas"),e.setAttribute("data-fabric","top"),e.style.cssText=t.style.cssText,e.setAttribute("draggable","true"),e}createContainerElement(){const t=m().createElement("div");return t.setAttribute("data-fabric","wrapper"),on(t,{position:"relative"}),he(t),t}applyCanvasStyle(t,e){const{styles:i,allowTouchScrolling:r}=e;on(t,s(s({},i),{},{"touch-action":r?"manipulation":j})),he(t)}setDimensions(t,e){super.setDimensions(t,e);const{el:s,ctx:i}=this.upper;oe(s,i,t,e)}setCSSDimensions(t){super.setCSSDimensions(t),ae(this.upper.el,t),ae(this.container,t)}cleanupDOM(t){const e=this.container,{el:s}=this.lower,{el:i}=this.upper;super.cleanupDOM(t),e.removeChild(i),e.removeChild(s),e.parentNode&&e.parentNode.replaceChild(s,e)}dispose(){super.dispose(),p().dispose(this.upper.el),delete this.upper,delete this.container}}class dn extends ue{constructor(){super(...arguments),t(this,"targets",[]),t(this,"_hoveredTargets",[]),t(this,"_objectsToRender",void 0),t(this,"_currentTransform",null),t(this,"_groupSelector",null),t(this,"contextTopDirty",!1)}static getDefaults(){return s(s({},super.getDefaults()),dn.ownDefaults)}get upperCanvasEl(){var t;return null===(t=this.elements.upper)||void 0===t?void 0:t.el}get contextTop(){var t;return null===(t=this.elements.upper)||void 0===t?void 0:t.ctx}get wrapperEl(){return this.elements.container}initElements(t){this.elements=new un(t,{allowTouchScrolling:this.allowTouchScrolling,containerClass:this.containerClass}),this._createCacheCanvas()}_onObjectAdded(t){this._objectsToRender=void 0,super._onObjectAdded(t)}_onObjectRemoved(t){this._objectsToRender=void 0,t===this._activeObject&&(this.fire("before:selection:cleared",{deselected:[t]}),this._discardActiveObject(),this.fire("selection:cleared",{deselected:[t]}),t.fire("deselected",{target:t})),t===this._hoveredTarget&&(this._hoveredTarget=void 0,this._hoveredTargets=[]),super._onObjectRemoved(t)}_onStackOrderChanged(){this._objectsToRender=void 0,super._onStackOrderChanged()}_chooseObjectsToRender(){const t=this._activeObject;return!this.preserveObjectStacking&&t?this._objects.filter((e=>!e.group&&e!==t)).concat(t):this._objects}renderAll(){this.cancelRequestedRender(),this.destroyed||(!this.contextTopDirty||this._groupSelector||this.isDrawingMode||(this.clearContext(this.contextTop),this.contextTopDirty=!1),this.hasLostContext&&(this.renderTopLayer(this.contextTop),this.hasLostContext=!1),!this._objectsToRender&&(this._objectsToRender=this._chooseObjectsToRender()),this.renderCanvas(this.getContext(),this._objectsToRender))}renderTopLayer(t){t.save(),this.isDrawingMode&&this._isCurrentlyDrawing&&(this.freeDrawingBrush&&this.freeDrawingBrush._render(),this.contextTopDirty=!0),this.selection&&this._groupSelector&&(this._drawSelection(t),this.contextTopDirty=!0),t.restore()}renderTop(){const t=this.contextTop;this.clearContext(t),this.renderTopLayer(t),this.fire("after:render",{ctx:t})}setTargetFindTolerance(t){t=Math.round(t),this.targetFindTolerance=t;const e=this.getRetinaScaling(),s=Math.ceil((2*t+1)*e);this.pixelFindCanvasEl.width=this.pixelFindCanvasEl.height=s,this.pixelFindContext.scale(e,e)}isTargetTransparent(t,e,s){const i=this.targetFindTolerance,r=this.pixelFindContext;this.clearContext(r),r.save(),r.translate(-e+i,-s+i),r.transform(...this.viewportTransform);const n=t.selectionBackgroundColor;t.selectionBackgroundColor="",t.render(r),t.selectionBackgroundColor=n,r.restore();const o=Math.round(i*this.getRetinaScaling());return _i(r,o,o,o)}_isSelectionKeyPressed(t){const e=this.selectionKey;return!!e&&(Array.isArray(e)?!!e.find((e=>!!e&&!0===t[e])):t[e])}_shouldClearSelection(t,e){const s=this.getActiveObjects(),i=this._activeObject;return!!(!e||e&&i&&s.length>1&&-1===s.indexOf(e)&&i!==e&&!this._isSelectionKeyPressed(t)||e&&!e.evented||e&&!e.selectable&&i&&i!==e)}_shouldCenterTransform(t,e,s){if(!t)return;let i;return e===z||e===G||e===N||e===W?i=this.centeredScaling||t.centeredScaling:e===B&&(i=this.centeredRotation||t.centeredRotation),i?!s:s}_getOriginFromCorner(t,e){const s={x:t.originX,y:t.originY};return e?(["ml","tl","bl"].includes(e)?s.x=A:["mr","tr","br"].includes(e)&&(s.x=M),["tl","mt","tr"].includes(e)?s.y=E:["bl","mb","br"].includes(e)&&(s.y=P),s):s}_setupCurrentTransform(t,e,i){var r;const n=e.group?Se(this.getScenePoint(t),void 0,e.group.calcTransformMatrix()):this.getScenePoint(t),{key:o="",control:a}=e.getActiveControl()||{},h=i&&a?null===(r=a.getActionHandler(t,e,a))||void 0===r?void 0:r.bind(a):Ie,c=((t,e,s,i)=>{if(!e||!t)return"drag";const r=i.controls[e];return r.getActionName(s,r,i)})(i,o,t,e),l=t[this.centeredKey],u=this._shouldCenterTransform(e,c,l)?{x:D,y:D}:this._getOriginFromCorner(e,o),d={target:e,action:c,actionHandler:h,actionPerformed:!1,corner:o,scaleX:e.scaleX,scaleY:e.scaleY,skewX:e.skewX,skewY:e.skewY,offsetX:n.x-e.left,offsetY:n.y-e.top,originX:u.x,originY:u.y,ex:n.x,ey:n.y,lastX:n.x,lastY:n.y,theta:yt(e.angle),width:e.width,height:e.height,shiftKey:t.shiftKey,altKey:l,original:s(s({},Ce(e)),{},{originX:u.x,originY:u.y})};this._currentTransform=d,this.fire("before:transform",{e:t,transform:d})}setCursor(t){this.upperCanvasEl.style.cursor=t}_drawSelection(t){const{x:e,y:s,deltaX:i,deltaY:r}=this._groupSelector,n=new ot(e,s).transform(this.viewportTransform),o=new ot(e+i,s+r).transform(this.viewportTransform),a=this.selectionLineWidth/2;let h=Math.min(n.x,o.x),c=Math.min(n.y,o.y),l=Math.max(n.x,o.x),u=Math.max(n.y,o.y);this.selectionColor&&(t.fillStyle=this.selectionColor,t.fillRect(h,c,l-h,u-c)),this.selectionLineWidth&&this.selectionBorderColor&&(t.lineWidth=this.selectionLineWidth,t.strokeStyle=this.selectionBorderColor,h+=a,c+=a,l-=a,u-=a,yi.prototype._setLineDash.call(this,t,this.selectionDashArray),t.strokeRect(h,c,l-h,u-c))}findTarget(t){if(this.skipTargetFind)return;const e=this.getViewportPoint(t),s=this._activeObject,i=this.getActiveObjects();if(this.targets=[],s&&i.length>=1){if(s.findControl(e,fe(t)))return s;if(i.length>1&&this.searchPossibleTargets([s],e))return s;if(s===this.searchPossibleTargets([s],e)){if(this.preserveObjectStacking){const i=this.targets;this.targets=[];const r=this.searchPossibleTargets(this._objects,e);return t[this.altSelectionKey]&&r&&r!==s?(this.targets=i,s):r}return s}}return this.searchPossibleTargets(this._objects,e)}_pointIsInObjectSelectionArea(t,e){let s=t.getCoords();const i=this.getZoom(),r=t.padding/i;if(r){const[t,e,i,n]=s,o=Math.atan2(e.y-t.y,e.x-t.x),a=rt(o)*r,h=nt(o)*r,c=a+h,l=a-h;s=[new ot(t.x-l,t.y-c),new ot(e.x+c,e.y-l),new ot(i.x+l,i.y+c),new ot(n.x-c,n.y+l)]}return Fs.isPointInPolygon(e,s)}_checkTarget(t,e){if(t&&t.visible&&t.evented&&this._pointIsInObjectSelectionArea(t,Se(e,void 0,this.viewportTransform))){if(!this.perPixelTargetFind&&!t.perPixelTargetFind||t.isEditing)return!0;if(!this.isTargetTransparent(t,e.x,e.y))return!0}return!1}_searchPossibleTargets(t,e){let s=t.length;for(;s--;){const i=t[s];if(this._checkTarget(i,e)){if(ht(i)&&i.subTargetCheck){const t=this._searchPossibleTargets(i._objects,e);t&&this.targets.push(t)}return i}}}searchPossibleTargets(t,e){const s=this._searchPossibleTargets(t,e);if(s&&ht(s)&&s.interactive&&this.targets[0]){const t=this.targets;for(let e=t.length-1;e>0;e--){const s=t[e];if(!ht(s)||!s.interactive)return s}return t[0]}return s}getViewportPoint(t){return this._pointer?this._pointer:this.getPointer(t,!0)}getScenePoint(t){return this._absolutePointer?this._absolutePointer:this.getPointer(t)}getPointer(t){let e=arguments.length>1&&void 0!==arguments[1]&&arguments[1];const s=this.upperCanvasEl,i=s.getBoundingClientRect();let r=ge(t),n=i.width||0,o=i.height||0;n&&o||(P in i&&E in i&&(o=Math.abs(i.top-i.bottom)),A in i&&M in i&&(n=Math.abs(i.right-i.left))),this.calcOffset(),r.x=r.x-this._offset.left,r.y=r.y-this._offset.top,e||(r=Se(r,void 0,this.viewportTransform));const a=this.getRetinaScaling();1!==a&&(r.x/=a,r.y/=a);const h=0===n||0===o?new ot(1,1):new ot(s.width/n,s.height/o);return r.multiply(h)}_setDimensionsImpl(t,e){this._resetTransformEventData(),super._setDimensionsImpl(t,e),this._isCurrentlyDrawing&&this.freeDrawingBrush&&this.freeDrawingBrush._setBrushStyles(this.contextTop)}_createCacheCanvas(){this.pixelFindCanvasEl=pt(),this.pixelFindContext=this.pixelFindCanvasEl.getContext("2d",{willReadFrequently:!0}),this.setTargetFindTolerance(this.targetFindTolerance)}getTopContext(){return this.elements.upper.ctx}getSelectionContext(){return this.elements.upper.ctx}getSelectionElement(){return this.elements.upper.el}getActiveObject(){return this._activeObject}getActiveObjects(){const t=this._activeObject;return se(t)?t.getObjects():t?[t]:[]}_fireSelectionEvents(t,e){let s=!1,i=!1;const r=this.getActiveObjects(),n=[],o=[];t.forEach((t=>{r.includes(t)||(s=!0,t.fire("deselected",{e:e,target:t}),o.push(t))})),r.forEach((i=>{t.includes(i)||(s=!0,i.fire("selected",{e:e,target:i}),n.push(i))})),t.length>0&&r.length>0?(i=!0,s&&this.fire("selection:updated",{e:e,selected:n,deselected:o})):r.length>0?(i=!0,this.fire("selection:created",{e:e,selected:n})):t.length>0&&(i=!0,this.fire("selection:cleared",{e:e,deselected:o})),i&&(this._objectsToRender=void 0)}setActiveObject(t,e){const s=this.getActiveObjects(),i=this._setActiveObject(t,e);return this._fireSelectionEvents(s,e),i}_setActiveObject(t,e){const s=this._activeObject;return s!==t&&(!(!this._discardActiveObject(e,t)&&this._activeObject)&&(!t.onSelect({e:e})&&(this._activeObject=t,se(t)&&s!==t&&t.set("canvas",this),t.setCoords(),!0)))}_discardActiveObject(t,e){const s=this._activeObject;return!!s&&(!s.onDeselect({e:t,object:e})&&(this._currentTransform&&this._currentTransform.target===s&&this.endCurrentTransform(t),se(s)&&s===this._hoveredTarget&&(this._hoveredTarget=void 0),this._activeObject=void 0,!0))}discardActiveObject(t){const e=this.getActiveObjects(),s=this.getActiveObject();e.length&&this.fire("before:selection:cleared",{e:t,deselected:[s]});const i=this._discardActiveObject(t);return this._fireSelectionEvents(e,t),i}endCurrentTransform(t){const e=this._currentTransform;this._finalizeCurrentTransform(t),e&&e.target&&(e.target.isMoving=!1),this._currentTransform=null}_finalizeCurrentTransform(t){const e=this._currentTransform,s=e.target,i={e:t,target:s,transform:e,action:e.action};s._scaling&&(s._scaling=!1),s.setCoords(),e.actionPerformed&&(this.fire("object:modified",i),s.fire(Q,i))}setViewportTransform(t){super.setViewportTransform(t);const e=this._activeObject;e&&e.setCoords()}destroy(){const t=this._activeObject;se(t)&&(t.removeAll(),t.dispose()),delete this._activeObject,super.destroy(),this.pixelFindContext=null,this.pixelFindCanvasEl=void 0}clear(){this.discardActiveObject(),this._activeObject=void 0,this.clearContext(this.contextTop),super.clear()}drawControls(t){const e=this._activeObject;e&&e._renderControls(t)}_toObject(t,e,s){const i=this._realizeGroupTransformOnObject(t),r=super._toObject(t,e,s);return t.set(i),r}_realizeGroupTransformOnObject(t){const{group:e}=t;if(e&&se(e)&&this._activeObject===e){const s=Bt(t,["angle","flipX","flipY",M,G,N,U,q,P]);return ye(t,e.calcOwnMatrix()),s}return{}}_setSVGObject(t,e,s){const i=this._realizeGroupTransformOnObject(e);super._setSVGObject(t,e,s),e.set(i)}}t(dn,"ownDefaults",{uniformScaling:!0,uniScaleKey:"shiftKey",centeredScaling:!1,centeredRotation:!1,centeredKey:"altKey",altActionKey:"shiftKey",selection:!0,selectionKey:"shiftKey",selectionColor:"rgba(100, 100, 255, 0.3)",selectionDashArray:[],selectionBorderColor:"rgba(255, 255, 255, 0.3)",selectionLineWidth:1,selectionFullyContained:!1,hoverCursor:"move",moveCursor:"move",defaultCursor:"default",freeDrawingCursor:"crosshair",notAllowedCursor:"not-allowed",perPixelTargetFind:!1,targetFindTolerance:0,skipTargetFind:!1,stopContextMenu:!1,fireRightClick:!1,fireMiddleClick:!1,enablePointerEvents:!1,containerClass:"canvas-container",preserveObjectStacking:!1});class gn{constructor(e){t(this,"targets",[]),t(this,"__disposer",void 0);const s=()=>{const{hiddenTextarea:t}=e.getActiveObject()||{};t&&t.focus()},i=e.upperCanvasEl;i.addEventListener("click",s),this.__disposer=()=>i.removeEventListener("click",s)}exitTextEditing(){this.target=void 0,this.targets.forEach((t=>{t.isEditing&&t.exitEditing()}))}add(t){this.targets.push(t)}remove(t){this.unregister(t),it(this.targets,t)}register(t){this.target=t}unregister(t){t===this.target&&(this.target=void 0)}onMouseMove(t){var e;(null===(e=this.target)||void 0===e?void 0:e.isEditing)&&this.target.updateSelectionOnMouseMove(t)}clear(){this.targets=[],this.target=void 0}dispose(){this.clear(),this.__disposer(),delete this.__disposer}}const fn=["target","oldTarget","fireCanvas","e"],pn={passive:!1},mn=(t,e)=>{const s=t.getViewportPoint(e),i=t.getScenePoint(e);return{viewportPoint:s,scenePoint:i,pointer:s,absolutePointer:i}},vn=function(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),i=1;i1?e-1:0),i=1;i1&&void 0!==arguments[1]?arguments[1]:{}),t(this,"_isClick",void 0),t(this,"textEditingManager",new gn(this)),["_onMouseDown","_onTouchStart","_onMouseMove","_onMouseUp","_onTouchEnd","_onResize","_onMouseWheel","_onMouseOut","_onMouseEnter","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragProgress","_onDragOver","_onDragEnter","_onDragLeave","_onDrop"].forEach((t=>{this[t]=this[t].bind(this)})),this.addOrRemove(vn,"add")}_getEventPrefix(){return this.enablePointerEvents?"pointer":"mouse"}addOrRemove(t,e){const s=this.upperCanvasEl,i=this._getEventPrefix();t(ne(s),"resize",this._onResize),t(s,i+"down",this._onMouseDown),t(s,"".concat(i,"move"),this._onMouseMove,pn),t(s,"".concat(i,"out"),this._onMouseOut),t(s,"".concat(i,"enter"),this._onMouseEnter),t(s,"wheel",this._onMouseWheel),t(s,"contextmenu",this._onContextMenu),t(s,"dblclick",this._onDoubleClick),t(s,"dragstart",this._onDragStart),t(s,"dragend",this._onDragEnd),t(s,"dragover",this._onDragOver),t(s,"dragenter",this._onDragEnter),t(s,"dragleave",this._onDragLeave),t(s,"drop",this._onDrop),this.enablePointerEvents||t(s,"touchstart",this._onTouchStart,pn)}removeListeners(){this.addOrRemove(yn,"remove");const t=this._getEventPrefix(),e=re(this.upperCanvasEl);yn(e,"".concat(t,"up"),this._onMouseUp),yn(e,"touchend",this._onTouchEnd,pn),yn(e,"".concat(t,"move"),this._onMouseMove,pn),yn(e,"touchmove",this._onMouseMove,pn)}_onMouseWheel(t){this.__onMouseWheel(t)}_onMouseOut(t){const e=this._hoveredTarget,i=s({e:t},mn(this,t));this.fire("mouse:out",s(s({},i),{},{target:e})),this._hoveredTarget=void 0,e&&e.fire("mouseout",s({},i)),this._hoveredTargets.forEach((t=>{this.fire("mouse:out",s(s({},i),{},{target:t})),t&&t.fire("mouseout",s({},i))})),this._hoveredTargets=[]}_onMouseEnter(t){this._currentTransform||this.findTarget(t)||(this.fire("mouse:over",s({e:t},mn(this,t))),this._hoveredTarget=void 0,this._hoveredTargets=[])}_onDragStart(t){this._isClick=!1;const e=this.getActiveObject();if(e&&e.onDragStart(t)){this._dragSource=e;const s={e:t,target:e};return this.fire("dragstart",s),e.fire("dragstart",s),void vn(this.upperCanvasEl,"drag",this._onDragProgress)}pe(t)}_renderDragEffects(t,e,s){let i=!1;const r=this._dropTarget;r&&r!==e&&r!==s&&(r.clearContextTop(),i=!0),null==e||e.clearContextTop(),s!==e&&(null==s||s.clearContextTop());const n=this.contextTop;n.save(),n.transform(...this.viewportTransform),e&&(n.save(),e.transform(n),e.renderDragSourceEffect(t),n.restore(),i=!0),s&&(n.save(),s.transform(n),s.renderDropTargetEffect(t),n.restore(),i=!0),n.restore(),i&&(this.contextTopDirty=!0)}_onDragEnd(t){const e=!!t.dataTransfer&&t.dataTransfer.dropEffect!==j,s=e?this._activeObject:void 0,i={e:t,target:this._dragSource,subTargets:this.targets,dragSource:this._dragSource,didDrop:e,dropTarget:s};yn(this.upperCanvasEl,"drag",this._onDragProgress),this.fire("dragend",i),this._dragSource&&this._dragSource.fire("dragend",i),delete this._dragSource,this._onMouseUp(t)}_onDragProgress(t){const e={e:t,target:this._dragSource,dragSource:this._dragSource,dropTarget:this._draggedoverTarget};this.fire("drag",e),this._dragSource&&this._dragSource.fire("drag",e)}findDragTargets(t){this.targets=[];return{target:this._searchPossibleTargets(this._objects,this.getViewportPoint(t)),targets:[...this.targets]}}_onDragOver(t){const e="dragover",{target:s,targets:i}=this.findDragTargets(t),r=this._dragSource,n={e:t,target:s,subTargets:i,dragSource:r,canDrop:!1,dropTarget:void 0};let o;this.fire(e,n),this._fireEnterLeaveEvents(s,n),s&&(s.canDrop(t)&&(o=s),s.fire(e,n));for(let s=0;s0)return;this.__onMouseUp(t),this._resetTransformEventData(),delete this.mainTouchId;const e=this._getEventPrefix(),s=re(this.upperCanvasEl);yn(s,"touchend",this._onTouchEnd,pn),yn(s,"touchmove",this._onMouseMove,pn),this._willAddMouseDown&&clearTimeout(this._willAddMouseDown),this._willAddMouseDown=setTimeout((()=>{vn(this.upperCanvasEl,"".concat(e,"down"),this._onMouseDown),this._willAddMouseDown=0}),400)}_onMouseUp(t){this.__onMouseUp(t),this._resetTransformEventData();const e=this.upperCanvasEl,s=this._getEventPrefix();if(this._isMainEvent(t)){const t=re(this.upperCanvasEl);yn(t,"".concat(s,"up"),this._onMouseUp),yn(t,"".concat(s,"move"),this._onMouseMove,pn),vn(e,"".concat(s,"move"),this._onMouseMove,pn)}}_onMouseMove(t){const e=this.getActiveObject();!this.allowTouchScrolling&&(!e||!e.shouldStartDragging(t))&&t.preventDefault&&t.preventDefault(),this.__onMouseMove(t)}_onResize(){this.calcOffset(),this._resetTransformEventData()}_shouldRender(t){const e=this.getActiveObject();return!!e!=!!t||e&&t&&e!==t}__onMouseUp(t){var e;this._cacheTransformEventData(t),this._handleEvent(t,"up:before");const s=this._currentTransform,i=this._isClick,r=this._target,{button:n}=t;if(n)return(this.fireMiddleClick&&1===n||this.fireRightClick&&2===n)&&this._handleEvent(t,"up"),void this._resetTransformEventData();if(this.isDrawingMode&&this._isCurrentlyDrawing)return void this._onMouseUpInDrawingMode(t);if(!this._isMainEvent(t))return;let o,a,h=!1;if(s&&(this._finalizeCurrentTransform(t),h=s.actionPerformed),!i){const e=r===this._activeObject;this.handleSelection(t),h||(h=this._shouldRender(r)||!e&&r===this._activeObject)}if(r){const e=r.findControl(this.getViewportPoint(t),fe(t)),{key:i,control:n}=e||{};if(a=i,r.selectable&&r!==this._activeObject&&"up"===r.activeOn)this.setActiveObject(r,t),h=!0;else if(n){const e=n.getMouseUpHandler(t,r,n);e&&(o=this.getScenePoint(t),e.call(n,t,s,o.x,o.y))}r.isMoving=!1}if(s&&(s.target!==r||s.corner!==a)){const e=s.target&&s.target.controls[s.corner],i=e&&e.getMouseUpHandler(t,s.target,e);o=o||this.getScenePoint(t),i&&i.call(e,t,s,o.x,o.y)}this._setCursorFromEvent(t,r),this._handleEvent(t,"up"),this._groupSelector=null,this._currentTransform=null,r&&(r.__corner=void 0),h?this.requestRenderAll():i||null!==(e=this._activeObject)&&void 0!==e&&e.isEditing||this.renderTop()}_basicEventHandler(t,e){const{target:s,subTargets:i=[]}=e;this.fire(t,e),s&&s.fire(t,e);for(let r=0;r{s=t.hoverCursor||s})),this.setCursor(s)}handleMultiSelection(t,e){const s=this._activeObject,i=se(s);if(s&&this._isSelectionKeyPressed(t)&&this.selection&&e&&e.selectable&&(s!==e||i)&&(i||!e.isDescendantOf(s)&&!s.isDescendantOf(e))&&!e.onSelect({e:t})&&!s.getActiveControl()){if(i){const i=s.getObjects();if(e===s){const s=this.getViewportPoint(t);if(!(e=this.searchPossibleTargets(i,s)||this.searchPossibleTargets(this._objects,s))||!e.selectable)return!1}e.group===s?(s.remove(e),this._hoveredTarget=e,this._hoveredTargets=[...this.targets],1===s.size()&&this._setActiveObject(s.item(0),t)):(s.multiSelectAdd(e),this._hoveredTarget=s,this._hoveredTargets=[...this.targets]),this._fireSelectionEvents(i,t)}else{s.exitEditing&&s.exitEditing();const i=new(tt.getClass("ActiveSelection"))([],{canvas:this});i.multiSelectAdd(s,e),this._hoveredTarget=i,this._setActiveObject(i,t),this._fireSelectionEvents([s],t)}return!0}return!1}handleSelection(t){if(!this.selection||!this._groupSelector)return!1;const{x:e,y:s,deltaX:i,deltaY:r}=this._groupSelector,n=new ot(e,s),o=n.add(new ot(i,r)),a=n.min(o),h=n.max(o).subtract(a),c=this.collectObjects({left:a.x,top:a.y,width:h.x,height:h.y},{includeIntersecting:!this.selectionFullyContained}),l=n.eq(o)?c[0]?[c[0]]:[]:c.length>1?c.filter((e=>!e.onSelect({e:t}))).reverse():c;if(1===l.length)this.setActiveObject(l[0],t);else if(l.length>1){const e=tt.getClass("ActiveSelection");this.setActiveObject(new e(l,{canvas:this}),t)}return this._groupSelector=null,!0}clear(){this.textEditingManager.clear(),super.clear()}destroy(){this.removeListeners(),this.textEditingManager.dispose(),super.destroy()}}const Cn={x1:0,y1:0,x2:0,y2:0},bn=s(s({},Cn),{},{r1:0,r2:0}),wn=(t,e)=>isNaN(t)&&"number"==typeof e?e:t,Sn=/^(\d+\.\d+)%|(\d+)%$/;function Tn(t){return t&&Sn.test(t)}function On(t,e){const s="number"==typeof t?t:"string"==typeof t?parseFloat(t)/(Tn(t)?100:1):NaN;return ds(0,wn(s,e),1)}const kn=/\s*;\s*/,Dn=/\s*:\s*/;function Mn(t,e){let s,i;const r=t.getAttribute("style");if(r){const t=r.split(kn);""===t[t.length-1]&&t.pop();for(let e=t.length;e--;){const[r,n]=t[e].split(Dn).map((t=>t.trim()));"stop-color"===r?s=n:"stop-opacity"===r&&(i=n)}}const n=new Nt(s||t.getAttribute("stop-color")||"rgb(0,0,0)");return{offset:On(t.getAttribute("offset"),0),color:n.toRgb(),opacity:wn(parseFloat(i||t.getAttribute("stop-opacity")||""),1)*n.getAlpha()*e}}function Pn(t,e){const s=[],i=t.getElementsByTagName("stop"),r=On(e,1);for(let t=i.length;t--;)s.push(Mn(i[t],r));return s}function En(t){return"linearGradient"===t.nodeName||"LINEARGRADIENT"===t.nodeName?"linear":"radial"}function An(t){return"userSpaceOnUse"===t.getAttribute("gradientUnits")?"pixels":"percentage"}function jn(t,e){return t.getAttribute(e)}function Fn(t,e){return function(t,e){let s,{width:i,height:r,gradientUnits:n}=e;return Object.keys(t).reduce(((e,o)=>{const a=t[o];return"Infinity"===a?s=1:"-Infinity"===a?s=0:(s="string"==typeof a?parseFloat(a):a,"string"==typeof a&&Tn(a)&&(s*=.01,"pixels"===n&&("x1"!==o&&"x2"!==o&&"r2"!==o||(s*=i),"y1"!==o&&"y2"!==o||(s*=r)))),e[o]=s,e}),{})}("linear"===En(t)?function(t){return{x1:jn(t,"x1")||0,y1:jn(t,"y1")||0,x2:jn(t,"x2")||"100%",y2:jn(t,"y2")||0}}(t):function(t){return{x1:jn(t,"fx")||jn(t,"cx")||"50%",y1:jn(t,"fy")||jn(t,"cy")||"50%",r1:0,x2:jn(t,"cx")||"50%",y2:jn(t,"cy")||"50%",r2:jn(t,"r")||"50%"}}(t),s(s({},e),{},{gradientUnits:An(t)}))}class Ln{constructor(t){const{type:e="linear",gradientUnits:i="pixels",coords:r={},colorStops:n=[],offsetX:o=0,offsetY:a=0,gradientTransform:h,id:c}=t||{};Object.assign(this,{type:e,gradientUnits:i,coords:s(s({},"radial"===e?bn:Cn),r),colorStops:n,offsetX:o,offsetY:a,gradientTransform:h,id:c?"".concat(c,"_").concat(ft()):ft()})}addColorStop(t){for(const e in t){const s=new Nt(t[e]);this.colorStops.push({offset:parseFloat(e),color:s.toRgb(),opacity:s.getAlpha()})}return this}toObject(t){return s(s({},Bt(this,t)),{},{type:this.type,coords:s({},this.coords),colorStops:this.colorStops.map((t=>s({},t))),offsetX:this.offsetX,offsetY:this.offsetY,gradientUnits:this.gradientUnits,gradientTransform:this.gradientTransform?[...this.gradientTransform]:void 0})}toSVG(t){let{additionalTransform:e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i=[],r=this.gradientTransform?this.gradientTransform.concat():T.concat(),n="pixels"===this.gradientUnits?"userSpaceOnUse":"objectBoundingBox",o=this.colorStops.map((t=>s({},t))).sort(((t,e)=>t.offset-e.offset));let a=-this.offsetX,h=-this.offsetY;var c;"objectBoundingBox"===n?(a/=t.width,h/=t.height):(a+=t.width/2,h+=t.height/2),(c=t)&&"function"==typeof c._renderPathCommands&&"percentage"!==this.gradientUnits&&(a-=t.pathOffset.x,h-=t.pathOffset.y),r[4]-=a,r[5]-=h;const l=['id="SVGID_'.concat(this.id,'"'),'gradientUnits="'.concat(n,'"'),'gradientTransform="'.concat(e?e+" ":"").concat(Jt(r),'"'),""].join(" ");if("linear"===this.type){const{x1:t,y1:e,x2:s,y2:r}=this.coords;i.push("\n')}else if("radial"===this.type){const{x1:t,y1:e,x2:s,y2:r,r1:n,r2:a}=this.coords,h=n>a;i.push("\n'),h&&(o.reverse(),o.forEach((t=>{t.offset=1-t.offset})));const c=Math.min(n,a);if(c>0){const t=c/Math.max(n,a);o.forEach((e=>{e.offset+=t*(1-e.offset)}))}}return o.forEach((t=>{let{color:e,offset:s,opacity:r}=t;i.push("\n')})),i.push("linear"===this.type?"":"","\n"),i.join("")}toLive(t){const{x1:e,y1:s,x2:i,y2:r,r1:n,r2:o}=this.coords,a="linear"===this.type?t.createLinearGradient(e,s,i,r):t.createRadialGradient(e,s,n,i,r,o);return this.colorStops.forEach((t=>{let{color:e,opacity:s,offset:i}=t;a.addColorStop(i,void 0!==s?new Nt(e).setAlpha(s).toRgba():e)})),a}static async fromObject(t){const{colorStops:e,gradientTransform:i}=t;return new this(s(s({},t),{},{colorStops:e?e.map((t=>s({},t))):void 0,gradientTransform:i?[...i]:void 0}))}static fromElement(t,e,i){const r=An(t),n=e._findCenterFromElement();return new this(s({id:t.getAttribute("id")||void 0,type:En(t),coords:Fn(t,{width:i.viewBoxWidth||i.width,height:i.viewBoxHeight||i.height}),colorStops:Pn(t,i.opacity),gradientUnits:r,gradientTransform:nr(t.getAttribute("gradientTransform")||"")},"pixels"===r?{offsetX:e.width/2-n.x,offsetY:e.height/2-n.y}:{offsetX:0,offsetY:0}))}}t(Ln,"type","Gradient"),tt.setClass(Ln,"gradient"),tt.setClass(Ln,"linear"),tt.setClass(Ln,"radial");const Rn=["type","source","patternTransform"];class In{get type(){return"pattern"}set type(t){a("warn","Setting type has no effect",t)}constructor(e){t(this,"repeat","repeat"),t(this,"offsetX",0),t(this,"offsetY",0),t(this,"crossOrigin",""),this.id=ft(),Object.assign(this,e)}isImageSource(){return!!this.source&&"string"==typeof this.source.src}isCanvasSource(){return!!this.source&&!!this.source.toDataURL}sourceToString(){return this.isImageSource()?this.source.src:this.isCanvasSource()?this.source.toDataURL():""}toLive(t){return this.source&&(!this.isImageSource()||this.source.complete&&0!==this.source.naturalWidth&&0!==this.source.naturalHeight)?t.createPattern(this.source,this.repeat):null}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const{repeat:e,crossOrigin:i}=this;return s(s({},Bt(this,t)),{},{type:"pattern",source:this.sourceToString(),repeat:e,crossOrigin:i,offsetX:Ut(this.offsetX,o.NUM_FRACTION_DIGITS),offsetY:Ut(this.offsetY,o.NUM_FRACTION_DIGITS),patternTransform:this.patternTransform?[...this.patternTransform]:null})}toSVG(t){let{width:e,height:s}=t;const{source:i,repeat:r,id:n}=this,o=wn(this.offsetX/e,0),a=wn(this.offsetY/s,0),h="repeat-y"===r||"no-repeat"===r?1+Math.abs(o||0):wn(i.width/e,0),c="repeat-x"===r||"no-repeat"===r?1+Math.abs(a||0):wn(i.height/s,0);return[''),''),"",""].join("\n")}static async fromObject(t,e){let{type:r,source:n,patternTransform:o}=t,a=i(t,Rn);const h=await Lt(n,s(s({},e),{},{crossOrigin:a.crossOrigin}));return new this(s(s({},a),{},{patternTransform:o&&o.slice(0),source:h}))}}t(In,"type","Pattern"),tt.setClass(In),tt.setClass(In,"pattern");class Bn{constructor(e){t(this,"color","rgb(0, 0, 0)"),t(this,"width",1),t(this,"shadow",null),t(this,"strokeLineCap","round"),t(this,"strokeLineJoin","round"),t(this,"strokeMiterLimit",10),t(this,"strokeDashArray",null),t(this,"limitedToCanvasSize",!1),this.canvas=e}_setBrushStyles(t){t.strokeStyle=this.color,t.lineWidth=this.width,t.lineCap=this.strokeLineCap,t.miterLimit=this.strokeMiterLimit,t.lineJoin=this.strokeLineJoin,t.setLineDash(this.strokeDashArray||[])}_saveAndTransform(t){const e=this.canvas.viewportTransform;t.save(),t.transform(e[0],e[1],e[2],e[3],e[4],e[5])}needsFullRender(){return new Nt(this.color).getAlpha()<1||!!this.shadow}_setShadow(){if(!this.shadow||!this.canvas)return;const t=this.canvas,e=this.shadow,s=t.contextTop,i=t.getZoom()*t.getRetinaScaling();s.shadowColor=e.color,s.shadowBlur=e.blur*i,s.shadowOffsetX=e.offsetX*i,s.shadowOffsetY=e.offsetY*i}_resetShadow(){const t=this.canvas.contextTop;t.shadowColor="",t.shadowBlur=t.shadowOffsetX=t.shadowOffsetY=0}_isOutSideCanvas(t){return t.x<0||t.x>this.canvas.getWidth()||t.y<0||t.y>this.canvas.getHeight()}}const Xn=["path","left","top"],Wn=["d"];class Yn extends yi{constructor(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},{path:s,left:r,top:n}=e,o=i(e,Xn);super(),Object.assign(this,Yn.ownDefaults),this.setOptions(o),this._setPath(t||[],!0),"number"==typeof r&&this.set(M,r),"number"==typeof n&&this.set(P,n)}_setPath(t,e){this.path=Xr(Array.isArray(t)?t:sn(t)),this.setBoundingBox(e)}_findCenterFromElement(){const t=this._calcBoundsFromPath();return new ot(t.left+t.width/2,t.top+t.height/2)}_renderPathCommands(t){const e=-this.pathOffset.x,s=-this.pathOffset.y;t.beginPath();for(const i of this.path)switch(i[0]){case"L":t.lineTo(i[1]+e,i[2]+s);break;case"M":t.moveTo(i[1]+e,i[2]+s);break;case"C":t.bezierCurveTo(i[1]+e,i[2]+s,i[3]+e,i[4]+s,i[5]+e,i[6]+s);break;case"Q":t.quadraticCurveTo(i[1]+e,i[2]+s,i[3]+e,i[4]+s);break;case"Z":t.closePath()}}_render(t){this._renderPathCommands(t),this._renderPaintInOrder(t)}toString(){return"#")}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return s(s({},super.toObject(t)),{},{path:this.path.map((t=>t.slice()))})}toDatalessObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=this.toObject(t);return this.sourcePath&&(delete e.path,e.sourcePath=this.sourcePath),e}_toSVG(){const t=nn(this.path,o.NUM_FRACTION_DIGITS);return["\n')]}_getOffsetTransform(){const t=o.NUM_FRACTION_DIGITS;return" translate(".concat(Ut(-this.pathOffset.x,t),", ").concat(Ut(-this.pathOffset.y,t),")")}toClipPathSVG(t){const e=this._getOffsetTransform();return"\t"+this._createBaseClipPathSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})}toSVG(t){const e=this._getOffsetTransform();return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,additionalTransform:e})}complexity(){return this.path.length}setDimensions(){this.setBoundingBox()}setBoundingBox(t){const{width:e,height:s,pathOffset:i}=this._calcDimensions();this.set({width:e,height:s,pathOffset:i}),t&&this.setPositionByOrigin(i,D,D)}_calcBoundsFromPath(){const t=[];let e=0,s=0,i=0,r=0;for(const n of this.path)switch(n[0]){case"L":i=n[1],r=n[2],t.push({x:e,y:s},{x:i,y:r});break;case"M":i=n[1],r=n[2],e=i,s=r;break;case"C":t.push(...Ir(i,r,n[1],n[2],n[3],n[4],n[5],n[6])),i=n[5],r=n[6];break;case"Q":t.push(...Ir(i,r,n[1],n[2],n[1],n[2],n[3],n[4])),i=n[3],r=n[4];break;case"Z":i=e,r=s}return me(t)}_calcDimensions(){const t=this._calcBoundsFromPath();return s(s({},t),{},{pathOffset:new ot(t.left+t.width/2,t.top+t.height/2)})}static fromObject(t){return this._fromObject(t,{extraParam:"path"})}static async fromElement(t,e,r){const n=ur(t,this.ATTRIBUTE_NAMES,r),{d:o}=n;return new this(o,s(s(s({},i(n,Wn)),e),{},{left:void 0,top:void 0}))}}t(Yn,"type","Path"),t(Yn,"cacheProperties",[...fs,"path","fillRule"]),t(Yn,"ATTRIBUTE_NAMES",[...ji,"d"]),tt.setClass(Yn),tt.setSVGClass(Yn);class Vn extends Bn{constructor(e){super(e),t(this,"decimate",.4),t(this,"drawStraightLine",!1),t(this,"straightLineKey","shiftKey"),this._points=[],this._hasStraightLine=!1}needsFullRender(){return super.needsFullRender()||this._hasStraightLine}static drawSegment(t,e,s){const i=e.midPointFrom(s);return t.quadraticCurveTo(e.x,e.y,i.x,i.y),i}onMouseDown(t,e){let{e:s}=e;this.canvas._isMainEvent(s)&&(this.drawStraightLine=!!this.straightLineKey&&s[this.straightLineKey],this._prepareForDrawing(t),this._addPoint(t),this._render())}onMouseMove(t,e){let{e:s}=e;if(this.canvas._isMainEvent(s)&&(this.drawStraightLine=!!this.straightLineKey&&s[this.straightLineKey],(!0!==this.limitedToCanvasSize||!this._isOutSideCanvas(t))&&this._addPoint(t)&&this._points.length>1))if(this.needsFullRender())this.canvas.clearContext(this.canvas.contextTop),this._render();else{const t=this._points,e=t.length,s=this.canvas.contextTop;this._saveAndTransform(s),this.oldEnd&&(s.beginPath(),s.moveTo(this.oldEnd.x,this.oldEnd.y)),this.oldEnd=Vn.drawSegment(s,t[e-2],t[e-1]),s.stroke(),s.restore()}}onMouseUp(t){let{e:e}=t;return!this.canvas._isMainEvent(e)||(this.drawStraightLine=!1,this.oldEnd=void 0,this._finalizeAndAddPath(),!1)}_prepareForDrawing(t){this._reset(),this._addPoint(t),this.canvas.contextTop.moveTo(t.x,t.y)}_addPoint(t){return!(this._points.length>1&&t.eq(this._points[this._points.length-1]))&&(this.drawStraightLine&&this._points.length>1&&(this._hasStraightLine=!0,this._points.pop()),this._points.push(t),!0)}_reset(){this._points=[],this._setBrushStyles(this.canvas.contextTop),this._setShadow(),this._hasStraightLine=!1}_render(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.canvas.contextTop,e=this._points[0],s=this._points[1];if(this._saveAndTransform(t),t.beginPath(),2===this._points.length&&e.x===s.x&&e.y===s.y){const t=this.width/1e3;e.x-=t,s.x+=t}t.moveTo(e.x,e.y);for(let i=1;i=n&&(i=t[e],a.push(i));return a.push(t[o]),a}_finalizeAndAddPath(){this.canvas.contextTop.closePath(),this.decimate&&(this._points=this.decimatePoints(this._points,this.decimate));const t=this.convertPointsToSVGPath(this._points);if(function(t){return"M 0 0 Q 0 0 0 0 L 0 0"===nn(t)}(t))return void this.canvas.requestRenderAll();const e=this.createPath(t);this.canvas.clearContext(this.canvas.contextTop),this.canvas.fire("before:path:created",{path:e}),this.canvas.add(e),this.canvas.requestRenderAll(),e.setCoords(),this._resetShadow(),this.canvas.fire("path:created",{path:e})}}const Hn=["left","top","radius"],zn=["radius","startAngle","endAngle","counterClockwise"];class Gn extends yi{static getDefaults(){return s(s({},super.getDefaults()),Gn.ownDefaults)}constructor(t){super(),Object.assign(this,Gn.ownDefaults),this.setOptions(t)}_set(t,e){return super._set(t,e),"radius"===t&&this.setRadius(e),this}_render(t){t.beginPath(),t.arc(0,0,this.radius,yt(this.startAngle),yt(this.endAngle),this.counterClockwise),this._renderPaintInOrder(t)}getRadiusX(){return this.get("radius")*this.get(G)}getRadiusY(){return this.get("radius")*this.get(N)}setRadius(t){this.radius=t,this.set({width:2*t,height:2*t})}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...zn,...t])}_toSVG(){const t=(this.endAngle-this.startAngle)%360;if(0===t)return["\n'];{const{radius:e}=this,s=yt(this.startAngle),i=yt(this.endAngle),r=rt(s)*e,n=nt(s)*e,o=rt(i)*e,a=nt(i)*e,h=t>180?1:0,c=this.counterClockwise?0:1;return['\n"]}}static async fromElement(t,e,r){const n=ur(t,this.ATTRIBUTE_NAMES,r),{left:o=0,top:a=0,radius:h=0}=n;return new this(s(s({},i(n,Hn)),{},{radius:h,left:o-h,top:a-h}))}static fromObject(t){return super._fromObject(t)}}t(Gn,"type","Circle"),t(Gn,"cacheProperties",[...fs,...zn]),t(Gn,"ownDefaults",{radius:0,startAngle:0,endAngle:360,counterClockwise:!1}),t(Gn,"ATTRIBUTE_NAMES",["cx","cy","r",...ji]),tt.setClass(Gn),tt.setSVGClass(Gn);class Nn extends Bn{constructor(e){super(e),t(this,"width",10),this.points=[]}drawDot(t){const e=this.addPoint(t),s=this.canvas.contextTop;this._saveAndTransform(s),this.dot(s,e),s.restore()}dot(t,e){t.fillStyle=e.fill,t.beginPath(),t.arc(e.x,e.y,e.radius,0,2*Math.PI,!1),t.closePath(),t.fill()}onMouseDown(t){this.points=[],this.canvas.clearContext(this.canvas.contextTop),this._setShadow(),this.drawDot(t)}_render(){const t=this.canvas.contextTop,e=this.points;this._saveAndTransform(t);for(let s=0;s0&&void 0!==arguments[0]?arguments[0]:[0,0,0,0],r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,Zn.ownDefaults),this.setOptions(r),this.x1=t,this.x2=s,this.y1=e,this.y2=i,this._setWidthHeight();const{left:n,top:o}=r;"number"==typeof n&&this.set(M,n),"number"==typeof o&&this.set(P,o)}_setWidthHeight(){const{x1:t,y1:e,x2:s,y2:i}=this;this.width=Math.abs(s-t),this.height=Math.abs(i-e);const{left:r,top:n,width:o,height:a}=me([{x:t,y:e},{x:s,y:i}]),h=new ot(r+o/2,n+a/2);this.setPositionByOrigin(h,D,D)}_set(t,e){return super._set(t,e),Qn.includes(t)&&this._setWidthHeight(),this}_render(t){t.beginPath();const e=this.calcLinePoints();t.moveTo(e.x1,e.y1),t.lineTo(e.x2,e.y2),t.lineWidth=this.strokeWidth;const s=t.strokeStyle;var i;Zt(this.stroke)?t.strokeStyle=this.stroke.toLive(t):t.strokeStyle=null!==(i=this.stroke)&&void 0!==i?i:t.fillStyle;this.stroke&&this._renderStroke(t),t.strokeStyle=s}_findCenterFromElement(){return new ot((this.x1+this.x2)/2,(this.y1+this.y2)/2)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return s(s({},super.toObject(t)),this.calcLinePoints())}_getNonTransformedDimensions(){const t=super._getNonTransformedDimensions();return"butt"===this.strokeLineCap&&(0===this.width&&(t.y-=this.strokeWidth),0===this.height&&(t.x-=this.strokeWidth)),t}calcLinePoints(){const{x1:t,x2:e,y1:s,y2:i,width:r,height:n}=this,o=t<=e?-1:1,a=s<=i?-1:1;return{x1:o*r/2,x2:o*-r/2,y1:a*n/2,y2:a*-n/2}}_toSVG(){const{x1:t,x2:e,y1:s,y2:i}=this.calcLinePoints();return["\n')]}static async fromElement(t,e,s){const r=ur(t,this.ATTRIBUTE_NAMES,s),{x1:n=0,y1:o=0,x2:a=0,y2:h=0}=r;return new this([n,o,a,h],i(r,Kn))}static fromObject(t){let{x1:e,y1:r,x2:n,y2:o}=t,a=i(t,Jn);return this._fromObject(s(s({},a),{},{points:[e,r,n,o]}),{extraParam:"points"})}}t(Zn,"type","Line"),t(Zn,"cacheProperties",[...fs,...Qn]),t(Zn,"ATTRIBUTE_NAMES",ji.concat(Qn)),tt.setClass(Zn),tt.setSVGClass(Zn);class $n extends yi{static getDefaults(){return s(s({},super.getDefaults()),$n.ownDefaults)}constructor(t){super(),Object.assign(this,$n.ownDefaults),this.setOptions(t)}_render(t){const e=this.width/2,s=this.height/2;t.beginPath(),t.moveTo(-e,s),t.lineTo(0,-s),t.lineTo(e,s),t.closePath(),this._renderPaintInOrder(t)}_toSVG(){const t=this.width/2,e=this.height/2;return["']}}t($n,"type","Triangle"),t($n,"ownDefaults",{width:100,height:100}),tt.setClass($n),tt.setSVGClass($n);const to=["rx","ry"];class eo extends yi{static getDefaults(){return s(s({},super.getDefaults()),eo.ownDefaults)}constructor(t){super(),Object.assign(this,eo.ownDefaults),this.setOptions(t)}_set(t,e){switch(super._set(t,e),t){case"rx":this.rx=e,this.set("width",2*e);break;case"ry":this.ry=e,this.set("height",2*e)}return this}getRx(){return this.get("rx")*this.get(G)}getRy(){return this.get("ry")*this.get(N)}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject([...to,...t])}_toSVG(){return["\n')]}_render(t){t.beginPath(),t.save(),t.transform(1,0,0,this.ry/this.rx,0,0),t.arc(0,0,this.rx,0,w,!1),t.restore(),this._renderPaintInOrder(t)}static async fromElement(t,e,s){const i=ur(t,this.ATTRIBUTE_NAMES,s);return i.left=(i.left||0)-i.rx,i.top=(i.top||0)-i.ry,new this(i)}}function so(t){if(!t)return[];const e=t.replace(/,/g," ").trim().split(/\s+/),s=[];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[],s=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),t(this,"strokeDiff",void 0),Object.assign(this,no.ownDefaults),this.setOptions(s),this.points=e;const{left:i,top:r}=s;this.initialized=!0,this.setBoundingBox(!0),"number"==typeof i&&this.set(M,i),"number"==typeof r&&this.set(P,r)}isOpen(){return!0}_projectStrokeOnPoints(t){return Si(this.points,t,this.isOpen())}_calcDimensions(t){t=s({scaleX:this.scaleX,scaleY:this.scaleY,skewX:this.skewX,skewY:this.skewY,strokeLineCap:this.strokeLineCap,strokeLineJoin:this.strokeLineJoin,strokeMiterLimit:this.strokeMiterLimit,strokeUniform:this.strokeUniform,strokeWidth:this.strokeWidth},t||{});const e=this.exactBoundingBox?this._projectStrokeOnPoints(t).map((t=>t.projectedPoint)):this.points;if(0===e.length)return{left:0,top:0,width:0,height:0,pathOffset:new ot,strokeOffset:new ot,strokeDiff:new ot};const i=me(e),r=jt(s(s({},t),{},{scaleX:1,scaleY:1})),n=me(this.points.map((t=>Ct(t,r,!0)))),o=new ot(this.scaleX,this.scaleY);let a=i.left+i.width/2,h=i.top+i.height/2;return this.exactBoundingBox&&(a-=h*Math.tan(yt(this.skewX)),h-=a*Math.tan(yt(this.skewY))),s(s({},i),{},{pathOffset:new ot(a,h),strokeOffset:new ot(n.left,n.top).subtract(new ot(i.left,i.top)).multiply(o),strokeDiff:new ot(i.width,i.height).subtract(new ot(n.width,n.height)).multiply(o)})}_findCenterFromElement(){const t=me(this.points);return new ot(t.left+t.width/2,t.top+t.height/2)}setDimensions(){this.setBoundingBox()}setBoundingBox(t){const{left:e,top:s,width:i,height:r,pathOffset:n,strokeOffset:o,strokeDiff:a}=this._calcDimensions();this.set({width:i,height:r,pathOffset:n,strokeOffset:o,strokeDiff:a}),t&&this.setPositionByOrigin(new ot(e+i/2,s+r/2),D,D)}isStrokeAccountedForInDimensions(){return this.exactBoundingBox}_getNonTransformedDimensions(){return this.exactBoundingBox?new ot(this.width,this.height):super._getNonTransformedDimensions()}_getTransformedDimensions(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.exactBoundingBox){let n;if(Object.keys(t).some((t=>this.strokeUniform||this.constructor.layoutProperties.includes(t)))){var e,s;const{width:i,height:r}=this._calcDimensions(t);n=new ot(null!==(e=t.width)&&void 0!==e?e:i,null!==(s=t.height)&&void 0!==s?s:r)}else{var i,r;n=new ot(null!==(i=t.width)&&void 0!==i?i:this.width,null!==(r=t.height)&&void 0!==r?r:this.height)}return n.multiply(new ot(t.scaleX||this.scaleX,t.scaleY||this.scaleY))}return super._getTransformedDimensions(t)}_set(t,e){const s=this.initialized&&this[t]!==e,i=super._set(t,e);return this.exactBoundingBox&&s&&((t===G||t===N)&&this.strokeUniform&&this.constructor.layoutProperties.includes("strokeUniform")||this.constructor.layoutProperties.includes(t))&&this.setDimensions(),i}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return s(s({},super.toObject(t)),{},{points:this.points.map((t=>{let{x:e,y:s}=t;return{x:e,y:s}}))})}_toSVG(){const t=[],e=this.pathOffset.x,s=this.pathOffset.y,i=o.NUM_FRACTION_DIGITS;for(let r=0,n=this.points.length;r\n')]}_render(t){const e=this.points.length,s=this.pathOffset.x,i=this.pathOffset.y;if(e&&!isNaN(this.points[e-1].y)){t.beginPath(),t.moveTo(this.points[0].x-s,this.points[0].y-i);for(let r=0;rvoid 0!==t));this._setStyleDeclaration(i,r,n)}getSelectionStyles(t,e,s){const i=[];for(let r=t;r<(e||t);r++)i.push(this.getStyleAtPosition(r,s));return i}getStyleAtPosition(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t);return e?this.getCompleteStyleDeclaration(s,i):this._getStyleDeclaration(s,i)}setSelectionStyles(t,e,s){for(let i=e;i<(s||e);i++)this._extendStyles(i,t);this._forceClearCache=!0}_getStyleDeclaration(t,e){var s;const i=this.styles&&this.styles[t];return i&&null!==(s=i[e])&&void 0!==s?s:{}}getCompleteStyleDeclaration(t,e){return s(s({},Bt(this,this.constructor._styleProperties)),this._getStyleDeclaration(t,e))}_setStyleDeclaration(t,e,s){this.styles[t][e]=s}_deleteStyleDeclaration(t,e){delete this.styles[t][e]}_getLineStyle(t){return!!this.styles[t]}_setLineStyle(t){this.styles[t]={}}_deleteLineStyle(t){delete this.styles[t]}}t(yo,"_styleProperties",uo);const _o=/ +/g,xo=/"/g;function Co(t,e,s,i,r){return"\t\t".concat(function(t,e){let{left:s,top:i,width:r,height:n}=e,a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:o.NUM_FRACTION_DIGITS;const h=Qt(K,t,!1),[c,l,u,d]=[s,i,r,n].map((t=>Ut(t,a)));return"')}(t,{left:e,top:s,width:i,height:r}),"\n")}const bo=["textAnchor","textDecoration","dx","dy","top","left","fontSize","strokeWidth"];let wo;class So extends yo{static getDefaults(){return s(s({},super.getDefaults()),So.ownDefaults)}constructor(e,s){super(),t(this,"__charBounds",[]),Object.assign(this,So.ownDefaults),this.setOptions(s),this.styles||(this.styles={}),this.text=e,this.initialized=!0,this.path&&this.setPathInfo(),this.initDimensions(),this.setCoords()}setPathInfo(){const t=this.path;t&&(t.segmentsInfo=Jr(t.path))}_splitText(){const t=this._splitTextIntoLines(this.text);return this.textLines=t.lines,this._textLines=t.graphemeLines,this._unwrappedTextLines=t._unwrappedLines,this._text=t.graphemeText,t}initDimensions(){this._splitText(),this._clearCache(),this.dirty=!0,this.path?(this.width=this.path.width,this.height=this.path.height):(this.width=this.calcTextWidth()||this.cursorWidth||this.MIN_TEXT_WIDTH,this.height=this.calcTextHeight()),this.textAlign.includes(fo)&&this.enlargeSpaces()}enlargeSpaces(){let t,e,s,i,r,n,o;for(let a=0,h=this._textLines.length;a')}_getCacheCanvasDimensions(){const t=super._getCacheCanvasDimensions(),e=this.fontSize;return t.width+=e*t.zoomX,t.height+=e*t.zoomY,t}_render(t){const e=this.path;e&&!e.isNotVisible()&&e._render(t),this._setTextStyles(t),this._renderTextLinesBackground(t),this._renderTextDecoration(t,"underline"),this._renderText(t),this._renderTextDecoration(t,"overline"),this._renderTextDecoration(t,"linethrough")}_renderText(t){this.paintFirst===J?(this._renderTextStroke(t),this._renderTextFill(t)):(this._renderTextFill(t),this._renderTextStroke(t))}_setTextStyles(t,e,s){if(t.textBaseline="alphabetic",this.path)switch(this.pathAlign){case D:t.textBaseline="middle";break;case"ascender":t.textBaseline=P;break;case"descender":t.textBaseline=E}t.font=this._getFontDeclaration(e,s)}calcTextWidth(){let t=this.getLineWidth(0);for(let e=1,s=this._textLines.length;et&&(t=s)}return t}_renderTextLine(t,e,s,i,r,n){this._renderChars(t,e,s,i,r,n)}_renderTextLinesBackground(t){if(!this.textBackgroundColor&&!this.styleHas("textBackgroundColor"))return;const e=t.fillStyle,s=this._getLeftOffset();let i=this._getTopOffset();for(let e=0,r=this._textLines.length;e=0:ie?t%=e:t<0&&(t+=e),this._setGraphemeOnPath(t,s),t+=s.kernedWidth}return{width:i,numOfSpaces:0}}_setGraphemeOnPath(t,e){const s=t+e.kernedWidth/2,i=this.path,r=Qr(i.path,s,i.segmentsInfo);e.renderLeft=r.x-i.pathOffset.x,e.renderTop=r.y-i.pathOffset.y,e.angle=r.angle+(this.pathSide===A?Math.PI:0)}_getGraphemeBox(t,e,s,i,r){const n=this.getCompleteStyleDeclaration(e,s),o=i?this.getCompleteStyleDeclaration(e,s-1):{},a=this._measureChar(t,n,i,o);let h,c=a.kernedWidth,l=a.width;0!==this.charSpacing&&(h=this._getWidthOfCharSpacing(),l+=h,c+=h);const u={width:l,left:0,height:n.fontSize,kernedWidth:c,deltaY:n.deltaY};if(s>0&&!r){const t=this.__charBounds[e][s-1];u.left=t.left+t.width+a.kernedWidth-a.width}return u}getHeightOfLine(t){if(this.__lineHeights[t])return this.__lineHeights[t];let e=this.getHeightOfChar(t,0);for(let s=1,i=this._textLines[t].length;s0){let e=i+u+f;"rtl"===this.direction&&(e=this.width-e-p),m&&v&&(t.fillStyle=v,t.fillRect(e,y+o*_+x,p,this.fontSize/15)),f=n.left,p=n.width,m=d,v=g,_=h,x=c}else p+=n.kernedWidth}let C=i+u+f;"rtl"===this.direction&&(C=this.width-C-p),t.fillStyle=g,d&&g&&t.fillRect(C,y+o*_+x,p-n,this.fontSize/15),s+=h}this._removeShadow(t)}_getFontDeclaration(){let{fontFamily:t=this.fontFamily,fontStyle:e=this.fontStyle,fontWeight:s=this.fontWeight,fontSize:i=this.fontSize}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=arguments.length>1?arguments[1]:void 0;const n=t.includes("'")||t.includes('"')||t.includes(",")||So.genericFonts.includes(t.toLowerCase())?t:'"'.concat(t,'"');return[e,s,"".concat(r?this.CACHE_FONT_SIZE:i,"px"),n].join(" ")}render(t){this.visible&&(this.canvas&&this.canvas.skipOffscreen&&!this.group&&!this.isOnScreen()||(this._forceClearCache&&this.initDimensions(),super.render(t)))}graphemeSplit(t){return ki(t)}_splitTextIntoLines(t){const e=t.split(this._reNewline),s=new Array(e.length),i=["\n"];let r=[];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[];return s(s({},super.toObject([...lo,...t])),{},{styles:Ei(this.styles,this.text)},this.path?{path:this.path.toObject()}:{})}set(t,e){const{textLayoutProperties:s}=this.constructor;super.set(t,e);let i=!1,r=!1;if("object"==typeof t)for(const e in t)"path"===e&&this.setPathInfo(),i=i||s.includes(e),r=r||"path"===e;else i=s.includes(t),r="path"===t;return r&&this.setPathInfo(),i&&this.initialized&&(this.initDimensions(),this.setCoords()),this}complexity(){return 1}static async fromElement(t,e,r){const n=ur(t,So.ATTRIBUTE_NAMES,r),o=s(s({},e),n),{textAnchor:a=M,textDecoration:h="",dx:c=0,dy:l=0,top:u=0,left:d=0,fontSize:g=O,strokeWidth:f=1}=o,p=i(o,bo),m=new this((t.textContent||"").replace(/^\s+|\s+$|\n+/g,"").replace(/\s+/g," "),s({left:d+c,top:u+l,underline:h.includes("underline"),overline:h.includes("overline"),linethrough:h.includes("line-through"),strokeWidth:0,fontSize:g},p)),v=m.getScaledHeight()/m.height,y=((m.height+m.strokeWidth)*m.lineHeight-m.height)*v,_=m.getScaledHeight()+y;let x=0;return a===D&&(x=m.getScaledWidth()/2),a===A&&(x=m.getScaledWidth()),m.set({left:m.left-x,top:m.top-(_-m.fontSize*(.07+m._fontSizeFraction))/m.lineHeight,strokeWidth:f}),m}static fromObject(t){return this._fromObject(s(s({},t),{},{styles:Ai(t.styles||{},t.text)}),{extraParam:"text"})}}t(So,"textLayoutProperties",co),t(So,"cacheProperties",[...fs,...lo]),t(So,"ownDefaults",go),t(So,"type","Text"),t(So,"genericFonts",["sans-serif","serif","cursive","fantasy","monospace"]),t(So,"ATTRIBUTE_NAMES",ji.concat("x","y","dx","dy","font-family","font-style","font-weight","font-size","letter-spacing","text-decoration","text-anchor")),vi(So,[class extends Be{_toSVG(){const t=this._getSVGLeftTopOffsets(),e=this._getSVGTextAndBg(t.textTop,t.textLeft);return this._wrapSVGTextAndBg(e)}toSVG(t){return this._createBaseSVGMarkup(this._toSVG(),{reviver:t,noStyle:!0,withShadow:!0})}_getSVGLeftTopOffsets(){return{textLeft:-this.width/2,textTop:-this.height/2,lineTop:this.getHeightOfLine(0)}}_wrapSVGTextAndBg(t){let{textBgRects:e,textSpans:s}=t;const i=this.getSvgTextDecoration(this);return[e.join(""),'\t\t",s.join(""),"\n"]}_getSVGTextAndBg(t,e){const s=[],i=[];let r,n=t;this.backgroundColor&&i.push(...Co(this.backgroundColor,-this.width/2,-this.height/2,this.width,this.height));for(let t=0,o=this._textLines.length;t").concat(Oi(t),"")}_setSVGTextLineText(t,e,s,i){const r=this.getHeightOfLine(e),n=this.textAlign.includes(fo),o=this._textLines[e];let a,h,c,l,u,d="",g=0;i+=r*(1-this._fontSizeFraction)/this.lineHeight;for(let r=0,f=o.length-1;r<=f;r++)u=r===f||this.charSpacing,d+=o[r],c=this.__charBounds[e][r],0===g?(s+=c.kernedWidth-c.width,g+=c.width):g+=c.kernedWidth,n&&!u&&this._reSpaceAndTab.test(o[r])&&(u=!0),u||(a=a||this.getCompleteStyleDeclaration(e,r),h=this.getCompleteStyleDeclaration(e,r+1),u=Pi(a,h,!0)),u&&(l=this._getStyleDeclaration(e,r),t.push(this._createTextCharSpan(d,l,s,i)),d="",a=h,"rtl"===this.direction?s-=g:s+=g,g=0)}_setSVGTextLineBg(t,e,s,i){const r=this._textLines[e],n=this.getHeightOfLine(e)/this.lineHeight;let o,a=0,h=0,c=this.getValueOfPropertyAt(e,0,"textBackgroundColor");for(let l=0;lt[e.replace("-","")])).join(" ")}}]),tt.setClass(So),tt.setSVGClass(So);class To{constructor(e){t(this,"target",void 0),t(this,"__mouseDownInPlace",!1),t(this,"__dragStartFired",!1),t(this,"__isDraggingOver",!1),t(this,"__dragStartSelection",void 0),t(this,"__dragImageDisposer",void 0),t(this,"_dispose",void 0),this.target=e;const s=[this.target.on("dragenter",this.dragEnterHandler.bind(this)),this.target.on("dragover",this.dragOverHandler.bind(this)),this.target.on("dragleave",this.dragLeaveHandler.bind(this)),this.target.on("dragend",this.dragEndHandler.bind(this)),this.target.on("drop",this.dropHandler.bind(this))];this._dispose=()=>{s.forEach((t=>t())),this._dispose=void 0}}isPointerOverSelection(t){const e=this.target,s=e.getSelectionStartFromPointer(t);return e.isEditing&&s>=e.selectionStart&&s<=e.selectionEnd&&e.selectionStart{_.remove()},re(t.target||this.target.hiddenTextarea).body.appendChild(_),null===(s=t.dataTransfer)||void 0===s||s.setDragImage(_,p.x,p.y)}onDragStart(t){this.__dragStartFired=!0;const e=this.target,i=this.isActive();if(i&&t.dataTransfer){const i=this.__dragStartSelection={selectionStart:e.selectionStart,selectionEnd:e.selectionEnd},r=e._text.slice(i.selectionStart,i.selectionEnd).join(""),n=s({text:e.text,value:r},i);t.dataTransfer.setData("text/plain",r),t.dataTransfer.setData("application/fabric",JSON.stringify({value:r,styles:e.getSelectionStyles(i.selectionStart,i.selectionEnd,!0)})),t.dataTransfer.effectAllowed="copyMove",this.setDragImage(t,n)}return e.abortCursorAnimation(),i}canDrop(t){if(this.target.editable&&!this.target.getActiveControl()&&!t.defaultPrevented){if(this.isActive()&&this.__dragStartSelection){const e=this.target.getSelectionStartFromPointer(t),s=this.__dragStartSelection;return es.selectionEnd}return!0}return!1}targetCanDrop(t){return this.target.canDrop(t)}dragEnterHandler(t){let{e:e}=t;const s=this.targetCanDrop(e);!this.__isDraggingOver&&s&&(this.__isDraggingOver=!0)}dragOverHandler(t){const{e:e}=t,s=this.targetCanDrop(e);!this.__isDraggingOver&&s?this.__isDraggingOver=!0:this.__isDraggingOver&&!s&&(this.__isDraggingOver=!1),this.__isDraggingOver&&(e.preventDefault(),t.canDrop=!0,t.dropTarget=this.target)}dragLeaveHandler(){(this.__isDraggingOver||this.isActive())&&(this.__isDraggingOver=!1)}dropHandler(t){var e;const{e:s}=t,i=s.defaultPrevented;this.__isDraggingOver=!1,s.preventDefault();let r=null===(e=s.dataTransfer)||void 0===e?void 0:e.getData("text/plain");if(r&&!i){const e=this.target,i=e.canvas;let n=e.getSelectionStartFromPointer(s);const{styles:o}=s.dataTransfer.types.includes("application/fabric")?JSON.parse(s.dataTransfer.getData("application/fabric")):{},a=r[Math.max(0,r.length-1)],h=0;if(this.__dragStartSelection){const t=this.__dragStartSelection.selectionStart,s=this.__dragStartSelection.selectionEnd;n>t&&n<=s?n=t:n>s&&(n-=s-t),e.removeChars(t,s),delete this.__dragStartSelection}e._reNewline.test(a)&&(e._reNewline.test(e._text[n])||n===e._text.length)&&(r=r.trimEnd()),t.didDrop=!0,t.dropTarget=e,e.insertChars(r,o,n),i.setActiveObject(e),e.enterEditing(s),e.selectionStart=Math.min(n+h,e._text.length),e.selectionEnd=Math.min(e.selectionStart+r.length,e._text.length),e.hiddenTextarea.value=e.text,e._updateTextarea(),e.hiddenTextarea.focus(),e.fire(H,{index:n+h,action:"drop"}),i.fire("text:changed",{target:e}),i.contextTopDirty=!0,i.requestRenderAll()}}dragEndHandler(t){let{e:e}=t;if(this.isActive()&&this.__dragStartFired&&this.__dragStartSelection){var s;const t=this.target,i=this.target.canvas,{selectionStart:r,selectionEnd:n}=this.__dragStartSelection,o=(null===(s=e.dataTransfer)||void 0===s?void 0:s.dropEffect)||j;o===j?(t.selectionStart=r,t.selectionEnd=n,t._updateTextarea(),t.hiddenTextarea.focus()):(t.clearContextTop(),"move"===o&&(t.removeChars(r,n),t.selectionStart=t.selectionEnd=r,t.hiddenTextarea&&(t.hiddenTextarea.value=t.text),t._updateTextarea(),t.fire(H,{index:r,action:"dragend"}),i.fire("text:changed",{target:t}),i.requestRenderAll()),t.exitEditing())}this.__dragImageDisposer&&this.__dragImageDisposer(),delete this.__dragImageDisposer,delete this.__dragStartSelection,this.__isDraggingOver=!1}dispose(){this._dispose&&this._dispose()}}const Oo=/[ \n\.,;!\?\-]/;class ko extends So{constructor(){super(...arguments),t(this,"_currentCursorOpacity",1)}initBehavior(){this._tick=this._tick.bind(this),this._onTickComplete=this._onTickComplete.bind(this),this.updateSelectionOnMouseMove=this.updateSelectionOnMouseMove.bind(this)}onDeselect(t){return this.isEditing&&this.exitEditing(),this.selected=!1,super.onDeselect(t)}_animateCursor(t){let{toValue:e,duration:s,delay:i,onComplete:r}=t;return As({startValue:this._currentCursorOpacity,endValue:e,duration:s,delay:i,onComplete:r,abort:()=>!this.canvas||this.selectionStart!==this.selectionEnd,onChange:t=>{this._currentCursorOpacity=t,this.renderCursorOrSelection()}})}_tick(t){this._currentTickState=this._animateCursor({toValue:0,duration:this.cursorDuration/2,delay:Math.max(t||0,100),onComplete:this._onTickComplete})}_onTickComplete(){var t;null===(t=this._currentTickCompleteState)||void 0===t||t.abort(),this._currentTickCompleteState=this._animateCursor({toValue:1,duration:this.cursorDuration,onComplete:this._tick})}initDelayedCursor(t){this.abortCursorAnimation(),this._tick(t?0:this.cursorDelay)}abortCursorAnimation(){let t=!1;[this._currentTickState,this._currentTickCompleteState].forEach((e=>{e&&!e.isDone()&&(t=!0,e.abort())})),this._currentCursorOpacity=1,t&&this.clearContextTop()}restartCursorIfNeeded(){[this._currentTickState,this._currentTickCompleteState].some((t=>!t||t.isDone()))&&this.initDelayedCursor()}selectAll(){return this.selectionStart=0,this.selectionEnd=this._text.length,this._fireSelectionChanged(),this._updateTextarea(),this}getSelectedText(){return this._text.slice(this.selectionStart,this.selectionEnd).join("")}findWordBoundaryLeft(t){let e=0,s=t-1;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s--;for(;/\S/.test(this._text[s])&&s>-1;)e++,s--;return t-e}findWordBoundaryRight(t){let e=0,s=t;if(this._reSpace.test(this._text[s]))for(;this._reSpace.test(this._text[s]);)e++,s++;for(;/\S/.test(this._text[s])&&s-1;)e++,s--;return t-e}findLineBoundaryRight(t){let e=0,s=t;for(;!/\n/.test(this._text[s])&&s0&&this._reSpace.test(s[t])&&(-1===e||!F.test(s[t-1]))?t-1:t,r=s[i];for(;i>0&&ithis.__selectionStartOnMouseDown?(this.selectionStart=this.__selectionStartOnMouseDown,this.selectionEnd=s):(this.selectionStart=s,this.selectionEnd=this.__selectionStartOnMouseDown),this.selectionStart===i&&this.selectionEnd===r||(this._fireSelectionChanged(),this._updateTextarea(),this.renderCursorOrSelection()))}_setEditingProps(){this.hoverCursor="text",this.canvas&&(this.canvas.defaultCursor=this.canvas.moveCursor="text"),this.borderColor=this.editingBorderColor,this.hasControls=this.selectable=!1,this.lockMovementX=this.lockMovementY=!0}fromStringToGraphemeSelection(t,e,s){const i=s.slice(0,t),r=this.graphemeSplit(i).length;if(t===e)return{selectionStart:r,selectionEnd:r};const n=s.slice(t,e);return{selectionStart:r,selectionEnd:r+this.graphemeSplit(n).length}}fromGraphemeToStringSelection(t,e,s){const i=s.slice(0,t).join("").length;if(t===e)return{selectionStart:i,selectionEnd:i};return{selectionStart:i,selectionEnd:i+s.slice(t,e).join("").length}}_updateTextarea(){if(this.cursorOffsetCache={},this.hiddenTextarea){if(!this.inCompositionMode){const t=this.fromGraphemeToStringSelection(this.selectionStart,this.selectionEnd,this._text);this.hiddenTextarea.selectionStart=t.selectionStart,this.hiddenTextarea.selectionEnd=t.selectionEnd}this.updateTextareaPosition()}}updateFromTextArea(){if(!this.hiddenTextarea)return;this.cursorOffsetCache={};const t=this.hiddenTextarea;this.text=t.value,this.set("dirty",!0),this.initDimensions(),this.setCoords();const e=this.fromStringToGraphemeSelection(t.selectionStart,t.selectionEnd,t.value);this.selectionEnd=this.selectionStart=e.selectionEnd,this.inCompositionMode||(this.selectionStart=e.selectionStart),this.updateTextareaPosition()}updateTextareaPosition(){if(this.selectionStart===this.selectionEnd){const t=this._calcTextareaPosition();this.hiddenTextarea.style.left=t.left,this.hiddenTextarea.style.top=t.top}}_calcTextareaPosition(){if(!this.canvas)return{left:"1px",top:"1px"};const t=this.inCompositionMode?this.compositionStart:this.selectionStart,e=this._getCursorBoundaries(t),s=this.get2DCursorLocation(t),i=s.lineIndex,r=s.charIndex,n=this.getValueOfPropertyAt(i,r,"fontSize")*this.lineHeight,o=e.leftOffset,a=this.getCanvasRetinaScaling(),h=this.canvas.upperCanvasEl,c=h.width/a,l=h.height/a,u=c-n,d=l-n,g=new ot(e.left+o,e.top+e.topOffset+n).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new ot(h.clientWidth/c,h.clientHeight/l));return g.x<0&&(g.x=0),g.x>u&&(g.x=u),g.y<0&&(g.y=0),g.y>d&&(g.y=d),g.x+=this.canvas._offset.left,g.y+=this.canvas._offset.top,{left:"".concat(g.x,"px"),top:"".concat(g.y,"px"),fontSize:"".concat(n,"px"),charHeight:n}}_saveEditingProps(){this._savedProps={hasControls:this.hasControls,borderColor:this.borderColor,lockMovementX:this.lockMovementX,lockMovementY:this.lockMovementY,hoverCursor:this.hoverCursor,selectable:this.selectable,defaultCursor:this.canvas&&this.canvas.defaultCursor,moveCursor:this.canvas&&this.canvas.moveCursor}}_restoreEditingProps(){this._savedProps&&(this.hoverCursor=this._savedProps.hoverCursor,this.hasControls=this._savedProps.hasControls,this.borderColor=this._savedProps.borderColor,this.selectable=this._savedProps.selectable,this.lockMovementX=this._savedProps.lockMovementX,this.lockMovementY=this._savedProps.lockMovementY,this.canvas&&(this.canvas.defaultCursor=this._savedProps.defaultCursor||this.canvas.defaultCursor,this.canvas.moveCursor=this._savedProps.moveCursor||this.canvas.moveCursor),delete this._savedProps)}_exitEditing(){const t=this.hiddenTextarea;this.selected=!1,this.isEditing=!1,t&&(t.blur&&t.blur(),t.parentNode&&t.parentNode.removeChild(t)),this.hiddenTextarea=null,this.abortCursorAnimation(),this.selectionStart!==this.selectionEnd&&this.clearContextTop()}exitEditing(){const t=this._textBeforeEdit!==this.text;return this._exitEditing(),this.selectionEnd=this.selectionStart,this._restoreEditingProps(),this._forceClearCache&&(this.initDimensions(),this.setCoords()),this.fire("editing:exited"),t&&this.fire(Q),this.canvas&&(this.canvas.fire("text:editing:exited",{target:this}),t&&this.canvas.fire("object:modified",{target:this})),this}_removeExtraneousStyles(){for(const t in this.styles)this._textLines[t]||delete this.styles[t]}removeStyleFromTo(t,e){const{lineIndex:s,charIndex:i}=this.get2DCursorLocation(t,!0),{lineIndex:r,charIndex:n}=this.get2DCursorLocation(e,!0);if(s!==r){if(this.styles[s])for(let t=i;t=n&&(t[s-e]=t[i],delete t[i])}}}shiftLineStyles(t,e){const s=Object.assign({},this.styles);for(const i in this.styles){const r=parseInt(i,10);r>t&&(this.styles[r+e]=s[r],s[r-e]||delete this.styles[r])}}insertNewlineStyleObject(t,e,i,r){const n={},o=this._unwrappedTextLines[t].length,a=o===e;let h=!1;i||(i=1),this.shiftLineStyles(t,i);const c=this.styles[t]?this.styles[t][0===e?e:e-1]:void 0;for(const s in this.styles[t]){const i=parseInt(s,10);i>=e&&(h=!0,n[i-e]=this.styles[t][s],a&&0===e||delete this.styles[t][s])}let l=!1;for(h&&!a&&(this.styles[t+i]=n,l=!0),(l||o>e)&&i--;i>0;)r&&r[i-1]?this.styles[t+i]={0:s({},r[i-1])}:c?this.styles[t+i]={0:s({},c)}:delete this.styles[t+i],i--;this._forceClearCache=!0}insertCharStyleObject(t,e,i,r){this.styles||(this.styles={});const n=this.styles[t],o=n?s({},n):{};i||(i=1);for(const t in o){const s=parseInt(t,10);s>=e&&(n[s+i]=o[s],o[s-i]||delete n[s])}if(this._forceClearCache=!0,r){for(;i--;)Object.keys(r[i]).length&&(this.styles[t]||(this.styles[t]={}),this.styles[t][e+i]=s({},r[i]));return}if(!n)return;const a=n[e?e-1:1];for(;a&&i--;)this.styles[t][e+i]=s({},a)}insertNewStyleBlock(t,e,s){const i=this.get2DCursorLocation(e,!0),r=[0];let n,o=0;for(let e=0;e0&&(this.insertCharStyleObject(i.lineIndex,i.charIndex,r[0],s),s=s&&s.slice(r[0]+1)),o&&this.insertNewlineStyleObject(i.lineIndex,i.charIndex+r[0],o),n=1;n0?this.insertCharStyleObject(i.lineIndex+n,0,r[n],s):s&&this.styles[i.lineIndex+n]&&s[0]&&(this.styles[i.lineIndex+n][0]=s[0]),s=s&&s.slice(r[n]+1);r[n]>0&&this.insertCharStyleObject(i.lineIndex+n,0,r[n],s)}removeChars(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:t+1;this.removeStyleFromTo(t,e),this._text.splice(t,e-t),this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}insertChars(t,e,s){let i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:s;i>s&&this.removeStyleFromTo(s,i);const r=this.graphemeSplit(t);this.insertNewStyleBlock(r,s,e),this._text=[...this._text.slice(0,s),...r,...this._text.slice(i)],this.text=this._text.join(""),this.set("dirty",!0),this.initDimensions(),this.setCoords(),this._removeExtraneousStyles()}setSelectionStartEndWithShift(t,e,s){s<=t?(e===t?this._selectionDirection=M:this._selectionDirection===A&&(this._selectionDirection=M,this.selectionEnd=t),this.selectionStart=s):s>t&&s{let[s,i]=t;return e.setAttribute(s,i)}));const{top:s,left:i,fontSize:r}=this._calcTextareaPosition();e.style.cssText="position: absolute; top: ".concat(s,"; left: ").concat(i,"; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ").concat(r,";"),(this.hiddenTextareaContainer||t.body).appendChild(e),Object.entries({blur:"blur",keydown:"onKeyDown",keyup:"onKeyUp",input:"onInput",copy:"copy",cut:"copy",paste:"paste",compositionstart:"onCompositionStart",compositionupdate:"onCompositionUpdate",compositionend:"onCompositionEnd"}).map((t=>{let[s,i]=t;return e.addEventListener(s,this[i].bind(this))})),this.hiddenTextarea=e}blur(){this.abortCursorAnimation()}onKeyDown(t){if(!this.isEditing)return;const e="rtl"===this.direction?this.keysMapRtl:this.keysMap;if(t.keyCode in e)this[e[t.keyCode]](t);else{if(!(t.keyCode in this.ctrlKeysMapDown)||!t.ctrlKey&&!t.metaKey)return;this[this.ctrlKeysMapDown[t.keyCode]](t)}t.stopImmediatePropagation(),t.preventDefault(),t.keyCode>=33&&t.keyCode<=40?(this.inCompositionMode=!1,this.clearContextTop(),this.renderCursorOrSelection()):this.canvas&&this.canvas.requestRenderAll()}onKeyUp(t){!this.isEditing||this._copyDone||this.inCompositionMode?this._copyDone=!1:t.keyCode in this.ctrlKeysMapUp&&(t.ctrlKey||t.metaKey)&&(this[this.ctrlKeysMapUp[t.keyCode]](t),t.stopImmediatePropagation(),t.preventDefault(),this.canvas&&this.canvas.requestRenderAll())}onInput(t){const e=this.fromPaste;if(this.fromPaste=!1,t&&t.stopPropagation(),!this.isEditing)return;const s=()=>{this.updateFromTextArea(),this.fire(H),this.canvas&&(this.canvas.fire("text:changed",{target:this}),this.canvas.requestRenderAll())};if(""===this.hiddenTextarea.value)return this.styles={},void s();const i=this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText,r=this._text.length,n=i.length,a=this.selectionStart,h=this.selectionEnd,c=a!==h;let l,u,d,g,f=n-r;const m=this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart,this.hiddenTextarea.selectionEnd,this.hiddenTextarea.value),v=a>m.selectionStart;c?(u=this._text.slice(a,h),f+=h-a):nl[0]))),c?(d=a,g=h):v?(d=h-u.length,g=h):(d=h,g=h+u.length),this.removeStyleFromTo(d,g)),y.length){const{copyPasteData:t}=p();e&&y.join("")===t.copiedText&&!o.disableStyleCopyPaste&&(l=t.copiedTextStyle),this.insertNewStyleBlock(y,a,l)}s()}onCompositionStart(){this.inCompositionMode=!0}onCompositionEnd(){this.inCompositionMode=!1}onCompositionUpdate(t){let{target:e}=t;const{selectionStart:s,selectionEnd:i}=e;this.compositionStart=s,this.compositionEnd=i,this.updateTextareaPosition()}copy(){if(this.selectionStart===this.selectionEnd)return;const{copyPasteData:t}=p();t.copiedText=this.getSelectedText(),o.disableStyleCopyPaste?t.copiedTextStyle=void 0:t.copiedTextStyle=this.getSelectionStyles(this.selectionStart,this.selectionEnd,!0),this._copyDone=!0}paste(){this.fromPaste=!0}_getWidthBeforeCursor(t,e){let s,i=this._getLineLeftOffset(t);return e>0&&(s=this.__charBounds[t][e-1],i+=s.left+s.width),i}getDownCursorOffset(t,e){const s=this._getSelectionForOffset(t,e),i=this.get2DCursorLocation(s),r=i.lineIndex;if(r===this._textLines.length-1||t.metaKey||34===t.keyCode)return this._text.length-s;const n=i.charIndex,o=this._getWidthBeforeCursor(r,n),a=this._getIndexOnLine(r+1,o);return this._textLines[r].slice(n).length+a+1+this.missingNewlineOffset(r)}_getSelectionForOffset(t,e){return t.shiftKey&&this.selectionStart!==this.selectionEnd&&e?this.selectionEnd:this.selectionStart}getUpCursorOffset(t,e){const s=this._getSelectionForOffset(t,e),i=this.get2DCursorLocation(s),r=i.lineIndex;if(0===r||t.metaKey||33===t.keyCode)return-s;const n=i.charIndex,o=this._getWidthBeforeCursor(r,n),a=this._getIndexOnLine(r-1,o),h=this._textLines[r].slice(0,n),c=this.missingNewlineOffset(r-1);return-this._textLines[r-1].length+a-h.length+(1-c)}_getIndexOnLine(t,e){const s=this._textLines[t];let i,r,n=this._getLineLeftOffset(t),o=0;for(let a=0,h=s.length;ae){r=!0;const t=n-i,s=n,h=Math.abs(t-e);o=Math.abs(s-e)=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorUpOrDown("Down",t)}moveCursorUp(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorUpOrDown("Up",t)}_moveCursorUpOrDown(t,e){const s=this["get".concat(t,"CursorOffset")](e,this._selectionDirection===A);if(e.shiftKey?this.moveCursorWithShift(s):this.moveCursorWithoutShift(s),0!==s){const t=this.text.length;this.selectionStart=ds(0,this.selectionStart,t),this.selectionEnd=ds(0,this.selectionEnd,t),this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea()}}moveCursorWithShift(t){const e=this._selectionDirection===M?this.selectionStart+t:this.selectionEnd+t;return this.setSelectionStartEndWithShift(this.selectionStart,this.selectionEnd,e),0!==t}moveCursorWithoutShift(t){return t<0?(this.selectionStart+=t,this.selectionEnd=this.selectionStart):(this.selectionEnd+=t,this.selectionStart=this.selectionEnd),0!==t}moveCursorLeft(t){0===this.selectionStart&&0===this.selectionEnd||this._moveCursorLeftOrRight("Left",t)}_move(t,e,s){let i;if(t.altKey)i=this["findWordBoundary".concat(s)](this[e]);else{if(!t.metaKey&&35!==t.keyCode&&36!==t.keyCode)return this[e]+="Left"===s?-1:1,!0;i=this["findLineBoundary".concat(s)](this[e])}return void 0!==i&&this[e]!==i&&(this[e]=i,!0)}_moveLeft(t,e){return this._move(t,e,"Left")}_moveRight(t,e){return this._move(t,e,"Right")}moveCursorLeftWithoutShift(t){let e=!0;return this._selectionDirection=M,this.selectionEnd===this.selectionStart&&0!==this.selectionStart&&(e=this._moveLeft(t,"selectionStart")),this.selectionEnd=this.selectionStart,e}moveCursorLeftWithShift(t){return this._selectionDirection===A&&this.selectionStart!==this.selectionEnd?this._moveLeft(t,"selectionEnd"):0!==this.selectionStart?(this._selectionDirection=M,this._moveLeft(t,"selectionStart")):void 0}moveCursorRight(t){this.selectionStart>=this._text.length&&this.selectionEnd>=this._text.length||this._moveCursorLeftOrRight("Right",t)}_moveCursorLeftOrRight(t,e){const s="moveCursor".concat(t).concat(e.shiftKey?"WithShift":"WithoutShift");this._currentCursorOpacity=1,this[s](e)&&(this.abortCursorAnimation(),this.initDelayedCursor(),this._fireSelectionChanged(),this._updateTextarea())}moveCursorRightWithShift(t){return this._selectionDirection===M&&this.selectionStart!==this.selectionEnd?this._moveRight(t,"selectionStart"):this.selectionEnd!==this._text.length?(this._selectionDirection=A,this._moveRight(t,"selectionEnd")):void 0}moveCursorRightWithoutShift(t){let e=!0;return this._selectionDirection=A,this.selectionStart===this.selectionEnd?(e=this._moveRight(t,"selectionStart"),this.selectionEnd=this.selectionStart):this.selectionStart=this.selectionEnd,e}}const Mo=t=>!!t.button;class Po extends Do{constructor(){super(...arguments),t(this,"draggableTextDelegate",void 0)}initBehavior(){this.on("mousedown",this._mouseDownHandler),this.on("mousedown:before",this._mouseDownHandlerBefore),this.on("mouseup",this.mouseUpHandler),this.on("mousedblclick",this.doubleClickHandler),this.on("tripleclick",this.tripleClickHandler),this.__lastClickTime=+new Date,this.__lastLastClickTime=+new Date,this.__lastPointer={},this.on("mousedown",this.onMouseDown),this.draggableTextDelegate=new To(this),super.initBehavior()}shouldStartDragging(){return this.draggableTextDelegate.isActive()}onDragStart(t){return this.draggableTextDelegate.onDragStart(t)}canDrop(t){return this.draggableTextDelegate.canDrop(t)}onMouseDown(t){if(!this.canvas)return;this.__newClickTime=+new Date;const e=t.pointer;this.isTripleClick(e)&&(this.fire("tripleclick",t),pe(t.e)),this.__lastLastClickTime=this.__lastClickTime,this.__lastClickTime=this.__newClickTime,this.__lastPointer=e,this.__lastSelected=this.selected&&!this.getActiveControl()}isTripleClick(t){return this.__newClickTime-this.__lastClickTime<500&&this.__lastClickTime-this.__lastLastClickTime<500&&this.__lastPointer.x===t.x&&this.__lastPointer.y===t.y}doubleClickHandler(t){this.isEditing&&this.selectWord(this.getSelectionStartFromPointer(t.e))}tripleClickHandler(t){this.isEditing&&this.selectLine(this.getSelectionStartFromPointer(t.e))}_mouseDownHandler(t){let{e:e}=t;this.canvas&&this.editable&&!Mo(e)&&!this.getActiveControl()&&(this.draggableTextDelegate.start(e)||(this.canvas.textEditingManager.register(this),this.selected&&(this.inCompositionMode=!1,this.setCursorByClick(e)),this.isEditing&&(this.__selectionStartOnMouseDown=this.selectionStart,this.selectionStart===this.selectionEnd&&this.abortCursorAnimation(),this.renderCursorOrSelection())))}_mouseDownHandlerBefore(t){let{e:e}=t;this.canvas&&this.editable&&!Mo(e)&&(this.selected=this===this.canvas._activeObject)}mouseUpHandler(t){let{e:e,transform:s}=t;const i=this.draggableTextDelegate.end(e);if(this.canvas){this.canvas.textEditingManager.unregister(this);const t=this.canvas._activeObject;if(t&&t!==this)return}!this.editable||this.group&&!this.group.interactive||s&&s.actionPerformed||Mo(e)||i||(this.__lastSelected&&!this.getActiveControl()?(this.selected=!1,this.__lastSelected=!1,this.enterEditing(e),this.selectionStart===this.selectionEnd?this.initDelayedCursor(!0):this.renderCursorOrSelection()):this.selected=!0)}setCursorByClick(t){const e=this.getSelectionStartFromPointer(t),s=this.selectionStart,i=this.selectionEnd;t.shiftKey?this.setSelectionStartEndWithShift(s,i,e):(this.selectionStart=e,this.selectionEnd=e),this.isEditing&&(this._fireSelectionChanged(),this._updateTextarea())}getSelectionStartFromPointer(t){const e=this.canvas.getScenePoint(t).transform(bt(this.calcTransformMatrix())).add(new ot(-this._getLeftOffset(),-this._getTopOffset()));let s=0,i=0,r=0;for(let t=0;t0&&(i+=this._textLines[t-1].length+this.missingNewlineOffset(t-1));let n=Math.abs(this._getLineLeftOffset(r));const o=this._textLines[r].length,a=this.__charBounds[r];for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:this.selectionStart||0,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selectionEnd,s=arguments.length>2?arguments[2]:void 0;return super.getSelectionStyles(t,e,s)}setSelectionStyles(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.selectionStart||0,s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.selectionEnd;return super.setSelectionStyles(t,e,s)}get2DCursorLocation(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectionStart,e=arguments.length>1?arguments[1]:void 0;return super.get2DCursorLocation(t,e)}render(t){super.render(t),this.cursorOffsetCache={},this.renderCursorOrSelection()}toCanvasElement(t){const e=this.isEditing;this.isEditing=!1;const s=super.toCanvasElement(t);return this.isEditing=e,s}renderCursorOrSelection(){if(!this.isEditing)return;const t=this.clearContextTop(!0);if(!t)return;const e=this._getCursorBoundaries();this.selectionStart===this.selectionEnd?this.renderCursor(t,e):this.renderSelection(t,e),this.canvas.contextTopDirty=!0,t.restore()}_getCursorBoundaries(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.selectionStart,e=arguments.length>1?arguments[1]:void 0;const s=this._getLeftOffset(),i=this._getTopOffset(),r=this._getCursorBoundariesOffsets(t,e);return{left:s,top:i,leftOffset:r.left,topOffset:r.top}}_getCursorBoundariesOffsets(t,e){return e?this.__getCursorBoundariesOffsets(t):this.cursorOffsetCache&&"top"in this.cursorOffsetCache?this.cursorOffsetCache:this.cursorOffsetCache=this.__getCursorBoundariesOffsets(t)}__getCursorBoundariesOffsets(t){let e=0,s=0;const{charIndex:i,lineIndex:r}=this.get2DCursorLocation(t);for(let t=0;t0?s:0)};return"rtl"===this.direction&&(this.textAlign===A||this.textAlign===fo||this.textAlign===mo?a.left*=-1:this.textAlign===M||this.textAlign===po?a.left=n-(s>0?s:0):this.textAlign!==D&&this.textAlign!==vo||(a.left=n-(s>0?s:0))),a}renderCursorAt(t){const e=this._getCursorBoundaries(t,!0);this._renderCursor(this.canvas.contextTop,e,t)}renderCursor(t,e){this._renderCursor(t,e,this.selectionStart)}_renderCursor(t,e,s){const i=this.get2DCursorLocation(s),r=i.lineIndex,n=i.charIndex>0?i.charIndex-1:0,o=this.getValueOfPropertyAt(r,n,"fontSize"),a=this.getObjectScaling().x*this.canvas.getZoom(),h=this.cursorWidth/a,c=this.getValueOfPropertyAt(r,n,"deltaY"),l=e.topOffset+(1-this._fontSizeFraction)*this.getHeightOfLine(r)/this.lineHeight-o*(1-this._fontSizeFraction);this.inCompositionMode&&this.renderSelection(t,e),t.fillStyle=this.cursorColor||this.getValueOfPropertyAt(r,n,K),t.globalAlpha=this._currentCursorOpacity,t.fillRect(e.left+e.leftOffset-h/2,l+e.top+c,h,o)}renderSelection(t,e){const s={selectionStart:this.inCompositionMode?this.hiddenTextarea.selectionStart:this.selectionStart,selectionEnd:this.inCompositionMode?this.hiddenTextarea.selectionEnd:this.selectionEnd};this._renderSelection(t,s,e)}renderDragSourceEffect(){const t=this.draggableTextDelegate.getDragStartSelection();this._renderSelection(this.canvas.contextTop,t,this._getCursorBoundaries(t.selectionStart,!0))}renderDropTargetEffect(t){const e=this.getSelectionStartFromPointer(t);this.renderCursorAt(e)}_renderSelection(t,e,s){const i=e.selectionStart,r=e.selectionEnd,n=this.textAlign.includes(fo),o=this.get2DCursorLocation(i),a=this.get2DCursorLocation(r),h=o.lineIndex,c=a.lineIndex,l=o.charIndex<0?0:o.charIndex,u=a.charIndex<0?0:a.charIndex;for(let e=h;e<=c;e++){const i=this._getLineLeftOffset(e)||0;let r=this.getHeightOfLine(e),o=0,a=0,d=0;if(e===h&&(a=this.__charBounds[h][l].left),e>=h&&e1)&&(r/=this.lineHeight);let g=s.left+i+a,f=r,p=0;const m=d-a;this.inCompositionMode?(t.fillStyle=this.compositionColor||"black",f=1,p=r):t.fillStyle=this.selectionColor,"rtl"===this.direction&&(this.textAlign===A||this.textAlign===fo||this.textAlign===mo?g=this.width-g-m:this.textAlign===M||this.textAlign===po?g=s.left+i-d:this.textAlign!==D&&this.textAlign!==vo||(g=s.left+i-d)),t.fillRect(g,s.top+s.topOffset+p,m,f),s.topOffset+=o}}getCurrentCharFontSize(){const t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,"fontSize")}getCurrentCharColor(){const t=this._getCurrentCharIndex();return this.getValueOfPropertyAt(t.l,t.c,K)}_getCurrentCharIndex(){const t=this.get2DCursorLocation(this.selectionStart,!0),e=t.charIndex>0?t.charIndex-1:0;return{l:t.lineIndex,c:e}}dispose(){this._exitEditing(),this.draggableTextDelegate.dispose(),super.dispose()}}t(Io,"ownDefaults",Ro),t(Io,"type","IText"),tt.setClass(Io),tt.setClass(Io,"i-text");class Bo extends Io{static getDefaults(){return s(s({},super.getDefaults()),Bo.ownDefaults)}constructor(t,e){super(t,s(s({},Bo.ownDefaults),e))}static createControls(){return{controls:pi()}}initDimensions(){this.initialized&&(this.isEditing&&this.initDelayedCursor(),this._clearCache(),this.dynamicMinWidth=0,this._styleMap=this._generateStyleMap(this._splitText()),this.dynamicMinWidth>this.width&&this._set("width",this.dynamicMinWidth),this.textAlign.includes(fo)&&this.enlargeSpaces(),this.height=this.calcTextHeight())}_generateStyleMap(t){let e=0,s=0,i=0;const r={};for(let n=0;n0?(s=0,i++,e++):!this.splitByGrapheme&&this._reSpaceAndTab.test(t.graphemeText[i])&&n>0&&(s++,i++),r[n]={line:e,offset:s},i+=t.graphemeLines[n].length,s+=t.graphemeLines[n].length;return r}styleHas(t,e){if(this._styleMap&&!this.isWrapping){const t=this._styleMap[e];t&&(e=t.line)}return super.styleHas(t,e)}isEmptyStyles(t){if(!this.styles)return!0;let e,s=0,i=t+1,r=!1;const n=this._styleMap[t],o=this._styleMap[t+1];n&&(t=n.line,s=n.offset),o&&(i=o.line,r=i===t,e=o.offset);const a=void 0===t?this.styles:{line:this.styles[t]};for(const t in a)for(const i in a[t]){const n=parseInt(i,10);if(n>=s&&(!r||n{let n=0;const o=e?this.graphemeSplit(t):this.wordSplit(t);return 0===o.length?[{word:[],width:0}]:o.map((t=>{const o=e?[t]:this.graphemeSplit(t),a=this._measureWord(o,r,n);return i=Math.max(a,i),n+=o.length+s.length,{word:o,width:a}}))})),largestWordWidth:i}}_measureWord(t,e){let s,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,r=0;for(let n=0,o=t.length;n3&&void 0!==arguments[3]?arguments[3]:0;const o=this._getWidthOfCharSpacing(),a=this.splitByGrapheme,h=[],c=a?"":" ";let l=0,u=[],d=0,g=0,f=!0;e-=n;const p=Math.max(e,i,this.dynamicMinWidth),m=r[t];let v;for(d=0,v=0;vp&&!f?(h.push(u),u=[],l=s,f=!0):l+=o,f||a||u.push(c),u=u.concat(e),g=a?0:this._measureWord([c],t,d),d++,f=!1}return v&&h.push(u),i+n>this.dynamicMinWidth&&(this.dynamicMinWidth=i-o+n),h}isEndOfWrapping(t){return!this._styleMap[t+1]||this._styleMap[t+1].line!==this._styleMap[t].line}missingNewlineOffset(t,e){return this.splitByGrapheme&&!e?this.isEndOfWrapping(t)?1:0:1}_splitTextIntoLines(t){const e=super._splitTextIntoLines(t),s=this._wrapText(e.lines,this.width),i=new Array(s.length);for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:[];return super.toObject(["minWidth","splitByGrapheme",...t])}}t(Bo,"type","Textbox"),t(Bo,"textLayoutProperties",[...Io.textLayoutProperties,"width"]),t(Bo,"ownDefaults",{minWidth:20,dynamicMinWidth:2,lockScalingFlip:!0,noScaleCache:!1,_wordJoiners:/[ \t\r]/,splitByGrapheme:!1}),tt.setClass(Bo);class Xo extends xr{shouldPerformLayout(t){return!!t.target.clipPath&&super.shouldPerformLayout(t)}shouldLayoutClipPath(){return!1}calcLayoutResult(t,e){const{target:s}=t,{clipPath:i,group:r}=s;if(!i||!this.shouldPerformLayout(t))return;const{width:n,height:o}=me(_r(s,i)),a=new ot(n,o);if(i.absolutePositioned){return{center:Se(i.getRelativeCenterPoint(),void 0,r?r.calcTransformMatrix():void 0),size:a}}{const r=i.getRelativeCenterPoint().transform(s.calcOwnMatrix(),!0);if(this.shouldPerformLayout(t)){const{center:s=new ot,correction:i=new ot}=this.calcBoundingBox(e,t)||{};return{center:s.add(r),correction:i.subtract(r),size:a}}return{center:s.getRelativeCenterPoint().add(r),size:a}}}}t(Xo,"type","clip-path"),tt.setClass(Xo);class Wo extends xr{getInitialSize(t,e){let{target:s}=t,{size:i}=e;return new ot(s.width||i.x,s.height||i.y)}}t(Wo,"type","fixed"),tt.setClass(Wo);class Yo extends Tr{subscribeTargets(t){const e=t.target;t.targets.reduce(((t,e)=>(e.parent&&t.add(e.parent),t)),new Set).forEach((t=>{t.layoutManager.subscribeTargets({target:t,targets:[e]})}))}unsubscribeTargets(t){const e=t.target,s=e.getObjects();t.targets.reduce(((t,e)=>(e.parent&&t.add(e.parent),t)),new Set).forEach((t=>{!s.some((e=>e.parent===t))&&t.layoutManager.unsubscribeTargets({target:t,targets:[e]})}))}}class Vo extends Dr{static getDefaults(){return s(s({},super.getDefaults()),Vo.ownDefaults)}constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),Object.assign(this,Vo.ownDefaults),this.setOptions(e);const{left:s,top:i,layoutManager:r}=e;this.groupInit(t,{left:s,top:i,layoutManager:null!=r?r:new Yo})}_shouldSetNestedCoords(){return!0}__objectSelectionMonitor(){}multiSelectAdd(){for(var t=arguments.length,e=new Array(t),s=0;s{const e=this._objects.findIndex((e=>e.isInFrontOf(t))),s=-1===e?this.size():e;this.insertAt(s,t)}))}canEnterGroup(t){return this.getObjects().some((e=>e.isDescendantOf(t)||t.isDescendantOf(e)))?(a("error","ActiveSelection: circular object trees are not supported, this call has no effect"),!1):super.canEnterGroup(t)}enterGroup(t,e){t.parent&&t.parent===t.group?t.parent._exitGroup(t):t.group&&t.parent!==t.group&&t.group.remove(t),this._enterGroup(t,e)}exitGroup(t,e){this._exitGroup(t,e),t.parent&&t.parent._enterGroup(t,!0)}_onAfterObjectsChange(t,e){super._onAfterObjectsChange(t,e);const s=new Set;e.forEach((t=>{const{parent:e}=t;e&&s.add(e)})),t===vr?s.forEach((t=>{t._onAfterObjectsChange(mr,e)})):s.forEach((t=>{t._set("dirty",!0)}))}onDeselect(){return this.removeAll(),!1}toString(){return"#")}shouldCache(){return!1}isOnACache(){return!1}_renderControls(t,e,i){t.save(),t.globalAlpha=this.isMoving?this.borderOpacityWhenMoving:1;const r=s(s({hasControls:!1},i),{},{forActiveSelection:!0});for(let e=0;e{t.applyTo(o)}));const{imageData:a}=o;return a.width===s&&a.height===i||(r.width=a.width,r.height=a.height),n.putImageData(a,0,0),o}}class zo{constructor(){let{tileSize:e=o.textureSize}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};t(this,"aPosition",new Float32Array([0,0,0,1,1,0,1,1])),t(this,"resources",{}),this.tileSize=e,this.setupGLContext(e,e),this.captureGPUInfo()}setupGLContext(t,e){this.dispose(),this.createWebGLCanvas(t,e)}createWebGLCanvas(t,e){const s=pt();s.width=t,s.height=e;const i=s.getContext("webgl",{alpha:!0,premultipliedAlpha:!1,depth:!1,stencil:!1,antialias:!1});i&&(i.clearColor(0,0,0,0),this.canvas=s,this.gl=i)}applyFilters(t,e,s,i,r,n){const o=this.gl,a=r.getContext("2d");if(!o||!a)return;let h;n&&(h=this.getCachedTexture(n,e));const c={originalWidth:e.width||e.originalWidth||0,originalHeight:e.height||e.originalHeight||0,sourceWidth:s,sourceHeight:i,destinationWidth:s,destinationHeight:i,context:o,sourceTexture:this.createTexture(o,s,i,h?void 0:e),targetTexture:this.createTexture(o,s,i),originalTexture:h||this.createTexture(o,s,i,h?void 0:e),passes:t.length,webgl:!0,aPosition:this.aPosition,programCache:this.programCache,pass:0,filterBackend:this,targetCanvas:r},l=o.createFramebuffer();return o.bindFramebuffer(o.FRAMEBUFFER,l),t.forEach((t=>{t&&t.applyTo(c)})),function(t){const e=t.targetCanvas,s=e.width,i=e.height,r=t.destinationWidth,n=t.destinationHeight;s===r&&i===n||(e.width=r,e.height=n)}(c),this.copyGLTo2D(o,c),o.bindTexture(o.TEXTURE_2D,null),o.deleteTexture(c.sourceTexture),o.deleteTexture(c.targetTexture),o.deleteFramebuffer(l),a.setTransform(1,0,0,1,0,0),c}dispose(){this.canvas&&(this.canvas=null,this.gl=null),this.clearWebGLCaches()}clearWebGLCaches(){this.programCache={},this.textureCache={}}createTexture(t,e,s,i,r){const{NEAREST:n,TEXTURE_2D:o,RGBA:a,UNSIGNED_BYTE:h,CLAMP_TO_EDGE:c,TEXTURE_MAG_FILTER:l,TEXTURE_MIN_FILTER:u,TEXTURE_WRAP_S:d,TEXTURE_WRAP_T:g}=t,f=t.createTexture();return t.bindTexture(o,f),t.texParameteri(o,l,r||n),t.texParameteri(o,u,r||n),t.texParameteri(o,d,c),t.texParameteri(o,g,c),i?t.texImage2D(o,0,a,a,h,i):t.texImage2D(o,0,a,e,s,0,a,h,null),f}getCachedTexture(t,e,s){const{textureCache:i}=this;if(i[t])return i[t];{const r=this.createTexture(this.gl,e.width,e.height,e,s);return r&&(i[t]=r),r}}evictCachesForKey(t){this.textureCache[t]&&(this.gl.deleteTexture(this.textureCache[t]),delete this.textureCache[t])}copyGLTo2D(t,e){const s=t.canvas,i=e.targetCanvas,r=i.getContext("2d");if(!r)return;r.translate(0,i.height),r.scale(1,-1);const n=s.height-i.height;r.drawImage(s,0,n,i.width,i.height,0,0,i.width,i.height)}copyGLTo2DPutImageData(t,e){const s=e.targetCanvas.getContext("2d"),i=e.destinationWidth,r=e.destinationHeight,n=i*r*4;if(!s)return;const o=new Uint8Array(this.imageBuffer,0,n),a=new Uint8ClampedArray(this.imageBuffer,0,n);t.readPixels(0,0,i,r,t.RGBA,t.UNSIGNED_BYTE,o);const h=new ImageData(a,i,r);s.putImageData(h,0,0)}captureGPUInfo(){if(this.gpuInfo)return this.gpuInfo;const t=this.gl,e={renderer:"",vendor:""};if(!t)return e;const s=t.getExtension("WEBGL_debug_renderer_info");if(s){const i=t.getParameter(s.UNMASKED_RENDERER_WEBGL),r=t.getParameter(s.UNMASKED_VENDOR_WEBGL);i&&(e.renderer=i.toLowerCase()),r&&(e.vendor=r.toLowerCase())}return this.gpuInfo=e,e}}let Go;function No(){const{WebGLProbe:t}=p();return t.queryWebGL(pt()),o.enableGLFiltering&&t.isSupported(o.textureSize)?new zo({tileSize:o.textureSize}):new Ho}function Uo(){return!Go&&(!(arguments.length>0&&void 0!==arguments[0])||arguments[0])&&(Go=No()),Go}function qo(t){Go=t}const Ko=["filters","resizeFilter","src","crossOrigin","type"],Jo=["cropX","cropY"];class Qo extends yi{static getDefaults(){return s(s({},super.getDefaults()),Qo.ownDefaults)}constructor(e,s){super(),t(this,"_lastScaleX",1),t(this,"_lastScaleY",1),t(this,"_filterScalingX",1),t(this,"_filterScalingY",1),this.filters=[],Object.assign(this,Qo.ownDefaults),this.setOptions(s),this.cacheKey="texture".concat(ft()),this.setElement("string"==typeof e?(this.canvas&&re(this.canvas.getElement())||m()).getElementById(e):e,s)}getElement(){return this._element}setElement(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};this.removeTexture(this.cacheKey),this.removeTexture("".concat(this.cacheKey,"_filtered")),this._element=t,this._originalElement=t,this._setWidthHeight(e),t.classList.add(Qo.CSS_CANVAS),0!==this.filters.length&&this.applyFilters(),this.resizeFilter&&this.applyResizeFilters()}removeTexture(t){const e=Uo(!1);e instanceof zo&&e.evictCachesForKey(t)}dispose(){super.dispose(),this.removeTexture(this.cacheKey),this.removeTexture("".concat(this.cacheKey,"_filtered")),this._cacheContext=null,["_originalElement","_element","_filteredEl","_cacheCanvas"].forEach((t=>{const e=this[t];e&&p().dispose(e),this[t]=void 0}))}getCrossOrigin(){return this._originalElement&&(this._originalElement.crossOrigin||null)}getOriginalSize(){const t=this.getElement();return t?{width:t.naturalWidth||t.width,height:t.naturalHeight||t.height}:{width:0,height:0}}_stroke(t){if(!this.stroke||0===this.strokeWidth)return;const e=this.width/2,s=this.height/2;t.beginPath(),t.moveTo(-e,-s),t.lineTo(e,-s),t.lineTo(e,s),t.lineTo(-e,s),t.lineTo(-e,-s),t.closePath()}toObject(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];const e=[];return this.filters.forEach((t=>{t&&e.push(t.toObject())})),s(s({},super.toObject([...Jo,...t])),{},{src:this.getSrc(),crossOrigin:this.getCrossOrigin(),filters:e},this.resizeFilter?{resizeFilter:this.resizeFilter.toObject()}:{})}hasCrop(){return!!this.cropX||!!this.cropY||this.width\n','\t\n',"\n"),o=' clip-path="url(#imageCrop_'+t+')" '}if(this.imageSmoothing||(a=' image-rendering="optimizeSpeed"'),t.push("\t\n")),this.stroke||this.strokeDashArray){const t=this.fill;this.fill=null,n=['\t\n')],this.fill=t}return r=this.paintFirst!==K?r.concat(n,t):r.concat(t,n),r}getSrc(t){const e=t?this._element:this._originalElement;return e?e.toDataURL?e.toDataURL():this.srcFromAttribute?e.getAttribute("src")||"":e.src:this.src||""}getSvgSrc(t){return this.getSrc(t)}setSrc(t){let{crossOrigin:e,signal:s}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Lt(t,{crossOrigin:e,signal:s}).then((t=>{void 0!==e&&this.set({crossOrigin:e}),this.setElement(t)}))}toString(){return'#')}applyResizeFilters(){const t=this.resizeFilter,e=this.minimumScaleTrigger,s=this.getTotalObjectScaling(),i=s.x,r=s.y,n=this._filteredEl||this._originalElement;if(this.group&&this.set("dirty",!0),!t||i>e&&r>e)return this._element=n,this._filterScalingX=1,this._filterScalingY=1,this._lastScaleX=i,void(this._lastScaleY=r);const o=pt(),a=n.width,h=n.height;o.width=a,o.height=h,this._element=o,this._lastScaleX=t.scaleX=i,this._lastScaleY=t.scaleY=r,Uo().applyFilters([t],n,a,h,this._element),this._filterScalingX=o.width/this._originalElement.width,this._filterScalingY=o.height/this._originalElement.height}applyFilters(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.filters||[];if(t=t.filter((t=>t&&!t.isNeutralState())),this.set("dirty",!0),this.removeTexture("".concat(this.cacheKey,"_filtered")),0===t.length)return this._element=this._originalElement,this._filteredEl=void 0,this._filterScalingX=1,void(this._filterScalingY=1);const e=this._originalElement,s=e.naturalWidth||e.width,i=e.naturalHeight||e.height;if(this._element===this._originalElement){const t=pt();t.width=s,t.height=i,this._element=t,this._filteredEl=t}else this._filteredEl&&(this._element=this._filteredEl,this._filteredEl.getContext("2d").clearRect(0,0,s,i),this._lastScaleX=1,this._lastScaleY=1);Uo().applyFilters(t,this._originalElement,s,i,this._element),this._originalElement.width===this._element.width&&this._originalElement.height===this._element.height||(this._filterScalingX=this._element.width/this._originalElement.width,this._filterScalingY=this._element.height/this._originalElement.height)}_render(t){t.imageSmoothingEnabled=this.imageSmoothing,!0!==this.isMoving&&this.resizeFilter&&this._needsResize()&&this.applyResizeFilters(),this._stroke(t),this._renderPaintInOrder(t)}drawCacheOnCanvas(t){t.imageSmoothingEnabled=this.imageSmoothing,super.drawCacheOnCanvas(t)}shouldCache(){return this.needsItsOwnCache()}_renderFill(t){const e=this._element;if(!e)return;const s=this._filterScalingX,i=this._filterScalingY,r=this.width,n=this.height,o=Math.max(this.cropX,0),a=Math.max(this.cropY,0),h=e.naturalWidth||e.width,c=e.naturalHeight||e.height,l=o*s,u=a*i,d=Math.min(r*s,h-l),g=Math.min(n*i,c-u),f=-r/2,p=-n/2,m=Math.min(r,h/s-o),v=Math.min(n,c/i-a);e&&t.drawImage(e,l,u,d,g,f,p,m,v)}_needsResize(){const t=this.getTotalObjectScaling();return t.x!==this._lastScaleX||t.y!==this._lastScaleY}_resetWidthHeight(){this.set(this.getOriginalSize())}_setWidthHeight(){let{width:t,height:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const s=this.getOriginalSize();this.width=t||s.width,this.height=e||s.height}parsePreserveAspectRatioAttribute(){const t=Kt(this.preserveAspectRatio||""),e=this.width,s=this.height,i={width:e,height:s};let r,n=this._element.width,o=this._element.height,a=1,h=1,c=0,l=0,u=0,d=0;return!t||t.alignX===j&&t.alignY===j?(a=e/n,h=s/o):("meet"===t.meetOrSlice&&(a=h=Mr(this._element,i),r=(e-n*a)/2,"Min"===t.alignX&&(c=-r),"Max"===t.alignX&&(c=r),r=(s-o*h)/2,"Min"===t.alignY&&(l=-r),"Max"===t.alignY&&(l=r)),"slice"===t.meetOrSlice&&(a=h=Pr(this._element,i),r=n-e/a,"Mid"===t.alignX&&(u=r/2),"Max"===t.alignX&&(u=r),r=o-s/h,"Mid"===t.alignY&&(d=r/2),"Max"===t.alignY&&(d=r),n=e/a,o=s/h)),{width:n,height:o,scaleX:a,scaleY:h,offsetLeft:c,offsetTop:l,cropX:u,cropY:d}}static fromObject(t,e){let{filters:r,resizeFilter:n,src:o,crossOrigin:a,type:h}=t,c=i(t,Ko);return Promise.all([Lt(o,s(s({},e),{},{crossOrigin:a})),r&&Rt(r,e),n&&Rt([n],e),It(c,e)]).then((t=>{let[e,i=[],[r]=[],n={}]=t;return new this(e,s(s({},c),{},{src:o,filters:i,resizeFilter:r},n))}))}static fromURL(t){let{crossOrigin:e=null,signal:s}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2?arguments[2]:void 0;return Lt(t,{crossOrigin:e,signal:s}).then((t=>new this(t,i)))}static async fromElement(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=arguments.length>2?arguments[2]:void 0;const i=ur(t,this.ATTRIBUTE_NAMES,s);return this.fromURL(i["xlink:href"],e,i).catch((t=>(a("log","Unable to parse Image",t),null)))}}function Zo(t){if(!qe.test(t.nodeName))return{};const e=t.getAttribute("viewBox");let s,i,r=1,n=1,o=0,a=0;const h=t.getAttribute("width"),c=t.getAttribute("height"),l=t.getAttribute("x")||0,u=t.getAttribute("y")||0,d=!(e&&Je.test(e)),g=!h||!c||"100%"===h||"100%"===c;let f="",p=0,m=0;if(d&&(l||u)&&t.parentNode&&"#document"!==t.parentNode.nodeName&&(f=" translate("+qt(l||"0")+" "+qt(u||"0")+") ",s=(t.getAttribute("transform")||"")+f,t.setAttribute("transform",s),t.removeAttribute("x"),t.removeAttribute("y")),d&&g)return{width:0,height:0};const v={width:0,height:0};if(d)return v.width=qt(h),v.height=qt(c),v;const y=e.match(Je);o=-parseFloat(y[1]),a=-parseFloat(y[2]);const _=parseFloat(y[3]),x=parseFloat(y[4]);v.minX=o,v.minY=a,v.viewBoxWidth=_,v.viewBoxHeight=x,g?(v.width=_,v.height=x):(v.width=qt(h),v.height=qt(c),r=v.width/_,n=v.height/x);const C=Kt(t.getAttribute("preserveAspectRatio")||"");if(C.alignX!==j&&("meet"===C.meetOrSlice&&(n=r=r>n?n:r),"slice"===C.meetOrSlice&&(n=r=r>n?r:n),p=v.width-_*r,m=v.height-x*r,"Mid"===C.alignX&&(p/=2),"Mid"===C.alignY&&(m/=2),"Min"===C.alignX&&(p=0),"Min"===C.alignY&&(m=0)),1===r&&1===n&&0===o&&0===a&&0===l&&0===u)return v;if((l||u)&&"#document"!==t.parentNode.nodeName&&(f=" translate("+qt(l||"0")+" "+qt(u||"0")+") "),s=f+" matrix("+r+" 0 0 "+n+" "+(o*r+p)+" "+(a*n+m)+") ","svg"===t.nodeName){for(i=t.ownerDocument.createElementNS(Ve,"g");t.firstChild;)i.appendChild(t.firstChild);t.appendChild(i)}else i=t,i.removeAttribute("x"),i.removeAttribute("y"),s=i.getAttribute("transform")+s;return i.setAttribute("transform",s),v}t(Qo,"type","Image"),t(Qo,"cacheProperties",[...fs,...Jo]),t(Qo,"ownDefaults",{strokeWidth:0,srcFromAttribute:!1,minimumScaleTrigger:.5,cropX:0,cropY:0,imageSmoothing:!0}),t(Qo,"CSS_CANVAS","canvas-img"),t(Qo,"ATTRIBUTE_NAMES",[...ji,"x","y","width","height","preserveAspectRatio","xlink:href","crossOrigin","image-rendering"]),tt.setClass(Qo),tt.setSVGClass(Qo);const $o=t=>t.tagName.replace("svg:",""),ta=Xe(["pattern","defs","symbol","metadata","clipPath","mask","desc"]);function ea(t,e){let s,i,r,n,o=[];for(r=0,n=e.length;r{const s=r.getAttribute(t);!e.hasAttribute(t)&&s&&e.setAttribute(t,s)})),!e.children.length)){const t=r.cloneNode(!0);for(;t.firstChild;)e.appendChild(t.firstChild)}e.removeAttribute(ia)}const na=["linearGradient","radialGradient","svg:linearGradient","svg:radialGradient"];function oa(t){const e=t.getElementsByTagName("style");let i,r;const n={};for(i=0,r=e.length;is.length>1&&t.trim())).forEach((t=>{if((t.match(/{/g)||[]).length>1&&t.trim().startsWith("@"))return;const e=t.split("{"),o={},a=e[1].trim().split(";").filter((function(t){return t.trim()}));for(i=0,r=a.length;i{""!==(t=t.replace(/^svg/i,"").trim())&&(n[t]=s(s({},n[t]||{}),o))}))}))}return n}const aa=t=>tt.getSVGClass($o(t).toLowerCase());class ha{constructor(t,e,s,i,r){this.elements=t,this.options=e,this.reviver=s,this.regexUrl=/^url\(['"]?#([^'"]+)['"]?\)/g,this.doc=i,this.clipPaths=r,this.gradientDefs=function(t){const e=ea(t,na),s={};let i=e.length;for(;i--;){const r=e[i];r.getAttribute("xlink:href")&&ra(t,r);const n=r.getAttribute("id");n&&(s[n]=r)}return s}(i),this.cssRules=oa(i)}parse(){return Promise.all(this.elements.map((t=>this.createObject(t))))}async createObject(t){const e=aa(t);if(e){const s=await e.fromElement(t,this.options,this.cssRules);return this.resolveGradient(s,t,K),this.resolveGradient(s,t,J),s instanceof Qo&&s._originalElement?cn(s,s.parsePreserveAspectRatioAttribute()):cn(s),await this.resolveClipPath(s,t),this.reviver&&this.reviver(t,s),s}return null}extractPropertyDefinition(t,e,s){const i=t[e],r=this.regexUrl;if(!r.test(i))return;r.lastIndex=0;const n=r.exec(i)[1];return r.lastIndex=0,s[n]}resolveGradient(t,e,i){const r=this.extractPropertyDefinition(t,i,this.gradientDefs);if(r){const n=e.getAttribute(i+"-opacity"),o=Ln.fromElement(r,t,s(s({},this.options),{},{opacity:n}));t.set(i,o)}}async resolveClipPath(t,e){const s=this.extractPropertyDefinition(t,"clipPath",this.clipPaths);if(s){const i=bt(t.calcTransformMatrix()),r=s[0].parentElement;let n=e;for(;n.parentElement&&n.getAttribute("clip-path")!==t.clipPath;)n=n.parentElement;n.parentElement.appendChild(r);const o=nr("".concat(n.getAttribute("transform")||""," ").concat(r.getAttribute("originalTransform")||""));r.setAttribute("transform","matrix(".concat(o.join(","),")"));const a=await Promise.all(s.map((t=>aa(t).fromElement(t,this.options,this.cssRules).then((t=>(cn(t),t.fillRule=t.clipRule,delete t.clipRule,t)))))),h=1===a.length?a[0]:new Dr(a),c=wt(i,h.calcTransformMatrix());h.clipPath&&await this.resolveClipPath(h,n);const{scaleX:l,scaleY:u,angle:d,skewX:g,translateX:f,translateY:p}=Ot(c);h.set({flipX:!1,flipY:!1}),h.set({scaleX:l,scaleY:u,angle:d,skewX:g,skewY:0}),h.setPositionByOrigin(new ot(f,p),D,D),t.clipPath=h}else delete t.clipPath}}const ca=t=>Ue.test($o(t)),la=()=>({objects:[],elements:[],options:{},allElements:[]});async function ua(t,e){let{crossOrigin:i,signal:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if(r&&r.aborted)return a("log",new c("parseSVGDocument")),la();const n=t.documentElement;!function(t){const e=ea(t,["use","svg:use"]),s=["x","y","xlink:href","href","transform"];for(const i of e){const e=i.attributes,r={};for(const t of e)t.value&&(r[t.name]=t.value);const n=(r["xlink:href"]||r.href||"").slice(1);if(""===n)return;const o=t.getElementById(n);if(null===o)return;let a=o.cloneNode(!0);const h=a.attributes,c={};for(const t of h)t.value&&(c[t.name]=t.value);const{x:l=0,y:u=0,transform:d=""}=r,g="".concat(d," ").concat(c.transform||""," translate(").concat(l,", ").concat(u,")");if(Zo(a),/^svg$/i.test(a.nodeName)){const t=a.ownerDocument.createElementNS(Ve,"g");Object.entries(c).forEach((e=>{let[s,i]=e;return t.setAttributeNS(Ve,s,i)})),t.append(...a.childNodes),a=t}for(const t of e){if(!t)continue;const{name:e,value:i}=t;if(!s.includes(e))if("style"===e){const t={};hr(i,t),Object.entries(c).forEach((e=>{let[s,i]=e;t[s]=i})),hr(c.style||"",t);const s=Object.entries(t).map((t=>t.join(":"))).join(";");a.setAttribute(e,s)}else!c[e]&&a.setAttribute(e,i)}a.setAttribute("transform",g),a.setAttribute("instantiated_by_use","1"),a.removeAttribute("id"),i.parentNode.replaceChild(a,i)}}(t);const o=Array.from(n.getElementsByTagName("*")),h=s(s({},Zo(n)),{},{crossOrigin:i,signal:r}),l=o.filter((t=>(Zo(t),ca(t)&&!function(t){let e=t;for(;e&&(e=e.parentElement);)if(e&&e.nodeName&&ta.test($o(e))&&!e.getAttribute("instantiated_by_use"))return!0;return!1}(t))));if(!l||l&&!l.length)return s(s({},la()),{},{options:h,allElements:o});const u={};o.filter((t=>"clipPath"===$o(t))).forEach((t=>{t.setAttribute("originalTransform",t.getAttribute("transform")||"");const e=t.getAttribute("id");u[e]=Array.from(t.getElementsByTagName("*")).filter((t=>ca(t)))}));const d=new ha(l,h,e,t,u);return{objects:await d.parse(),elements:l,options:h,allElements:o}}function da(t,e,s){return ua((new(v().DOMParser)).parseFromString(t.trim(),"text/xml"),e,s)}function ga(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return new Promise(((e,i)=>{hn(t.replace(/^\n\s*/,"").trim(),{onComplete:t=>{const s=t.responseXML;s&&e(s),i()},signal:s.signal})})).then((t=>ua(t,e,s))).catch((()=>la()))}const fa=Y,pa=t=>function(e,s,i){const{points:r,pathOffset:n}=i;return new ot(r[t]).subtract(n).transform(wt(i.getViewportTransform(),i.calcTransformMatrix()))},ma=(t,e,s,i)=>{const{target:r,pointIndex:n}=e,o=r,a=Se(new ot(s,i),void 0,o.calcOwnMatrix());return o.points[n]=a.add(o.pathOffset),o.setDimensions(),!0},va=(t,e)=>function(i,r,n,o){const a=r.target,h=new ot(a.points[(t>0?t:a.points.length)-1]),c=h.subtract(a.pathOffset).transform(a.calcOwnMatrix()),l=e(i,s(s({},r),{},{pointIndex:t}),n,o),u=h.subtract(a.pathOffset).transform(a.calcOwnMatrix()).subtract(c);return a.left-=u.x,a.top-=u.y,l},ya=t=>Xs(fa,va(t,ma));const _a=(t,e,s)=>{const{path:i,pathOffset:r}=t,n=i[e];return new ot(n[s]-r.x,n[s+1]-r.y).transform(wt(t.getViewportTransform(),t.calcTransformMatrix()))};function xa(t,e,s){const{commandIndex:i,pointIndex:r}=this;return _a(s,i,r)}function Ca(t,e,i,r){const{target:n}=e,{commandIndex:o,pointIndex:a}=this,h=((t,e,s,i,r)=>{const{path:n,pathOffset:o}=t,a=n[(i>0?i:n.length)-1],h=new ot(a[r],a[r+1]),c=h.subtract(o).transform(t.calcOwnMatrix()),l=Se(new ot(e,s),void 0,t.calcOwnMatrix());n[i][r]=l.x+o.x,n[i][r+1]=l.y+o.y,t.setDimensions();const u=h.subtract(t.pathOffset).transform(t.calcOwnMatrix()).subtract(c);return t.left-=u.x,t.top-=u.y,t.set("dirty",!0),!0})(n,i,r,o,a);return ke(this.actionName,s(s({},Fe(t,e,i,r)),{},{commandIndex:o,pointIndex:a})),h}class ba extends zs{constructor(t){super(t)}render(t,e,i,r,n){const o=s(s({},r),{},{cornerColor:this.controlFill,cornerStrokeColor:this.controlStroke,transparentCorners:!this.controlFill});super.render(t,e,i,o,n)}}class wa extends ba{constructor(t){super(t)}render(t,e,s,i,r){const{path:n}=r,{commandIndex:o,pointIndex:a,connectToCommandIndex:h,connectToPointIndex:c}=this;t.save(),t.strokeStyle=this.controlStroke,this.connectionDashArray&&t.setLineDash(this.connectionDashArray);const[l]=n[o],u=_a(r,h,c);if("Q"===l){const i=_a(r,o,a+2);t.moveTo(i.x,i.y),t.lineTo(e,s)}else t.moveTo(e,s);t.lineTo(u.x,u.y),t.stroke(),t.restore(),super.render(t,e,s,i,r)}}const Sa=(t,e,i,r,n,o)=>new(i?wa:ba)(s(s({commandIndex:t,pointIndex:e,actionName:"modifyPath",positionHandler:xa,actionHandler:Ca,connectToCommandIndex:n,connectToPointIndex:o},r),i?r.controlPointStyle:r.pointStyle));var Ta=Object.freeze({__proto__:null,changeWidth:Ys,createObjectDefaultControls:gi,createPathControls:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s={};let i="M";return t.path.forEach(((t,r)=>{const n=t[0];switch("Z"!==n&&(s["c_".concat(r,"_").concat(n)]=Sa(r,t.length-2,!1,e)),n){case"C":s["c_".concat(r,"_C_CP_1")]=Sa(r,1,!0,e,r-1,(t=>"C"===t?5:"Q"===t?3:1)(i)),s["c_".concat(r,"_C_CP_2")]=Sa(r,3,!0,e,r,5);break;case"Q":s["c_".concat(r,"_Q_CP_1")]=Sa(r,1,!0,e,r,3)}i=n})),s},createPolyActionHandler:ya,createPolyControls:function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const i={};for(let r=0;r<("number"==typeof t?t:t.points.length);r++)i["p".concat(r)]=new zs(s({actionName:fa,positionHandler:pa(r),actionHandler:ya(r)},e));return i},createPolyPositionHandler:pa,createResizeControls:fi,createTextboxDefaultControls:pi,dragHandler:Ie,factoryPolyActionHandler:va,getLocalPoint:Re,polyActionHandler:ma,renderCircleControl:Vs,renderSquareControl:Hs,rotationStyleHandler:Gs,rotationWithSnapping:Ns,scaleCursorStyleHandler:Js,scaleOrSkewActionName:ci,scaleSkewCursorStyleHandler:li,scalingEqually:Zs,scalingX:$s,scalingXOrSkewingY:ui,scalingY:ti,scalingYOrSkewingX:di,skewCursorStyleHandler:ri,skewHandlerX:oi,skewHandlerY:ai,wrapWithFireEvent:Xs,wrapWithFixedAnchor:Ws});const Oa=t=>void 0!==t.webgl,ka=(t,e)=>{const s=pt(),i=pt().getContext("webgl"),r={imageBuffer:new ArrayBuffer(t*e*4)},n={destinationWidth:t,destinationHeight:e,targetCanvas:s};let o;s.width=t,s.height=e,o=v().performance.now(),zo.prototype.copyGLTo2D.call(r,i,n);const a=v().performance.now()-o;o=v().performance.now(),zo.prototype.copyGLTo2DPutImageData.call(r,i,n);return a>v().performance.now()-o},Da="precision highp float",Ma="\n ".concat(Da,";\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }"),Pa=["type"],Ea=["type"],Aa=new RegExp(Da,"g");class ja{get type(){return this.constructor.type}constructor(){let t=i(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},Pa);Object.assign(this,this.constructor.defaults,t)}getFragmentSource(){return Ma}getVertexSource(){return"\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }"}createProgram(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.getFragmentSource(),s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:this.getVertexSource();const{WebGLProbe:{GLPrecision:i="highp"}}=p();"highp"!==i&&(e=e.replace(Aa,Da.replace("highp",i)));const r=t.createShader(t.VERTEX_SHADER),n=t.createShader(t.FRAGMENT_SHADER),o=t.createProgram();if(!r||!n||!o)throw new h("Vertex, fragment shader or program creation error");if(t.shaderSource(r,s),t.compileShader(r),!t.getShaderParameter(r,t.COMPILE_STATUS))throw new h("Vertex shader compile error for ".concat(this.type,": ").concat(t.getShaderInfoLog(r)));if(t.shaderSource(n,e),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS))throw new h("Fragment shader compile error for ".concat(this.type,": ").concat(t.getShaderInfoLog(n)));if(t.attachShader(o,r),t.attachShader(o,n),t.linkProgram(o),!t.getProgramParameter(o,t.LINK_STATUS))throw new h('Shader link error for "'.concat(this.type,'" ').concat(t.getProgramInfoLog(o)));const a=this.getUniformLocations(t,o)||{};return a.uStepW=t.getUniformLocation(o,"uStepW"),a.uStepH=t.getUniformLocation(o,"uStepH"),{program:o,attributeLocations:this.getAttributeLocations(t,o),uniformLocations:a}}getAttributeLocations(t,e){return{aPosition:t.getAttribLocation(e,"aPosition")}}getUniformLocations(t,e){const s=this.constructor.uniformLocations,i={};for(let r=0;r1){const s=t.destinationWidth,i=t.destinationHeight;t.sourceWidth===s&&t.sourceHeight===i||(e.deleteTexture(t.targetTexture),t.targetTexture=t.filterBackend.createTexture(e,s,i)),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t.targetTexture,0)}else e.bindFramebuffer(e.FRAMEBUFFER,null),e.finish()}_swapTextures(t){t.passes--,t.pass++;const e=t.targetTexture;t.targetTexture=t.sourceTexture,t.sourceTexture=e}isNeutralState(t){return!1}applyTo(t){Oa(t)?(this._setupFrameBuffer(t),this.applyToWebGL(t),this._swapTextures(t)):this.applyTo2d(t)}applyTo2d(t){}getCacheKey(){return this.type}retrieveShader(t){const e=this.getCacheKey();return t.programCache[e]||(t.programCache[e]=this.createProgram(t.context)),t.programCache[e]}applyToWebGL(t){const e=t.context,s=this.retrieveShader(t);0===t.pass&&t.originalTexture?e.bindTexture(e.TEXTURE_2D,t.originalTexture):e.bindTexture(e.TEXTURE_2D,t.sourceTexture),e.useProgram(s.program),this.sendAttributeData(e,s.attributeLocations,t.aPosition),e.uniform1f(s.uniformLocations.uStepW,1/t.sourceWidth),e.uniform1f(s.uniformLocations.uStepH,1/t.sourceHeight),this.sendUniformData(e,s.uniformLocations),e.viewport(0,0,t.destinationWidth,t.destinationHeight),e.drawArrays(e.TRIANGLE_STRIP,0,4)}bindAdditionalTexture(t,e,s){t.activeTexture(s),t.bindTexture(t.TEXTURE_2D,e),t.activeTexture(t.TEXTURE0)}unbindAdditionalTexture(t,e){t.activeTexture(e),t.bindTexture(t.TEXTURE_2D,null),t.activeTexture(t.TEXTURE0)}sendUniformData(t,e){}createHelpLayer(t){if(!t.helpLayer){const e=pt();e.width=t.sourceWidth,e.height=t.sourceHeight,t.helpLayer=e}}toObject(){const t=Object.keys(this.constructor.defaults||{});return s({type:this.type},t.reduce(((t,e)=>(t[e]=this[e],t)),{}))}toJSON(){return this.toObject()}static async fromObject(t,e){return new this(i(t,Ea))}}t(ja,"type","BaseFilter"),t(ja,"uniformLocations",[]);const Fa={multiply:"gl_FragColor.rgb *= uColor.rgb;\n",screen:"gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n",add:"gl_FragColor.rgb += uColor.rgb;\n",difference:"gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n",subtract:"gl_FragColor.rgb -= uColor.rgb;\n",lighten:"gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n",darken:"gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n",exclusion:"gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n",overlay:"\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n ",tint:"\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n "};class La extends ja{getCacheKey(){return"".concat(this.type,"_").concat(this.mode)}getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ".concat(Fa[this.mode],"\n }\n }\n ")}applyTo2d(t){let{imageData:{data:e}}=t;const s=new Nt(this.color).getSource(),i=s[0]*this.alpha,r=s[1]*this.alpha,n=s[2]*this.alpha,o=1-this.alpha;for(let t=0;tnew this(s(s({},o),{},{image:t}))))}}t(Ba,"type","BlendImage"),t(Ba,"defaults",{mode:"multiply",alpha:1}),t(Ba,"uniformLocations",["uTransformMatrix","uImage"]),tt.setClass(Ba);class Xa extends ja{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n "}applyTo(t){Oa(t)?(this.aspectRatio=t.sourceWidth/t.sourceHeight,t.passes++,this._setupFrameBuffer(t),this.horizontal=!0,this.applyToWebGL(t),this._swapTextures(t),this._setupFrameBuffer(t),this.horizontal=!1,this.applyToWebGL(t),this._swapTextures(t)):this.applyTo2d(t)}applyTo2d(t){t.imageData=this.simpleBlur(t)}simpleBlur(t){let{ctx:e,imageData:s,filterBackend:{resources:i}}=t;const{width:r,height:n}=s;i.blurLayer1||(i.blurLayer1=pt(),i.blurLayer2=pt());const o=i.blurLayer1,a=i.blurLayer2;o.width===r&&o.height===n||(a.width=o.width=r,a.height=o.height=n);const h=o.getContext("2d"),c=a.getContext("2d"),l=15,u=.06*this.blur*.5;let d,g,f,p;for(h.putImageData(s,0,0),c.clearRect(0,0,r,n),p=-15;p<=l;p++)d=(Math.random()-.5)/4,g=p/l,f=u*g*r+d,c.globalAlpha=1-Math.abs(g),c.drawImage(o,f,d),h.drawImage(a,0,0),c.globalAlpha=1,c.clearRect(0,0,a.width,a.height);for(p=-15;p<=l;p++)d=(Math.random()-.5)/4,g=p/l,f=u*g*n+d,c.globalAlpha=1-Math.abs(g),c.drawImage(o,d,f),h.drawImage(a,0,0),c.globalAlpha=1,c.clearRect(0,0,a.width,a.height);e.drawImage(o,0,0);const m=e.getImageData(0,0,o.width,o.height);return h.globalAlpha=1,h.clearRect(0,0,o.width,o.height),m}sendUniformData(t,e){const s=this.chooseRightDelta();t.uniform2fv(e.uDelta,s)}isNeutralState(){return 0===this.blur}chooseRightDelta(){let t=1;const e=[0,0];this.horizontal?this.aspectRatio>1&&(t=1/this.aspectRatio):this.aspectRatio<1&&(t=this.aspectRatio);const s=t*this.blur*.12;return this.horizontal?e[0]=s:e[1]=s,e}}t(Xa,"type","Blur"),t(Xa,"defaults",{blur:0}),t(Xa,"uniformLocations",["uDelta"]),tt.setClass(Xa);class Wa extends ja{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n"}applyTo2d(t){let{imageData:{data:e}}=t;const s=Math.round(255*this.brightness);for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:{};super(t),this.subFilters=t.subFilters||[]}applyTo(t){Oa(t)&&(t.passes+=this.subFilters.length-1),this.subFilters.forEach((e=>{e.applyTo(t)}))}toObject(){return{type:this.type,subFilters:this.subFilters.map((t=>t.toObject()))}}isNeutralState(){return!this.subFilters.some((t=>!t.isNeutralState()))}static fromObject(t,e){return Promise.all((t.subFilters||[]).map((t=>tt.getClass(t.type).fromObject(t,e)))).then((t=>new this({subFilters:t})))}}t(Ja,"type","Composed"),tt.setClass(Ja);class Qa extends ja{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }"}isNeutralState(){return 0===this.contrast}applyTo2d(t){let{imageData:{data:e}}=t;const s=Math.floor(255*this.contrast),i=259*(s+255)/(255*(259-s));for(let t=0;t=a||m<0||m>=o||(y=4*(v*o+m),_=i[w*r+b],u+=s[y]*_,d+=s[y+1]*_,g+=s[y+2]*_,l||(f+=s[y+3]*_));c[p]=u,c[p+1]=d,c[p+2]=g,c[p+3]=l?s[p+3]:f}t.imageData=h}sendUniformData(t,e){t.uniform1fv(e.uMatrix,this.matrix)}toObject(){return s(s({},super.toObject()),{},{opaque:this.opaque,matrix:[...this.matrix]})}}t($a,"type","Convolute"),t($a,"defaults",{opaque:!1,matrix:[0,0,0,0,1,0,0,0,0]}),t($a,"uniformLocations",["uMatrix","uOpaque","uHalfSize","uSize"]),tt.setClass($a);const th="Gamma";class eh extends ja{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n"}constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(t),this.gamma=t.gamma||this.constructor.defaults.gamma.concat()}applyTo2d(t){let{imageData:{data:e}}=t;const s=this.gamma,i=1/s[0],r=1/s[1],n=1/s[2];this.rgbValues||(this.rgbValues={r:new Uint8Array(256),g:new Uint8Array(256),b:new Uint8Array(256)});const o=this.rgbValues;for(let t=0;t<256;t++)o.r[t]=255*Math.pow(t/255,i),o.g[t]=255*Math.pow(t/255,r),o.b[t]=255*Math.pow(t/255,n);for(let t=0;tr[0]&&i>r[1]&&o>r[2]&&s"\n color += texture2D(uTexture, vTexCoord + ".concat(t,") * uTaps[").concat(e,"] + texture2D(uTexture, vTexCoord - ").concat(t,") * uTaps[").concat(e,"];\n sum += 2.0 * uTaps[").concat(e,"];\n "))).join("\n"),"\n gl_FragColor = color / sum;\n }\n ")}applyToForWebgl(t){t.passes++,this.width=t.sourceWidth,this.horizontal=!0,this.dW=Math.round(this.width*this.scaleX),this.dH=t.sourceHeight,this.tempScale=this.dW/this.width,this.taps=this.getTaps(),t.destinationWidth=this.dW,super.applyTo(t),t.sourceWidth=t.destinationWidth,this.height=t.sourceHeight,this.horizontal=!1,this.dH=Math.round(this.height*this.scaleY),this.tempScale=this.dH/this.height,this.taps=this.getTaps(),t.destinationHeight=this.dH,super.applyTo(t),t.sourceHeight=t.destinationHeight}applyTo(t){Oa(t)?this.applyToForWebgl(t):this.applyTo2d(t)}isNeutralState(){return 1===this.scaleX&&1===this.scaleY}lanczosCreate(t){return e=>{if(e>=t||e<=-t)return 0;if(e<1.1920929e-7&&e>-1.1920929e-7)return 1;const s=(e*=Math.PI)/t;return Math.sin(e)/e*Math.sin(s)/s}}applyTo2d(t){const e=t.imageData,s=this.scaleX,i=this.scaleY;this.rcpScaleX=1/s,this.rcpScaleY=1/i;const r=e.width,n=e.height,o=Math.round(r*s),a=Math.round(n*i);let h;h="sliceHack"===this.resizeType?this.sliceByTwo(t,r,n,o,a):"hermite"===this.resizeType?this.hermiteFastResize(t,r,n,o,a):"bilinear"===this.resizeType?this.bilinearFiltering(t,r,n,o,a):"lanczos"===this.resizeType?this.lanczosResize(t,r,n,o,a):new ImageData(o,a),t.imageData=h}sliceByTwo(t,e,s,i,r){const n=t.imageData,o=.5;let a=!1,h=!1,c=e*o,l=s*o;const u=t.filterBackend.resources;let d=0,g=0;const f=e;let p=0;u.sliceByTwo||(u.sliceByTwo=pt());const m=u.sliceByTwo;(m.width<1.5*e||m.height=e)){D=Math.floor(1e3*Math.abs(x-m.x)),p[D]||(p[D]={});for(let t=v.y-f;t<=v.y+f;t++)t<0||t>=s||(M=Math.floor(1e3*Math.abs(t-m.y)),p[D][M]||(p[D][M]=h(Math.sqrt(Math.pow(D*u,2)+Math.pow(M*d,2))/1e3)),C=p[D][M],C>0&&(b=4*(t*e+x),w+=C,S+=C*n[b],T+=C*n[b+1],O+=C*n[b+2],k+=C*n[b+3]))}b=4*(_*i+y),a[b]=S/w,a[b+1]=T/w,a[b+2]=O/w,a[b+3]=k/w}return++y1&&n<-1||(l=2*n*n*n-3*n*n+1,l>0&&(s=4*(t+i*e),v+=l*c[s+3],g+=l,c[s+3]<255&&(l=l*c[s+3]/250),f+=l*c[s],p+=l*c[s+1],m+=l*c[s+2],d+=l))}}u[r]=f/d,u[r+1]=p/d,u[r+2]=m/d,u[r+3]=v/g}return l}}t(ch,"type","Resize"),t(ch,"defaults",{resizeType:"hermite",scaleX:1,scaleY:1,lanczosLobes:3}),t(ch,"uniformLocations",["uDelta","uTaps"]),tt.setClass(ch);class lh extends ja{getFragmentSource(){return"\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n"}applyTo2d(t){let{imageData:{data:e}}=t;const s=-this.saturation;for(let t=0;t;\n\nclass BaseConfiguration {\n /**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\n browserShadowBlurConstant = 1;\n\n /**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\n DPI = 96;\n\n /**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n devicePixelRatio =\n typeof window !== 'undefined' ? window.devicePixelRatio : 1; // eslint-disable-line no-restricted-globals\n\n /**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n perfLimitSizeTotal = 2097152;\n\n /**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\n maxCacheSideLimit = 4096;\n\n /**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n minCacheSideLimit = 256;\n\n /**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n * @deprecated\n */\n disableStyleCopyPaste = false;\n\n /**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\n enableGLFiltering = true;\n\n /**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n *\n * In order to support old hardware set to `2048` to avoid OOM\n *\n * @since 2.0.0\n * @type Number\n * @default\n */\n textureSize = 4096;\n\n /**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\n forceGLPutImageData = false;\n\n /**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from\n * the curve is very hard to hit any cache.\n * Enable only if you know why it could be useful.\n * Candidate for removal/simplification\n * @default false\n */\n cachesBoundsOfCurve = false;\n\n /**\n * Map of font files\n * Map of font files\n */\n fontPaths: Record = {};\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * Used in exporting methods (`toObject`, `toJSON`, `toSVG`)\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n */\n NUM_FRACTION_DIGITS = 4;\n}\n\nexport class Configuration extends BaseConfiguration {\n constructor(config?: TConfiguration) {\n super();\n this.configure(config);\n }\n\n configure(config: TConfiguration = {}) {\n Object.assign(this, config);\n }\n\n /**\n * Map of font files\n */\n addFonts(\n paths: Record = {},\n ) {\n this.fontPaths = {\n ...this.fontPaths,\n ...paths,\n };\n }\n\n removeFonts(fontFamilys: string[] = []) {\n fontFamilys.forEach((fontFamily) => {\n delete this.fontPaths[fontFamily];\n });\n }\n\n clearFonts() {\n this.fontPaths = {};\n }\n\n restoreDefaults(keys?: (keyof T)[]) {\n const defaults = new BaseConfiguration() as T;\n const config =\n keys?.reduce((acc, key) => {\n acc[key] = defaults[key];\n return acc;\n }, {} as T) || defaults;\n this.configure(config);\n }\n}\n\nexport const config = new Configuration();\n","export const log = (\n severity: 'log' | 'warn' | 'error',\n ...optionalParams: any[]\n) =>\n // eslint-disable-next-line no-restricted-syntax\n console[severity]('fabric', ...optionalParams);\n\nexport class FabricError extends Error {\n constructor(message?: string, options?: ErrorOptions) {\n super(`fabric: ${message}`, options);\n }\n}\n\nexport class SignalAbortedError extends FabricError {\n constructor(context: string) {\n super(`${context} 'options.signal' is in 'aborted' state`);\n }\n}\n","export type GLPrecision = 'lowp' | 'mediump' | 'highp';\n\nexport abstract class GLProbe {\n declare GLPrecision: GLPrecision | undefined;\n abstract queryWebGL(canvas: HTMLCanvasElement): void;\n abstract isSupported(textureSize: number): boolean;\n}\n","import { log } from '../../util/internals/console';\nimport { GLProbe } from './GLProbe';\nimport type { GLPrecision } from './GLProbe';\n\n/**\n * Lazy initialize WebGL constants\n */\nexport class WebGLProbe extends GLProbe {\n declare maxTextureSize?: number;\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {GLPrecision} Precision to test can be any of following\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n private testPrecision(\n gl: WebGLRenderingContext,\n precision: GLPrecision,\n ): boolean {\n const fragmentSource = `precision ${precision} float;\\nvoid main(){}`;\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n if (!fragmentShader) {\n return false;\n }\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);\n }\n\n /**\n * query browser for WebGL\n */\n queryWebGL(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext('webgl');\n if (gl) {\n this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this.GLPrecision = (['highp', 'mediump', 'lowp'] as const).find(\n (precision) => this.testPrecision(gl, precision),\n );\n gl.getExtension('WEBGL_lose_context')!.loseContext();\n log('log', `WebGL: max texture size ${this.maxTextureSize}`);\n }\n }\n\n isSupported(textureSize: number) {\n return !!this.maxTextureSize && this.maxTextureSize >= textureSize;\n }\n}\n","/* eslint-disable no-restricted-globals */\nimport { WebGLProbe } from '../filters/GLProbes/WebGLProbe';\nimport type { TCopyPasteData, TFabricEnv } from './types';\n\nconst copyPasteData: TCopyPasteData = {};\n\nexport const getEnv = (): TFabricEnv => {\n return {\n document,\n window,\n isTouchSupported:\n 'ontouchstart' in window ||\n 'ontouchstart' in document ||\n (window && window.navigator && window.navigator.maxTouchPoints > 0),\n WebGLProbe: new WebGLProbe(),\n dispose() {\n // noop\n },\n copyPasteData,\n };\n};\n","/**\n * This file is consumed by fabric.\n * The `./node` and `./browser` files define the env variable that is used by this module.\n * The `./browser` module is defined to be the default env and doesn't set the env at all.\n * This is done in order to support isomorphic usage for browser and node applications\n * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env.\n */\n\nimport { config } from '../config';\nimport { getEnv as getBrowserEnv } from './browser';\nimport type { TFabricEnv } from './types';\nimport type { DOMWindow } from 'jsdom';\n\nlet env: TFabricEnv;\n\n/**\n * Sets the environment variables used by fabric.\\\n * This is exposed for special cases, such as configuring a test environment, and should be used with care.\n *\n * **CAUTION**: Must be called before using the package.\n *\n * @example\n * Passing `window` and `document` objects to fabric (in case they are mocked or something)\n * import { getEnv, setEnv } from 'fabric';\n * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in.\n * setEnv({ ...getEnv(), window, document });\n * // done with setup, using fabric is now safe\n */\nexport const setEnv = (value: TFabricEnv) => {\n env = value;\n};\n\n/**\n * In order to support SSR we **MUST** access the browser env only after the window has loaded\n */\nexport const getEnv = () => env || (env = getBrowserEnv());\n\nexport const getFabricDocument = (): Document => getEnv().document;\n\nexport const getFabricWindow = (): (Window & typeof globalThis) | DOMWindow =>\n getEnv().window;\n\n/**\n * @returns the config value if defined, fallbacks to the environment value\n */\nexport const getDevicePixelRatio = () =>\n Math.max(config.devicePixelRatio ?? getFabricWindow().devicePixelRatio, 1);\n","import { config } from './config';\nimport type { TRectBounds } from './typedefs';\n\nexport class Cache {\n /**\n * Cache of widths of chars in text rendering.\n */\n charWidthsCache: Record<\n /** fontFamily */ string,\n Record<\n /** fontStyleCacheKey */ string,\n Record\n >\n > = {};\n\n /**\n * @return {Object} reference to cache\n */\n getFontCache({\n fontFamily,\n fontStyle,\n fontWeight,\n }: {\n fontFamily: string;\n fontStyle: string;\n fontWeight: string | number;\n }) {\n fontFamily = fontFamily.toLowerCase();\n if (!this.charWidthsCache[fontFamily]) {\n this.charWidthsCache[fontFamily] = {};\n }\n const fontCache = this.charWidthsCache[fontFamily];\n const cacheKey = `${fontStyle.toLowerCase()}_${(\n fontWeight + ''\n ).toLowerCase()}`;\n if (!fontCache[cacheKey]) {\n fontCache[cacheKey] = {};\n }\n return fontCache[cacheKey];\n }\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @param {String} [fontFamily] font family to clear\n */\n clearFontCache(fontFamily?: string) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n this.charWidthsCache = {};\n } else if (this.charWidthsCache[fontFamily]) {\n delete this.charWidthsCache[fontFamily];\n }\n }\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @param {number} ar aspect ratio\n * @return {number[]} Limited dimensions X and Y\n */\n limitDimsByArea(ar: number) {\n const { perfLimitSizeTotal } = config;\n const roughWidth = Math.sqrt(perfLimitSizeTotal * ar);\n // we are not returning a point on purpose, to avoid circular dependencies\n // this is an internal utility\n return [\n Math.floor(roughWidth),\n Math.floor(perfLimitSizeTotal / roughWidth),\n ];\n }\n\n /**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\n boundsOfCurveCache: Record = {};\n}\n\nexport const cache = new Cache();\n","import type { TMat2D } from './typedefs';\n// use this syntax so babel plugin see this import here\nimport { version } from '../package.json';\n\nexport const VERSION = version;\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport const halfPI = Math.PI / 2;\nexport const twoMathPi = Math.PI * 2;\nexport const PiBy180 = Math.PI / 180;\n\nexport const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]) as TMat2D;\nexport const DEFAULT_SVG_FONT_SIZE = 16;\nexport const ALIASING_LIMIT = 2;\n\n/* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\nexport const kRect = 1 - 0.5522847498;\n\nexport const CENTER = 'center';\nexport const LEFT = 'left';\nexport const TOP = 'top';\nexport const BOTTOM = 'bottom';\nexport const RIGHT = 'right';\nexport const NONE = 'none';\n\nexport const reNewline = /\\r?\\n/;\n\nexport const MOVING = 'moving';\nexport const SCALING = 'scaling';\nexport const ROTATING = 'rotating';\nexport const ROTATE = 'rotate';\nexport const SKEWING = 'skewing';\nexport const RESIZING = 'resizing';\nexport const MODIFY_POLY = 'modifyPoly';\nexport const MODIFY_PATH = 'modifyPath';\nexport const CHANGED = 'changed';\nexport const SCALE = 'scale';\nexport const SCALE_X = 'scaleX';\nexport const SCALE_Y = 'scaleY';\nexport const SKEW_X = 'skewX';\nexport const SKEW_Y = 'skewY';\nexport const FILL = 'fill';\nexport const STROKE = 'stroke';\nexport const MODIFIED = 'modified';\n","import { FabricError } from './util/internals/console';\n\n/*\n * This Map connects the objects type value with their\n * class implementation. It used from any object to understand which are\n * the classes to enlive when requesting a object.type = 'path' for example.\n * Objects uses it for clipPath, Canvas uses it for everything.\n * This is necessary for generic code to run and enlive instances from serialized representation.\n * You can customize which classes get enlived from SVG parsing using this classRegistry.\n * The Registry start empty and gets filled in depending which files you import.\n * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from\n * different sources you will need to import all fabric because you may need all classes.\n */\n\nexport const JSON = 'json';\nexport const SVG = 'svg';\n\nexport class ClassRegistry {\n declare [JSON]: Map;\n declare [SVG]: Map;\n\n constructor() {\n this[JSON] = new Map();\n this[SVG] = new Map();\n }\n\n has(classType: string): boolean {\n return this[JSON].has(classType);\n }\n\n getClass(classType: string): T {\n const constructor = this[JSON].get(classType);\n if (!constructor) {\n throw new FabricError(`No class registered for ${classType}`);\n }\n return constructor;\n }\n\n setClass(classConstructor: any, classType?: string) {\n if (classType) {\n this[JSON].set(classType, classConstructor);\n } else {\n this[JSON].set(classConstructor.type, classConstructor);\n // legacy\n // @TODO: needs to be removed in fabric 7 or 8\n this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);\n }\n }\n\n getSVGClass(SVGTagName: string): any {\n return this[SVG].get(SVGTagName);\n }\n\n setSVGClass(classConstructor: any, SVGTagName?: string) {\n this[SVG].set(\n SVGTagName ?? classConstructor.type.toLowerCase(),\n classConstructor,\n );\n }\n}\n\nexport const classRegistry = new ClassRegistry();\n","import type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type { AnimationBase } from './AnimationBase';\n\n/**\n * Array holding all running animations\n */\nclass AnimationRegistry extends Array {\n /**\n * Remove a single animation using an animation context\n * @param {AnimationBase} context\n */\n remove(context: AnimationBase) {\n const index = this.indexOf(context);\n index > -1 && this.splice(index, 1);\n }\n\n /**\n * Cancel all running animations on the next frame\n */\n cancelAll() {\n const animations = this.splice(0);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations attached to a canvas on the next frame\n * @param {StaticCanvas} canvas\n */\n cancelByCanvas(canvas: StaticCanvas) {\n if (!canvas) {\n return [];\n }\n const animations = this.filter(\n (animation) =>\n animation.target === canvas ||\n (typeof animation.target === 'object' &&\n (animation.target as FabricObject)?.canvas === canvas),\n );\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations for target on the next frame\n * @param target\n */\n cancelByTarget(target: AnimationBase['target']) {\n if (!target) {\n return [];\n }\n const animations = this.filter((animation) => animation.target === target);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n}\n\nexport const runningAnimations = new AnimationRegistry();\n","export type TEventCallback = (options: T) => any;\n\ntype EventRegistryObject = {\n [K in keyof E]?: TEventCallback;\n};\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\nexport class Observable {\n private __eventListeners: Record =\n {} as Record;\n\n /**\n * Observes specified event\n * @alias on\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n on(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n on(handlers: EventRegistryObject): VoidFunction;\n on(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (!this.__eventListeners) {\n this.__eventListeners = {} as Record;\n }\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this.on(eventName as K, handler as TEventCallback);\n });\n return () => this.off(arg0);\n } else if (handler) {\n const eventName = arg0;\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n return () => this.off(eventName, handler);\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * Observes specified event **once**\n * @alias once\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n once(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n once(handlers: EventRegistryObject): VoidFunction;\n once(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n const disposers: VoidFunction[] = [];\n Object.entries(arg0).forEach(([eventName, handler]) => {\n disposers.push(this.once(eventName as K, handler as TEventCallback));\n });\n return () => disposers.forEach((d) => d());\n } else if (handler) {\n const disposer = this.on(\n arg0,\n function onceHandler(this: Observable, ...args) {\n handler.call(this, ...args);\n disposer();\n },\n );\n return disposer;\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * @private\n * @param {string} eventName\n * @param {Function} [handler]\n */\n private _removeEventListener(\n eventName: K,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n\n if (handler) {\n const eventListener = this.__eventListeners[eventName];\n const index = eventListener.indexOf(handler);\n index > -1 && eventListener.splice(index, 1);\n } else {\n this.__eventListeners[eventName] = [];\n }\n }\n\n /**\n * Unsubscribe all event listeners for eventname.\n * Do not use this pattern. You could kill internal fabricJS events.\n * We know we should have protected events for internal flows, but we don't have yet\n * @deprecated\n * @param {string} eventName event name (eg. 'after:render')\n */\n off(eventName: K): void;\n /**\n * unsubscribe an event listener\n * @param {string} eventName event name (eg. 'after:render')\n * @param {TEventCallback} handler event listener to unsubscribe\n */\n off(eventName: K, handler: TEventCallback): void;\n /**\n * unsubscribe event listeners\n * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n */\n off(handlers: EventRegistryObject): void;\n /**\n * unsubscribe all event listeners\n */\n off(): void;\n off(\n arg0?: K | EventRegistryObject,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners) {\n return;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (typeof arg0 === 'undefined') {\n for (const eventName in this.__eventListeners) {\n this._removeEventListener(eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (typeof arg0 === 'object') {\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this._removeEventListener(eventName as K, handler as TEventCallback);\n });\n } else {\n this._removeEventListener(arg0, handler);\n }\n }\n\n /**\n * Fires event with an optional options object\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n */\n fire(eventName: K, options?: EventSpec[K]) {\n if (!this.__eventListeners) {\n return;\n }\n\n const listenersForEvent = this.__eventListeners[eventName]?.concat();\n if (listenersForEvent) {\n for (let i = 0; i < listenersForEvent.length; i++) {\n listenersForEvent[i].call(this, options || {});\n }\n }\n }\n}\n","/**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\nexport const removeFromArray = (array: T[], value: T): T[] => {\n const idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the cosin value for angle.\n */\nexport const cos = (angle: TRadian): number => {\n if (angle === 0) {\n return 1;\n }\n const angleSlice = Math.abs(angle) / halfPI;\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n case 2:\n return -1;\n }\n return Math.cos(angle);\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the sin value for angle.\n */\nexport const sin = (angle: TRadian): number => {\n if (angle === 0) {\n return 0;\n }\n const angleSlice = angle / halfPI;\n const value = Math.sign(angle);\n switch (angleSlice) {\n case 1:\n return value;\n case 2:\n return 0;\n case 3:\n return -value;\n }\n return Math.sin(angle);\n};\n","import type { TMat2D, TRadian } from './typedefs';\nimport { cos } from './util/misc/cos';\nimport { sin } from './util/misc/sin';\n\nexport interface XY {\n x: number;\n y: number;\n}\n\n/**\n * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com)\n */\nexport class Point implements XY {\n declare x: number;\n\n declare y: number;\n\n constructor();\n constructor(x: number, y: number);\n constructor(point?: XY);\n constructor(arg0: number | XY = 0, y = 0) {\n if (typeof arg0 === 'object') {\n this.x = arg0.x;\n this.y = arg0.y;\n } else {\n this.x = arg0;\n this.y = y;\n }\n }\n\n /**\n * Adds another point to this one and returns another one\n * @param {XY} that\n * @return {Point} new Point instance with added values\n */\n add(that: XY): Point {\n return new Point(this.x + that.x, this.y + that.y);\n }\n\n /**\n * Adds another point to this one\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n addEquals(that: XY): Point {\n this.x += that.x;\n this.y += that.y;\n return this;\n }\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {Point} new Point with added value\n */\n scalarAdd(scalar: number): Point {\n return new Point(this.x + scalar, this.y + scalar);\n }\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarAddEquals(scalar: number): Point {\n this.x += scalar;\n this.y += scalar;\n return this;\n }\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {XY} that\n * @return {Point} new Point object with subtracted values\n */\n subtract(that: XY): Point {\n return new Point(this.x - that.x, this.y - that.y);\n }\n\n /**\n * Subtracts another point from this point\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n subtractEquals(that: XY): Point {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n }\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarSubtract(scalar: number): Point {\n return new Point(this.x - scalar, this.y - scalar);\n }\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarSubtractEquals(scalar: number): Point {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n }\n\n /**\n * Multiplies this point by another value and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n multiply(that: XY): Point {\n return new Point(this.x * that.x, this.y * that.y);\n }\n\n /**\n * Multiplies this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarMultiply(scalar: number): Point {\n return new Point(this.x * scalar, this.y * scalar);\n }\n\n /**\n * Multiplies this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarMultiplyEquals(scalar: number): Point {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n }\n\n /**\n * Divides this point by another and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n divide(that: XY): Point {\n return new Point(this.x / that.x, this.y / that.y);\n }\n\n /**\n * Divides this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarDivide(scalar: number): Point {\n return new Point(this.x / scalar, this.y / scalar);\n }\n\n /**\n * Divides this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarDivideEquals(scalar: number): Point {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n }\n\n /**\n * Returns true if this point is equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n eq(that: XY): boolean {\n return this.x === that.x && this.y === that.y;\n }\n\n /**\n * Returns true if this point is less than another one\n * @param {XY} that\n * @return {Boolean}\n */\n lt(that: XY): boolean {\n return this.x < that.x && this.y < that.y;\n }\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n lte(that: XY): boolean {\n return this.x <= that.x && this.y <= that.y;\n }\n\n /**\n\n * Returns true if this point is greater another one\n * @param {XY} that\n * @return {Boolean}\n */\n gt(that: XY): boolean {\n return this.x > that.x && this.y > that.y;\n }\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n gte(that: XY): boolean {\n return this.x >= that.x && this.y >= that.y;\n }\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {XY} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {Point}\n */\n lerp(that: XY, t = 0.5): Point {\n t = Math.max(Math.min(1, t), 0);\n return new Point(\n this.x + (that.x - this.x) * t,\n this.y + (that.y - this.y) * t,\n );\n }\n\n /**\n * Returns distance from this point and another one\n * @param {XY} that\n * @return {Number}\n */\n distanceFrom(that: XY): number {\n const dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /**\n * Returns the point between this point and another one\n * @param {XY} that\n * @return {Point}\n */\n midPointFrom(that: XY): Point {\n return this.lerp(that);\n }\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {XY} that\n * @return {Point}\n */\n min(that: XY): Point {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n }\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {XY} that\n * @return {Point}\n */\n max(that: XY): Point {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n }\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY(x: number, y: number) {\n this.x = x;\n this.y = y;\n return this;\n }\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX(x: number) {\n this.x = x;\n return this;\n }\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY(y: number) {\n this.y = y;\n return this;\n }\n\n /**\n * Sets x/y of this point from another point\n * @param {XY} that\n * @chainable\n */\n setFromPoint(that: XY) {\n this.x = that.x;\n this.y = that.y;\n return this;\n }\n\n /**\n * Swaps x/y of this point and another point\n * @param {XY} that\n */\n swap(that: XY) {\n const x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n }\n\n /**\n * return a cloned instance of the point\n * @return {Point}\n */\n clone(): Point {\n return new Point(this.x, this.y);\n }\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {XY} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\n rotate(radians: TRadian, origin: XY = ZERO): Point {\n // TODO benchmark and verify the add and subtract how much cost\n // and then in case early return if no origin is passed\n const sinus = sin(radians),\n cosinus = cos(radians);\n const p = this.subtract(origin);\n const rotated = new Point(\n p.x * cosinus - p.y * sinus,\n p.x * sinus + p.y * cosinus,\n );\n return rotated.add(origin);\n }\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {TMat2D} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\n transform(t: TMat2D, ignoreOffset = false): Point {\n return new Point(\n t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]),\n t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5]),\n );\n }\n}\n\nexport const ZERO = new Point(0, 0);\n","import type { Constructor, TBBox } from './typedefs';\nimport { removeFromArray } from './util/internals/removeFromArray';\nimport { Point } from './Point';\nimport type { ActiveSelection } from './shapes/ActiveSelection';\nimport type { Group } from './shapes/Group';\nimport type { InteractiveFabricObject } from './shapes/Object/InteractiveObject';\nimport type { FabricObject } from './shapes/Object/FabricObject';\n\nexport const isCollection = (\n fabricObject?: FabricObject,\n): fabricObject is Group | ActiveSelection => {\n return !!fabricObject && Array.isArray((fabricObject as Group)._objects);\n};\n\nexport function createCollectionMixin(Base: TBase) {\n class Collection extends Base {\n /**\n * @type {FabricObject[]}\n * @TODO needs to end up in the constructor too\n */\n _objects: FabricObject[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectAdded(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectRemoved(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onStackOrderChanged(object: FabricObject) {\n // subclasses should override this method\n }\n\n /**\n * Adds objects to collection\n * Objects should be instances of (or inherit from) FabricObject\n * @param {...FabricObject[]} objects to add\n * @returns {number} new array length\n */\n add(...objects: FabricObject[]): number {\n const size = this._objects.push(...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {number} index Index to insert object at\n * @param {...FabricObject[]} objects Object(s) to insert\n * @returns {number} new array length\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n this._objects.splice(index, 0, ...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return this._objects.length;\n }\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @private\n * @param {...FabricObject[]} objects objects to remove\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const array = this._objects,\n removed: FabricObject[] = [];\n objects.forEach((object) => {\n const index = array.indexOf(object);\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n array.splice(index, 1);\n removed.push(object);\n this._onObjectRemoved(object);\n }\n });\n return removed;\n }\n\n /**\n * Executes given function for each object in this group\n * A simple shortcut for getObjects().forEach, before es6 was more complicated,\n * now is just a shortcut.\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n */\n forEachObject(\n callback: (\n object: FabricObject,\n index: number,\n array: FabricObject[],\n ) => any,\n ) {\n this.getObjects().forEach((object, index, objects) =>\n callback(object, index, objects),\n );\n }\n\n /**\n * Returns an array of children objects of this instance\n * @param {...String} [types] When specified, only objects of these types are returned\n * @return {Array}\n */\n getObjects(...types: string[]) {\n if (types.length === 0) {\n return [...this._objects];\n }\n return this._objects.filter((o) => o.isType(...types));\n }\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Object} object at index\n */\n item(index: number) {\n return this._objects[index];\n }\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty() {\n return this._objects.length === 0;\n }\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size() {\n return this._objects.length;\n }\n\n /**\n * Returns true if collection contains an object.\\\n * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons**\n * instead of `a.contains(b)` use `b.isDescendantOf(a)`\n * @param {Object} object Object to check against\n * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`\n * @return {Boolean} `true` if collection contains an object\n */\n contains(object: FabricObject, deep?: boolean): boolean {\n if (this._objects.includes(object)) {\n return true;\n } else if (deep) {\n return this._objects.some(\n (obj) =>\n obj instanceof Collection &&\n (obj as unknown as Collection).contains(object, true),\n );\n }\n return false;\n }\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity() {\n return this._objects.reduce((memo, current) => {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @returns {boolean} true if change occurred\n */\n sendObjectToBack(object: FabricObject) {\n if (!object || object === this._objects[0]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @returns {boolean} true if change occurred\n */\n bringObjectToFront(object: FabricObject) {\n if (!object || object === this._objects[this._objects.length - 1]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.push(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional parameter, `intersecting` allows to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @returns {boolean} true if change occurred\n */\n sendObjectBackwards(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n const newIdx = this.findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional parameter, intersecting allows to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @returns {boolean} true if change occurred\n */\n bringObjectForward(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n const newIdx = this.findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {number} index Position to move to\n * @returns {boolean} true if change occurred\n */\n moveObjectTo(object: FabricObject, index: number) {\n if (object === this._objects[index]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n findNewLowerIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse down the stack looking for the nearest intersecting object\n for (let i = idx - 1; i >= 0; --i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n }\n\n findNewUpperIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse up the stack looking for the nearest intersecting object\n for (let i = idx + 1; i < this._objects.length; ++i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n }\n\n /**\n * Given a bounding box, return all the objects of the collection that are contained in the bounding box.\n * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well.\n * This is meant to work with selection. Is not a generic method.\n * @param {TBBox} bbox a bounding box in scene coordinates\n * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting\n * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise\n */\n collectObjects(\n { left, top, width, height }: TBBox,\n { includeIntersecting = true }: { includeIntersecting?: boolean } = {},\n ) {\n const objects: InteractiveFabricObject[] = [],\n tl = new Point(left, top),\n br = tl.add(new Point(width, height));\n\n // we iterate reverse order to collect top first in case of click.\n for (let i = this._objects.length - 1; i >= 0; i--) {\n const object = this._objects[i] as unknown as InteractiveFabricObject;\n if (\n object.selectable &&\n object.visible &&\n ((includeIntersecting && object.intersectsWithRect(tl, br)) ||\n object.isContainedWithinRect(tl, br) ||\n (includeIntersecting && object.containsPoint(tl)) ||\n (includeIntersecting && object.containsPoint(br)))\n ) {\n objects.push(object);\n }\n }\n\n return objects;\n }\n }\n\n // https://github.com/microsoft/TypeScript/issues/32080\n return Collection as typeof Collection & TBase;\n}\n","import { Observable } from './Observable';\n\nexport class CommonMethods extends Observable {\n /**\n * Sets object's properties from options, for initialization only\n * @protected\n * @param {Object} [options] Options object\n */\n protected _setOptions(options: any = {}) {\n for (const prop in options) {\n this.set(prop, options[prop]);\n }\n }\n\n /**\n * @private\n */\n _setObject(obj: Record) {\n for (const prop in obj) {\n this._set(prop, obj[prop]);\n }\n }\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n */\n set(key: string | Record, value?: any) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n return this;\n }\n\n _set(key: string, value: any) {\n this[key as keyof this] = value;\n }\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n */\n toggle(property: string) {\n const value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n }\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get(property: string): any {\n return this[property as keyof this];\n }\n}\n","import { getFabricWindow } from '../../env';\n\nexport function requestAnimFrame(callback: FrameRequestCallback): number {\n return getFabricWindow().requestAnimationFrame(callback);\n}\n\nexport function cancelAnimFrame(handle: number): void {\n return getFabricWindow().cancelAnimationFrame(handle);\n}\n","let id = 0;\n\nexport const uid = () => id++;\n","import { getFabricDocument } from '../../env';\nimport type { ImageFormat } from '../../typedefs';\nimport { FabricError } from '../internals/console';\n/**\n * Creates canvas element\n * @return {CanvasElement} initialized canvas element\n */\nexport const createCanvasElement = (): HTMLCanvasElement => {\n const element = getFabricDocument().createElement('canvas');\n if (!element || typeof element.getContext === 'undefined') {\n throw new FabricError('Failed to create `canvas` element');\n }\n return element;\n};\n\n/**\n * Creates image element (works on client and node)\n * @return {HTMLImageElement} HTML image element\n */\nexport const createImage = (): HTMLImageElement =>\n getFabricDocument().createElement('img');\n\n/**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @return {CanvasElement} initialized canvas element\n */\nexport const copyCanvasElement = (\n canvas: HTMLCanvasElement,\n): HTMLCanvasElement => {\n const newCanvas = createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d')?.drawImage(canvas, 0, 0);\n return newCanvas;\n};\n\n/**\n * since 2.6.0 moved from canvas instance to utility.\n * possibly useless\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @return {String} data url\n */\nexport const toDataURL = (\n canvasEl: HTMLCanvasElement,\n format: ImageFormat,\n quality: number,\n) => canvasEl.toDataURL(`image/${format}`, quality);\n\nexport const isHTMLCanvas = (\n canvas?: HTMLCanvasElement | string,\n): canvas is HTMLCanvasElement => {\n return !!canvas && (canvas as HTMLCanvasElement).getContext !== undefined;\n};\n","import type { TRadian, TDegree } from '../../typedefs';\nimport { PiBy180 } from '../../constants';\n\n/**\n * Transforms degrees to radians.\n * @param {TDegree} degrees value in degrees\n * @return {TRadian} value in radians\n */\nexport const degreesToRadians = (degrees: TDegree): TRadian =>\n (degrees * PiBy180) as TRadian;\n\n/**\n * Transforms radians to degrees.\n * @param {TRadian} radians value in radians\n * @return {TDegree} value in degrees\n */\nexport const radiansToDegrees = (radians: TRadian): TDegree =>\n (radians / PiBy180) as TDegree;\n","import { iMatrix } from '../../constants';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TDegree, TRadian, TMat2D } from '../../typedefs';\nimport { cos } from './cos';\nimport { degreesToRadians, radiansToDegrees } from './radiansDegreesConversion';\nimport { sin } from './sin';\n\nexport type TRotateMatrixArgs = {\n angle?: TDegree;\n};\n\nexport type TTranslateMatrixArgs = {\n translateX?: number;\n translateY?: number;\n};\n\nexport type TScaleMatrixArgs = {\n scaleX?: number;\n scaleY?: number;\n flipX?: boolean;\n flipY?: boolean;\n skewX?: TDegree;\n skewY?: TDegree;\n};\n\nexport type TComposeMatrixArgs = TTranslateMatrixArgs &\n TRotateMatrixArgs &\n TScaleMatrixArgs;\n\nexport type TQrDecomposeOut = Required<\n Omit\n>;\n\nexport const isIdentityMatrix = (mat: TMat2D) =>\n mat.every((value, index) => value === iMatrix[index]);\n\n/**\n * Apply transform t to point p\n * @deprecated use {@link Point#transform}\n * @param {Point | XY} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\nexport const transformPoint = (\n p: XY,\n t: TMat2D,\n ignoreOffset?: boolean,\n): Point => new Point(p).transform(t, ignoreOffset);\n\n/**\n * Invert transformation t\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\nexport const invertTransform = (t: TMat2D): TMat2D => {\n const a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0] as TMat2D,\n { x, y } = new Point(t[4], t[5]).transform(r, true);\n r[4] = -x;\n r[5] = -y;\n return r;\n};\n\n/**\n * Multiply matrix A by matrix B to nest transformations\n * @param {TMat2D} a First transformMatrix\n * @param {TMat2D} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {TMat2D} The product of the two transform matrices\n */\nexport const multiplyTransformMatrices = (\n a: TMat2D,\n b: TMat2D,\n is2x2?: boolean,\n): TMat2D =>\n [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5],\n ] as TMat2D;\n\n/**\n * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it\n *\n * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))`\n *\n * @param matrices an array of matrices\n * @param [is2x2] flag to multiply matrices as 2x2 matrices\n * @returns the multiplication product\n */\nexport const multiplyTransformMatrixArray = (\n matrices: (TMat2D | undefined | null | false)[],\n is2x2?: boolean,\n) =>\n matrices.reduceRight(\n (product: TMat2D, curr) =>\n curr && product\n ? multiplyTransformMatrices(curr, product, is2x2)\n : curr || product,\n undefined as unknown as TMat2D,\n ) || iMatrix.concat();\n\nexport const calcPlaneRotation = ([a, b]: TMat2D) =>\n Math.atan2(b, a) as TRadian;\n\n/**\n * Decomposes standard 2x3 matrix into transform components\n * @param {TMat2D} a transformMatrix\n * @return {Object} Components of transform\n */\nexport const qrDecompose = (a: TMat2D): TQrDecomposeOut => {\n const angle = calcPlaneRotation(a),\n denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),\n scaleX = Math.sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);\n return {\n angle: radiansToDegrees(angle),\n scaleX,\n scaleY,\n skewX: radiansToDegrees(skewX),\n skewY: 0 as TDegree,\n translateX: a[4] || 0,\n translateY: a[5] || 0,\n };\n};\n\n/**\n * Generate a translation matrix\n *\n * A translation matrix in the form of\n * [ 1 0 x ]\n * [ 0 1 y ]\n * [ 0 0 1 ]\n *\n * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details\n *\n * @param {number} x translation on X axis\n * @param {number} [y] translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createTranslateMatrix = (x: number, y = 0): TMat2D => [\n 1,\n 0,\n 0,\n 1,\n x,\n y,\n];\n\n/**\n * Generate a rotation matrix around around a point (x,y), defaulting to (0,0)\n *\n * A matrix in the form of\n * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x]\n * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y]\n * [0 0 1 ]\n *\n *\n * @param {TDegree} angle rotation in degrees\n * @param {XY} [pivotPoint] pivot point to rotate around\n * @returns {TMat2D} matrix\n */\nexport function createRotateMatrix(\n { angle = 0 }: TRotateMatrixArgs = {},\n { x = 0, y = 0 }: Partial = {},\n): TMat2D {\n const angleRadiant = degreesToRadians(angle),\n cosValue = cos(angleRadiant),\n sinValue = sin(angleRadiant);\n return [\n cosValue,\n sinValue,\n -sinValue,\n cosValue,\n x ? x - (cosValue * x - sinValue * y) : 0,\n y ? y - (sinValue * x + cosValue * y) : 0,\n ];\n}\n\n/**\n * Generate a scale matrix around the point (0,0)\n *\n * A matrix in the form of\n * [x 0 0]\n * [0 y 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale\n *\n * @param {number} x scale on X axis\n * @param {number} [y] scale on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createScaleMatrix = (x: number, y: number = x): TMat2D => [\n x,\n 0,\n 0,\n y,\n 0,\n 0,\n];\n\nexport const angleToSkew = (angle: TDegree) =>\n Math.tan(degreesToRadians(angle));\n\nexport const skewToAngle = (value: TRadian) =>\n radiansToDegrees(Math.atan(value));\n\n/**\n * Generate a skew matrix for the X axis\n *\n * A matrix in the form of\n * [1 x 0]\n * [0 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx\n *\n * @param {TDegree} skewValue translation on X axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewXMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n 0,\n angleToSkew(skewValue),\n 1,\n 0,\n 0,\n];\n\n/**\n * Generate a skew matrix for the Y axis\n *\n * A matrix in the form of\n * [1 0 0]\n * [y 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy\n *\n * @param {TDegree} skewValue translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewYMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n angleToSkew(skewValue),\n 0,\n 1,\n 0,\n 0,\n];\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @return {Number[]} transform matrix\n */\nexport const calcDimensionsMatrix = ({\n scaleX = 1,\n scaleY = 1,\n flipX = false,\n flipY = false,\n skewX = 0 as TDegree,\n skewY = 0 as TDegree,\n}: TScaleMatrixArgs) => {\n let matrix = createScaleMatrix(\n flipX ? -scaleX : scaleX,\n flipY ? -scaleY : scaleY,\n );\n if (skewX) {\n matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true);\n }\n if (skewY) {\n matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true);\n }\n return matrix;\n};\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\nexport const composeMatrix = (options: TComposeMatrixArgs): TMat2D => {\n const { translateX = 0, translateY = 0, angle = 0 as TDegree } = options;\n let matrix = createTranslateMatrix(translateX, translateY);\n if (angle) {\n matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ angle }));\n }\n const scaleMatrix = calcDimensionsMatrix(options);\n if (!isIdentityMatrix(scaleMatrix)) {\n matrix = multiplyTransformMatrices(matrix, scaleMatrix);\n }\n return matrix;\n};\n","import { noop } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {},\n) =>\n new Promise(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n >(\n serializedObj: Record,\n instance: T,\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor & {\n fromObject(options: any, context: Abortable): Promise;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n }),\n ),\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record,\n>(\n serializedObject: any,\n { signal }: Abortable = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n /**\n * clipPath or shadow or gradient or text on a path or a pattern,\n * or the backgroundImage or overlayImage of canvas\n * If we have a type and there is a classe registered for it, we enlive it.\n * If there is no class registered for it we return the value as is\n * */\n if (value.type && classRegistry.has(value.type)) {\n return enlivenObjects([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n","/**\n * Populates an object with properties of another object\n * @param {Object} source Source object\n * @param {string[]} properties Properties names to include\n * @returns object populated with the picked keys\n */\nexport const pick = >(\n source: T,\n keys: (keyof T)[] = [],\n) => {\n return keys.reduce((o, key) => {\n if (key in source) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n\nexport const pickBy = >(\n source: T,\n predicate: (value: T[K], key: K, collection: T) => boolean,\n) => {\n return (Object.keys(source) as (keyof T)[]).reduce((o, key) => {\n if (predicate(source[key], key, source)) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n","/**\n * Map of the 148 color names with HEX code\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\nexport const ColorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#0FF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000',\n blanchedalmond: '#FFEBCD',\n blue: '#00F',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#0FF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#F0F',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#789',\n lightslategrey: '#789',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#0F0',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#F0F',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#639',\n red: '#F00',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FF0',\n yellowgreen: '#9ACD32',\n};\n","import type { TRGBAColorSource } from './typedefs';\n\n/**\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\nexport const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n};\n\n/**\n * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson}\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @param {Number} a Alpha color value pass through\n * @return {TRGBColorSource} Hsl color\n */\nexport const rgb2Hsl = (\n r: number,\n g: number,\n b: number,\n a: number,\n): TRGBAColorSource => {\n r /= 255;\n g /= 255;\n b /= 255;\n const maxValue = Math.max(r, g, b),\n minValue = Math.min(r, g, b);\n\n let h!: number, s: number;\n const l = (maxValue + minValue) / 2;\n\n if (maxValue === minValue) {\n h = s = 0; // achromatic\n } else {\n const d = maxValue - minValue;\n s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue);\n switch (maxValue) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a];\n};\n\nexport const fromAlphaToFloat = (value = '1') =>\n parseFloat(value) / (value.endsWith('%') ? 100 : 1);\n\n/**\n * Convert a value in the inclusive range [0, 255] to hex\n */\nexport const hexify = (value: number) =>\n Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0');\n\n/**\n * Calculate the grey average value for rgb and pass through alpha\n */\nexport const greyAverage = ([\n r,\n g,\n b,\n a = 1,\n]: TRGBAColorSource): TRGBAColorSource => {\n const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11);\n return [avg, avg, avg, a];\n};\n","import { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { ColorNameMap } from './color_map';\nimport { reHSLa, reHex, reRGBa } from './constants';\nimport type { TRGBAColorSource, TColorArg } from './typedefs';\nimport {\n hue2rgb,\n hexify,\n rgb2Hsl,\n fromAlphaToFloat,\n greyAverage,\n} from './util';\n\n/**\n * @class Color common color operations\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors}\n */\nexport class Color {\n private declare _source: TRGBAColorSource;\n isUnrecognised = false;\n\n /**\n *\n * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list\n */\n constructor(color?: TColorArg) {\n if (!color) {\n // we default to black as canvas does\n this.setSource([0, 0, 0, 1]);\n } else if (color instanceof Color) {\n this.setSource([...color._source]);\n } else if (Array.isArray(color)) {\n const [r, g, b, a = 1] = color;\n this.setSource([r, g, b, a]);\n } else {\n this.setSource(this._tryParsingColor(color));\n }\n }\n\n /**\n * @private\n * @param {string} [color] Color value to parse\n * @returns {TRGBAColorSource}\n */\n protected _tryParsingColor(color: string) {\n if (color in ColorNameMap) {\n color = ColorNameMap[color as keyof typeof ColorNameMap];\n }\n return color === 'transparent'\n ? ([255, 255, 255, 0] as TRGBAColorSource)\n : Color.sourceFromHex(color) ||\n Color.sourceFromRgb(color) ||\n Color.sourceFromHsl(color) ||\n // color is not recognized\n // we default to black as canvas does\n // eslint-disable-next-line no-constant-binary-expression\n ((this.isUnrecognised = true) && ([0, 0, 0, 1] as TRGBAColorSource));\n }\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {TRGBAColorSource}\n */\n getSource() {\n return this._source;\n }\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {TRGBAColorSource} source\n */\n setSource(source: TRGBAColorSource) {\n this._source = source;\n }\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb() {\n const [r, g, b] = this.getSource();\n return `rgb(${r},${g},${b})`;\n }\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba() {\n return `rgba(${this.getSource().join(',')})`;\n }\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl() {\n const [h, s, l] = rgb2Hsl(...this.getSource());\n return `hsl(${h},${s}%,${l}%)`;\n }\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla() {\n const [h, s, l, a] = rgb2Hsl(...this.getSource());\n return `hsla(${h},${s}%,${l}%,${a})`;\n }\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex() {\n const fullHex = this.toHexa();\n return fullHex.slice(0, 6);\n }\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa() {\n const [r, g, b, a] = this.getSource();\n return `${hexify(r)}${hexify(g)}${hexify(b)}${hexify(Math.round(a * 255))}`;\n }\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha() {\n return this.getSource()[3];\n }\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {Color} thisArg\n */\n setAlpha(alpha: number) {\n this._source[3] = alpha;\n return this;\n }\n\n /**\n * Transforms color to its grayscale representation\n * @return {Color} thisArg\n */\n toGrayscale() {\n this.setSource(greyAverage(this.getSource()));\n return this;\n }\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {Color} thisArg\n */\n toBlackWhite(threshold: number) {\n const [average, , , a] = greyAverage(this.getSource()),\n bOrW = average < (threshold || 127) ? 0 : 255;\n this.setSource([bOrW, bOrW, bOrW, a]);\n return this;\n }\n\n /**\n * Overlays color with another color\n * @param {String|Color} otherColor\n * @return {Color} thisArg\n */\n overlayWith(otherColor: string | Color) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n const source = this.getSource(),\n otherAlpha = 0.5,\n otherSource = otherColor.getSource(),\n [R, G, B] = source.map((value, index) =>\n Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha),\n );\n\n this.setSource([R, G, B, source[3]]);\n return this;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {Color}\n */\n static fromRgb(color: string): Color {\n return Color.fromRgba(color);\n }\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromRgba(color: string): Color {\n return new Color(Color.sourceFromRgb(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromRgb(color: string): TRGBAColorSource | undefined {\n const match = color.match(reRGBa());\n if (match) {\n const [r, g, b] = match.slice(1, 4).map((value) => {\n const parsedValue = parseFloat(value);\n return value.endsWith('%')\n ? Math.round(parsedValue * 2.55)\n : parsedValue;\n });\n return [r, g, b, fromAlphaToFloat(match[4])];\n }\n }\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf Color\n * @return {Color}\n */\n static fromHsl(color: string): Color {\n return Color.fromHsla(color);\n }\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromHsla(color: string): Color {\n return new Color(Color.sourceFromHsl(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {TRGBAColorSource | undefined} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n static sourceFromHsl(color: string): TRGBAColorSource | undefined {\n const match = color.match(reHSLa());\n if (!match) {\n return;\n }\n const match1degrees = Color.parseAngletoDegrees(match[1]);\n\n const h = (((match1degrees % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / 100,\n l = parseFloat(match[3]) / 100;\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n fromAlphaToFloat(match[4]),\n ];\n }\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf Color\n * @param {String} color Color value ex: FF5555\n * @return {Color}\n */\n static fromHex(color: string): Color {\n return new Color(Color.sourceFromHex(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromHex(color: string): TRGBAColorSource | undefined {\n if (color.match(reHex())) {\n const value = color.slice(color.indexOf('#') + 1),\n isShortNotation = value.length <= 4;\n let expandedValue: string[];\n if (isShortNotation) {\n expandedValue = value.split('').map((hex) => hex + hex);\n } else {\n expandedValue = value.match(/.{2}/g)!;\n }\n const [r, g, b, a = 255] = expandedValue.map((hexCouple) =>\n parseInt(hexCouple, 16),\n );\n return [r, g, b, a / 255];\n }\n }\n\n /**\n * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad)\n * into degrees without the 'deg' suffix\n * @static\n * @memberOf Color\n * @param {String} value ex: 0deg, 0.5turn, 2rad\n * @return {Number} number in degrees or NaN if inputs are invalid\n */\n static parseAngletoDegrees(value: string): number {\n const lowercase = value.toLowerCase();\n const numeric = parseFloat(lowercase);\n\n if (lowercase.includes('rad')) {\n return radiansToDegrees(numeric);\n }\n\n if (lowercase.includes('turn')) {\n return numeric * 360;\n }\n\n // Value is probably just a number already in degrees eg '50'\n return numeric;\n }\n}\n","/**\n * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`)\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb\n * Formal syntax at the time of writing:\n * =\n * rgb( [ | none ]{3} [ / [ | none ] ]? ) |\n * rgb( [ | none ]{3} [ / [ | none ] ]? )\n * = | \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an rgba or rgb CSS color value\n *\n * /^ # Beginning of the string\n * rgba? # \"rgb\" or \"rgba\"\n * \\(\\s* # Opening parenthesis and optional whitespace\n * (\\d{0,3} # 0 to three digits R channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the first color component\n * %? # Optional percent sign after the first color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits G channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the second color component\n * %? # Optional percent sign after the second color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits B channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the third color component\n * %? # Optional percent sign after the third color component\n * \\s* # Optional whitespace\n * (?: # Beginning of non-capturing group for alpha value\n * \\s* # Optional whitespace\n * [,/] # Comma or slash separator for alpha value\n * \\s* # Optional whitespace\n * (\\d{0,3} # Zero to three digits\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for alpha value\n * %? # Optional percent sign after alpha value\n * \\s* # Optional whitespace\n * )? # End of non-capturing group for alpha value (optional)\n * \\) # Closing parenthesis\n * $ # End of the string\n *\n * The alpha channel can be in the format 0.4 .7 or 1 or 73%\n *\n * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color.\n * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us\n */\nexport const reRGBa = () =>\n /^rgba?\\(\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl\n * Formal syntax at the time of writing:\n * =\n * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? )\n *\n * =\n * |\n * \n *\n * =\n * |\n * \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an hsla or hsl CSS color value\n *\n * /^hsla?\\( // Matches the beginning of the string and the opening parenthesis of \"hsl\" or \"hsla\"\n * \\s* // Matches any whitespace characters (space, tab, etc.) zero or more times\n * (\\d{0,3} // Hue: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Hue: Optional (non capture group) decimal with one or more digits.\n * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad\n * ) // Hue: End capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Saturation: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group\n * %?) // Saturation: match optional % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Lightness: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group\n * %?) // Lightness: match % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * (?: // Alpha: Begins a non-capturing group for the alpha value\n * \\s* // Matches any whitespace characters zero or more times\n * [,/] // Matches a comma or forward slash\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d*(?:\\.\\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group\n * \\s* // Matches any whitespace characters zero or more times\n * )? // Makes the alpha value group optional\n * \\) // Matches the closing parenthesis\n * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode\n *\n * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color.\n * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us.\n */\nexport const reHSLa = () =>\n /^hsla?\\(\\s*([+-]?\\d{0,3}(?:\\.\\d+)?(?:deg|turn|rad)?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d*(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n */\nexport const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i;\n","/**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @param {number|string} number number to operate on\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {number}\n */\nexport const toFixed = (number: number | string, fractionDigits: number) =>\n parseFloat(Number(number).toFixed(fractionDigits));\n","import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return ``;\n};\n","import type { FabricObject } from '../shapes/Object/Object';\nimport type { TFiller } from '../typedefs';\nimport type { FabricText } from '../shapes/Text/Text';\nimport type { Pattern } from '../Pattern';\nimport type { Path } from '../shapes/Path';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\n\nexport const isFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && (filler as TFiller).toLive !== undefined;\n};\n\nexport const isSerializableFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && typeof (filler as TFiller).toObject === 'function';\n};\n\nexport const isPattern = (filler: TFiller): filler is Pattern => {\n return (\n !!filler && (filler as Pattern).offsetX !== undefined && 'source' in filler\n );\n};\n\nexport const isTextObject = (\n fabricObject?: FabricObject,\n): fabricObject is FabricText => {\n return (\n !!fabricObject &&\n typeof (fabricObject as FabricText)._renderText === 'function'\n );\n};\n\nexport const isPath = (fabricObject?: FabricObject): fabricObject is Path => {\n // we could use instanceof but that would mean pulling in Text code for a simple check\n // @todo discuss what to do and how to do\n return (\n !!fabricObject &&\n typeof (fabricObject as Path)._renderPathCommands === 'function'\n );\n};\n\nexport const isActiveSelection = (\n fabricObject?: FabricObject,\n): fabricObject is ActiveSelection =>\n !!fabricObject && 'multiSelectionStacking' in fabricObject;\n","/**\n * Returns element scroll offsets\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\nexport function getScrollLeftTop(element: HTMLElement | null) {\n const doc = element && getDocumentFromElement(element);\n let left = 0,\n top = 0;\n if (!element || !doc) {\n return { left, top };\n }\n let elementLoop: HTMLElement | Document | ShadowRoot = element;\n const docElement = doc.documentElement,\n body = doc.body || {\n scrollLeft: 0,\n scrollTop: 0,\n };\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (\n elementLoop &&\n (elementLoop.parentNode || (elementLoop as unknown as ShadowRoot).host)\n ) {\n elementLoop = (elementLoop.parentNode ||\n (elementLoop as unknown as ShadowRoot).host) as\n | HTMLElement\n | Document\n | ShadowRoot;\n if (elementLoop === doc) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n } else {\n left += (elementLoop as HTMLElement).scrollLeft || 0;\n top += (elementLoop as HTMLElement).scrollTop || 0;\n }\n\n if (\n elementLoop.nodeType === 1 &&\n (elementLoop as HTMLElement).style.position === 'fixed'\n ) {\n break;\n }\n }\n\n return { left, top };\n}\n\nexport const getDocumentFromElement = (el: HTMLElement) =>\n el.ownerDocument || null;\n\nexport const getWindowFromElement = (el: HTMLElement) =>\n el.ownerDocument?.defaultView || null;\n","import { NONE } from '../../constants';\nimport type { TSize } from '../../typedefs';\nimport {\n getDocumentFromElement,\n getWindowFromElement,\n getScrollLeftTop,\n} from '../../util/dom_misc';\n\nexport const setCanvasDimensions = (\n el: HTMLCanvasElement,\n ctx: CanvasRenderingContext2D,\n { width, height }: TSize,\n retinaScaling = 1,\n) => {\n el.width = width;\n el.height = height;\n if (retinaScaling > 1) {\n el.setAttribute('width', (width * retinaScaling).toString());\n el.setAttribute('height', (height * retinaScaling).toString());\n ctx.scale(retinaScaling, retinaScaling);\n }\n};\n\nexport type CSSDimensions = {\n width: number | string;\n height: number | string;\n};\n\nexport const setCSSDimensions = (\n el: HTMLElement,\n { width, height }: Partial,\n) => {\n width && (el.style.width = typeof width === 'number' ? `${width}px` : width);\n height &&\n (el.style.height = typeof height === 'number' ? `${height}px` : height);\n};\n\n/**\n * Returns offset for a given element\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\nexport function getElementOffset(element: HTMLElement) {\n const doc = element && getDocumentFromElement(element),\n offset = { left: 0, top: 0 };\n\n if (!doc) {\n return offset;\n }\n const elemStyle: CSSStyleDeclaration =\n getWindowFromElement(element)?.getComputedStyle(element, null) ||\n ({} as CSSStyleDeclaration);\n offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;\n offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;\n offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;\n offset.top += parseInt(elemStyle.paddingTop, 10) || 0;\n\n let box = { left: 0, top: 0 };\n\n const docElem = doc.documentElement;\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n const scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left:\n box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top,\n };\n}\n\n/**\n * Makes element unselectable\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\nexport function makeElementUnselectable(element: HTMLElement) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = () => false;\n }\n element.style.userSelect = NONE;\n return element;\n}\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport type { CSSDimensions } from './util';\nimport { setCSSDimensions, getElementOffset } from './util';\nimport { createCanvasElement, isHTMLCanvas } from '../../util/misc/dom';\nimport { setCanvasDimensions } from './util';\nimport { FabricError } from '../../util/internals/console';\n\nexport type CanvasItem = {\n el: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n};\n\nexport class StaticCanvasDOMManager {\n /**\n * Keeps a copy of the canvas style before setting retina scaling and other potions\n * in order to return it to original state on dispose\n * @type string\n */\n private _originalCanvasStyle?: string;\n\n lower: CanvasItem;\n\n constructor(arg0?: string | HTMLCanvasElement) {\n const el = this.createLowerCanvas(arg0);\n this.lower = { el, ctx: el.getContext('2d')! };\n }\n\n protected createLowerCanvas(arg0?: HTMLCanvasElement | string) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n const el = isHTMLCanvas(arg0)\n ? arg0\n : (arg0 &&\n (getFabricDocument().getElementById(arg0) as HTMLCanvasElement)) ||\n createCanvasElement();\n if (el.hasAttribute('data-fabric')) {\n throw new FabricError(\n 'Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?',\n );\n }\n this._originalCanvasStyle = el.style.cssText;\n el.setAttribute('data-fabric', 'main');\n el.classList.add('lower-canvas');\n return el;\n }\n\n cleanupDOM({ width, height }: TSize) {\n const { el } = this.lower;\n // restore canvas style and attributes\n el.classList.remove('lower-canvas');\n el.removeAttribute('data-fabric');\n // restore canvas size to original size in case retina scaling was applied\n el.setAttribute('width', `${width}`);\n el.setAttribute('height', `${height}`);\n el.style.cssText = this._originalCanvasStyle || '';\n this._originalCanvasStyle = undefined;\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n const { el, ctx } = this.lower;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial) {\n setCSSDimensions(this.lower.el, size);\n }\n\n /**\n * Calculates canvas element offset relative to the document\n */\n calcOffset() {\n return getElementOffset(this.lower.el);\n }\n\n dispose() {\n getEnv().dispose(this.lower.el);\n // @ts-expect-error disposing\n delete this.lower;\n }\n}\n","import { iMatrix } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TFiller, TMat2D, TOptions } from '../typedefs';\n\ninterface CanvasDrawableOptions {\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n backgroundVpt: boolean;\n\n /**\n * Background color of canvas instance.\n * @type {(String|TFiller)}\n * @default\n */\n backgroundColor: TFiller | string;\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n backgroundImage?: FabricObject;\n\n /**\n * if set to false overlay image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n overlayVpt: boolean;\n\n /**\n * Overlay color of canvas instance.\n * @since 1.3.9\n * @type {(String|TFiller)}\n * @default\n */\n overlayColor: TFiller | string;\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n overlayImage?: FabricObject;\n}\n\ninterface CanvasRenderingOptions {\n /**\n * Indicates whether {@link StaticCanvas#add}, {@link StaticCanvas#insertAt} and {@link StaticCanvas#remove},\n * {@link StaticCanvas#moveTo}, {@link StaticCanvas#clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are queued and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: boolean;\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @type Boolean\n * @default true\n */\n skipOffscreen: boolean;\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: boolean;\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: boolean;\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type FabricObject\n */\n clipPath?: FabricObject;\n}\n\nexport interface CanvasExportOptions {\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: boolean;\n\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: boolean;\n}\n\nexport interface StaticCanvasOptions\n extends CanvasDrawableOptions,\n CanvasRenderingOptions,\n CanvasExportOptions {\n /**\n * Width in virtual/logical pixels of the canvas.\n * The canvas can be larger than width if retina scaling is active\n * @type number\n */\n width: number;\n\n /**\n * Height in virtual/logical pixels of the canvas.\n * The canvas can be taller than width if retina scaling is active\n * @type height\n */\n height: number;\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n controlsAboveOverlay: boolean;\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n allowTouchScrolling: boolean;\n\n /**\n * The transformation (a Canvas 2D API transform matrix) which focuses the viewport\n * @type Array\n * @example Default transform\n * canvas.viewportTransform = [1, 0, 0, 1, 0, 0];\n * @example Scale by 70% and translate toward bottom-right by 50, without skewing\n * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];\n * @default\n */\n viewportTransform: TMat2D;\n}\n\nexport const staticCanvasDefaults: TOptions = {\n backgroundVpt: true,\n backgroundColor: '',\n overlayVpt: true,\n overlayColor: '',\n\n includeDefaultValues: true,\n svgViewportTransformation: true,\n\n renderOnAddRemove: true,\n skipOffscreen: true,\n enableRetinaScaling: true,\n imageSmoothingEnabled: true,\n\n /**\n * @todo move to Canvas\n */\n controlsAboveOverlay: false,\n /**\n * @todo move to Canvas\n */\n allowTouchScrolling: false,\n\n viewportTransform: [...iMatrix],\n};\n","import { config } from '../config';\nimport { CENTER, VERSION } from '../constants';\nimport type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs';\nimport type { Gradient } from '../gradient/Gradient';\nimport { createCollectionMixin, isCollection } from '../Collection';\nimport { CommonMethods } from '../CommonMethods';\nimport type { Pattern } from '../Pattern';\nimport { Point } from '../Point';\nimport type { TCachedFabricObject } from '../shapes/Object/Object';\nimport type {\n Abortable,\n Constructor,\n TCornerPoint,\n TDataUrlOptions,\n TFiller,\n TMat2D,\n TSize,\n TSVGReviver,\n TToCanvasElementOptions,\n TValidToObjectMethod,\n TOptions,\n} from '../typedefs';\nimport {\n cancelAnimFrame,\n requestAnimFrame,\n} from '../util/animation/AnimationFrameProvider';\nimport { runningAnimations } from '../util/animation/AnimationRegistry';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement, toDataURL } from '../util/misc/dom';\nimport { invertTransform, transformPoint } from '../util/misc/matrix';\nimport type { EnlivenObjectOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { toFixed } from '../util/misc/toFixed';\nimport { isFiller, isPattern, isTextObject } from '../util/typeAssertions';\nimport { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager';\nimport type { CSSDimensions } from './DOMManagers/util';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\nimport { staticCanvasDefaults } from './StaticCanvasOptions';\nimport { log, FabricError } from '../util/internals/console';\nimport { getDevicePixelRatio } from '../env';\n\n/**\n * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset\n * Better try to restrict with types to avoid confusion.\n */\nexport type TCanvasSizeOptions =\n | {\n backstoreOnly?: true;\n cssOnly?: false;\n }\n | {\n backstoreOnly?: false;\n cssOnly?: true;\n };\n\nexport type TSVGExportOptions = {\n suppressPreamble?: boolean;\n viewBox?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n encoding?: 'UTF-8'; // test Encoding type and see what happens\n width?: string;\n height?: string;\n reviver?: TSVGReviver;\n};\n\n/**\n * Static canvas class\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260\nexport class StaticCanvas<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends StaticCanvasEvents = StaticCanvasEvents,\n >\n extends createCollectionMixin(CommonMethods)\n implements StaticCanvasOptions\n{\n declare width: number;\n declare height: number;\n\n // background\n declare backgroundVpt: boolean;\n declare backgroundColor: TFiller | string;\n declare backgroundImage?: FabricObject;\n // overlay\n declare overlayVpt: boolean;\n declare overlayColor: TFiller | string;\n declare overlayImage?: FabricObject;\n\n declare clipPath?: FabricObject;\n\n declare includeDefaultValues: boolean;\n\n // rendering config\n declare renderOnAddRemove: boolean;\n declare skipOffscreen: boolean;\n declare enableRetinaScaling: boolean;\n declare imageSmoothingEnabled: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare controlsAboveOverlay: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare allowTouchScrolling: boolean;\n\n declare viewportTransform: TMat2D;\n\n /**\n * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries}\n */\n declare vptCoords: TCornerPoint;\n\n /**\n * A reference to the canvas actual HTMLCanvasElement.\n * Can be use to read the raw pixels, but never write or manipulate\n * @type HTMLCanvasElement\n */\n get lowerCanvasEl() {\n return this.elements.lower?.el;\n }\n\n get contextContainer() {\n return this.elements.lower?.ctx;\n }\n\n /**\n * If true the Canvas is in the process or has been disposed/destroyed.\n * No more rendering operation will be executed on this canvas.\n * @type boolean\n */\n declare destroyed?: boolean;\n\n /**\n * Started the process of disposing but not done yet.\n * WIll likely complete the render cycle already scheduled but stopping adding more.\n * @type boolean\n */\n declare disposed?: boolean;\n\n declare _offset: { left: number; top: number };\n protected declare hasLostContext: boolean;\n protected declare nextRenderHandle: number;\n\n declare elements: StaticCanvasDOMManager;\n\n /**\n * When true control drawing is skipped.\n * This boolean is used to avoid toDataURL to export controls.\n * Usage of this boolean to build up other flows and features is not supported\n * @type Boolean\n * @default false\n */\n protected declare skipControlsDrawing: boolean;\n\n static ownDefaults = staticCanvasDefaults;\n\n // reference to\n protected declare __cleanupTask?: {\n (): void;\n kill: (reason?: any) => void;\n };\n\n static getDefaults(): Record {\n return StaticCanvas.ownDefaults;\n }\n\n constructor(\n el?: string | HTMLCanvasElement,\n options: TOptions = {},\n ) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof StaticCanvas).getDefaults(),\n );\n this.set(options);\n this.initElements(el);\n this._setDimensionsImpl({\n width: this.width || this.elements.lower.el.width || 0,\n height: this.height || this.elements.lower.el.height || 0,\n });\n this.skipControlsDrawing = false;\n this.viewportTransform = [...this.viewportTransform];\n this.calcViewportBoundaries();\n }\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new StaticCanvasDOMManager(el);\n }\n\n add(...objects: FabricObject[]) {\n const size = super.add(...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n insertAt(index: number, ...objects: FabricObject[]) {\n const size = super.insertAt(index, ...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return removed;\n }\n\n _onObjectAdded(obj: FabricObject) {\n if (obj.canvas && (obj.canvas as StaticCanvas) !== this) {\n log(\n 'warn',\n 'Canvas is trying to add an object that belongs to a different canvas.\\n' +\n 'Resulting to default behavior: removing object from previous canvas and adding to new canvas',\n );\n obj.canvas.remove(obj);\n }\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added', { target: this });\n }\n\n _onObjectRemoved(obj: FabricObject) {\n obj._set('canvas', undefined);\n this.fire('object:removed', { target: obj });\n obj.fire('removed', { target: this });\n }\n\n _onStackOrderChanged() {\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * @private\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling() {\n return this.enableRetinaScaling ? getDevicePixelRatio() : 1;\n }\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n */\n calcOffset() {\n return (this._offset = this.elements.calcOffset());\n }\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth(): number {\n return this.width;\n }\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight(): number {\n return this.height;\n }\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setWidth(\n value: TSize['width'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setWidth(\n value: CSSDimensions['width'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setWidth(value: number, options?: never) {\n return this.setDimensions({ width: value }, options);\n }\n\n /**s\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setHeight(\n value: TSize['height'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setHeight(\n value: CSSDimensions['height'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setHeight(value: CSSDimensions['height'], options?: never) {\n return this.setDimensions({ height: value }, options);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: Partial,\n { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {},\n ) {\n if (!cssOnly) {\n const size = {\n width: this.width,\n height: this.height,\n ...(dimensions as Partial),\n };\n this.elements.setDimensions(size, this.getRetinaScaling());\n this.hasLostContext = true;\n this.width = size.width;\n this.height = size.height;\n }\n if (!backstoreOnly) {\n this.elements.setCSSDimensions(dimensions);\n }\n\n this.calcOffset();\n }\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n */\n setDimensions(\n dimensions: Partial,\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setDimensions(\n dimensions: Partial,\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setDimensions(dimensions: Partial, options?: never): void;\n setDimensions(\n dimensions: Partial,\n options?: TCanvasSizeOptions,\n ) {\n this._setDimensionsImpl(dimensions, options);\n if (!options || !options.cssOnly) {\n this.requestRenderAll();\n }\n }\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom() {\n return this.viewportTransform[0];\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n this.viewportTransform = vpt;\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Sets zoom level of this canvas instance, the zoom centered around point\n * meaning that following zoom to point with the same point will have the visual\n * effect of the zoom originating from that point. The point won't move.\n * It has nothing to do with canvas center or visual center of the viewport.\n * @param {Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n zoomToPoint(point: Point, value: number) {\n // TODO: just change the scale, preserve other transformations\n const before = point,\n vpt: TMat2D = [...this.viewportTransform];\n const newPoint = transformPoint(point, invertTransform(vpt));\n vpt[0] = value;\n vpt[3] = value;\n const after = transformPoint(newPoint, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n this.setViewportTransform(vpt);\n }\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n setZoom(value: number) {\n this.zoomToPoint(new Point(0, 0), value);\n }\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {Point} point to move to\n */\n absolutePan(point: Point) {\n const vpt: TMat2D = [...this.viewportTransform];\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n }\n\n /**\n * Pans viewpoint relatively\n * @param {Point} point (position vector) to move by\n */\n relativePan(point: Point) {\n return this.absolutePan(\n new Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5],\n ),\n );\n }\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement(): HTMLCanvasElement {\n return this.elements.lower.el;\n }\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n */\n clearContext(ctx: CanvasRenderingContext2D) {\n ctx.clearRect(0, 0, this.width, this.height);\n }\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext(): CanvasRenderingContext2D {\n return this.elements.lower.ctx;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n this.remove(...this.getObjects());\n this.backgroundImage = undefined;\n this.overlayImage = undefined;\n this.backgroundColor = '';\n this.overlayColor = '';\n this.clearContext(this.getContext());\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Renders the canvas\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n this.renderCanvas(this.getContext(), this._objects);\n }\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n */\n renderAndReset() {\n this.nextRenderHandle = 0;\n this.renderAll();\n }\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n */\n requestRenderAll() {\n if (!this.nextRenderHandle && !this.disposed && !this.destroyed) {\n this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset());\n }\n }\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport\n */\n calcViewportBoundaries(): TCornerPoint {\n const width = this.width,\n height = this.height,\n iVpt = invertTransform(this.viewportTransform),\n a = transformPoint({ x: 0, y: 0 }, iVpt),\n b = transformPoint({ x: width, y: height }, iVpt),\n // we don't support vpt flipping\n // but the code is robust enough to mostly work with flipping\n min = a.min(b),\n max = a.max(b);\n return (this.vptCoords = {\n tl: min,\n tr: new Point(max.x, min.y),\n bl: new Point(min.x, max.y),\n br: max,\n });\n }\n\n cancelRequestedRender() {\n if (this.nextRenderHandle) {\n cancelAnimFrame(this.nextRenderHandle);\n this.nextRenderHandle = 0;\n }\n }\n\n drawControls(_ctx: CanvasRenderingContext2D) {\n // Static canvas has no controls\n }\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n */\n renderCanvas(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n if (this.destroyed) {\n return;\n }\n\n const v = this.viewportTransform,\n path = this.clipPath;\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n // @ts-expect-error node-canvas stuff\n ctx.patternQuality = 'best';\n this.fire('before:render', { ctx });\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n if (path) {\n path._set('canvas', this);\n // needed to setup a couple of variables\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCanvas(ctx, path as TCachedFabricObject);\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n this.fire('after:render', { ctx });\n\n if (this.__cleanupTask) {\n this.__cleanupTask();\n this.__cleanupTask = undefined;\n }\n }\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n const v = this.viewportTransform;\n ctx.save();\n ctx.transform(...v);\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n ctx.globalCompositeOperation = 'destination-in';\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n for (let i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay(\n ctx: CanvasRenderingContext2D,\n property: 'background' | 'overlay',\n ) {\n const fill = this[`${property}Color`],\n object = this[`${property}Image`],\n v = this.viewportTransform,\n needsVpt = this[`${property}Vpt`];\n if (!fill && !object) {\n return;\n }\n const isAFiller = isFiller(fill);\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */)! : fill;\n if (needsVpt) {\n ctx.transform(...v);\n }\n if (isAFiller) {\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n const m = ((fill as Gradient<'linear'>).gradientTransform ||\n (fill as Pattern).patternTransform) as TMat2D;\n m && ctx.transform(...m);\n }\n ctx.fill();\n ctx.restore();\n }\n if (object) {\n ctx.save();\n const { skipOffscreen } = this;\n // if the object doesn't move with the viewport,\n // the offscreen concept does not apply;\n this.skipOffscreen = needsVpt;\n if (needsVpt) {\n ctx.transform(...v);\n }\n object.render(ctx);\n this.skipOffscreen = skipOffscreen;\n ctx.restore();\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n * @deprecated migrate to `getCenterPoint`\n */\n getCenter() {\n return {\n top: this.height / 2,\n left: this.width / 2,\n };\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * @return {Point}\n */\n getCenterPoint() {\n return new Point(this.width / 2, this.height / 2);\n }\n\n /**\n * Centers object horizontally in the canvas\n */\n centerObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getCenterPoint().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically in the canvas\n * @param {FabricObject} object Object to center vertically\n */\n centerObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n centerObject(object: FabricObject) {\n return this._centerObject(object, this.getCenterPoint());\n }\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObject(object: FabricObject) {\n return this._centerObject(object, this.getVpCenter());\n }\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getVpCenter().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getVpCenter().y),\n );\n }\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {Point} vpCenter, viewport center\n */\n getVpCenter(): Point {\n return transformPoint(\n this.getCenterPoint(),\n invertTransform(this.viewportTransform),\n );\n }\n\n /**\n * @private\n * @param {FabricObject} object Object to center\n * @param {Point} center Center point\n */\n _centerObject(object: FabricObject, center: Point) {\n object.setXY(center, CENTER, CENTER);\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Returns dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON(propertiesToInclude?: string[]) {\n return this.toDatalessObject(propertiesToInclude);\n }\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n }\n\n /**\n * Returns Object representation of canvas\n * this alias is provided because if you call JSON.stringify on an instance,\n * the toJSON object will be invoked if it exists.\n * Having a toJSON method means you can do JSON.stringify(myCanvas)\n * @return {Object} JSON compatible object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example JSON without default values\n * var json = canvas.toJSON();\n */\n toJSON() {\n return this.toObject();\n }\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n }\n\n /**\n * @private\n */\n _toObjectMethod(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const clipPath = this.clipPath;\n const clipPathData =\n clipPath && !clipPath.excludeFromExport\n ? this._toObject(clipPath, methodName, propertiesToInclude)\n : null;\n return {\n version: VERSION,\n ...pick(this, propertiesToInclude as (keyof this)[]),\n objects: this._objects\n .filter((object) => !object.excludeFromExport)\n .map((instance) =>\n this._toObject(instance, methodName, propertiesToInclude),\n ),\n ...this.__serializeBgOverlay(methodName, propertiesToInclude),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n let originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n const object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = !!originalValue;\n }\n return object;\n }\n\n /**\n * @private\n */\n __serializeBgOverlay(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const data: any = {},\n bgImage = this.backgroundImage,\n overlayImage = this.overlayImage,\n bgColor = this.backgroundColor,\n overlayColor = this.overlayColor;\n\n if (isFiller(bgColor)) {\n if (!bgColor.excludeFromExport) {\n data.background = bgColor.toObject(propertiesToInclude);\n }\n } else if (bgColor) {\n data.background = bgColor;\n }\n\n if (isFiller(overlayColor)) {\n if (!overlayColor.excludeFromExport) {\n data.overlay = overlayColor.toObject(propertiesToInclude);\n }\n } else if (overlayColor) {\n data.overlay = overlayColor;\n }\n\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(\n bgImage,\n methodName,\n propertiesToInclude,\n );\n }\n if (overlayImage && !overlayImage.excludeFromExport) {\n data.overlayImage = this._toObject(\n overlayImage,\n methodName,\n propertiesToInclude,\n );\n }\n\n return data;\n }\n\n /* _TO_SVG_START_ */\n\n declare svgViewportTransformation: boolean;\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-coordinate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG(options: TSVGExportOptions = {}, reviver?: TSVGReviver) {\n options.reviver = reviver;\n const markup: string[] = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n if (this.clipPath) {\n markup.push(`\\n`);\n }\n this._setSVGBgOverlayColor(markup, 'background');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n this._setSVGObjects(markup, reviver);\n if (this.clipPath) {\n markup.push('\\n');\n }\n this._setSVGBgOverlayColor(markup, 'overlay');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n }\n\n /**\n * @private\n */\n _setSVGPreamble(markup: string[], options: TSVGExportOptions): void {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n',\n );\n }\n\n /**\n * @private\n */\n _setSVGHeader(markup: string[], options: TSVGExportOptions): void {\n const width = options.width || `${this.width}`,\n height = options.height || `${this.height}`,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,\n optViewBox = options.viewBox;\n let viewBox: string;\n if (optViewBox) {\n viewBox = `viewBox=\"${optViewBox.x} ${optViewBox.y} ${optViewBox.width} ${optViewBox.height}\" `;\n } else if (this.svgViewportTransformation) {\n const vpt = this.viewportTransform;\n viewBox = `viewBox=\"${toFixed(\n -vpt[4] / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS)} ${toFixed(\n this.width / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS)}\" `;\n } else {\n viewBox = `viewBox=\"0 0 ${this.width} ${this.height}\" `;\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ',\n VERSION,\n '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n this.createSVGClipPathMarkup(options),\n '\\n',\n );\n }\n\n createSVGClipPathMarkup(options: TSVGExportOptions): string {\n const clipPath = this.clipPath;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n return `\\n${clipPath.toClipPathSVG(\n options.reviver,\n )}\\n`;\n }\n return '';\n }\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup(): string {\n return (['background', 'overlay'] as const)\n .map((prop) => {\n const fill = this[`${prop}Color`];\n if (isFiller(fill)) {\n const shouldTransform = this[`${prop}Vpt`],\n vpt = this.viewportTransform,\n object = {\n // otherwise circular dependency\n isType: () => false,\n width: this.width / (shouldTransform ? vpt[0] : 1),\n height: this.height / (shouldTransform ? vpt[3] : 1),\n };\n return fill.toSVG(object as FabricObject, {\n additionalTransform: shouldTransform ? matrixToSVG(vpt) : '',\n });\n }\n })\n .join('');\n }\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup(): string {\n const objects: FabricObject[] = [],\n fontList: Record = {},\n fontPaths = config.fontPaths;\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n if (isCollection(object)) {\n object._objects.forEach(add);\n }\n });\n\n objects.forEach((obj) => {\n if (!isTextObject(obj)) {\n return;\n }\n const { styles, fontFamily } = obj;\n if (fontList[fontFamily] || !fontPaths[fontFamily]) {\n return;\n }\n fontList[fontFamily] = true;\n if (!styles) {\n return;\n }\n Object.values(styles).forEach((styleRow) => {\n Object.values(styleRow).forEach(({ fontFamily = '' }) => {\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n });\n });\n });\n\n const fontListMarkup = Object.keys(fontList)\n .map(\n (fontFamily) =>\n `\\t\\t@font-face {\\n\\t\\t\\tfont-family: '${fontFamily}';\\n\\t\\t\\tsrc: url('${fontPaths[fontFamily]}');\\n\\t\\t}\\n`,\n )\n .join('');\n\n if (fontListMarkup) {\n return `\\t\\n`;\n }\n return '';\n }\n\n /**\n * @private\n */\n _setSVGObjects(markup: string[], reviver?: TSVGReviver) {\n this.forEachObject((fabricObject) => {\n if (fabricObject.excludeFromExport) {\n return;\n }\n this._setSVGObject(markup, fabricObject, reviver);\n });\n }\n\n /**\n * This is its own function because the Canvas ( non static ) requires extra code here\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n markup.push(instance.toSVG(reviver));\n }\n\n /**\n * @private\n */\n _setSVGBgOverlayImage(\n markup: string[],\n property: 'overlayImage' | 'backgroundImage',\n reviver?: TSVGReviver,\n ) {\n const bgOrOverlay = this[property];\n if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) {\n markup.push(bgOrOverlay.toSVG(reviver));\n }\n }\n\n /**\n * @TODO this seems to handle patterns but fail at gradients.\n * @private\n */\n _setSVGBgOverlayColor(markup: string[], property: 'background' | 'overlay') {\n const filler = this[`${property}Color`];\n if (!filler) {\n return;\n }\n if (isFiller(filler)) {\n const repeat = (filler as Pattern).repeat || '',\n finalWidth = this.width,\n finalHeight = this.height,\n shouldInvert = this[`${property}Vpt`],\n additionalTransform = shouldInvert\n ? matrixToSVG(invertTransform(this.viewportTransform))\n : '';\n markup.push(\n `\\n`,\n );\n } else {\n markup.push(\n '\\n',\n );\n }\n }\n /* _TO_SVG_END_ */\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n *\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n *\n * @param {String|Object} json JSON string or object\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @param {Object} [options] options\n * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {Promise} instance\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll());\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * }).then((canvas) => {\n * ... canvas is restored, add your code.\n * });\n *\n */\n loadFromJSON(\n json: string | Record,\n reviver?: EnlivenObjectOptions['reviver'],\n { signal }: Abortable = {},\n ): Promise {\n if (!json) {\n return Promise.reject(new FabricError('`json` is undefined'));\n }\n\n // parse json if it wasn't already\n const serialized = typeof json === 'string' ? JSON.parse(json) : json;\n const {\n objects = [],\n backgroundImage,\n background,\n overlayImage,\n overlay,\n clipPath,\n } = serialized;\n const renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n return Promise.all([\n enlivenObjects(objects, {\n reviver,\n signal,\n }),\n enlivenObjectEnlivables(\n {\n backgroundImage,\n backgroundColor: background,\n overlayImage,\n overlayColor: overlay,\n clipPath,\n },\n { signal },\n ),\n ]).then(([enlived, enlivedMap]) => {\n this.clear();\n this.add(...enlived);\n this.set(serialized);\n this.set(enlivedMap);\n this.renderOnAddRemove = renderOnAddRemove;\n return this;\n });\n }\n\n /**\n * Clones canvas instance\n * @param {string[]} [properties] Array of properties to include in the cloned canvas and children\n */\n clone(properties: string[]) {\n const data = this.toObject(properties);\n const canvas = this.cloneWithoutData();\n return canvas.loadFromJSON(data);\n }\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size.\n */\n cloneWithoutData() {\n const el = createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n return new (this.constructor as Constructor)(el);\n }\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link https://jsfiddle.net/xsjua1rd/ demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n * @example Generate dataURL with objects that overlap a specified object\n * var myObject;\n * var dataURL = canvas.toDataURL({\n * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject)\n * });\n */\n toDataURL(options = {} as TDataUrlOptions): string {\n const {\n format = 'png',\n quality = 1,\n multiplier = 1,\n enableRetinaScaling = false,\n } = options;\n const finalMultiplier =\n multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1);\n\n return toDataURL(\n this.toCanvasElement(finalMultiplier, options),\n format,\n quality,\n );\n }\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [options] Cropping informations\n * @param {Number} [options.left] Cropping left offset.\n * @param {Number} [options.top] Cropping top offset.\n * @param {Number} [options.width] Cropping width.\n * @param {Number} [options.height] Cropping height.\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n */\n toCanvasElement(\n multiplier = 1,\n { width, height, left, top, filter } = {} as TToCanvasElementOptions,\n ): HTMLCanvasElement {\n const scaledWidth = (width || this.width) * multiplier,\n scaledHeight = (height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n originalSkipControlsDrawing = this.skipControlsDrawing,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (left || 0)) * multiplier,\n translateY = (vp[5] - (top || 0)) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY] as TMat2D,\n originalRetina = this.enableRetinaScaling,\n canvasEl = createCanvasElement(),\n objectsToRender = filter\n ? this._objects.filter((obj) => filter(obj))\n : this._objects;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.enableRetinaScaling = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.skipControlsDrawing = true;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d')!, objectsToRender);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.enableRetinaScaling = originalRetina;\n this.skipControlsDrawing = originalSkipControlsDrawing;\n return canvasEl;\n }\n\n /**\n * Waits until rendering has settled to destroy the canvas\n * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed\n * @throws if aborted by a consequent call\n */\n dispose() {\n !this.disposed &&\n this.elements.cleanupDOM({ width: this.width, height: this.height });\n runningAnimations.cancelByCanvas(this);\n this.disposed = true;\n return new Promise((resolve, reject) => {\n const task = () => {\n this.destroy();\n resolve(true);\n };\n task.kill = reject;\n if (this.__cleanupTask) {\n this.__cleanupTask.kill('aborted');\n }\n\n if (this.destroyed) {\n resolve(false);\n } else if (this.nextRenderHandle) {\n this.__cleanupTask = task;\n } else {\n task();\n }\n });\n }\n\n /**\n * Clears the canvas element, disposes objects and frees resources.\n *\n * Invoked as part of the **async** operation of {@link dispose}.\n *\n * **CAUTION**:\n *\n * This method is **UNSAFE**.\n * You may encounter a race condition using it if there's a requested render.\n * Call this method only if you are sure rendering has settled.\n * Consider using {@link dispose} as it is **SAFE**\n *\n * @private\n */\n destroy() {\n this.destroyed = true;\n this.cancelRequestedRender();\n this.forEachObject((object) => object.dispose());\n this._objects = [];\n if (this.backgroundImage) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = undefined;\n if (this.overlayImage) {\n this.overlayImage.dispose();\n }\n this.overlayImage = undefined;\n this.elements.dispose();\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString() {\n return `#`;\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport { getScrollLeftTop } from './dom_misc';\n\nconst touchEvents = ['touchstart', 'touchmove', 'touchend'];\n\nfunction getTouchInfo(event: TouchEvent | MouseEvent): MouseEvent | Touch {\n const touchProp = (event as TouchEvent).changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event as MouseEvent;\n}\n\nexport const getPointer = (event: TPointerEvent): Point => {\n const element = event.target as HTMLElement,\n scroll = getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top);\n};\n\nexport const isTouchEvent = (event: TPointerEvent) =>\n touchEvents.includes(event.type) ||\n (event as PointerEvent).pointerType === 'touch';\n\nexport const stopEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n};\n","import type { XY } from '../../Point';\nimport type { TBBox } from '../../typedefs';\n\n/**\n * Calculates bounding box (left, top, width, height) from given `points`\n * @param {XY[]} points\n * @return {Object} Object with left, top, width, height properties\n */\nexport const makeBoundingBoxFromPoints = (points: XY[]): TBBox => {\n let left = 0,\n top = 0,\n width = 0,\n height = 0;\n\n for (let i = 0, len = points.length; i < len; i++) {\n const { x, y } = points[i];\n if (x > width || !i) width = x;\n if (x < left || !i) left = x;\n if (y > height || !i) height = y;\n if (y < top || !i) top = y;\n }\n\n return {\n left,\n top,\n width: width - left,\n height: height - top,\n };\n};\n","import { Point } from '../../Point';\nimport { CENTER } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from './matrix';\n\n/**\n * given an object and a transform, apply the inverse transform to the object,\n * this is equivalent to remove from that object that transformation, so that\n * added in a space with the removed transform, the object will be the same as before.\n * Removing from an object a transform that scale by 2 is like scaling it by 1/2.\n * Removing from an object a transform that rotate by 30deg is like rotating by 30deg\n * in the opposite direction.\n * This util is used to add objects inside transformed groups or nested groups.\n * @param {FabricObject} object the object you want to transform\n * @param {TMat2D} transform the destination transform\n */\nexport const removeTransformFromObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const inverted = invertTransform(transform),\n finalTransform = multiplyTransformMatrices(\n inverted,\n object.calcOwnMatrix(),\n );\n applyTransformToObject(object, finalTransform);\n};\n\n/**\n * given an object and a transform, apply the transform to the object.\n * this is equivalent to change the space where the object is drawn.\n * Adding to an object a transform that scale by 2 is like scaling it by 2.\n * This is used when removing an object from an active selection for example.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const addTransformToObject = (object: FabricObject, transform: TMat2D) =>\n applyTransformToObject(\n object,\n multiplyTransformMatrices(transform, object.calcOwnMatrix()),\n );\n\n/**\n * discard an object transform state and apply the one from the matrix.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const applyTransformToObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const { translateX, translateY, scaleX, scaleY, ...otherOptions } =\n qrDecompose(transform),\n center = new Point(translateX, translateY);\n object.flipX = false;\n object.flipY = false;\n Object.assign(object, otherOptions);\n object.set({ scaleX, scaleY });\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n/**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @param {FabricObject} target object to transform\n */\nexport const resetObjectTransform = (target: FabricObject) => {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n};\n\n/**\n * Extract Object transform values\n * @param {FabricObject} target object to read from\n * @return {Object} Components of transform\n */\nexport const saveObjectTransform = (target: FabricObject) => ({\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top,\n});\n\n/**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform.\n * Use to calculate the boxes around objects for controls.\n * @param {Number} width\n * @param {Number} height\n * @param {TMat2D} t\n * @returns {Point} size\n */\nexport const sizeAfterTransform = (\n width: number,\n height: number,\n t: TMat2D,\n) => {\n const dimX = width / 2,\n dimY = height / 2,\n points = [\n new Point(-dimX, -dimY),\n new Point(dimX, -dimY),\n new Point(-dimX, dimY),\n new Point(dimX, dimY),\n ].map((p) => p.transform(t)),\n bbox = makeBoundingBoxFromPoints(points);\n return new Point(bbox.width, bbox.height);\n};\n","import { iMatrix } from '../../constants';\nimport type { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { invertTransform, multiplyTransformMatrices } from './matrix';\nimport { applyTransformToObject } from './objectTransforms';\n\n/**\n * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\\\n * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`)\n * @param [from]\n * @param [to]\n * @returns\n */\nexport const calcPlaneChangeMatrix = (\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n) => multiplyTransformMatrices(invertTransform(to), from);\n\n/**\n * Sends a point from the source coordinate plane to the destination coordinate plane.\\\n * From the canvas/viewer's perspective the point remains unchanged.\n *\n * @example Send point from canvas plane to group plane\n * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 });\n * var group = new Group([obj], { strokeWidth: 0 });\n * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix());\n * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix());\n * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group\n *\n * @param {Point} point\n * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane.\n * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane.\n * @returns {Point} transformed point\n */\nexport const sendPointToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to));\n\n/**\n * See {@link sendPointToPlane}\n */\nexport const sendVectorToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to), true);\n\n/**\n *\n * A util that abstracts applying transform to objects.\\\n * Sends `object` to the destination coordinate plane by applying the relevant transformations.\\\n * Changes the space/plane where `object` is drawn.\\\n * From the canvas/viewer's perspective `object` remains unchanged.\n *\n * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer\n * let obj, obj2;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * // render\n * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix());\n * obj.clipPath = undefined;\n * obj2.clipPath = clipPath;\n * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer\n *\n * @example Clip an object's clip path with an existing object\n * let obj, existingObj;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix());\n * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo);\n * clipPath.clipPath = existingObj;\n *\n * @param {FabricObject} object\n * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas.\n * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane.\n * @returns {Matrix} the transform matrix that was applied to `object`\n */\nexport const sendObjectToPlane = (\n object: FabricObject,\n from?: TMat2D,\n to?: TMat2D,\n): TMat2D => {\n const t = calcPlaneChangeMatrix(from, to);\n applyTransformToObject(\n object,\n multiplyTransformMatrices(t, object.calcOwnMatrix()),\n );\n return t;\n};\n","import type {\n ObjectModificationEvents,\n TModificationEvents,\n} from '../EventTypeDefs';\n\nexport const fireEvent = (\n eventName: TModificationEvents,\n options: ObjectModificationEvents[typeof eventName],\n) => {\n const {\n transform: { target },\n } = options;\n target.canvas?.fire(`object:${eventName}`, {\n ...options,\n target,\n });\n target.fire(eventName, options);\n};\n","import type { TOriginX, TOriginY } from '../../typedefs';\n\nconst originOffset = {\n left: -0.5,\n top: -0.5,\n center: 0,\n bottom: 0.5,\n right: 0.5,\n};\n/**\n * Resolves origin value relative to center\n * @private\n * @param {TOriginX | TOriginY} originValue originX / originY\n * @returns number\n */\n\nexport const resolveOrigin = (\n originValue: TOriginX | TOriginY | number,\n): number =>\n typeof originValue === 'string'\n ? originOffset[originValue]\n : originValue - 0.5;\n","import type {\n TPointerEvent,\n Transform,\n TransformAction,\n BasicTransformEvent,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TOriginX, TOriginY } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\nimport { CENTER } from '../constants';\n\nexport const NOT_ALLOWED_CURSOR = 'not-allowed';\n\n/**\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {FabricObject} [target] inserted back to help overriding. Unused\n */\nexport const getActionFromCorner = (\n alreadySelected: boolean,\n corner: string | undefined,\n e: TPointerEvent,\n target: FabricObject,\n) => {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n const control = target.controls[corner];\n return control.getActionName(e, control, target);\n};\n\n/**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\nexport function isTransformCentered(transform: Transform) {\n return (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) &&\n resolveOrigin(transform.originY) === resolveOrigin(CENTER)\n );\n}\n\nexport function invertOrigin(origin: TOriginX | TOriginY) {\n return -resolveOrigin(origin) + 0.5;\n}\n\nexport const isLocked = (\n target: FabricObject,\n lockingKey:\n | 'lockMovementX'\n | 'lockMovementY'\n | 'lockRotation'\n | 'lockScalingX'\n | 'lockScalingY'\n | 'lockSkewingX'\n | 'lockSkewingY'\n | 'lockScalingFlip',\n) => target[lockingKey];\n\nexport const commonEventInfo: TransformAction<\n Transform,\n BasicTransformEvent\n> = (eventData, transform, x, y) => {\n return {\n e: eventData,\n transform,\n pointer: new Point(x, y),\n };\n};\n\n/**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n * @param {Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\nexport function findCornerQuadrant(\n fabricObject: FabricObject,\n control: Control,\n): number {\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle(),\n cornerAngle =\n angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round((cornerAngle % 360) / 45);\n}\n\n/**\n * @returns the normalized point (rotated relative to center) in local coordinates\n */\nfunction normalizePoint(\n target: FabricObject,\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n): Point {\n const center = target.getRelativeCenterPoint(),\n p =\n typeof originX !== 'undefined' && typeof originY !== 'undefined'\n ? target.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n )\n : new Point(target.left, target.top),\n p2 = target.angle\n ? point.rotate(-degreesToRadians(target.angle), center)\n : point;\n return p2.subtract(p);\n}\n\n/**\n * Transforms a point to the offset from the given origin\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\nexport function getLocalPoint(\n { target, corner }: Transform,\n originX: TOriginX,\n originY: TOriginY,\n x: number,\n y: number,\n) {\n const control = target.controls[corner],\n zoom = target.canvas?.getZoom() || 1,\n padding = target.padding / zoom,\n localPoint = normalizePoint(target, new Point(x, y), originX, originY);\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { LEFT, TOP, MOVING } from '../constants';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo, isLocked } from './util';\n\n/**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\nexport const dragHandler: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target, offsetX, offsetY } = transform,\n newLeft = x - offsetX,\n newTop = y - offsetY,\n moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,\n moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;\n moveX && target.set(LEFT, newLeft);\n moveY && target.set(TOP, newTop);\n if (moveX || moveY) {\n fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));\n }\n return moveX || moveY;\n};\n","import type { TSVGReviver } from '../../typedefs';\nimport { uid } from '../../util/internals/uid';\nimport { colorPropToSVG, matrixToSVG } from '../../util/misc/svgParsing';\nimport { FILL, NONE, STROKE } from '../../constants';\nimport type { FabricObject } from './FabricObject';\nimport { isFiller } from '../../util/typeAssertions';\n\nexport class FabricObjectSVGExportMixin {\n /**\n * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed.\n * This reference is a UID in the fabric namespace and is temporary stored here.\n * @type {String}\n */\n declare clipPathId?: string;\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(\n this: FabricObjectSVGExportMixin & FabricObject,\n skipShadow?: boolean,\n ) {\n const fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray\n ? this.strokeDashArray.join(' ')\n : NONE,\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = colorPropToSVG(FILL, this.fill),\n stroke = colorPropToSVG(STROKE, this.stroke);\n\n return [\n stroke,\n 'stroke-width: ',\n strokeWidth,\n '; ',\n 'stroke-dasharray: ',\n strokeDashArray,\n '; ',\n 'stroke-linecap: ',\n strokeLineCap,\n '; ',\n 'stroke-dashoffset: ',\n strokeDashOffset,\n '; ',\n 'stroke-linejoin: ',\n strokeLineJoin,\n '; ',\n 'stroke-miterlimit: ',\n strokeMiterLimit,\n '; ',\n fill,\n 'fill-rule: ',\n fillRule,\n '; ',\n 'opacity: ',\n opacity,\n ';',\n filter,\n visibility,\n ].join('');\n }\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';\n }\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons(\n this: FabricObjectSVGExportMixin & FabricObject & { id?: string },\n ) {\n return [\n this.id ? `id=\"${this.id}\" ` : '',\n this.clipPath\n ? `clip-path=\"url(#${\n (this.clipPath as FabricObjectSVGExportMixin & FabricObject)\n .clipPathId\n })\" `\n : '',\n ].join('');\n }\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform(\n this: FabricObjectSVGExportMixin & FabricObject,\n full?: boolean,\n additionalTransform = '',\n ) {\n const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = `transform=\"${matrixToSVG(transform)}`;\n return `${svgTransform}${additionalTransform}\" `;\n }\n\n /**\n * Returns svg representation of an instance\n * This function is implemented in each subclass\n * This is just because typescript otherwise cryies all the time\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(_reviver?: TSVGReviver): string[] {\n return [''];\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver,\n });\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver,\n })\n );\n }\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n reviver,\n additionalTransform = '',\n }: { reviver?: TSVGReviver; additionalTransform?: string } = {},\n ) {\n const commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n }\n\n /**\n * @private\n */\n _createBaseSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n noStyle,\n reviver,\n withShadow,\n additionalTransform,\n }: {\n noStyle?: boolean;\n reviver?: TSVGReviver;\n withShadow?: boolean;\n additionalTransform?: string;\n } = {},\n ): string {\n const styleInfo = noStyle ? '' : `style=\"${this.getSvgStyles()}\" `,\n shadowInfo = withShadow ? `style=\"${this.getSvgFilter()}\" ` : '',\n clipPath = this.clipPath as FabricObjectSVGExportMixin & FabricObject,\n vectorEffect = this.strokeUniform\n ? 'vector-effect=\"non-scaling-stroke\" '\n : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke,\n fill = this.fill,\n shadow = this.shadow,\n markup = [],\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n let clipPathMarkup;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n clipPathMarkup = `\\n${clipPath.toClipPathSVG(reviver)}\\n`;\n }\n if (absoluteClipPath) {\n markup.push('\\n');\n }\n markup.push(\n '\\n',\n );\n const commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(),\n ' ',\n additionalTransform ? `transform=\"${additionalTransform}\" ` : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (isFiller(fill)) {\n markup.push(fill.toSVG(this));\n }\n if (isFiller(stroke)) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n }\n\n addPaintOrder(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.paintFirst !== FILL ? ` paint-order=\"${this.paintFirst}\" ` : '';\n }\n}\n","export function getSvgRegex(arr: string[]) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n}\n","import { getSvgRegex } from './getSvgRegex';\nimport { LEFT, TOP } from '../constants';\n\nexport const reNum = String.raw`(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)`;\n\nexport const svgNS = 'http://www.w3.org/2000/svg';\n\nexport const reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' +\n reNum +\n '))?\\\\s+(.*)',\n);\n\nexport const svgValidTagNames = [\n 'path',\n 'circle',\n 'polygon',\n 'polyline',\n 'ellipse',\n 'rect',\n 'line',\n 'image',\n 'text',\n ],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = [\n 'pattern',\n 'defs',\n 'symbol',\n 'metadata',\n 'clipPath',\n 'mask',\n 'desc',\n ],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n attributesMap = {\n cx: LEFT,\n x: LEFT,\n r: 'radius',\n cy: TOP,\n y: TOP,\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing',\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n\nexport const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n\nexport const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n\nexport const svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n// matches, e.g.: +14.56e-12, etc.\nexport const reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*' +\n '$',\n);\n","import type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n\nconst unitVectorX = new Point(1, 0);\nconst zero = new Point();\n\n/**\n * Rotates `vector` with `radians`\n * @param {Point} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotateVector = (vector: Point, radians: TRadian) =>\n vector.rotate(radians);\n\n/**\n * Creates a vector from points represented as a point\n *\n * @param {Point} from\n * @param {Point} to\n * @returns {Point} vector\n */\nexport const createVector = (from: XY, to: XY): Point =>\n new Point(to).subtract(from);\n\n/**\n * return the magnitude of a vector\n * @return {number}\n */\nexport const magnitude = (point: Point) => point.distanceFrom(zero);\n\n/**\n * Calculates the angle between 2 vectors\n * @param {Point} a\n * @param {Point} b\n * @returns the angle in radians from `a` to `b`\n */\nexport const calcAngleBetweenVectors = (a: Point, b: Point): TRadian =>\n Math.atan2(crossProduct(a, b), dotProduct(a, b)) as TRadian;\n\n/**\n * Calculates the angle between the x axis and the vector\n * @param {Point} v\n * @returns the angle in radians of `v`\n */\nexport const calcVectorRotation = (v: Point) =>\n calcAngleBetweenVectors(unitVectorX, v);\n\n/**\n * @param {Point} v\n * @returns {Point} vector representing the unit vector pointing to the direction of `v`\n */\nexport const getUnitVector = (v: Point): Point =>\n v.eq(zero) ? v : v.scalarDivide(magnitude(v));\n\n/**\n * @param {Point} v\n * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true`\n * @returns {Point} the unit orthogonal vector\n */\nexport const getOrthonormalVector = (\n v: Point,\n counterClockwise = true,\n): Point =>\n getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1));\n\n/**\n * Cross product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number} the magnitude of Z vector\n */\nexport const crossProduct = (a: Point, b: Point): number =>\n a.x * b.y - a.y * b.x;\n\n/**\n * Dot product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number}\n */\nexport const dotProduct = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\n\n/**\n * Checks if the vector is between two others. It is considered\n * to be inside when the vector to be tested is between the\n * initial vector and the final vector (included) in a counterclockwise direction.\n * @param {Point} t vector to be tested\n * @param {Point} a initial vector\n * @param {Point} b final vector\n * @returns {boolean} true if the vector is among the others\n */\nexport const isBetweenVectors = (t: Point, a: Point, b: Point): boolean => {\n if (t.eq(a) || t.eq(b)) return true;\n const AxB = crossProduct(a, b),\n AxT = crossProduct(a, t),\n BxT = crossProduct(b, t);\n return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0);\n};\n","import { classRegistry } from './ClassRegistry';\nimport { Color } from './color/Color';\nimport { config } from './config';\nimport { reNum } from './parser/constants';\nimport { Point } from './Point';\nimport type { FabricObject } from './shapes/Object/FabricObject';\nimport type { TClassProperties } from './typedefs';\nimport { uid } from './util/internals/uid';\nimport { pickBy } from './util/misc/pick';\nimport { degreesToRadians } from './util/misc/radiansDegreesConversion';\nimport { toFixed } from './util/misc/toFixed';\nimport { rotateVector } from './util/misc/vectors';\n\n/**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * - (?:\\s|^): This part captures either a whitespace character (\\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down:\n * - (-?\\d+): Captures an optional minus sign followed by one or more digits (integer part of the number).\n * - (?:\\.\\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number).\n * - (?:px)?: Optionally captures the \"px\" unit.\n * - (?:\\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: Similar to the previous step, this captures the vertical offset.\n\n(\\d+(?:\\.\\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign.\n\n(?:\\s+(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and \"px\" unit.\n\n(?:$|\\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.\n */\n// eslint-disable-next-line max-len\n\nconst shadowOffsetRegex = '(-?\\\\d+(?:\\\\.\\\\d*)?(?:px)?(?:\\\\s?|$))?';\n\nconst reOffsetsAndBlur = new RegExp(\n '(?:\\\\s|^)' +\n shadowOffsetRegex +\n shadowOffsetRegex +\n '(' +\n reNum +\n '?(?:px)?)?(?:\\\\s?|$)(?:$|\\\\s)',\n);\n\nexport const shadowDefaultValues: Partial> = {\n color: 'rgb(0,0,0)',\n blur: 0,\n offsetX: 0,\n offsetY: 0,\n affectStroke: false,\n includeDefaultValues: true,\n nonScaling: false,\n};\n\nexport type SerializedShadowOptions = {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n affectStroke: boolean;\n nonScaling: boolean;\n type: string;\n};\n\nexport class Shadow {\n /**\n * Shadow color\n * @type String\n * @default\n */\n declare color: string;\n\n /**\n * Shadow blur\n * @type Number\n */\n declare blur: number;\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n declare offsetX: number;\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n declare offsetY: number;\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n declare affectStroke: boolean;\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n declare includeDefaultValues: boolean;\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n declare nonScaling: boolean;\n\n declare id: number;\n\n static ownDefaults = shadowDefaultValues;\n\n static type = 'shadow';\n\n /**\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n */\n constructor(options: Partial>);\n constructor(svgAttribute: string);\n constructor(arg0: string | Partial>) {\n const options: Partial> =\n typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;\n Object.assign(this, Shadow.ownDefaults, options);\n this.id = uid();\n }\n\n /**\n * @param {String} value Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n static parseShadow(value: string) {\n const shadowStr = value.trim(),\n [, offsetX = 0, offsetY = 0, blur = 0] = (\n reOffsetsAndBlur.exec(shadowStr) || []\n ).map((value) => parseFloat(value) || 0),\n color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim();\n\n return {\n color,\n offsetX,\n offsetY,\n blur,\n };\n }\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n }\n\n /**\n * Returns SVG representation of a shadow\n * @param {FabricObject} object\n * @return {String} SVG representation of a shadow\n */\n toSVG(object: FabricObject) {\n const offset = rotateVector(\n new Point(this.offsetX, this.offsetY),\n degreesToRadians(-object.angle),\n ),\n BLUR_BOX = 20,\n color = new Color(this.color);\n let fBoxX = 40,\n fBoxY = 40;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX =\n toFixed(\n (Math.abs(offset.x) + this.blur) / object.width,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n fBoxY =\n toFixed(\n (Math.abs(offset.y) + this.blur) / object.height,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return `\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\n\\t\\n\\n`;\n }\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject() {\n const data: SerializedShadowOptions = {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling,\n type: (this.constructor as typeof Shadow).type,\n };\n const defaults = Shadow.ownDefaults as SerializedShadowOptions;\n return !this.includeDefaultValues\n ? pickBy(data, (value, key) => value !== defaults[key])\n : data;\n }\n\n static async fromObject(options: Partial>) {\n return new this(options);\n }\n}\n\nclassRegistry.setClass(Shadow, 'shadow');\n","export const capValue = (min: number, value: number, max: number) =>\n Math.max(min, Math.min(value, max));\n","import {\n TOP,\n LEFT,\n SCALE_Y,\n SCALE_X,\n SKEW_X,\n SKEW_Y,\n FILL,\n STROKE,\n} from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { InteractiveFabricObject } from './InteractiveObject';\nimport type { FabricObject } from './Object';\n\nexport const stateProperties = [\n TOP,\n LEFT,\n SCALE_X,\n SCALE_Y,\n 'flipX',\n 'flipY',\n 'originX',\n 'originY',\n 'angle',\n 'opacity',\n 'globalCompositeOperation',\n 'shadow',\n 'visible',\n SKEW_X,\n SKEW_Y,\n];\n\nexport const cacheProperties = [\n FILL,\n STROKE,\n 'strokeWidth',\n 'strokeDashArray',\n 'width',\n 'height',\n 'paintFirst',\n 'strokeUniform',\n 'strokeLineCap',\n 'strokeDashOffset',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'backgroundColor',\n 'clipPath',\n];\n\nexport const fabricObjectDefaultValues: Partial<\n TClassProperties\n> = {\n // see composeMatrix() to see order of transforms. First defaults listed based on this\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n angle: 0,\n flipX: false,\n flipY: false,\n scaleX: 1,\n scaleY: 1,\n minScaleLimit: 0,\n skewX: 0,\n skewY: 0,\n originX: LEFT,\n originY: TOP,\n strokeWidth: 1,\n strokeUniform: false,\n padding: 0,\n opacity: 1,\n paintFirst: FILL,\n fill: 'rgb(0,0,0)',\n fillRule: 'nonzero',\n stroke: null,\n strokeDashArray: null,\n strokeDashOffset: 0,\n strokeLineCap: 'butt',\n strokeLineJoin: 'miter',\n strokeMiterLimit: 4,\n globalCompositeOperation: 'source-over',\n backgroundColor: '',\n shadow: null,\n visible: true,\n includeDefaultValues: true,\n excludeFromExport: false,\n objectCaching: true,\n clipPath: undefined,\n inverted: false,\n absolutePositioned: false,\n centeredRotation: true,\n centeredScaling: false,\n dirty: true,\n} as const;\n\nexport const interactiveObjectDefaultValues: Partial<\n TClassProperties\n> = {\n noScaleCache: true,\n lockMovementX: false,\n lockMovementY: false,\n lockRotation: false,\n lockScalingX: false,\n lockScalingY: false,\n lockSkewingX: false,\n lockSkewingY: false,\n lockScalingFlip: false,\n cornerSize: 13,\n touchCornerSize: 24,\n transparentCorners: true,\n cornerColor: 'rgb(178,204,255)',\n cornerStrokeColor: '',\n cornerStyle: 'rect',\n cornerDashArray: null,\n hasControls: true,\n borderColor: 'rgb(178,204,255)',\n borderDashArray: null,\n borderOpacityWhenMoving: 0.4,\n borderScaleFactor: 1,\n hasBorders: true,\n selectionBackgroundColor: '',\n selectable: true,\n evented: true,\n perPixelTargetFind: false,\n activeOn: 'down',\n hoverCursor: null,\n moveCursor: null,\n};\n","/**\n * Easing functions\n * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner}\n */\n\nimport { twoMathPi, halfPI } from '../../constants';\nimport type { TEasingFunction } from './types';\n\nconst normalize = (a: number, c: number, p: number, s: number) => {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = (p / twoMathPi) * Math.asin(1);\n } else {\n s = (p / twoMathPi) * Math.asin(c / a);\n }\n }\n return { a, c, p, s };\n};\n\nconst elastic = (\n a: number,\n s: number,\n p: number,\n t: number,\n d: number,\n): number =>\n a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * twoMathPi) / p);\n\n/**\n * Default sinusoidal easing\n */\nexport const defaultEasing: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Cubic easing in\n */\nexport const easeInCubic: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 3 + b;\n\n/**\n * Cubic easing out\n */\nexport const easeOutCubic: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 3 + 1) + b;\n\n/**\n * Cubic easing in and out\n */\nexport const easeInOutCubic: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 3 + b;\n }\n return (c / 2) * ((t - 2) ** 3 + 2) + b;\n};\n\n/**\n * Quartic easing in\n */\nexport const easeInQuart: TEasingFunction = (t, b, c, d) =>\n c * (t /= d) * t ** 3 + b;\n\n/**\n * Quartic easing out\n */\nexport const easeOutQuart: TEasingFunction = (t, b, c, d) =>\n -c * ((t = t / d - 1) * t ** 3 - 1) + b;\n\n/**\n * Quartic easing in and out\n */\nexport const easeInOutQuart: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 4 + b;\n }\n return (-c / 2) * ((t -= 2) * t ** 3 - 2) + b;\n};\n\n/**\n * Quintic easing in\n */\nexport const easeInQuint: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 5 + b;\n\n/**\n * Quintic easing out\n */\nexport const easeOutQuint: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 5 + 1) + b;\n\n/**\n * Quintic easing in and out\n */\nexport const easeInOutQuint: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 5 + b;\n }\n return (c / 2) * ((t - 2) ** 5 + 2) + b;\n};\n\n/**\n * Sinusoidal easing in\n */\nexport const easeInSine: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Sinusoidal easing out\n */\nexport const easeOutSine: TEasingFunction = (t, b, c, d) =>\n c * Math.sin((t / d) * halfPI) + b;\n\n/**\n * Sinusoidal easing in and out\n */\nexport const easeInOutSine: TEasingFunction = (t, b, c, d) =>\n (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b;\n\n/**\n * Exponential easing in\n */\nexport const easeInExpo: TEasingFunction = (t, b, c, d) =>\n t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b;\n\n/**\n * Exponential easing out\n */\nexport const easeOutExpo: TEasingFunction = (t, b, c, d) =>\n t === d ? b + c : c * -(2 ** ((-10 * t) / d) + 1) + b;\n\n/**\n * Exponential easing in and out\n */\nexport const easeInOutExpo: TEasingFunction = (t, b, c, d) => {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * 2 ** (10 * (t - 1)) + b;\n }\n return (c / 2) * -(2 ** (-10 * --t) + 2) + b;\n};\n\n/**\n * Circular easing in\n */\nexport const easeInCirc: TEasingFunction = (t, b, c, d) =>\n -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n\n/**\n * Circular easing out\n */\nexport const easeOutCirc: TEasingFunction = (t, b, c, d) =>\n c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n\n/**\n * Circular easing in and out\n */\nexport const easeInOutCirc: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (-c / 2) * (Math.sqrt(1 - t ** 2) - 1) + b;\n }\n return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n};\n\n/**\n * Elastic easing in\n */\nexport const easeInElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP } = normalize(a, c, p, s);\n return -elastic(normA, normS, normP, t, d) + b;\n};\n\n/**\n * Elastic easing out\n */\nexport const easeOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n return (\n normA * 2 ** (-10 * t) * Math.sin(((t * d - normS) * twoMathPi) / normP) +\n normC +\n b\n );\n};\n\n/**\n * Elastic easing in and out\n */\nexport const easeInOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(normA, normS, normP, t, d) + b;\n }\n return (\n normA *\n Math.pow(2, -10 * (t -= 1)) *\n Math.sin(((t * d - normS) * twoMathPi) / normP) *\n 0.5 +\n normC +\n b\n );\n};\n\n/**\n * Backwards easing in\n */\nexport const easeInBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * (t /= d) * t * ((s + 1) * t - s) + b;\n\n/**\n * Backwards easing out\n */\nexport const easeOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n\n/**\n * Backwards easing in and out\n */\nexport const easeInOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n return (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n};\n\n/**\n * Bouncing easing out\n */\nexport const easeOutBounce: TEasingFunction = (t, b, c, d) => {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n};\n\n/**\n * Bouncing easing in\n */\nexport const easeInBounce: TEasingFunction = (t, b, c, d) =>\n c - easeOutBounce(d - t, 0, c, d) + b;\n\n/**\n * Bouncing easing in and out\n */\nexport const easeInOutBounce: TEasingFunction = (t, b, c, d) =>\n t < d / 2\n ? easeInBounce(t * 2, 0, c, d) * 0.5 + b\n : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n\n/**\n * Quadratic easing in\n */\nexport const easeInQuad: TEasingFunction = (t, b, c, d) => c * (t /= d) * t + b;\n\n/**\n * Quadratic easing out\n */\nexport const easeOutQuad: TEasingFunction = (t, b, c, d) =>\n -c * (t /= d) * (t - 2) + b;\n\n/**\n * Quadratic easing in and out\n */\nexport const easeInOutQuad: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 2 + b;\n }\n return (-c / 2) * (--t * (t - 2) - 1) + b;\n};\n","import { noop } from '../../constants';\nimport { requestAnimFrame } from './AnimationFrameProvider';\nimport { runningAnimations } from './AnimationRegistry';\nimport { defaultEasing } from './easing';\nimport type {\n AnimationState,\n TAbortCallback,\n TBaseAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultAbort = () => false;\n\nexport abstract class AnimationBase<\n T extends number | number[] = number | number[],\n> {\n declare readonly startValue: T;\n declare readonly endValue: T;\n declare readonly duration: number;\n declare readonly delay: number;\n\n protected declare readonly byValue: T;\n protected declare readonly easing: TEasingFunction;\n\n private declare readonly _onStart: VoidFunction;\n private declare readonly _onChange: TOnAnimationChangeCallback;\n private declare readonly _onComplete: TOnAnimationChangeCallback;\n private declare readonly _abort: TAbortCallback;\n\n /**\n * Used to register the animation to a target object\n * so that it can be cancelled within the object context\n */\n declare readonly target?: unknown;\n\n private _state: AnimationState = 'pending';\n /**\n * Time %, or the ratio of `timeElapsed / duration`\n * @see tick\n */\n durationProgress = 0;\n /**\n * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)`\n */\n valueProgress = 0;\n /**\n * Current value\n */\n declare value: T;\n /**\n * Animation start time ms\n */\n private declare startTime: number;\n\n constructor({\n startValue,\n byValue,\n duration = 500,\n delay = 0,\n easing = defaultEasing,\n onStart = noop,\n onChange = noop,\n onComplete = noop,\n abort = defaultAbort,\n target,\n }: TBaseAnimationOptions) {\n this.tick = this.tick.bind(this);\n\n this.duration = duration;\n this.delay = delay;\n this.easing = easing;\n this._onStart = onStart;\n this._onChange = onChange;\n this._onComplete = onComplete;\n this._abort = abort;\n this.target = target;\n\n this.startValue = startValue;\n this.byValue = byValue;\n this.value = this.startValue;\n this.endValue = Object.freeze(this.calculate(this.duration).value);\n }\n\n get state() {\n return this._state;\n }\n\n isDone() {\n return this._state === 'aborted' || this._state === 'completed';\n }\n\n /**\n * Calculate the current value based on the easing parameters\n * @param timeElapsed in ms\n * @protected\n */\n protected abstract calculate(timeElapsed: number): {\n value: T;\n valueProgress: number;\n };\n\n start() {\n const firstTick: FrameRequestCallback = (timestamp) => {\n if (this._state !== 'pending') return;\n this.startTime = timestamp || +new Date();\n this._state = 'running';\n this._onStart();\n this.tick(this.startTime);\n };\n\n this.register();\n\n // setTimeout(cb, 0) will run cb on the next frame, causing a delay\n // we don't want that\n if (this.delay > 0) {\n setTimeout(() => requestAnimFrame(firstTick), this.delay);\n } else {\n requestAnimFrame(firstTick);\n }\n }\n\n private tick(t: number) {\n const durationMs = (t || +new Date()) - this.startTime;\n const boundDurationMs = Math.min(durationMs, this.duration);\n this.durationProgress = boundDurationMs / this.duration;\n const { value, valueProgress } = this.calculate(boundDurationMs);\n this.value = Object.freeze(value);\n this.valueProgress = valueProgress;\n\n if (this._state === 'aborted') {\n return;\n } else if (\n this._abort(this.value, this.valueProgress, this.durationProgress)\n ) {\n this._state = 'aborted';\n this.unregister();\n } else if (durationMs >= this.duration) {\n this.durationProgress = this.valueProgress = 1;\n this._onChange(this.endValue, this.valueProgress, this.durationProgress);\n this._state = 'completed';\n this._onComplete(\n this.endValue,\n this.valueProgress,\n this.durationProgress,\n );\n this.unregister();\n } else {\n this._onChange(this.value, this.valueProgress, this.durationProgress);\n requestAnimFrame(this.tick);\n }\n }\n\n private register() {\n runningAnimations.push(this as unknown as AnimationBase);\n }\n\n private unregister() {\n runningAnimations.remove(this as unknown as AnimationBase);\n }\n\n abort() {\n this._state = 'aborted';\n this.unregister();\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ValueAnimationOptions } from './types';\n\nexport class ValueAnimation extends AnimationBase {\n constructor({\n startValue = 0,\n endValue = 100,\n ...otherOptions\n }: ValueAnimationOptions) {\n super({\n ...otherOptions,\n startValue,\n byValue: endValue - startValue,\n });\n }\n\n protected calculate(timeElapsed: number) {\n const value = this.easing(\n timeElapsed,\n this.startValue,\n this.byValue,\n this.duration,\n );\n return {\n value,\n valueProgress: Math.abs((value - this.startValue) / this.byValue),\n };\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ArrayAnimationOptions } from './types';\n\nexport class ArrayAnimation extends AnimationBase {\n constructor({\n startValue = [0],\n endValue = [100],\n ...options\n }: ArrayAnimationOptions) {\n super({\n ...options,\n startValue,\n byValue: endValue.map((value, i) => value - startValue[i]),\n });\n }\n protected calculate(timeElapsed: number) {\n const values = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n );\n return {\n value: values,\n valueProgress: Math.abs(\n (values[0] - this.startValue[0]) / this.byValue[0],\n ),\n };\n }\n}\n","import { Color } from '../../color/Color';\nimport type { TRGBAColorSource } from '../../color/typedefs';\nimport { halfPI } from '../../constants';\nimport { capValue } from '../misc/capValue';\nimport { AnimationBase } from './AnimationBase';\nimport type {\n ColorAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultColorEasing: TEasingFunction = (\n timeElapsed,\n startValue,\n byValue,\n duration,\n) => {\n const durationProgress = 1 - Math.cos((timeElapsed / duration) * halfPI);\n return startValue + byValue * durationProgress;\n};\n\nconst wrapColorCallback = (\n callback?: TOnAnimationChangeCallback,\n) =>\n callback &&\n ((rgba: TRGBAColorSource, valueProgress: number, durationProgress: number) =>\n callback(new Color(rgba).toRgba(), valueProgress, durationProgress));\n\nexport class ColorAnimation extends AnimationBase {\n constructor({\n startValue,\n endValue,\n easing = defaultColorEasing,\n onChange,\n onComplete,\n abort,\n ...options\n }: ColorAnimationOptions) {\n const startColor = new Color(startValue).getSource();\n const endColor = new Color(endValue).getSource();\n super({\n ...options,\n startValue: startColor,\n byValue: endColor.map(\n (value, i) => value - startColor[i],\n ) as TRGBAColorSource,\n easing,\n onChange: wrapColorCallback(onChange),\n onComplete: wrapColorCallback(onComplete),\n abort: wrapColorCallback(abort),\n });\n }\n protected calculate(timeElapsed: number) {\n const [r, g, b, a] = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n ) as TRGBAColorSource;\n const value = [\n ...[r, g, b].map(Math.round),\n capValue(0, a, 1),\n ] as TRGBAColorSource;\n return {\n value,\n valueProgress:\n // to correctly calculate the change ratio we must find a changed value\n value\n .map((p, i) =>\n this.byValue[i] !== 0\n ? Math.abs((p - this.startValue[i]) / this.byValue[i])\n : 0,\n )\n .find((p) => p !== 0) || 0,\n };\n }\n}\n","import { ValueAnimation } from './ValueAnimation';\nimport { ArrayAnimation } from './ArrayAnimation';\nimport { ColorAnimation } from './ColorAnimation';\nimport type {\n ValueAnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n} from './types';\nimport type { TColorArg } from '../../color/typedefs';\n\nexport type TAnimation =\n T extends TColorArg\n ? ColorAnimation\n : T extends number[]\n ? ArrayAnimation\n : ValueAnimation;\n\nconst isArrayAnimation = (\n options: ArrayAnimationOptions | ValueAnimationOptions,\n): options is ArrayAnimationOptions => {\n return Array.isArray(options.startValue) || Array.isArray(options.endValue);\n};\n\n/**\n * Changes value(s) from startValue to endValue within a certain period of time,\n * invoking callbacks as the value(s) change.\n *\n * @example\n * animate({\n * startValue: 1,\n * endValue: 0,\n * onChange: (v) => {\n * obj.set('opacity', v);\n * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll`\n * canvas.renderAll();\n * }\n * });\n *\n * @example Using lists:\n * animate({\n * startValue: [1, 2, 3],\n * endValue: [2, 4, 6],\n * onChange: ([x, y, zoom]) => {\n * canvas.zoomToPoint(new Point(x, y), zoom);\n * canvas.renderAll();\n * }\n * });\n *\n */\nexport function animate(options: ArrayAnimationOptions): ArrayAnimation;\nexport function animate(options: ValueAnimationOptions): ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n>(\n options: T,\n): T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n R extends T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation,\n>(options: T): R {\n const animation = (\n isArrayAnimation(options)\n ? new ArrayAnimation(options)\n : new ValueAnimation(options)\n ) as R;\n animation.start();\n return animation;\n}\n\nexport function animateColor(options: ColorAnimationOptions) {\n const animation = new ColorAnimation(options);\n animation.start();\n return animation;\n}\n","import { Point } from './Point';\nimport { createVector } from './util/misc/vectors';\n\n/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\nexport type IntersectionType = 'Intersection' | 'Coincident' | 'Parallel';\n\nexport class Intersection {\n declare points: Point[];\n\n declare status?: IntersectionType;\n\n constructor(status?: IntersectionType) {\n this.status = status;\n this.points = [];\n }\n\n /**\n * Used to verify if a point is alredy in the collection\n * @param {Point} point\n * @returns {boolean}\n */\n private includes(point: Point): boolean {\n return this.points.some((p) => p.eq(point));\n }\n\n /**\n * Appends points of intersection\n * @param {...Point[]} points\n * @return {Intersection} thisArg\n * @chainable\n */\n private append(...points: Point[]): Intersection {\n this.points = this.points.concat(\n points.filter((point) => {\n return !this.includes(point);\n }),\n );\n return this;\n }\n\n /**\n * check if point T is on the segment or line defined between A and B\n *\n * @param {Point} T the point we are checking for\n * @param {Point} A one extremity of the segment\n * @param {Point} B the other extremity of the segment\n * @param [infinite] if true checks if `T` is on the line defined by `A` and `B`\n * @returns true if `T` is contained\n */\n static isPointContained(T: Point, A: Point, B: Point, infinite = false) {\n if (A.eq(B)) {\n // Edge case: the segment is a point, we check for coincidence,\n // infinite param has no meaning because there are infinite lines to consider\n return T.eq(A);\n } else if (A.x === B.x) {\n // Edge case: horizontal line.\n // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y\n return (\n T.x === A.x &&\n (infinite || (T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)))\n );\n } else if (A.y === B.y) {\n // Edge case: vertical line.\n // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x\n return (\n T.y === A.y &&\n (infinite || (T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)))\n );\n } else {\n // Generic case: sloped line.\n // we check that AT has the same slope as AB\n // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size\n // for the infinite case we check the absolute value of the slope, since direction is meaningless\n const AB = createVector(A, B);\n const AT = createVector(A, T);\n const s = AT.divide(AB);\n return infinite\n ? Math.abs(s.x) === Math.abs(s.y)\n : s.x === s.y && s.x >= 0 && s.x <= 1;\n }\n }\n\n /**\n * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points}\n * @see https://en.wikipedia.org/wiki/Point_in_polygon\n * @param point\n * @param points polygon points\n * @returns\n */\n static isPointInPolygon(point: Point, points: Point[]) {\n const other = new Point(point).setX(\n Math.min(point.x - 1, ...points.map((p) => p.x)),\n );\n let hits = 0;\n for (let index = 0; index < points.length; index++) {\n const inter = this.intersectSegmentSegment(\n // polygon side\n points[index],\n points[(index + 1) % points.length],\n // ray\n point,\n other,\n );\n if (inter.includes(point)) {\n // point is on the polygon side\n return true;\n }\n hits += Number(inter.status === 'Intersection');\n }\n return hits % 2 === 1;\n }\n\n /**\n * Checks if a line intersects another\n * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection}\n * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule}\n * @static\n * @param {Point} a1\n * @param {Point} a2\n * @param {Point} b1\n * @param {Point} b2\n * @param {boolean} [aInfinite=true] check segment intersection by passing `false`\n * @param {boolean} [bInfinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLineLine(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n aInfinite = true,\n bInfinite = true,\n ): Intersection {\n const a2xa1x = a2.x - a1.x,\n a2ya1y = a2.y - a1.y,\n b2xb1x = b2.x - b1.x,\n b2yb1y = b2.y - b1.y,\n a1xb1x = a1.x - b1.x,\n a1yb1y = a1.y - b1.y,\n uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x,\n ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x,\n uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y;\n if (uB !== 0) {\n const ua = uaT / uB,\n ub = ubT / uB;\n if (\n (aInfinite || (0 <= ua && ua <= 1)) &&\n (bInfinite || (0 <= ub && ub <= 1))\n ) {\n return new Intersection('Intersection').append(\n new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y),\n );\n } else {\n return new Intersection();\n }\n } else {\n if (uaT === 0 || ubT === 0) {\n const segmentsCoincide =\n aInfinite ||\n bInfinite ||\n Intersection.isPointContained(a1, b1, b2) ||\n Intersection.isPointContained(a2, b1, b2) ||\n Intersection.isPointContained(b1, a1, a2) ||\n Intersection.isPointContained(b2, a1, a2);\n return new Intersection(segmentsCoincide ? 'Coincident' : undefined);\n } else {\n return new Intersection('Parallel');\n }\n }\n }\n\n /**\n * Checks if a segment intersects a line\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} s1 boundary point of segment\n * @param {Point} s2 other boundary point of segment\n * @param {Point} l1 point on line\n * @param {Point} l2 other point on line\n * @return {Intersection}\n */\n static intersectSegmentLine(\n s1: Point,\n s2: Point,\n l1: Point,\n l2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(s1, s2, l1, l2, false, true);\n }\n\n /**\n * Checks if a segment intersects another\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point} b1 boundary point of segment\n * @param {Point} b2 other boundary point of segment\n * @return {Intersection}\n */\n static intersectSegmentSegment(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(a1, a2, b1, b2, false, false);\n }\n\n /**\n * Checks if line intersects polygon\n *\n * @todo account for stroke\n *\n * @static\n * @see {@link intersectSegmentPolygon} for segment intersection\n * @param {Point} a1 point on line\n * @param {Point} a2 other point on line\n * @param {Point[]} points polygon points\n * @param {boolean} [infinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLinePolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n infinite = true,\n ): Intersection {\n const result = new Intersection();\n const length = points.length;\n\n for (let i = 0, b1, b2, inter; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false);\n if (inter.status === 'Coincident') {\n return inter;\n }\n result.append(...inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if segment intersects polygon\n * @static\n * @see {@link intersectLinePolygon} for line intersection\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point[]} points polygon points\n * @return {Intersection}\n */\n static intersectSegmentPolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n ): Intersection {\n return Intersection.intersectLinePolygon(a1, a2, points, false);\n }\n\n /**\n * Checks if polygon intersects another polygon\n *\n * @todo account for stroke\n *\n * @static\n * @param {Point[]} points1\n * @param {Point[]} points2\n * @return {Intersection}\n */\n static intersectPolygonPolygon(\n points1: Point[],\n points2: Point[],\n ): Intersection {\n const result = new Intersection(),\n length = points1.length;\n const coincidences: Intersection[] = [];\n\n for (let i = 0; i < length; i++) {\n const a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectSegmentPolygon(a1, a2, points2);\n if (inter.status === 'Coincident') {\n coincidences.push(inter);\n result.append(a1, a2);\n } else {\n result.append(...inter.points);\n }\n }\n\n if (coincidences.length > 0 && coincidences.length === points1.length) {\n return new Intersection('Coincident');\n } else if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @see {@link intersectPolygonPolygon} for polygon intersection\n * @param {Point[]} points polygon points\n * @param {Point} r1 top left point of rect\n * @param {Point} r2 bottom right point of rect\n * @return {Intersection}\n */\n static intersectPolygonRectangle(\n points: Point[],\n r1: Point,\n r2: Point,\n ): Intersection {\n const min = r1.min(r2),\n max = r1.max(r2),\n topRight = new Point(max.x, min.y),\n bottomLeft = new Point(min.x, max.y);\n\n return Intersection.intersectPolygonPolygon(points, [\n min,\n topRight,\n max,\n bottomLeft,\n ]);\n }\n}\n","import type {\n TBBox,\n TCornerPoint,\n TDegree,\n TMat2D,\n TOriginX,\n TOriginY,\n} from '../../typedefs';\nimport { SCALE_X, SCALE_Y, iMatrix } from '../../constants';\nimport { Intersection } from '../../Intersection';\nimport { Point } from '../../Point';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n createRotateMatrix,\n createTranslateMatrix,\n composeMatrix,\n invertTransform,\n multiplyTransformMatrices,\n transformPoint,\n calcPlaneRotation,\n} from '../../util/misc/matrix';\nimport { radiansToDegrees } from '../../util/misc/radiansDegreesConversion';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type { ControlProps } from './types/ControlProps';\nimport { resolveOrigin } from '../../util/misc/resolveOrigin';\nimport type { Group } from '../Group';\nimport { calcDimensionsMatrix } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport { CommonMethods } from '../../CommonMethods';\nimport type { BaseProps } from './types/BaseProps';\nimport type { FillStrokeProps } from './types/FillStrokeProps';\nimport { CENTER, LEFT, TOP } from '../../constants';\n\ntype TMatrixCache = {\n key: number[];\n value: TMat2D;\n};\n\ntype TACoords = TCornerPoint;\n\nexport class ObjectGeometry\n extends CommonMethods\n implements\n Pick,\n BaseProps,\n Pick\n{\n // #region Geometry\n\n declare padding: number;\n\n /**\n * Describe object's corner position in scene coordinates.\n * The coordinates are derived from the following:\n * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth.\n * The coordinates do not depend on viewport changes.\n * The coordinates get updated with {@link setCoords}.\n * You can calculate them without updating with {@link calcACoords()}\n */\n declare aCoords: TACoords;\n\n /**\n * storage cache for object transform matrix\n */\n declare ownMatrixCache?: TMatrixCache;\n\n /**\n * storage cache for object full transform matrix\n */\n declare matrixCache?: TMatrixCache;\n\n /**\n * A Reference of the Canvas where the object is actually added\n * @type StaticCanvas | Canvas;\n * @default undefined\n * @private\n */\n declare canvas?: StaticCanvas | Canvas;\n\n /**\n * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane\n */\n getX(): number {\n return this.getXY().x;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane\n */\n setX(value: number) {\n this.setXY(this.getXY().setX(value));\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane\n */\n getY(): number {\n return this.getXY().y;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane\n */\n setY(value: number) {\n this.setXY(this.getXY().setY(value));\n }\n\n /**\n * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getX}\n */\n getRelativeX(): number {\n return this.left;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this method is identical to {@link setX}\n */\n setRelativeX(value: number) {\n this.left = value;\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getY}\n */\n getRelativeY(): number {\n return this.top;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link setY}\n */\n setRelativeY(value: number) {\n this.top = value;\n }\n\n /**\n * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane\n */\n getXY(): Point {\n const relativePosition = this.getRelativeXY();\n return this.group\n ? transformPoint(relativePosition, this.group.calcTransformMatrix())\n : relativePosition;\n }\n\n /**\n * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate.\n * You can specify {@link originX} and {@link originY} values,\n * that otherwise are the object's current values.\n * @example Set object's bottom left corner to point (5,5) on canvas\n * object.setXY(new Point(5, 5), 'left', 'bottom').\n * @param {Point} point position in scene coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setXY(point: Point, originX?: TOriginX, originY?: TOriginY) {\n if (this.group) {\n point = transformPoint(\n point,\n invertTransform(this.group.calcTransformMatrix()),\n );\n }\n this.setRelativeXY(point, originX, originY);\n }\n\n /**\n * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n */\n getRelativeXY(): Point {\n return new Point(this.left, this.top);\n }\n\n /**\n * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas)\n * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setRelativeXY(\n point: Point,\n originX: TOriginX = this.originX,\n originY: TOriginY = this.originY,\n ) {\n this.setPositionByOrigin(point, originX, originY);\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return false;\n }\n\n /**\n * @return {Point[]} [tl, tr, br, bl] in the scene plane\n */\n getCoords(): Point[] {\n const { tl, tr, br, bl } =\n this.aCoords || (this.aCoords = this.calcACoords());\n const coords = [tl, tr, br, bl];\n if (this.group) {\n const t = this.group.calcTransformMatrix();\n return coords.map((p) => transformPoint(p, t));\n }\n return coords;\n }\n\n /**\n * Checks if object intersects with the scene rect formed by {@link tl} and {@link br}\n */\n intersectsWithRect(tl: Point, br: Point): boolean {\n const intersection = Intersection.intersectPolygonRectangle(\n this.getCoords(),\n tl,\n br,\n );\n return intersection.status === 'Intersection';\n }\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject(other: ObjectGeometry): boolean {\n const intersection = Intersection.intersectPolygonPolygon(\n this.getCoords(),\n other.getCoords(),\n );\n\n return (\n intersection.status === 'Intersection' ||\n intersection.status === 'Coincident' ||\n other.isContainedWithinObject(this) ||\n this.isContainedWithinObject(other)\n );\n }\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject(other: ObjectGeometry): boolean {\n const points = this.getCoords();\n return points.every((point) => other.containsPoint(point));\n }\n\n /**\n * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br}\n */\n isContainedWithinRect(tl: Point, br: Point): boolean {\n const { left, top, width, height } = this.getBoundingRect();\n return (\n left >= tl.x &&\n left + width <= br.x &&\n top >= tl.y &&\n top + height <= br.y\n );\n }\n\n isOverlapping(other: T): boolean {\n return (\n this.intersectsWithObject(other) ||\n this.isContainedWithinObject(other) ||\n other.isContainedWithinObject(this)\n );\n }\n\n /**\n * Checks if point is inside the object\n * @param {Point} point Point to check against\n * @return {Boolean} true if point is inside the object\n */\n containsPoint(point: Point): boolean {\n return Intersection.isPointInPolygon(point, this.getCoords());\n }\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n const points = this.getCoords();\n // if some point is on screen, the object is on screen.\n if (\n points.some(\n (point) =>\n point.x <= br.x &&\n point.x >= tl.x &&\n point.y <= br.y &&\n point.y >= tl.y,\n )\n ) {\n return true;\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n // check if the object is so big that it contains the entire viewport\n return this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n const allPointsAreOutside = this.getCoords().every(\n (point) =>\n (point.x >= br.x || point.x <= tl.x) &&\n (point.y >= br.y || point.y <= tl.y),\n );\n // check if the object is so big that it contains the entire viewport\n return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect(): TBBox {\n return makeBoundingBoxFromPoints(this.getCoords());\n }\n\n /**\n * Returns width of an object's bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} width value\n */\n getScaledWidth(): number {\n return this._getTransformedDimensions().x;\n }\n\n /**\n * Returns height of an object bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} height value\n */\n getScaledHeight(): number {\n return this._getTransformedDimensions().y;\n }\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {void}\n */\n scale(value: number): void {\n this._set(SCALE_X, value);\n this._set(SCALE_Y, value);\n this.setCoords();\n }\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {void}\n */\n scaleToWidth(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n }\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {void}\n */\n scaleToHeight(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n }\n\n getCanvasRetinaScaling() {\n return this.canvas?.getRetinaScaling() || 1;\n }\n\n /**\n * Returns the object angle relative to canvas counting also the group property\n * @returns {TDegree}\n */\n getTotalAngle(): TDegree {\n return this.group\n ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix()))\n : this.angle;\n }\n\n /**\n * Retrieves viewportTransform from Object's canvas if available\n * @return {TMat2D}\n */\n getViewportTransform(): TMat2D {\n return this.canvas?.viewportTransform || (iMatrix.concat() as TMat2D);\n }\n\n /**\n * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates.\n * those never change with zoom or viewport changes.\n * @return {TCornerPoint}\n */\n calcACoords(): TCornerPoint {\n const rotateMatrix = createRotateMatrix({ angle: this.angle }),\n { x, y } = this.getRelativeCenterPoint(),\n tMatrix = createTranslateMatrix(x, y),\n finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n return {\n // corners\n tl: transformPoint({ x: -w, y: -h }, finalMatrix),\n tr: transformPoint({ x: w, y: -h }, finalMatrix),\n bl: transformPoint({ x: -w, y: h }, finalMatrix),\n br: transformPoint({ x: w, y: h }, finalMatrix),\n };\n }\n\n /**\n * Sets corner and controls position coordinates based on current angle, width and height, left and top.\n * aCoords are used to quickly find an object on the canvas.\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n */\n setCoords(): void {\n this.aCoords = this.calcACoords();\n }\n\n transformMatrixKey(skipGroup = false): number[] {\n let prefix: number[] = [];\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup);\n }\n prefix.push(\n this.top,\n this.left,\n this.width,\n this.height,\n this.scaleX,\n this.scaleY,\n this.angle,\n this.strokeWidth,\n this.skewX,\n this.skewY,\n +this.flipX,\n +this.flipY,\n resolveOrigin(this.originX),\n resolveOrigin(this.originY),\n );\n\n return prefix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {TMat2D} transform matrix for the object\n */\n calcTransformMatrix(skipGroup = false): TMat2D {\n let matrix = this.calcOwnMatrix();\n if (skipGroup || !this.group) {\n return matrix;\n }\n const key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache;\n if (cache && cache.key.every((x, i) => x === key[i])) {\n return cache.value;\n }\n if (this.group) {\n matrix = multiplyTransformMatrices(\n this.group.calcTransformMatrix(false),\n matrix,\n );\n }\n this.matrixCache = {\n key,\n value: matrix,\n };\n return matrix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {TMat2D} transform matrix for the object\n */\n calcOwnMatrix(): TMat2D {\n const key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache;\n if (cache && cache.key === key) {\n return cache.value;\n }\n const center = this.getRelativeCenterPoint(),\n options = {\n angle: this.angle,\n translateX: center.x,\n translateY: center.y,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY,\n },\n value = composeMatrix(options);\n this.ownMatrixCache = {\n key,\n value,\n };\n return value;\n }\n\n /**\n * Calculate object dimensions from its properties\n * @private\n * @returns {Point} dimensions\n */\n _getNonTransformedDimensions(): Point {\n return new Point(this.width, this.height).scalarAdd(this.strokeWidth);\n }\n\n /**\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * @private\n * @param {object} [options] transform options\n * @returns {Point} dimensions\n */\n _calculateCurrentDimensions(options?: any): Point {\n return this._getTransformedDimensions(options)\n .transform(this.getViewportTransform(), true)\n .scalarAdd(2 * this.padding);\n }\n\n // #region Origin\n\n declare top: number;\n declare left: number;\n declare width: number;\n declare height: number;\n declare flipX: boolean;\n declare flipY: boolean;\n declare scaleX: number;\n declare scaleY: number;\n declare skewX: number;\n declare skewY: number;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originX: TOriginX;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originY: TOriginY;\n declare angle: TDegree;\n declare strokeWidth: number;\n declare strokeUniform: boolean;\n\n /**\n * Object containing this object.\n * can influence its size and position\n */\n declare group?: Group;\n\n /**\n * Calculate object bounding box dimensions from its properties scale, skew.\n * This bounding box is aligned with object angle and not with canvas axis or screen.\n * @param {Object} [options]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @private\n * @returns {Point} dimensions\n */\n _getTransformedDimensions(options: any = {}): Point {\n const dimOptions = {\n // if scaleX or scaleY are negative numbers,\n // this will return dimensions that are negative.\n // and this will break assumptions around the codebase\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n width: this.width,\n height: this.height,\n strokeWidth: this.strokeWidth,\n ...options,\n };\n // stroke is applied before/after transformations are applied according to `strokeUniform`\n const strokeWidth = dimOptions.strokeWidth;\n let preScalingStrokeValue = strokeWidth,\n postScalingStrokeValue = 0;\n\n if (this.strokeUniform) {\n preScalingStrokeValue = 0;\n postScalingStrokeValue = strokeWidth;\n }\n const dimX = dimOptions.width + preScalingStrokeValue,\n dimY = dimOptions.height + preScalingStrokeValue,\n noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0;\n let finalDimensions;\n if (noSkew) {\n finalDimensions = new Point(\n dimX * dimOptions.scaleX,\n dimY * dimOptions.scaleY,\n );\n } else {\n finalDimensions = sizeAfterTransform(\n dimX,\n dimY,\n calcDimensionsMatrix(dimOptions),\n );\n }\n\n return finalDimensions.scalarAdd(postScalingStrokeValue);\n }\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToGivenOrigin(\n point: Point,\n fromOriginX: TOriginX,\n fromOriginY: TOriginY,\n toOriginX: TOriginX,\n toOriginY: TOriginY,\n ): Point {\n let x = point.x,\n y = point.y;\n const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX),\n offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY);\n\n if (offsetX || offsetY) {\n const dim = this._getTransformedDimensions();\n x += offsetX * dim.x;\n y += offsetY * dim.y;\n }\n\n return new Point(x, y);\n }\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToCenterPoint(\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n if (originX === CENTER && originY === CENTER) {\n return point;\n }\n const p = this.translateToGivenOrigin(\n point,\n originX,\n originY,\n CENTER,\n CENTER,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), point);\n }\n return p;\n }\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {Point} center The point which corresponds to center of the object\n * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToOriginPoint(\n center: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n const p = this.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), center);\n }\n return p;\n }\n\n /**\n * Returns the center coordinates of the object relative to canvas\n * @return {Point}\n */\n getCenterPoint(): Point {\n const relCenter = this.getRelativeCenterPoint();\n return this.group\n ? transformPoint(relCenter, this.group.calcTransformMatrix())\n : relCenter;\n }\n\n /**\n * Returns the center coordinates of the object relative to it's parent\n * @return {Point}\n */\n getRelativeCenterPoint(): Point {\n return this.translateToCenterPoint(\n new Point(this.left, this.top),\n this.originX,\n this.originY,\n );\n }\n\n /**\n * Returns the position of the object as if it has a different origin.\n * Take an object that has left, top set to 100, 100 with origin 'left', 'top'.\n * Return the values of left top ( wrapped in a point ) that you would need to keep\n * the same position if origin where different.\n * Alternatively you can use this to also find which point in the parent plane is a specific origin\n * ( where is the bottom right corner of my object? )\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n getPointByOrigin(originX: TOriginX, originY: TOriginY): Point {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n }\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {Point} pos The new position of the object\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin(pos: Point, originX: TOriginX, originY: TOriginY) {\n const center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(\n center,\n this.originX,\n this.originY,\n );\n this.set({ left: position.x, top: position.y });\n }\n\n /**\n * @private\n */\n _getLeftTopCoords() {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n LEFT,\n TOP,\n );\n }\n}\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport {\n ALIASING_LIMIT,\n CENTER,\n iMatrix,\n LEFT,\n SCALE_X,\n SCALE_Y,\n STROKE,\n FILL,\n TOP,\n VERSION,\n} from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport { Shadow } from '../../Shadow';\nimport type {\n TDegree,\n TFiller,\n TSize,\n TCacheCanvasDimensions,\n Abortable,\n TOptions,\n ImageFormat,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { runningAnimations } from '../../util/animation/AnimationRegistry';\nimport { capValue } from '../../util/misc/capValue';\nimport { createCanvasElement, toDataURL } from '../../util/misc/dom';\nimport { invertTransform, qrDecompose } from '../../util/misc/matrix';\nimport { enlivenObjectEnlivables } from '../../util/misc/objectEnlive';\nimport {\n resetObjectTransform,\n saveObjectTransform,\n} from '../../util/misc/objectTransforms';\nimport { sendObjectToPlane } from '../../util/misc/planeChange';\nimport { pick, pickBy } from '../../util/misc/pick';\nimport { toFixed } from '../../util/misc/toFixed';\nimport type { Group } from '../Group';\nimport { StaticCanvas } from '../../canvas/StaticCanvas';\nimport {\n isFiller,\n isSerializableFiller,\n isTextObject,\n} from '../../util/typeAssertions';\nimport type { FabricImage } from '../Image';\nimport {\n cacheProperties,\n fabricObjectDefaultValues,\n stateProperties,\n} from './defaultValues';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { SerializedObjectProps } from './types/SerializedObjectProps';\nimport type { ObjectProps } from './types/ObjectProps';\nimport { getDevicePixelRatio, getEnv } from '../../env';\nimport { log } from '../../util/internals/console';\nimport type { TColorArg } from '../../color/typedefs';\nimport type { TAnimation } from '../../util/animation/animate';\nimport { animate, animateColor } from '../../util/animation/animate';\nimport type {\n AnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n ValueAnimationOptions,\n} from '../../util/animation/types';\nimport { ObjectGeometry } from './ObjectGeometry';\n\ntype TAncestor = FabricObject;\ntype TCollection = Group;\n\nexport type Ancestors =\n | [FabricObject | Group]\n | [FabricObject | Group, ...Group[]]\n | Group[];\n\nexport type AncestryComparison = {\n /**\n * common ancestors of `this` and`other`(may include`this` | `other`)\n */\n common: Ancestors;\n /**\n * ancestors that are of `this` only\n */\n fork: Ancestors;\n /**\n * ancestors that are of `other` only\n */\n otherFork: Ancestors;\n};\n\nexport type TCachedFabricObject = T &\n Required<\n Pick<\n T,\n | 'zoomX'\n | 'zoomY'\n | '_cacheCanvas'\n | '_cacheContext'\n | 'cacheTranslationX'\n | 'cacheTranslationY'\n >\n > & {\n _cacheContext: CanvasRenderingContext2D;\n };\n\nexport type ObjectToCanvasElementOptions = {\n format?: ImageFormat;\n /** Multiplier to scale by */\n multiplier?: number;\n /** Cropping left offset. Introduced in v1.2.14 */\n left?: number;\n /** Cropping top offset. Introduced in v1.2.14 */\n top?: number;\n /** Cropping width. Introduced in v1.2.14 */\n width?: number;\n /** Cropping height. Introduced in v1.2.14 */\n height?: number;\n /** Enable retina scaling for clone image. Introduce in 1.6.4 */\n enableRetinaScaling?: boolean;\n /** Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 */\n withoutTransform?: boolean;\n /** Remove current object shadow. Introduced in 2.4.2 */\n withoutShadow?: boolean;\n /** Account for canvas viewport transform */\n viewportTransform?: boolean;\n /** Function to create the output canvas to export onto */\n canvasProvider?: (el?: HTMLCanvasElement) => T;\n};\n\ntype toDataURLOptions = ObjectToCanvasElementOptions & {\n quality?: number;\n};\n\n/**\n * Root object class from which all 2d shape classes inherit from\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n * @fires modified\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\nexport class FabricObject<\n Props extends TOptions = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends ObjectGeometry\n implements ObjectProps\n{\n declare minScaleLimit: number;\n\n declare opacity: number;\n\n declare paintFirst: 'fill' | 'stroke';\n declare fill: string | TFiller | null;\n declare fillRule: CanvasFillRule;\n declare stroke: string | TFiller | null;\n declare strokeDashArray: number[] | null;\n declare strokeDashOffset: number;\n declare strokeLineCap: CanvasLineCap;\n declare strokeLineJoin: CanvasLineJoin;\n declare strokeMiterLimit: number;\n\n declare globalCompositeOperation: GlobalCompositeOperation;\n declare backgroundColor: string;\n\n declare shadow: Shadow | null;\n\n declare visible: boolean;\n\n declare includeDefaultValues: boolean;\n declare excludeFromExport: boolean;\n\n declare objectCaching: boolean;\n\n declare clipPath?: FabricObject;\n declare inverted: boolean;\n declare absolutePositioned: boolean;\n declare centeredRotation: boolean;\n declare centeredScaling: boolean;\n\n /**\n * This list of properties is used to check if the state of an object is changed.\n * This state change now is only used for children of groups to understand if a group\n * needs its cache regenerated during a .set call\n * @type Array\n */\n static stateProperties: string[] = stateProperties;\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n static cacheProperties: string[] = cacheProperties;\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n declare dirty: boolean;\n\n /**\n * Quick access for the _cacheCanvas rendering context\n * This is part of the objectCaching feature\n * since 1.7.0\n * @type boolean\n * @default undefined\n * @private\n */\n _cacheContext: CanvasRenderingContext2D | null = null;\n\n /**\n * A reference to the HTMLCanvasElement that is used to contain the cache of the object\n * this canvas element is resized and cleared as needed\n * Is marked private, you can read it, don't use it since it is handled by fabric\n * since 1.7.0\n * @type HTMLCanvasElement\n * @default undefined\n * @private\n */\n declare _cacheCanvas?: HTMLCanvasElement;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, X axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomX?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomY?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationX?: number;\n\n /**\n * translation of the cacheCanvas away from the center, for subpixel accuracy and crispness\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationY?: number;\n\n /**\n * A reference to the parent of the object, usually a Group\n * @type number\n * @default undefined\n * @private\n */\n declare group?: Group;\n\n /**\n * Indicate if the object is sitting on a cache dedicated to it\n * or is part of a larger cache for many object ( a group for example)\n * @type number\n * @default undefined\n * @private\n */\n declare ownCaching?: boolean;\n\n /**\n * Private. indicates if the object inside a group is on a transformed context or not\n * or is part of a larger cache for many object ( a group for example)\n * @type boolean\n * @default undefined\n * @private\n */\n declare _transformDone?: boolean;\n\n static ownDefaults = fabricObjectDefaultValues;\n\n static getDefaults(): Record {\n return FabricObject.ownDefaults;\n }\n\n /**\n * The class type.\n * This is used for serialization and deserialization purposes and internally it can be used\n * to identify classes.\n * When we transform a class in a plain JS object we need a way to recognize which class it was,\n * and the type is the way we do that. It has no other purposes and you should not give one.\n * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type).\n * To idenfity a class use instanceof class ( instanceof Rect ).\n * We do not do that in fabricJS code because we want to try to have code splitting possible.\n */\n static type = 'FabricObject';\n\n /**\n * Legacy identifier of the class. Prefer using utils like isType or instanceOf\n * Will be removed in fabric 7 or 8.\n * The setter exists to avoid type errors in old code and possibly current deserialization code.\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n const name = (this.constructor as typeof FabricObject).type;\n if (name === 'FabricObject') {\n return 'object';\n }\n return name.toLowerCase();\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, FabricObject.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas() {\n this._cacheCanvas = createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n }\n\n /**\n * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize(\n dims: TSize & { zoomX: number; zoomY: number; capped: boolean } & any,\n ) {\n const width = dims.width,\n height = dims.height,\n max = config.maxCacheSideLimit,\n min = config.minCacheSideLimit;\n if (\n width <= max &&\n height <= max &&\n width * height <= config.perfLimitSizeTotal\n ) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n const ar = width / height,\n [limX, limY] = cache.limitDimsByArea(ar),\n x = capValue(min, limX, max),\n y = capValue(min, limY, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const objectScale = this.getTotalObjectScaling(),\n // calculate dimensions without skewing\n dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),\n neededX = (dim.x * objectScale.x) / this.scaleX,\n neededY = (dim.y * objectScale.y) / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.x,\n zoomY: objectScale.y,\n x: neededX,\n y: neededY,\n };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const canvas = this._cacheCanvas!,\n context = this._cacheContext,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = config.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n zoomX = dims.zoomX,\n zoomY = dims.zoomY,\n dimensionsChanged = width !== canvas.width || height !== canvas.height,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY;\n\n if (!canvas || !context) {\n return false;\n }\n\n let drawingWidth,\n drawingHeight,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\n if (dimensionsChanged) {\n const canvasWidth = (this._cacheCanvas as HTMLCanvasElement).width,\n canvasHeight = (this._cacheCanvas as HTMLCanvasElement).height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking =\n (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize &&\n canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (\n sizeGrowing &&\n !dims.capped &&\n (width > minCacheSize || height > minCacheSize)\n ) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (isTextObject(this) && this.path) {\n shouldRedraw = true;\n shouldResizeCanvas = true;\n // IMHO in those lines we are using zoomX and zoomY not the this version.\n additionalWidth += this.getHeightOfLine(0) * this.zoomX!;\n additionalHeight += this.getHeightOfLine(0) * this.zoomY!;\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX =\n Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY =\n Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n context.translate(this.cacheTranslationX, this.cacheTranslationY);\n context.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n }\n\n /**\n * Sets object's properties from options, for class constructor only.\n * Needs to be overridden for different defaults.\n * @protected\n * @param {Object} [options] Options object\n */\n protected setOptions(options: Record = {}) {\n this._setOptions(options);\n }\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform(ctx: CanvasRenderingContext2D) {\n const needFullTransform =\n (this.group && !this.group._transformDone) ||\n (this.group && this.canvas && ctx === (this.canvas as Canvas).contextTop);\n const m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Point}\n */\n getObjectScaling() {\n // if the object is a top level one, on the canvas, we go for simple aritmetic\n // otherwise the complex method with angles will return approximations and decimals\n // and will likely kill the cache when not needed\n // https://github.com/fabricjs/fabric.js/issues/7157\n if (!this.group) {\n return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY));\n }\n // if we are inside a group total zoom calculation is complex, we defer to generic matrices\n const options = qrDecompose(this.calcTransformMatrix());\n return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY));\n }\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling() {\n const scale = this.getObjectScaling();\n if (this.canvas) {\n const zoom = this.canvas.getZoom();\n const retina = this.getCanvasRetinaScaling();\n return scale.scalarMultiply(zoom * retina);\n }\n return scale;\n }\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity() {\n let opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n }\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @todo: this is a control action issue, not a geometry one\n * @private\n * @param {Number} value, unconstrained\n * @return {Number} constrained value;\n */\n _constrainScale(value: number): number {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\n return value;\n }\n\n /**\n * Handles setting values on the instance and handling internal side effects\n * @protected\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (key === SCALE_X || key === SCALE_Y) {\n value = this._constrainScale(value);\n }\n if (key === SCALE_X && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n // i don't like this automatic initialization here\n } else if (key === 'shadow' && value && !(value instanceof Shadow)) {\n value = new Shadow(value);\n }\n\n const isChanged = this[key as keyof this] !== value;\n this[key as keyof this] = value;\n\n // invalidate caches\n if (\n isChanged &&\n (this.constructor as typeof FabricObject).cacheProperties.includes(key)\n ) {\n this.dirty = true;\n }\n // a dirty child makes the parent dirty.\n // but a non dirty child does not make the parent not dirty.\n // the parent could be dirty for some other reason.\n this.parent &&\n (this.dirty ||\n (isChanged &&\n (this.constructor as typeof FabricObject).stateProperties.includes(\n key,\n ))) &&\n this.parent._set('dirty', true);\n\n return this;\n }\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf FabricObject.prototype\n * @return {Boolean}\n */\n isNotVisible() {\n return (\n this.opacity === 0 ||\n (!this.width && !this.height && this.strokeWidth === 0) ||\n !this.visible\n );\n }\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.shouldCache()) {\n this.renderCache();\n (this as TCachedFabricObject).drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n this.drawObject(ctx);\n this.dirty = false;\n }\n ctx.restore();\n }\n\n drawSelectionBackground(_ctx: CanvasRenderingContext2D) {\n /* no op */\n }\n\n renderCache(options?: any) {\n options = options || {};\n if (!this._cacheCanvas || !this._cacheContext) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty() && this._cacheContext) {\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n }\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas() {\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke() {\n return (\n this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0\n );\n }\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill() {\n return this.fill && this.fill !== 'transparent';\n }\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache() {\n if (\n this.paintFirst === STROKE &&\n this.hasFill() &&\n this.hasStroke() &&\n !!this.shadow\n ) {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache() {\n this.ownCaching =\n this.needsItsOwnCache() ||\n (this.objectCaching && (!this.parent || !this.parent.isOnACache()));\n return this.ownCaching;\n }\n\n /**\n * Check if this object will cast a shadow with an offset.\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n * @deprecated\n */\n willDrawShadow() {\n return (\n !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0)\n );\n }\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {FabricObject} clipPath\n */\n drawClipPathOnCache(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (clipPath.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (clipPath.absolutePositioned) {\n const m = invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {boolean} forClipping apply clipping styles\n */\n drawObject(ctx: CanvasRenderingContext2D, forClipping?: boolean) {\n const originalFill = this.fill,\n originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n }\n this._render(ctx);\n this._drawClipPath(ctx, this.clipPath);\n this.fill = originalFill;\n this.stroke = originalStroke;\n }\n\n /**\n * Prepare clipPath state and cache and draw it on instance's cache\n * @param {CanvasRenderingContext2D} ctx\n * @param {FabricObject} clipPath\n */\n _drawClipPath(ctx: CanvasRenderingContext2D, clipPath?: FabricObject) {\n if (!clipPath) {\n return;\n }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n clipPath._set('canvas', this.canvas);\n clipPath.shouldCache();\n clipPath._transformDone = true;\n clipPath.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx, clipPath as TCachedFabricObject);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(this: TCachedFabricObject, ctx: CanvasRenderingContext2D) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(\n this._cacheCanvas,\n -this.cacheTranslationX,\n -this.cacheTranslationY,\n );\n }\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty(skipCanvas = false) {\n if (this.isNotVisible()) {\n return false;\n }\n const canvas = this._cacheCanvas;\n const ctx = this._cacheContext;\n if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned)) {\n if (canvas && ctx && !skipCanvas) {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n }\n return true;\n }\n }\n return false;\n }\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n if (!this.backgroundColor) {\n return;\n }\n const dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y);\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity(ctx: CanvasRenderingContext2D) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n }\n\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n decl: Pick<\n this,\n | 'stroke'\n | 'strokeWidth'\n | 'strokeLineCap'\n | 'strokeDashOffset'\n | 'strokeLineJoin'\n | 'strokeMiterLimit'\n >,\n ) {\n const stroke = decl.stroke;\n if (stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n if (isFiller(stroke)) {\n if (\n (stroke as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (stroke as Gradient<'linear'>).gradientTransform ||\n (stroke as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, stroke);\n } else {\n // is a simple gradient or pattern\n ctx.strokeStyle = stroke.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, stroke);\n }\n } else {\n // is a color\n ctx.strokeStyle = decl.stroke as string;\n }\n }\n }\n\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n if (fill) {\n if (isFiller(fill)) {\n ctx.fillStyle = fill.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, fill);\n } else {\n ctx.fillStyle = fill;\n }\n }\n }\n\n _setClippingProperties(ctx: CanvasRenderingContext2D) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n }\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n */\n _setLineDash(ctx: CanvasRenderingContext2D, dashArray?: number[] | null) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies of the dash array when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push(...dashArray);\n }\n ctx.setLineDash(dashArray);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n const shadow = this.shadow,\n canvas = this.canvas,\n retinaScaling = this.getCanvasRetinaScaling(),\n [sx, , , sy] = canvas?.viewportTransform || iMatrix,\n multX = sx * retinaScaling,\n multY = sy * retinaScaling,\n scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling();\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur =\n (shadow.blur *\n config.browserShadowBlurConstant *\n (multX + multY) *\n (scaling.x + scaling.y)) /\n 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TFiller} filler {@link Pattern} or {@link Gradient}\n */\n _applyPatternGradientTransform(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n if (!isFiller(filler)) {\n return { offsetX: 0, offsetY: 0 };\n }\n const t =\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform;\n const offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if ((filler as Gradient<'linear'>).gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n }\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} _ctx Context to render on\n */\n _render(_ctx: CanvasRenderingContext2D) {\n // placeholder to be overridden\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._setFillStyles(ctx, this);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform) {\n const scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.x, 1 / scaling.y);\n }\n this._setLineDash(ctx, this.strokeDashArray);\n this._setStrokeStyles(ctx, this);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Gradient} filler\n */\n _applyPatternForTransformedGradient(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n const dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = createCanvasElement(),\n retinaScaling = this.getCanvasRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n // in case width and height are less than 1px, we have to round up.\n // since the pattern is no-repeat, this is fine\n pCanvas.width = Math.ceil(width);\n pCanvas.height = Math.ceil(height);\n const pCtx = pCanvas.getContext('2d');\n if (!pCtx) {\n return;\n }\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling,\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx)!;\n pCtx.fill();\n ctx.translate(\n -this.width / 2 - this.strokeWidth / 2,\n -this.height / 2 - this.strokeWidth / 2,\n );\n ctx.scale(\n (retinaScaling * this.scaleX) / dims.zoomX,\n (retinaScaling * this.scaleY) / dims.zoomY,\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat') ?? '';\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement() {\n return new Point(this.left + this.width / 2, this.top + this.height / 2);\n }\n\n /**\n * Clones an instance.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {Promise}\n */\n clone(propertiesToInclude?: string[]): Promise {\n const objectForm = this.toObject(propertiesToInclude);\n return (this.constructor as typeof FabricObject).fromObject(\n objectForm,\n ) as unknown as Promise;\n }\n\n /**\n * Creates an instance of Image out of an object\n * makes use of toCanvasElement.\n * Once this method was based on toDataUrl and loadImage, so it also had a quality\n * and format option. toCanvasElement is faster and produce no loss of quality.\n * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.\n * toCanvasElement and then toBlob from the obtained canvas is also a good option.\n * @todo fix the export type, it could not be Image but the type that getClass return for 'image'.\n * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {FabricImage} Object cloned as image.\n */\n cloneAsImage(options: ObjectToCanvasElementOptions): FabricImage {\n const canvasEl = this.toCanvasElement(options);\n // TODO: how to import Image w/o an import cycle?\n const ImageClass = classRegistry.getClass('image');\n return new ImageClass(canvasEl);\n }\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {ObjectToCanvasElementOptions} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform\n * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas\n * @return {HTMLCanvasElement} Returns DOM element with the FabricObject\n */\n toCanvasElement(options: ObjectToCanvasElementOptions = {}) {\n const origParams = saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1,\n multiplier = (options.multiplier || 1) * retinaScaling,\n canvasProvider: (el: HTMLCanvasElement) => StaticCanvas =\n options.canvasProvider ||\n ((el: HTMLCanvasElement) =>\n new StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n }));\n delete this.group;\n if (options.withoutTransform) {\n resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n if (options.viewportTransform) {\n sendObjectToPlane(this, this.getViewportTransform());\n }\n\n this.setCoords();\n const el = createCanvasElement(),\n boundingRect = this.getBoundingRect(),\n shadow = this.shadow,\n shadowOffset = new Point();\n\n if (shadow) {\n const shadowBlur = shadow.blur;\n const scaling = shadow.nonScaling\n ? new Point(1, 1)\n : this.getObjectScaling();\n // consider non scaling shadow.\n shadowOffset.x =\n 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x);\n shadowOffset.y =\n 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y);\n }\n const width = boundingRect.width + shadowOffset.x,\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n const canvas = canvasProvider(el);\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(\n new Point(canvas.width / 2, canvas.height / 2),\n CENTER,\n CENTER,\n );\n const originalCanvas = this.canvas;\n // static canvas and canvas have both an array of InteractiveObjects\n // @ts-expect-error this needs to be fixed somehow, or ignored globally\n canvas._objects = [this];\n this.set('canvas', canvas);\n this.setCoords();\n const canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.set('canvas', originalCanvas);\n this.shadow = originalShadow;\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams);\n this.setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n // since render has settled it is safe to destroy canvas\n canvas.destroy();\n return canvasEl;\n }\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL(options: toDataURLOptions = {}) {\n return toDataURL(\n this.toCanvasElement(options),\n options.format || 'png',\n options.quality || 1,\n );\n }\n\n /**\n * Returns true if any of the specified types is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType(...types: string[]) {\n return (\n types.includes((this.constructor as typeof FabricObject).type) ||\n types.includes(this.type)\n );\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity() {\n return 1;\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {TDegree} angle Angle value (in degrees)\n */\n rotate(angle: TDegree) {\n const { centeredRotation, originX, originY } = this;\n\n if (centeredRotation) {\n const { x, y } = this.getRelativeCenterPoint();\n this.originX = CENTER;\n this.originY = CENTER;\n this.left = x;\n this.top = y;\n }\n\n this.set('angle', angle);\n\n if (centeredRotation) {\n const { x, y } = this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n this.left = x;\n this.top = y;\n this.originX = originX;\n this.originY = originY;\n }\n }\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup() {\n // implemented by sub-classes, as needed.\n }\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation(ctx: CanvasRenderingContext2D) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n\n /**\n * cancel instance's running animations\n * override if necessary to dispose artifacts such as `clipPath`\n */\n dispose() {\n runningAnimations.cancelByTarget(this);\n this.off();\n this._set('canvas', undefined);\n // clear caches\n this._cacheCanvas && getEnv().dispose(this._cacheCanvas);\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n // #region Animation methods\n /**\n * List of properties to consider for animating colors.\n * @type String[]\n */\n static colorProperties: string[] = [FILL, STROKE, 'backgroundColor'];\n\n /**\n * Animates object's properties\n * @param {Record} animatable map of keys and end values\n * @param {Partial>} options\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @return {Record>} map of animation contexts\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n */\n animate(\n animatable: Record,\n options?: Partial>,\n ): Record> {\n return Object.entries(animatable).reduce(\n (acc, [key, endValue]) => {\n acc[key] = this._animate(key, endValue, options);\n return acc;\n },\n {} as Record>,\n );\n }\n\n /**\n * @private\n * @param {String} key Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n */\n _animate(\n key: string,\n endValue: T,\n options: Partial> = {},\n ): TAnimation {\n const path = key.split('.');\n const propIsColor = (\n this.constructor as typeof FabricObject\n ).colorProperties.includes(path[path.length - 1]);\n const { abort, startValue, onChange, onComplete } = options;\n const animationOptions = {\n ...options,\n target: this,\n // path.reduce... is the current value in case start value isn't provided\n startValue:\n startValue ?? path.reduce((deep: any, key) => deep[key], this),\n endValue,\n abort: abort?.bind(this),\n onChange: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n path.reduce((deep: Record, key, index) => {\n if (index === path.length - 1) {\n deep[key] = value;\n }\n return deep[key];\n }, this);\n onChange &&\n // @ts-expect-error generic callback arg0 is wrong\n onChange(value, valueProgress, durationProgress);\n },\n onComplete: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n this.setCoords();\n onComplete &&\n // @ts-expect-error generic callback arg0 is wrong\n onComplete(value, valueProgress, durationProgress);\n },\n } as AnimationOptions;\n\n return (\n propIsColor\n ? animateColor(animationOptions as ColorAnimationOptions)\n : animate(\n animationOptions as ValueAnimationOptions | ArrayAnimationOptions,\n )\n ) as TAnimation;\n }\n\n // #region Object stacking methods\n\n /**\n * A reference to the parent of the object\n * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref\n */\n declare parent?: Group;\n\n /**\n * Checks if object is descendant of target\n * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons\n * @param {TAncestor} target\n * @returns {boolean}\n */\n isDescendantOf(target: TAncestor): boolean {\n const { parent, group } = this;\n return (\n parent === target ||\n group === target ||\n // walk up\n (!!parent && parent.isDescendantOf(target)) ||\n (!!group && group !== parent && group.isDescendantOf(target))\n );\n }\n\n /**\n * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top\n */\n getAncestors(): Ancestors {\n const ancestors: TAncestor[] = [];\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let parent: TAncestor | undefined = this;\n do {\n parent = parent.parent;\n parent && ancestors.push(parent);\n } while (parent);\n return ancestors as Ancestors;\n }\n\n /**\n * Compare ancestors\n *\n * @param {StackedObject} other\n * @returns {AncestryComparison} an object that represent the ancestry situation.\n */\n findCommonAncestors(other: T): AncestryComparison {\n if (this === other) {\n return {\n fork: [],\n otherFork: [],\n common: [this, ...this.getAncestors()],\n } as AncestryComparison;\n }\n const ancestors = this.getAncestors();\n const otherAncestors = other.getAncestors();\n // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case\n if (\n ancestors.length === 0 &&\n otherAncestors.length > 0 &&\n this === otherAncestors[otherAncestors.length - 1]\n ) {\n return {\n fork: [],\n otherFork: [\n other,\n ...otherAncestors.slice(0, otherAncestors.length - 1),\n ],\n common: [this],\n } as AncestryComparison;\n }\n // compare ancestors\n for (let i = 0, ancestor; i < ancestors.length; i++) {\n ancestor = ancestors[i];\n if (ancestor === other) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n for (let j = 0; j < otherAncestors.length; j++) {\n if (this === otherAncestors[j]) {\n return {\n fork: [],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: [this, ...ancestors],\n } as AncestryComparison;\n }\n if (ancestor === otherAncestors[j]) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n }\n }\n // nothing shared\n return {\n fork: [this, ...ancestors],\n otherFork: [other, ...otherAncestors],\n common: [],\n } as AncestryComparison;\n }\n\n /**\n *\n * @param {StackedObject} other\n * @returns {boolean}\n */\n hasCommonAncestors(other: T): boolean {\n const commonAncestors = this.findCommonAncestors(other);\n return commonAncestors && !!commonAncestors.common.length;\n }\n\n /**\n *\n * @param {FabricObject} other object to compare against\n * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined`\n */\n isInFrontOf(other: T): boolean | undefined {\n if (this === other) {\n return undefined;\n }\n const ancestorData = this.findCommonAncestors(other);\n\n if (ancestorData.fork.includes(other as any)) {\n return true;\n }\n if (ancestorData.otherFork.includes(this as any)) {\n return false;\n }\n // if there isn't a common ancestor, we take the canvas.\n // if there is no canvas, there is nothing to compare\n const firstCommonAncestor = ancestorData.common[0] || this.canvas;\n if (!firstCommonAncestor) {\n return undefined;\n }\n const headOfFork = ancestorData.fork.pop(),\n headOfOtherFork = ancestorData.otherFork.pop(),\n thisIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfFork as any,\n ),\n otherIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfOtherFork as any,\n );\n return thisIndex > -1 && thisIndex > otherIndex;\n }\n\n // #region Serialization\n /**\n * Define a list of custom properties that will be serialized when\n * instance.toObject() gets called\n */\n static customProperties: string[] = [];\n\n /**\n * Returns an object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject(propertiesToInclude: any[] = []): any {\n const propertiesToSerialize = propertiesToInclude.concat(\n FabricObject.customProperties,\n (this.constructor as typeof FabricObject).customProperties || [],\n );\n let clipPathData: Partial | undefined;\n const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n const {\n clipPath,\n fill,\n stroke,\n shadow,\n strokeDashArray,\n left,\n top,\n originX,\n originY,\n width,\n height,\n strokeWidth,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit,\n scaleX,\n scaleY,\n angle,\n flipX,\n flipY,\n opacity,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX,\n skewY,\n } = this;\n if (clipPath && !clipPath.excludeFromExport) {\n clipPathData = clipPath.toObject(\n propertiesToSerialize.concat('inverted', 'absolutePositioned'),\n );\n }\n const toFixedBound = (val: number) => toFixed(val, NUM_FRACTION_DIGITS);\n const object = {\n ...pick(this, propertiesToSerialize as (keyof this)[]),\n type: (this.constructor as typeof FabricObject).type,\n version: VERSION,\n originX,\n originY,\n left: toFixedBound(left),\n top: toFixedBound(top),\n width: toFixedBound(width),\n height: toFixedBound(height),\n fill: isSerializableFiller(fill) ? fill.toObject() : fill,\n stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke,\n strokeWidth: toFixedBound(strokeWidth),\n strokeDashArray: strokeDashArray\n ? strokeDashArray.concat()\n : strokeDashArray,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit: toFixedBound(strokeMiterLimit),\n scaleX: toFixedBound(scaleX),\n scaleY: toFixedBound(scaleY),\n angle: toFixedBound(angle),\n flipX,\n flipY,\n opacity: toFixedBound(opacity),\n shadow: shadow ? shadow.toObject() : shadow,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX: toFixedBound(skewX),\n skewY: toFixedBound(skewY),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n\n return !this.includeDefaultValues\n ? this._removeDefaultValues(object)\n : object;\n }\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: any[]): any {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n }\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues(object: T): Partial {\n // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance\n // ownDefault vs prototype is swappable only if you change all the fabric objects consistently.\n const defaults = (this.constructor as typeof FabricObject).getDefaults();\n const hasStaticDefaultValues = Object.keys(defaults).length > 0;\n const baseValues = hasStaticDefaultValues\n ? defaults\n : Object.getPrototypeOf(this);\n\n return pickBy(object, (value, key) => {\n if (key === LEFT || key === TOP || key === 'type') {\n return true;\n }\n const baseValue = baseValues[key];\n return (\n value !== baseValue &&\n // basically a check for [] === []\n !(\n Array.isArray(value) &&\n Array.isArray(baseValue) &&\n value.length === 0 &&\n baseValue.length === 0\n )\n );\n });\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString() {\n return `#<${(this.constructor as typeof FabricObject).type}>`;\n }\n\n /**\n *\n * @param {Function} klass\n * @param {object} object\n * @param {object} [options]\n * @param {string} [options.extraParam] property to pass as first argument to the constructor\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static _fromObject(\n { type, ...serializedObjectOptions }: Record,\n { extraParam, ...options }: Abortable & { extraParam?: string } = {},\n ): Promise {\n return enlivenObjectEnlivables(serializedObjectOptions, options).then(\n (enlivedObjectOptions) => {\n // from the resulting enlived options, extract options.extraParam to arg0\n // to avoid accidental overrides later\n if (extraParam) {\n delete enlivedObjectOptions[extraParam];\n return new this(\n serializedObjectOptions[extraParam],\n // @ts-expect-error different signature\n enlivedObjectOptions,\n );\n } else {\n return new this(enlivedObjectOptions);\n }\n },\n ) as Promise;\n }\n\n /**\n *\n * @param {object} object\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n object: T,\n options?: Abortable,\n ) {\n return this._fromObject(object, options);\n }\n}\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n","import type {\n TModificationEvents,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\n/**\n * Wrap an action handler with firing an event if the action is performed\n * @param {TModificationEvents} eventName the event we want to fire\n * @param {TransformActionHandler} actionHandler the function to wrap\n * @param {object} extraEventInfo extra information to pas to the event handler\n * @return {TransformActionHandler} a function with an action handler signature\n */\nexport const wrapWithFireEvent = <\n T extends Transform,\n P extends object = Record,\n>(\n eventName: TModificationEvents,\n actionHandler: TransformActionHandler,\n extraEventInfo?: P,\n) => {\n return ((eventData, transform, x, y) => {\n const actionPerformed = actionHandler(eventData, transform, x, y);\n if (actionPerformed) {\n fireEvent(eventName, {\n ...commonEventInfo(eventData, transform, x, y),\n ...extraEventInfo,\n });\n }\n return actionPerformed;\n }) as TransformActionHandler;\n};\n","import type { Transform, TransformActionHandler } from '../EventTypeDefs';\n\n/**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\nexport function wrapWithFixedAnchor(\n actionHandler: TransformActionHandler,\n) {\n return ((eventData, transform, x, y) => {\n const { target, originX, originY } = transform,\n centerPoint = target.getRelativeCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, originX, originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n // flipping requires to change the transform origin, so we read from the mutated transform\n // instead of leveraging the one destructured before\n target.setPositionByOrigin(\n constraint,\n transform.originX,\n transform.originY,\n );\n return actionPerformed;\n }) as TransformActionHandler;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { CENTER, LEFT, RESIZING, RIGHT } from '../constants';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { getLocalPoint, isTransformCentered } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Action handler to change object's width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const changeObjectWidth: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const localPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // make sure the control changes width ONLY from it's side of target\n if (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) ||\n (resolveOrigin(transform.originX) === resolveOrigin(RIGHT) &&\n localPoint.x < 0) ||\n (resolveOrigin(transform.originX) === resolveOrigin(LEFT) &&\n localPoint.x > 0)\n ) {\n const { target } = transform,\n strokePadding =\n target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width,\n newWidth = Math.ceil(\n Math.abs((localPoint.x * multiplier) / target.scaleX) - strokePadding,\n );\n target.set('width', Math.max(newWidth, 0));\n // check against actual target width in case `newWidth` was rejected\n return oldWidth !== target.width;\n }\n return false;\n};\n\nexport const changeWidth = wrapWithFireEvent(\n RESIZING,\n wrapWithFixedAnchor(changeObjectWidth),\n);\n","import { FILL, STROKE, twoMathPi } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\n\nexport type ControlRenderingStyleOverride = Partial<\n Pick<\n InteractiveFabricObject,\n | 'cornerStyle'\n | 'cornerSize'\n | 'cornerColor'\n | 'cornerStrokeColor'\n | 'cornerDashArray'\n | 'transparentCorners'\n >\n>;\n\nexport type ControlRenderer<\n O extends InteractiveFabricObject = InteractiveFabricObject,\n> = (\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: O,\n) => void;\n\n/**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCircleControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n let myLeft = left,\n myTop = top,\n size;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // TODO: use proper ellipse code.\n if (xSize > ySize) {\n size = xSize;\n ctx.scale(1.0, ySize / xSize);\n myTop = (top * xSize) / ySize;\n } else if (ySize > xSize) {\n size = ySize;\n ctx.scale(xSize / ySize, 1.0);\n myLeft = (left * ySize) / xSize;\n } else {\n size = xSize;\n }\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n}\n\n/**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderSquareControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle();\n ctx.rotate(degreesToRadians(angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n ctx[`${methodName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);\n if (stroke) {\n ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n }\n ctx.restore();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type {\n ControlActionHandler,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { Intersection } from '../Intersection';\nimport { Point } from '../Point';\nimport { SCALE } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport type { TCornerPoint, TDegree, TMat2D } from '../typedefs';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { renderCircleControl, renderSquareControl } from './controlRendering';\n\nexport class Control {\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the control set.\n * @type {Boolean}\n * @default true\n */\n visible = true;\n\n /**\n * Name of the action that the control will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName = SCALE;\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle = 0;\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x = 0;\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y = 0;\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX = 0;\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY = 0;\n\n /**\n * Sets the length of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeX = 0;\n\n /**\n * Sets the height of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeY = 0;\n\n /**\n * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeX = 0;\n\n /**\n * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeY = 0;\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle = 'crosshair';\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection = false;\n\n constructor(options?: Partial) {\n Object.assign(this, options);\n }\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare actionHandler: TransformActionHandler;\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseDownHandler?: ControlActionHandler;\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseUpHandler?: ControlActionHandler;\n\n shouldActivate(\n controlKey: string,\n fabricObject: InteractiveFabricObject,\n pointer: Point,\n { tl, tr, br, bl }: TCornerPoint,\n ) {\n // TODO: locking logic can be handled here instead of in the control handler logic\n return (\n fabricObject.canvas?.getActiveObject() === fabricObject &&\n fabricObject.isControlVisible(controlKey) &&\n Intersection.isPointInPolygon(pointer, [tl, tr, br, bl])\n );\n }\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getActionHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): TransformActionHandler | undefined {\n return this.actionHandler;\n }\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseDownHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseDownHandler;\n }\n\n /**\n * Returns control mouseUp handler.\n * During actions the fabricObject or the control can be of different obj\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseUpHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseUpHandler;\n }\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.cursorStyle;\n }\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n getActionName(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.actionName;\n }\n\n /**\n * Returns controls visibility\n * @param {FabricObject} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility(fabricObject: InteractiveFabricObject, controlKey: string) {\n return fabricObject._controlsVisibility?.[controlKey] ?? this.visible;\n }\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility(\n visibility: boolean,\n name: string,\n fabricObject: InteractiveFabricObject,\n ) {\n this.visible = visibility;\n }\n\n positionHandler(\n dim: Point,\n finalMatrix: TMat2D,\n fabricObject: InteractiveFabricObject,\n currentControl: Control,\n ) {\n return new Point(\n this.x * dim.x + this.offsetX,\n this.y * dim.y + this.offsetY,\n ).transform(finalMatrix);\n }\n\n /**\n * Returns the coords for this control based on object values.\n * @param {Number} objectAngle angle from the fabric object holding the control\n * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if\n * isTouch is true)\n * @param {Number} centerX x coordinate where the control center should be\n * @param {Number} centerY y coordinate where the control center should be\n * @param {boolean} isTouch true if touch corner, false if normal corner\n */\n calcCornerCoords(\n angle: TDegree,\n objectCornerSize: number,\n centerX: number,\n centerY: number,\n isTouch: boolean,\n fabricObject: InteractiveFabricObject,\n ) {\n const t = multiplyTransformMatrixArray([\n createTranslateMatrix(centerX, centerY),\n createRotateMatrix({ angle }),\n createScaleMatrix(\n (isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize,\n (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize,\n ),\n ]);\n return {\n tl: new Point(-0.5, -0.5).transform(t),\n tr: new Point(0.5, -0.5).transform(t),\n br: new Point(0.5, 0.5).transform(t),\n bl: new Point(-0.5, 0.5).transform(t),\n };\n }\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {FabricObject} fabricObject the object where the control is about to be rendered\n */\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: InteractiveFabricObject,\n ) {\n styleOverride = styleOverride || {};\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n renderCircleControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n break;\n default:\n renderSquareControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n }\n }\n}\n","import type {\n ControlCursorCallback,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { ROTATING } from '../constants';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { isLocked, NOT_ALLOWED_CURSOR } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const rotationStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (fabricObject.lockRotation) {\n return NOT_ALLOWED_CURSOR;\n }\n return control.cursorStyle;\n};\n\n/**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\nconst rotateObjectWithSnapping: TransformActionHandler = (\n eventData,\n { target, ex, ey, theta, originX, originY },\n x,\n y,\n) => {\n const pivotPoint = target.translateToOriginPoint(\n target.getRelativeCenterPoint(),\n originX,\n originY,\n );\n\n if (isLocked(target, 'lockRotation')) {\n return false;\n }\n\n const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x);\n let angle = radiansToDegrees(curAngle - lastAngle + theta);\n\n if (target.snapAngle && target.snapAngle > 0) {\n const snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n const hasRotated = target.angle !== angle;\n // TODO: why aren't we using set?\n target.angle = angle;\n return hasRotated;\n};\n\nexport const rotationWithSnapping = wrapWithFireEvent(\n ROTATING,\n wrapWithFixedAnchor(rotateObjectWithSnapping),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxis } from '../typedefs';\nimport type { Canvas } from '../canvas/Canvas';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n invertOrigin,\n isLocked,\n isTransformCentered,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport { SCALE_X, SCALE_Y, SCALING } from '../constants';\n\ntype ScaleTransform = Transform & {\n gestureScale?: number;\n signX?: number;\n signY?: number;\n};\n\ntype ScaleBy = TAxis | 'equally' | '' | undefined;\n\n/**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\nexport function scaleIsProportional(\n eventData: TPointerEvent,\n fabricObject: FabricObject,\n): boolean {\n const canvas = fabricObject.canvas as Canvas,\n uniformIsToggled = eventData[canvas.uniScaleKey!];\n return (\n (canvas.uniformScaling && !uniformIsToggled) ||\n (!canvas.uniformScaling && uniformIsToggled)\n );\n}\n\n/**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\nexport function scalingIsForbidden(\n fabricObject: FabricObject,\n by: ScaleBy,\n scaleProportionally: boolean,\n) {\n const lockX = isLocked(fabricObject, 'lockScalingX'),\n lockY = isLocked(fabricObject, 'lockScalingY');\n if (lockX && lockY) {\n return true;\n }\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n if (lockX && by === 'x') {\n return true;\n }\n if (lockY && by === 'y') {\n return true;\n }\n // code crashes because of a division by 0 if a 0 sized object is scaled\n // forbid to prevent scaling to happen. ISSUE-9475\n const { width, height, strokeWidth } = fabricObject;\n if (width === 0 && strokeWidth === 0 && by !== 'y') {\n return true;\n }\n if (height === 0 && strokeWidth === 0 && by !== 'x') {\n return true;\n }\n return false;\n}\n\nconst scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];\n\n/**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n const scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by =\n control.x !== 0 && control.y === 0\n ? 'x'\n : control.x === 0 && control.y !== 0\n ? 'y'\n : '';\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control);\n return `${scaleMap[n]}-resize`;\n};\n\n/**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\nfunction scaleObject(\n eventData: TPointerEvent,\n transform: ScaleTransform,\n x: number,\n y: number,\n options: { by?: ScaleBy } = {},\n) {\n const target = transform.target,\n by = options.by,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally);\n let newPoint, scaleX, scaleY, dim, signX, signY;\n\n if (forbidScaling) {\n return false;\n }\n if (transform.gestureScale) {\n scaleX = transform.scaleX * transform.gestureScale;\n scaleY = transform.scaleY * transform.gestureScale;\n } else {\n newPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1;\n signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1;\n if (!transform.signX) {\n transform.signX = signX;\n }\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (\n isLocked(target, 'lockScalingFlip') &&\n (transform.signX !== signX || transform.signY !== signY)\n ) {\n return false;\n }\n\n dim = target._getTransformedDimensions();\n // missing detection of flip and logic to switch the origin\n if (scaleProportionally && !by) {\n // uniform scaling\n const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n { original } = transform,\n originalDistance =\n Math.abs((dim.x * original.scaleX) / target.scaleX) +\n Math.abs((dim.y * original.scaleY) / target.scaleY),\n scale = distance / originalDistance;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n } else {\n scaleX = Math.abs((newPoint.x * target.scaleX) / dim.x);\n scaleY = Math.abs((newPoint.y * target.scaleY) / dim.y);\n }\n // if we are scaling by center, we need to double the scale\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = invertOrigin(transform.originX);\n scaleX *= -1;\n transform.signX = signX;\n }\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = invertOrigin(transform.originY);\n scaleY *= -1;\n transform.signY = signY;\n }\n }\n // minScale is taken care of in the setter.\n const oldScaleX = target.scaleX,\n oldScaleY = target.scaleY;\n if (!by) {\n !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX);\n !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY);\n } else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set(SCALE_X, scaleX);\n by === 'y' && target.set(SCALE_Y, scaleY);\n }\n return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n}\n\n/**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scaleObjectFromCorner: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y);\n};\n\n/**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'x' });\n};\n\n/**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'y' });\n};\n\nexport const scalingEqually = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectFromCorner),\n);\n\nexport const scalingX = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectX),\n);\n\nexport const scalingY = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectY),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { TAxis, TAxisKey } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n isLocked,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport {\n CENTER,\n SCALE_X,\n SCALE_Y,\n SKEWING,\n SKEW_X,\n SKEW_Y,\n} from '../constants';\n\nexport type SkewTransform = Transform & { skewingSide: -1 | 1 };\n\nconst AXIS_KEYS: Record<\n TAxis,\n {\n counterAxis: TAxis;\n scale: TAxisKey<'scale'>;\n skew: TAxisKey<'skew'>;\n lockSkewing: TAxisKey<'lockSkewing'>;\n origin: TAxisKey<'origin'>;\n flip: TAxisKey<'flip'>;\n }\n> = {\n x: {\n counterAxis: 'y',\n scale: SCALE_X,\n skew: SKEW_X,\n lockSkewing: 'lockSkewingX',\n origin: 'originX',\n flip: 'flipX',\n },\n y: {\n counterAxis: 'x',\n scale: SCALE_Y,\n skew: SKEW_Y,\n lockSkewing: 'lockSkewingY',\n origin: 'originY',\n flip: 'flipY',\n },\n};\n\nconst skewMap = ['ns', 'nesw', 'ew', 'nwse'];\n\n/**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const skewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) {\n return NOT_ALLOWED_CURSOR;\n }\n if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control) % 4;\n return `${skewMap[n]}-resize`;\n};\n\n/**\n * Since skewing is applied before scaling, calculations are done in a scaleless plane\n * @see https://github.com/fabricjs/fabric.js/pull/8380\n */\nfunction skewObject(\n axis: TAxis,\n { target, ex, ey, skewingSide, ...transform }: SkewTransform,\n pointer: Point,\n) {\n const { skew: skewKey } = AXIS_KEYS[axis],\n offset = pointer\n .subtract(new Point(ex, ey))\n .divide(new Point(target.scaleX, target.scaleY))[axis],\n skewingBefore = target[skewKey],\n skewingStart = transform[skewKey],\n shearingStart = Math.tan(degreesToRadians(skewingStart)),\n // let a, b be the size of target\n // let a' be the value of a after applying skewing\n // then:\n // a' = a + b * skewA => skewA = (a' - a) / b\n // the value b is tricky since skewY is applied before skewX\n b =\n axis === 'y'\n ? target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n // since skewY is applied before skewX, b (=width) is not affected by skewX\n skewX: 0,\n }).x\n : target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n }).y;\n\n const shearing =\n (2 * offset * skewingSide) /\n // we max out fractions to safeguard from asymptotic behavior\n Math.max(b, 1) +\n // add starting state\n shearingStart;\n\n const skewing = radiansToDegrees(Math.atan(shearing));\n\n target.set(skewKey, skewing);\n const changed = skewingBefore !== target[skewKey];\n\n if (changed && axis === 'y') {\n // we don't want skewing to affect scaleX\n // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer\n const { skewX, scaleX } = target,\n dimBefore = target._getTransformedDimensions({ skewY: skewingBefore }),\n dimAfter = target._getTransformedDimensions(),\n compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1;\n compensationFactor !== 1 &&\n target.set(SCALE_X, compensationFactor * scaleX);\n }\n\n return changed;\n}\n\n/**\n * Wrapped Action handler for skewing on a given axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nfunction skewHandler(\n axis: TAxis,\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n) {\n const { target } = transform,\n {\n counterAxis,\n origin: originKey,\n lockSkewing: lockSkewingKey,\n skew: skewKey,\n flip: flipKey,\n } = AXIS_KEYS[axis];\n if (isLocked(target, lockSkewingKey)) {\n return false;\n }\n\n const { origin: counterOriginKey, flip: counterFlipKey } =\n AXIS_KEYS[counterAxis],\n counterOriginFactor =\n resolveOrigin(transform[counterOriginKey]) *\n (target[counterFlipKey] ? -1 : 1),\n // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively.\n // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively.\n // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer,\n // so we factor skewing direction by this value.\n skewingSide = (-Math.sign(counterOriginFactor) *\n (target[flipKey] ? -1 : 1)) as 1 | -1,\n skewingDirection =\n ((target[skewKey] === 0 &&\n // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing\n getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0) ||\n // in case target has skewing we use that as the direction\n target[skewKey] > 0\n ? 1\n : -1) * skewingSide,\n // anchor to the opposite side of the skewing direction\n // normalize value from [-1, 1] to origin value [0, 1]\n origin = -skewingDirection * 0.5 + 0.5;\n\n const finalHandler = wrapWithFireEvent(\n SKEWING,\n wrapWithFixedAnchor((eventData, transform, x, y) =>\n skewObject(axis, transform, new Point(x, y)),\n ),\n );\n\n return finalHandler(\n eventData,\n {\n ...transform,\n [originKey]: origin,\n skewingSide,\n },\n x,\n y,\n );\n}\n\n/**\n * Wrapped Action handler for skewing on the X axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('x', eventData, transform, x, y);\n};\n\n/**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('y', eventData, transform, x, y);\n};\n","import type {\n ControlCallback,\n ControlCursorCallback,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { SCALE_X, SCALE_Y, SKEW_X, SKEW_Y } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxisKey } from '../typedefs';\nimport { scaleCursorStyleHandler, scalingX, scalingY } from './scale';\nimport { skewCursorStyleHandler, skewHandlerX, skewHandlerY } from './skew';\n\nfunction isAltAction(eventData: TPointerEvent, target: FabricObject) {\n return eventData[target.canvas!.altActionKey!];\n}\n\n/**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\nexport const scaleOrSkewActionName: ControlCallback<\n TAxisKey<'skew' | 'scale'> | ''\n> = (eventData, control, fabricObject) => {\n const isAlternative = isAltAction(eventData, fabricObject);\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_X : SCALE_Y;\n }\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_Y : SCALE_X;\n }\n return '';\n};\n\n/**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleSkewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n return isAltAction(eventData, fabricObject)\n ? skewCursorStyleHandler(eventData, control, fabricObject)\n : scaleCursorStyleHandler(eventData, control, fabricObject);\n};\n/**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingXOrSkewingY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerY(eventData, transform, x, y)\n : scalingX(eventData, transform, x, y);\n};\n\n/**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingYOrSkewingX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerX(eventData, transform, x, y)\n : scalingY(eventData, transform, x, y);\n};\n","import { RESIZING, ROTATE } from '../constants';\nimport { changeWidth } from './changeWidth';\nimport { Control } from './Control';\nimport { rotationStyleHandler, rotationWithSnapping } from './rotate';\nimport { scaleCursorStyleHandler, scalingEqually } from './scale';\nimport {\n scaleOrSkewActionName,\n scaleSkewCursorStyleHandler,\n scalingXOrSkewingY,\n scalingYOrSkewingX,\n} from './scaleSkew';\n\n// use this function if you want to generate new controls for every instance\nexport const createObjectDefaultControls = () => ({\n ml: new Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mr: new Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mb: new Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n mt: new Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n tl: new Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n tr: new Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n bl: new Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n br: new Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n mtr: new Control({\n x: 0,\n y: -0.5,\n actionHandler: rotationWithSnapping,\n cursorStyleHandler: rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: ROTATE,\n }),\n});\n\nexport const createResizeControls = () => ({\n mr: new Control({\n x: 0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n ml: new Control({\n x: -0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n});\n\nexport const createTextboxDefaultControls = () => ({\n ...createObjectDefaultControls(),\n ...createResizeControls(),\n});\n","import { Point, ZERO } from '../../Point';\nimport type { TCornerPoint, TDegree } from '../../typedefs';\nimport { FabricObject } from './Object';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport type { TQrDecomposeOut } from '../../util/misc/matrix';\nimport {\n calcDimensionsMatrix,\n createRotateMatrix,\n createTranslateMatrix,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../../util/misc/matrix';\nimport type { Control } from '../../controls/Control';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { ControlRenderingStyleOverride } from '../../controls/controlRendering';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { createObjectDefaultControls } from '../../controls/commonControls';\nimport { interactiveObjectDefaultValues } from './defaultValues';\nimport { SCALE } from '../../constants';\n\nexport type TOCoord = Point & {\n corner: TCornerPoint;\n touchCorner: TCornerPoint;\n};\n\nexport type TControlSet = Record;\n\nexport type TBorderRenderingStyleOverride = Partial<\n Pick\n>;\n\nexport type TStyleOverride = ControlRenderingStyleOverride &\n TBorderRenderingStyleOverride &\n Partial<\n Pick & {\n forActiveSelection: boolean;\n }\n >;\n\nexport class InteractiveFabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n declare noScaleCache: boolean;\n\n declare snapAngle?: TDegree;\n declare snapThreshold?: TDegree;\n\n declare lockMovementX: boolean;\n declare lockMovementY: boolean;\n declare lockRotation: boolean;\n declare lockScalingX: boolean;\n declare lockScalingY: boolean;\n declare lockSkewingX: boolean;\n declare lockSkewingY: boolean;\n declare lockScalingFlip: boolean;\n\n declare cornerSize: number;\n declare touchCornerSize: number;\n declare transparentCorners: boolean;\n declare cornerColor: string;\n declare cornerStrokeColor: string;\n declare cornerStyle: 'rect' | 'circle';\n declare cornerDashArray: number[] | null;\n declare hasControls: boolean;\n\n declare borderColor: string;\n declare borderDashArray: number[] | null;\n declare borderOpacityWhenMoving: number;\n declare borderScaleFactor: number;\n declare hasBorders: boolean;\n declare selectionBackgroundColor: string;\n\n declare selectable: boolean;\n declare evented: boolean;\n declare perPixelTargetFind: boolean;\n declare activeOn: 'down' | 'up';\n\n declare hoverCursor: CSSStyleDeclaration['cursor'] | null;\n declare moveCursor: CSSStyleDeclaration['cursor'] | null;\n\n /**\n * The object's controls' position in viewport coordinates\n * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}.\n * `corner/touchCorner` describe the 4 points forming the interactive area of the corner.\n * Used to draw and locate controls.\n */\n declare oCoords: Record;\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * this isn't cleaned automatically. Non selected objects may have wrong values\n * @type [string]\n */\n declare __corner?: string;\n\n /**\n * a map of control visibility for this object.\n * this was left when controls were introduced to not break the api too much\n * this takes priority over the generic control visibility\n */\n declare _controlsVisibility: Record;\n\n /**\n * holds the controls for the object.\n * controls are added by default_controls.js\n */\n declare controls: TControlSet;\n\n /**\n * internal boolean to signal the code that the object is\n * part of the move action.\n */\n declare isMoving?: boolean;\n\n /**\n * A boolean used from the gesture module to keep tracking of a scaling\n * action when there is no scaling transform in place.\n * This is an edge case and is used twice in all codebase.\n * Probably added to keep track of some performance issues\n * @TODO use git blame to investigate why it was added\n * DON'T USE IT. WE WILL TRY TO REMOVE IT\n */\n declare _scaling?: boolean;\n\n declare canvas?: Canvas;\n\n static ownDefaults = interactiveObjectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...InteractiveFabricObject.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof InteractiveFabricObject).createControls(),\n InteractiveFabricObject.ownDefaults,\n );\n this.setOptions(options);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults\n * @param {Object} [options] Options object\n */\n static createControls(): { controls: Record } {\n return { controls: createObjectDefaultControls() };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n const transform = targetCanvas._currentTransform,\n target = transform.target,\n action = transform.action;\n if (\n this === (target as unknown as this) &&\n action &&\n action.startsWith(SCALE)\n ) {\n return false;\n }\n }\n return super._updateCacheCanvas();\n }\n\n getActiveControl() {\n const key = this.__corner;\n return key\n ? {\n key,\n control: this.controls[key],\n coord: this.oCoords[key],\n }\n : undefined;\n }\n\n /**\n * Determines which corner is under the mouse cursor, represented by `pointer`.\n * This function is return a corner only if the object is the active one.\n * This is done to avoid selecting corner of non active object and activating transformations\n * rather than drag action. The default behavior of fabricJS is that if you want to transform\n * an object, first you select it to show the control set\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found.\n */\n findControl(\n pointer: Point,\n forTouch = false,\n ): { key: string; control: Control; coord: TOCoord } | undefined {\n if (!this.hasControls || !this.canvas) {\n return undefined;\n }\n\n this.__corner = undefined;\n const cornerEntries = Object.entries(this.oCoords);\n for (let i = cornerEntries.length - 1; i >= 0; i--) {\n const [key, corner] = cornerEntries[i];\n const control = this.controls[key];\n\n if (\n control.shouldActivate(\n key,\n this,\n pointer,\n forTouch ? corner.touchCorner : corner.corner,\n )\n ) {\n // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2);\n this.__corner = key;\n\n return { key, control, coord: this.oCoords[key] };\n }\n }\n\n return undefined;\n }\n\n /**\n * Calculates the coordinates of the center of each control plus the corners of the control itself\n * This basically just delegates to each control positionHandler\n * WARNING: changing what is passed to positionHandler is a breaking change, since position handler\n * is a public api and should be done just if extremely necessary\n * @return {Record}\n */\n calcOCoords(): Record {\n const vpt = this.getViewportTransform(),\n center = this.getCenterPoint(),\n tMatrix = createTranslateMatrix(center.x, center.y),\n rMatrix = createRotateMatrix({\n angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0),\n }),\n positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix),\n startMatrix = multiplyTransformMatrices(vpt, positionMatrix),\n finalMatrix = multiplyTransformMatrices(startMatrix, [\n 1 / vpt[0],\n 0,\n 0,\n 1 / vpt[3],\n 0,\n 0,\n ]),\n transformOptions = this.group\n ? qrDecompose(this.calcTransformMatrix())\n : undefined;\n // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it\n if (transformOptions) {\n transformOptions.scaleX = Math.abs(transformOptions.scaleX);\n transformOptions.scaleY = Math.abs(transformOptions.scaleY);\n }\n const dim = this._calculateCurrentDimensions(transformOptions),\n coords: Record = {};\n\n this.forEachControl((control, key) => {\n const position = control.positionHandler(dim, finalMatrix, this, control);\n // coords[key] are sometimes used as points. Those are points to which we add\n // the property corner and touchCorner from `_calcCornerCoords`.\n // don't remove this assign for an object spread.\n coords[key] = Object.assign(\n position,\n this._calcCornerCoords(control, position),\n );\n });\n\n // debug code\n /*\n const canvas = this.canvas;\n setTimeout(function () {\n if (!canvas) return;\n canvas.contextTop.clearRect(0, 0, 700, 700);\n canvas.contextTop.fillStyle = 'green';\n Object.keys(coords).forEach(function(key) {\n const control = coords[key];\n canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n });\n } 50);\n */\n return coords;\n }\n\n /**\n * Sets the coordinates that determine the interaction area of each control\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @todo evaluate simplification of code switching to circle interaction area at runtime\n * @private\n */\n private _calcCornerCoords(control: Control, position: Point) {\n const angle = this.getTotalAngle();\n const corner = control.calcCornerCoords(\n angle,\n this.cornerSize,\n position.x,\n position.y,\n false,\n this,\n );\n const touchCorner = control.calcCornerCoords(\n angle,\n this.touchCornerSize,\n position.x,\n position.y,\n true,\n this,\n );\n return { corner, touchCorner };\n }\n\n /**\n * @override set controls' coordinates as well\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n * @return {void}\n */\n setCoords(): void {\n super.setCoords();\n this.canvas && (this.oCoords = this.calcOCoords());\n }\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the control's key and the object that is calling the iterator\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl(\n fn: (\n control: Control,\n key: string,\n fabricObject: InteractiveFabricObject,\n ) => any,\n ) {\n for (const i in this.controls) {\n fn(this.controls[i], i, this);\n }\n }\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @todo evaluate if make this disappear in favor of a pre-render hook for objects\n * this was added by Andrea Bogazzi to make possible some feature for work reasons\n * it seemed a good option, now is an edge case\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n */\n drawSelectionBackground(ctx: CanvasRenderingContext2D): void {\n if (\n !this.selectionBackgroundColor ||\n (this.canvas && (this.canvas._activeObject as unknown as this) !== this)\n ) {\n return;\n }\n ctx.save();\n const center = this.getRelativeCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.getViewportTransform();\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n }\n\n /**\n * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style.\n * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center\n * @param {Point} size the control box size used\n */\n strokeBorders(ctx: CanvasRenderingContext2D, size: Point): void {\n ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size\n * @param {TStyleOverride} styleOverride object to override the object style\n */\n _drawBorders(\n ctx: CanvasRenderingContext2D,\n size: Point,\n styleOverride: TStyleOverride = {},\n ): void {\n const options = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n borderDashArray: this.borderDashArray,\n ...styleOverride,\n };\n ctx.save();\n ctx.strokeStyle = options.borderColor;\n this._setLineDash(ctx, options.borderDashArray);\n this.strokeBorders(ctx, size);\n options.hasControls && this.drawControlsConnectingLines(ctx, size);\n ctx.restore();\n }\n\n /**\n * Renders controls and borders for the object\n * the context here is not transformed\n * @todo move to interactivity\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TStyleOverride} [styleOverride] properties to override the object style\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: TStyleOverride = {},\n ) {\n const { hasBorders, hasControls } = this;\n const styleOptions = {\n hasBorders,\n hasControls,\n ...styleOverride,\n };\n const vpt = this.getViewportTransform(),\n shouldDrawBorders = styleOptions.hasBorders,\n shouldDrawControls = styleOptions.hasControls;\n const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix());\n const options = qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n // since interactive groups have been introduced, an object could be inside a group and needing controls\n // the following equality check `this.group === this.parent` covers:\n // object without a group ( undefined === undefined )\n // object inside a group\n // excludes object inside a group but multi selected since group and parent will differ in value\n if (this.group === this.parent) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.flipX) {\n options.angle -= 180;\n }\n ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle));\n shouldDrawBorders && this.drawBorders(ctx, options, styleOverride);\n shouldDrawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {TStyleOverride} [styleOverride] object to override the object style\n */\n drawBorders(\n ctx: CanvasRenderingContext2D,\n options: TQrDecomposeOut,\n styleOverride: TStyleOverride,\n ): void {\n let size;\n if ((styleOverride && styleOverride.forActiveSelection) || this.group) {\n const bbox = sizeAfterTransform(\n this.width,\n this.height,\n calcDimensionsMatrix(options),\n ),\n stroke = !this.isStrokeAccountedForInDimensions()\n ? (this.strokeUniform\n ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1)\n : // this is extremely confusing. options comes from the upper function\n // and is the qrDecompose of a matrix that takes in account zoom too\n new Point(options.scaleX, options.scaleY)\n ).scalarMultiply(this.strokeWidth)\n : ZERO;\n size = bbox\n .add(stroke)\n .scalarAdd(this.borderScaleFactor)\n .scalarAdd(this.padding * 2);\n } else {\n size = this._calculateCurrentDimensions().scalarAdd(\n this.borderScaleFactor,\n );\n }\n this._drawBorders(ctx, size, styleOverride);\n }\n\n /**\n * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size object size x = width, y = height\n */\n drawControlsConnectingLines(\n ctx: CanvasRenderingContext2D,\n size: Point,\n ): void {\n let shouldStroke = false;\n\n ctx.beginPath();\n this.forEachControl((control, key) => {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(this, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * size.x, control.y * size.y);\n ctx.lineTo(\n control.x * size.x + control.offsetX,\n control.y * size.y + control.offsetY,\n );\n }\n });\n shouldStroke && ctx.stroke();\n }\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * Be aware that since fabric 6.0 this function does not call setCoords anymore.\n * setCoords needs to be called manually if the object of which we are rendering controls\n * is outside the standard selection and transform process.\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {ControlRenderingStyleOverride} styleOverride object to override the object style\n */\n drawControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: ControlRenderingStyleOverride = {},\n ) {\n ctx.save();\n const retinaScaling = this.getCanvasRetinaScaling();\n const { cornerStrokeColor, cornerDashArray, cornerColor } = this;\n const options = {\n cornerStrokeColor,\n cornerDashArray,\n cornerColor,\n ...styleOverride,\n };\n ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);\n ctx.strokeStyle = ctx.fillStyle = options.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = options.cornerStrokeColor;\n }\n this._setLineDash(ctx, options.cornerDashArray);\n this.forEachControl((control, key) => {\n if (control.getVisibility(this, key)) {\n const p = this.oCoords[key];\n control.render(ctx, p.x, p.y, options, this);\n }\n });\n ctx.restore();\n }\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr',\n * but since the control api allow for any control name, can be any string.\n * @returns {boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible(controlKey: string): boolean {\n return (\n this.controls[controlKey] &&\n this.controls[controlKey].getVisibility(this, controlKey)\n );\n }\n\n /**\n * Sets the visibility of the specified control.\n * please do not use.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * but since the control api allow for any control name, can be any string.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details\n */\n setControlVisible(controlKey: string, visible: boolean) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n this._controlsVisibility[controlKey] = visible;\n }\n\n /**\n * Sets the visibility state of object controls, this is just a bulk option for setControlVisible;\n * @param {Record} [options] with an optional key per control\n * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n */\n setControlsVisibility(options: Record = {}) {\n Object.entries(options).forEach(([controlKey, visibility]) =>\n this.setControlVisible(controlKey, visibility),\n );\n }\n\n /**\n * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box\n * that is in the canvas.contextContainer.\n * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object.\n * Example: blinking cursor text selection, drag effects.\n * @todo discuss swapping restoreManually with a renderCallback, but think of async issues\n * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else.\n * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed\n * with the object transformMatrix, or restored to neutral transform\n */\n clearContextTop(\n restoreManually?: boolean,\n ): CanvasRenderingContext2D | undefined {\n if (!this.canvas) {\n return;\n }\n const ctx = this.canvas.contextTop;\n if (!ctx) {\n return;\n }\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n // we add 4 pixel, to be sure to do not leave any pixel out\n const width = this.width + 4,\n height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n\n restoreManually || ctx.restore();\n return ctx;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {TPointerEvent} [options.e] event if the process is generated by an event\n * @param {FabricObject} [options.object] next object we are setting as active, and reason why\n * this is being deselected\n */\n onDeselect(_options?: {\n e?: TPointerEvent;\n object?: InteractiveFabricObject;\n }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {Event} [_options.e] event if the process is generated by an event\n */\n onSelect(_options?: { e?: TPointerEvent }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * Override to customize Drag behavior\n * Fired from {@link Canvas#_onMouseMove}\n * @returns true in order for the window to start a drag session\n */\n shouldStartDragging(_e: TPointerEvent) {\n return false;\n }\n\n /**\n * Override to customize Drag behavior\\\n * Fired once a drag session has started\n * @returns true to handle the drag event\n */\n onDragStart(_e: DragEvent) {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * @public\n * @param {DragEvent} _e\n * @returns {boolean} true if the object currently dragged can be dropped on the target\n */\n canDrop(_e: DragEvent): boolean {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the source of a drag event\n * example: render the selection status for the part of text that is being dragged from a text object\n * @public\n * @param {DragEvent} _e\n */\n renderDragSourceEffect(_e: DragEvent) {\n // for subclasses\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the target of a drag event\n * used to show that the underly object can receive a drop, or to show how the\n * object will change when dropping. example: show the cursor where the text is about to be dropped\n * @public\n * @param {DragEvent} _e\n */\n renderDropTargetEffect(_e: DragEvent) {\n // for subclasses\n }\n}\n","import type { Constructor } from '../typedefs';\n\n/***\n * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern\n */\nexport function applyMixins(\n derivedCtor: T,\n constructors: S[],\n) {\n constructors.forEach((baseCtor) => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\n name !== 'constructor' &&\n Object.defineProperty(\n derivedCtor.prototype,\n name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||\n Object.create(null),\n );\n });\n });\n return derivedCtor as T & { prototype: InstanceType };\n}\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport { FabricObjectSVGExportMixin } from './FabricObjectSVGExportMixin';\nimport { InteractiveFabricObject } from './InteractiveObject';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { classRegistry } from '../../ClassRegistry';\n\n// TODO somehow we have to make a tree-shakeable import\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FabricObject<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Props extends TFabricObjectProps = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObjectSVGExportMixin {}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class FabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends InteractiveFabricObject {}\n\napplyMixins(FabricObject, [FabricObjectSVGExportMixin]);\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n\nexport { cacheProperties } from './defaultValues';\n","/**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer\n * @return {boolean} true if transparent\n */\nexport const isTransparent = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n tolerance: number,\n): boolean => {\n tolerance = Math.round(tolerance);\n const size = tolerance * 2 + 1;\n const { data } = ctx.getImageData(x - tolerance, y - tolerance, size, size);\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (let i = 3; i < data.length; i += 4) {\n const alphaChannel = data[i];\n if (alphaChannel > 0) {\n return false;\n }\n }\n return true;\n};\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport { createVector } from '../vectors';\nimport type { TProjectStrokeOnPointsOptions, TProjection } from './types';\n\n/**\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n * @todo consider removing skewing from points before calculating stroke projection,\n * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537\n */\nexport abstract class StrokeProjectionsBase {\n declare options: TProjectStrokeOnPointsOptions;\n declare scale: Point;\n declare strokeUniformScalar: Point;\n declare strokeProjectionMagnitude: number;\n\n constructor(options: TProjectStrokeOnPointsOptions) {\n this.options = options;\n this.strokeProjectionMagnitude = this.options.strokeWidth / 2;\n this.scale = new Point(this.options.scaleX, this.options.scaleY);\n this.strokeUniformScalar = this.options.strokeUniform\n ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY)\n : new Point(1, 1);\n }\n\n /**\n * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account.\n */\n protected createSideVector(from: XY, to: XY) {\n const v = createVector(from, to);\n return this.options.strokeUniform ? v.multiply(this.scale) : v;\n }\n\n protected abstract calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude?: number,\n ): Point;\n\n protected projectOrthogonally(from: Point, to: Point, magnitude?: number) {\n return this.applySkew(\n from.add(this.calcOrthogonalProjection(from, to, magnitude)),\n );\n }\n\n protected isSkewed() {\n return this.options.skewX !== 0 || this.options.skewY !== 0;\n }\n\n protected applySkew(point: Point) {\n const p = new Point(point);\n // skewY must be applied before skewX as this distortion affects skewX calculation\n p.y += p.x * Math.tan(degreesToRadians(this.options.skewY));\n p.x += p.y * Math.tan(degreesToRadians(this.options.skewX));\n return p;\n }\n\n protected scaleUnitVector(unitVector: Point, scalar: number) {\n return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar);\n }\n\n protected abstract projectPoints(): Point[];\n\n public abstract project(): TProjection[];\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { halfPI, twoMathPi } from '../../../constants';\nimport type { TRadian } from '../../../typedefs';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport {\n calcAngleBetweenVectors,\n calcVectorRotation,\n crossProduct,\n getOrthonormalVector,\n getUnitVector,\n isBetweenVectors,\n magnitude,\n rotateVector,\n} from '../vectors';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nconst zeroVector = new Point();\n\n/**\n * class in charge of finding projections for each type of line join\n * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)}\n *\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin\n * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n *\n */\nexport class StrokeLineJoinProjections extends StrokeProjectionsBase {\n /**\n * The point being projected (the angle ∠BAC)\n */\n declare A: Point;\n /**\n * The point before A\n */\n declare B: Point;\n /**\n * The point after A\n */\n declare C: Point;\n /**\n * The AB vector\n */\n AB: Point;\n /**\n * The AC vector\n */\n AC: Point;\n /**\n * The angle of A (∠BAC)\n */\n alpha: TRadian;\n /**\n * The bisector of A (∠BAC)\n */\n bisector: Point;\n\n static getOrthogonalRotationFactor(vector1: Point, vector2?: Point) {\n const angle = vector2\n ? calcAngleBetweenVectors(vector1, vector2)\n : calcVectorRotation(vector1);\n return Math.abs(angle) < halfPI ? -1 : 1;\n }\n\n constructor(A: XY, B: XY, C: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.B = new Point(B);\n this.C = new Point(C);\n this.AB = this.createSideVector(this.A, this.B);\n this.AC = this.createSideVector(this.A, this.C);\n this.alpha = calcAngleBetweenVectors(this.AB, this.AC);\n this.bisector = getUnitVector(\n // if AC is also the zero vector nothing will be projected\n // in that case the next point will handle the projection\n rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2),\n );\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n const orthogonalProjection = getOrthonormalVector(vector);\n const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(\n orthogonalProjection,\n this.bisector,\n );\n return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide);\n }\n\n /**\n * BEVEL\n * Calculation: the projection points are formed by the vector orthogonal to the vertex.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel\n */\n projectBevel() {\n const projections: Point[] = [];\n // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C`\n (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(\n (to) => {\n projections.push(this.projectOrthogonally(this.A, to));\n projections.push(\n this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude),\n );\n },\n );\n return projections;\n }\n\n /**\n * MITER\n * Calculation: the corner is formed by extending the outer edges of the stroke\n * at the tangents of the path segments until they intersect.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter\n */\n projectMiter() {\n const projections: Point[] = [],\n alpha = Math.abs(this.alpha),\n hypotUnitScalar = 1 / Math.sin(alpha / 2),\n miterVector = this.scaleUnitVector(\n this.bisector,\n -this.strokeProjectionMagnitude * hypotUnitScalar,\n );\n\n // When two line segments meet at a sharp angle, it is possible for the join to extend,\n // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes\n // a limit on the extent of the line join.\n // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit\n // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit\n const strokeMiterLimit = this.options.strokeUniform\n ? magnitude(\n this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit),\n )\n : this.options.strokeMiterLimit;\n\n if (\n magnitude(miterVector) / this.strokeProjectionMagnitude <=\n strokeMiterLimit\n ) {\n projections.push(this.applySkew(this.A.add(miterVector)));\n }\n /* when the miter-limit is reached, the stroke line join becomes of type bevel.\n We always need two orthogonal projections which are basically bevel-type projections,\n so regardless of whether the miter-limit was reached or not, we include these projections.\n */\n projections.push(...this.projectBevel());\n\n return projections;\n }\n\n /**\n * ROUND (without skew)\n * Calculation: the projections are the two vectors parallel to X and Y axes\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew\n */\n private projectRoundNoSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [],\n // correctSide is used to only consider projecting for the outer side\n correctSide = new Point(\n StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector),\n StrokeLineJoinProjections.getOrthogonalRotationFactor(\n new Point(this.bisector.y, this.bisector.x),\n ),\n ),\n radiusOnAxisX = new Point(1, 0)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide),\n radiusOnAxisY = new Point(0, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide);\n\n [radiusOnAxisX, radiusOnAxisY].forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.A.add(vector));\n }\n });\n return projections;\n }\n\n /**\n * ROUND (with skew)\n * Calculation: the projections are the points furthest from the vertex in\n * the direction of the X and Y axes after distortion.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew\n */\n private projectRoundWithSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [];\n\n const { skewX, skewY, scaleX, scaleY, strokeUniform } = this.options,\n shearing = new Point(\n Math.tan(degreesToRadians(skewX)),\n Math.tan(degreesToRadians(skewY)),\n );\n // The points furthest from the vertex in the direction of the X and Y axes after distortion\n const circleRadius = this.strokeProjectionMagnitude,\n newY = strokeUniform\n ? circleRadius /\n scaleY /\n Math.sqrt(1 / scaleY ** 2 + (1 / scaleX ** 2) * shearing.y ** 2)\n : circleRadius / Math.sqrt(1 + shearing.y ** 2),\n furthestY = new Point(\n // Safe guard due to floating point precision. In some situations the square root\n // was returning NaN because of a negative number close to zero.\n Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)),\n newY,\n ),\n newX = strokeUniform\n ? circleRadius /\n Math.sqrt(\n 1 +\n (shearing.x ** 2 * (1 / scaleY) ** 2) /\n (1 / scaleX + (1 / scaleX) * shearing.x * shearing.y) ** 2,\n )\n : circleRadius /\n Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2),\n furthestX = new Point(\n newX,\n Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0)),\n );\n\n [\n furthestX,\n furthestX.scalarMultiply(-1),\n furthestY,\n furthestY.scalarMultiply(-1),\n ]\n // We need to skew the vector here as this information is used to check if\n // it is between the start and end of the circle segment\n .map((vector) =>\n this.applySkew(\n strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector,\n ),\n )\n .forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.applySkew(this.A).add(vector));\n }\n });\n\n return projections;\n }\n\n projectRound() {\n const projections: Point[] = [];\n /* Include the start and end points of the circle segment, so that only\n the projections contained within it are included */\n // add the orthogonal projections (start and end points of circle segment)\n projections.push(...this.projectBevel());\n // let's determines which one of the orthogonal projection is the beginning and end of the circle segment.\n // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different.\n const isStraightLine = this.alpha % twoMathPi === 0,\n // change the origin of the projections to point A\n // so that the cross product calculation is correct\n newOrigin = this.applySkew(this.A),\n proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin),\n proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin),\n // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector.\n comparisonVector = isStraightLine\n ? this.applySkew(this.AB.scalarMultiply(-1))\n : this.applySkew(\n this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1),\n ),\n // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0)\n isProj0Start = crossProduct(proj0, comparisonVector) > 0,\n startCircle = isProj0Start ? proj0 : proj1,\n endCircle = isProj0Start ? proj1 : proj0;\n if (!this.isSkewed()) {\n projections.push(...this.projectRoundNoSkew(startCircle, endCircle));\n } else {\n projections.push(...this.projectRoundWithSkew(startCircle, endCircle));\n }\n return projections;\n }\n\n /**\n * Project stroke width on points returning projections for each point as follows:\n * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel)\n * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke.\n * - `round`: same as `bevel` when it has no skew, with skew are 4 points.\n */\n protected projectPoints() {\n switch (this.options.strokeLineJoin) {\n case 'miter':\n return this.projectMiter();\n case 'round':\n return this.projectRound();\n default:\n return this.projectBevel();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n angle: this.alpha,\n bisector: this.bisector,\n }));\n }\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { getOrthonormalVector, getUnitVector } from '../vectors';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\n/**\n * class in charge of finding projections for each type of line cap for start/end of an open path\n * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)}\n *\n * Reference:\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap\n * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n */\nexport class StrokeLineCapProjections extends StrokeProjectionsBase {\n /**\n * edge point\n */\n declare A: Point;\n /**\n * point next to edge point\n */\n declare T: Point;\n\n constructor(A: XY, T: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.T = new Point(T);\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n return this.scaleUnitVector(getOrthonormalVector(vector), magnitude);\n }\n\n /**\n * OPEN PATH START/END - Line cap: Butt\n * Calculation: to find the projections, just find the points orthogonal to the stroke\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt\n */\n projectButt() {\n return [\n this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude),\n this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude),\n ];\n }\n\n /**\n * OPEN PATH START/END - Line cap: Round\n * Calculation: same as stroke line join `round`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round\n */\n projectRound() {\n const projections: Point[] = [];\n\n if (!this.isSkewed() && this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(\n this.applySkew(this.A.add(projection)),\n this.applySkew(this.A.subtract(projection)),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(\n this.A,\n this.T,\n this.T,\n this.options,\n ).projectRound(),\n );\n }\n\n return projections;\n }\n\n /**\n * OPEN PATH START/END - Line cap: Square\n * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square\n */\n projectSquare() {\n const projections: Point[] = [];\n\n if (this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(this.A.add(projection), this.A.subtract(projection));\n } else {\n const orthogonalProjection = this.calcOrthogonalProjection(\n this.A,\n this.T,\n this.strokeProjectionMagnitude,\n );\n const strokePointingOut = this.scaleUnitVector(\n getUnitVector(this.createSideVector(this.A, this.T)),\n -this.strokeProjectionMagnitude,\n );\n const projectedA = this.A.add(strokePointingOut);\n projections.push(\n projectedA.add(orthogonalProjection),\n projectedA.subtract(orthogonalProjection),\n );\n }\n\n return projections.map((p) => this.applySkew(p));\n }\n\n protected projectPoints() {\n switch (this.options.strokeLineCap) {\n case 'round':\n return this.projectRound();\n case 'square':\n return this.projectSquare();\n default:\n return this.projectButt();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n }));\n }\n}\n","import { Point, type XY } from '../../../Point';\nimport { findIndexRight } from '../../internals/findRight';\nimport { StrokeLineCapProjections } from './StrokeLineCapProjections';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nexport * from './types';\n\n/**\n *\n * Used to calculate object's bounding box\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n *\n */\nexport const projectStrokeOnPoints = (\n points: XY[],\n options: TProjectStrokeOnPointsOptions,\n openPath = false,\n): TProjection[] => {\n const projections: TProjection[] = [];\n\n if (points.length === 0) {\n return projections;\n }\n\n // first we remove duplicate neighboring points\n const reduced = points.reduce(\n (reduced, point) => {\n if (!reduced[reduced.length - 1].eq(point)) {\n reduced.push(new Point(point));\n }\n return reduced;\n },\n [new Point(points[0])],\n );\n\n if (reduced.length === 1) {\n openPath = true;\n } else if (!openPath) {\n // remove points from end in case they equal the first point\n // in order to correctly project the first point\n const start = reduced[0];\n const index = findIndexRight(reduced, (point) => !point.eq(start));\n reduced.splice(index + 1);\n }\n\n reduced.forEach((A, index, points) => {\n let B: XY, C: XY;\n if (index === 0) {\n C = points[1];\n B = openPath ? A : points[points.length - 1];\n } else if (index === points.length - 1) {\n B = points[index - 1];\n C = openPath ? A : points[0];\n } else {\n B = points[index - 1];\n C = points[index + 1];\n }\n\n if (openPath && points.length === 1) {\n projections.push(\n ...new StrokeLineCapProjections(A, A, options).project(),\n );\n } else if (openPath && (index === 0 || index === points.length - 1)) {\n projections.push(\n ...new StrokeLineCapProjections(\n A,\n index === 0 ? C : B,\n options,\n ).project(),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(A, B, C, options).project(),\n );\n }\n });\n\n return projections;\n};\n","export const findIndexRight = (\n array: T[],\n predicate: (value: T, index: number, array: T[]) => boolean,\n) => {\n for (let index = array.length - 1; index >= 0; index--) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n","import type { TextStyle } from '../../shapes/Text/StyledText';\n\nexport const cloneStyles = (style: TextStyle): TextStyle => {\n const newObj: TextStyle = {};\n Object.keys(style).forEach((key) => {\n newObj[key] = {};\n Object.keys(style[key]).forEach((keyInner) => {\n newObj[key][keyInner] = { ...style[key][keyInner] };\n });\n });\n return newObj;\n};\n","/**\n * Capitalizes a string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\nexport const capitalize = (string: string, firstLetterOnly = false): string =>\n `${string.charAt(0).toUpperCase()}${\n firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()\n }`;\n\n/**\n * Escapes XML in a string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\nexport const escapeXml = (string: string): string =>\n string\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n\n/**\n * Divide a string in the user perceived single units\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\nexport const graphemeSplit = (textstring: string): string[] => {\n const graphemes = [];\n for (let i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr as string);\n }\n return graphemes;\n};\n\n// taken from mdn in the charAt doc page.\nconst getWholeChar = (str: string, i: number): string | boolean => {\n const code = str.charCodeAt(i);\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xd800 || code > 0xdfff) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 <= code && code <= 0xdbff) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n const next = str.charCodeAt(i + 1);\n if (0xdc00 > next || next > 0xdfff) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n const prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 > prev || prev > 0xdbff) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n};\n","import { reNewline } from '../../constants';\nimport type {\n TextStyle,\n TextStyleDeclaration,\n} from '../../shapes/Text/StyledText';\nimport { cloneStyles } from '../internals/cloneStyles';\nimport { graphemeSplit } from '../lang_string';\n\nexport type TextStyleArray = {\n start: number;\n end: number;\n style: TextStyleDeclaration;\n}[];\n\n/**\n * @param {Object} prevStyle first style to compare\n * @param {Object} thisStyle second style to compare\n * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties\n * @return {boolean} true if the style changed\n */\nexport const hasStyleChanged = (\n prevStyle: TextStyleDeclaration,\n thisStyle: TextStyleDeclaration,\n forTextSpans = false,\n) =>\n prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.deltaY !== thisStyle.deltaY ||\n (forTextSpans &&\n (prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough));\n\n/**\n * Returns the array form of a text object's inline styles property with styles grouped in ranges\n * rather than per character. This format is less verbose, and is better suited for storage\n * so it is used in serialization (not during runtime).\n * @param {object} styles per character styles for a text object\n * @param {String} text the text string that the styles are applied to\n * @return {{start: number, end: number, style: object}[]}\n */\nexport const stylesToArray = (\n styles: TextStyle,\n text: string,\n): TextStyleArray => {\n const textLines = text.split('\\n'),\n stylesArray = [];\n let charIndex = -1,\n prevStyle = {};\n // clone style structure to prevent mutation\n styles = cloneStyles(styles);\n\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n if (!styles[i]) {\n //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle\n charIndex += chars.length;\n prevStyle = {};\n continue;\n }\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n const thisStyle = styles[i][c];\n //check if style exists for this character\n if (thisStyle && Object.keys(thisStyle).length > 0) {\n if (hasStyleChanged(prevStyle, thisStyle, true)) {\n stylesArray.push({\n start: charIndex,\n end: charIndex + 1,\n style: thisStyle,\n });\n } else {\n //if style is the same as previous character, increase end index\n stylesArray[stylesArray.length - 1].end++;\n }\n }\n prevStyle = thisStyle || {};\n }\n }\n return stylesArray;\n};\n\n/**\n * Returns the object form of the styles property with styles that are assigned per\n * character rather than grouped by range. This format is more verbose, and is\n * only used during runtime (not for serialization/storage)\n * @param {Array} styles the serialized form of a text object's styles\n * @param {String} text the text string that the styles are applied to\n * @return {Object}\n */\nexport const stylesFromArray = (\n styles: TextStyleArray | TextStyle,\n text: string,\n): TextStyle => {\n if (!Array.isArray(styles)) {\n // clone to prevent mutation\n return cloneStyles(styles);\n }\n const textLines = text.split(reNewline),\n stylesObject: TextStyle = {};\n let charIndex = -1,\n styleIndex = 0;\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n //check if there's a style collection that includes the current character\n if (\n styles[styleIndex] &&\n styles[styleIndex].start <= charIndex &&\n charIndex < styles[styleIndex].end\n ) {\n //create object for line index if it doesn't exist\n stylesObject[i] = stylesObject[i] || {};\n //assign a style at this character's index\n stylesObject[i][c] = { ...styles[styleIndex].style };\n //if character is at the end of the current style collection, move to the next\n if (charIndex === styles[styleIndex].end - 1) {\n styleIndex++;\n }\n }\n }\n }\n return stylesObject;\n};\n","import { FILL, STROKE } from '../constants';\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nexport const SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n FILL,\n 'fill-opacity',\n 'fill-rule',\n 'opacity',\n STROKE,\n 'stroke-dasharray',\n 'stroke-linecap',\n 'stroke-dashoffset',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke-width',\n 'id',\n 'paint-order',\n 'vector-effect',\n 'instantiated_by_use',\n 'clip-path',\n];\n","export function selectorMatches(element: HTMLElement, selector: string) {\n const nodeName = element.nodeName;\n const classNames = element.getAttribute('class');\n const id = element.getAttribute('id');\n const azAz = '(?![a-zA-Z\\\\-]+)';\n let matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n const splitClassNames = classNames.split(' ');\n for (let i = splitClassNames.length; i--; ) {\n matcher = new RegExp('\\\\.' + splitClassNames[i] + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\nimport { doesSomeParentMatch } from './doesSomeParentMatch';\n\n/**\n * @private\n */\n\nexport function elementMatchesRule(element: HTMLElement, selectors: string[]) {\n let parentMatching = true;\n // start from rightmost selector.\n const firstMatching = selectorMatches(element, selectors.pop()!);\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && selectors.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\n\nexport function doesSomeParentMatch(element: HTMLElement, selectors: string[]) {\n let selector: string,\n parentMatching = true;\n while (\n element.parentElement &&\n element.parentElement.nodeType === 1 &&\n selectors.length\n ) {\n if (parentMatching) {\n selector = selectors.pop()!;\n }\n element = element.parentElement;\n parentMatching = selectorMatches(element, selector!);\n }\n return selectors.length === 0;\n}\n","import { attributesMap } from './constants';\n\nexport const normalizeAttr = (\n attr: keyof typeof attributesMap | string,\n): string => attributesMap[attr as keyof typeof attributesMap] ?? attr;\n","import { reNum } from '../../parser/constants';\n\nconst regex = new RegExp(`(${reNum})`, 'gi');\n\nexport const cleanupSvgAttribute = (attributeValue: string) =>\n attributeValue\n .replace(regex, ' $1 ')\n // replace annoying commas and arbitrary whitespace with single spaces\n .replace(/,/gi, ' ')\n .replace(/\\s+/gi, ' ');\n","import { ROTATE, SCALE, SKEW_X, SKEW_Y, iMatrix } from '../constants';\nimport { reNum } from './constants';\nimport type { TMat2D } from '../typedefs';\nimport { cleanupSvgAttribute } from '../util/internals/cleanupSvgAttribute';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createSkewXMatrix,\n createSkewYMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\n\n// == begin transform regexp\nconst p = `(${reNum})`;\nconst skewX = String.raw`(skewX)\\(${p}\\)`;\nconst skewY = String.raw`(skewY)\\(${p}\\)`;\nconst rotate = String.raw`(rotate)\\(${p}(?: ${p} ${p})?\\)`;\nconst scale = String.raw`(scale)\\(${p}(?: ${p})?\\)`;\nconst translate = String.raw`(translate)\\(${p}(?: ${p})?\\)`;\nconst matrix = String.raw`(matrix)\\(${p} ${p} ${p} ${p} ${p} ${p}\\)`;\nconst transform = `(?:${matrix}|${translate}|${rotate}|${scale}|${skewX}|${skewY})`;\nconst transforms = `(?:${transform}*)`;\nconst transformList = String.raw`^\\s*(?:${transforms}?)\\s*$`;\n// http://www.w3.org/TR/SVG/coords.html#TransformAttribute\nconst reTransformList = new RegExp(transformList);\nconst reTransform = new RegExp(transform);\nconst reTransformAll = new RegExp(transform, 'g');\n// == end transform regexp\n\n/**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {TTransformMatrix} Array of 6 elements representing transformation matrix\n */\nexport function parseTransformAttribute(attributeValue: string): TMat2D {\n // first we clean the string\n attributeValue = cleanupSvgAttribute(attributeValue)\n // remove spaces around front parentheses\n .replace(/\\s*([()])\\s*/gi, '$1');\n\n // start with identity matrix\n const matrices: TMat2D[] = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (\n !attributeValue ||\n (attributeValue && !reTransformList.test(attributeValue))\n ) {\n return [...iMatrix];\n }\n\n for (const match of attributeValue.matchAll(reTransformAll)) {\n const transformMatch = reTransform.exec(match[0]);\n if (!transformMatch) {\n continue;\n }\n let matrix: TMat2D = iMatrix;\n const matchedParams = transformMatch.filter((m) => !!m);\n const [, operation, ...rawArgs] = matchedParams;\n const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map((arg) =>\n parseFloat(arg),\n );\n\n switch (operation) {\n case 'translate':\n matrix = createTranslateMatrix(arg0, arg1);\n break;\n case ROTATE:\n matrix = createRotateMatrix({ angle: arg0 }, { x: arg1, y: arg2 });\n break;\n case SCALE:\n matrix = createScaleMatrix(arg0, arg1);\n break;\n case SKEW_X:\n matrix = createSkewXMatrix(arg0);\n break;\n case SKEW_Y:\n matrix = createSkewYMatrix(arg0);\n break;\n case 'matrix':\n matrix = [arg0, arg1, arg2, arg3, arg4, arg5];\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix);\n }\n\n return multiplyTransformMatrixArray(matrices);\n}\n","import { multiplyTransformMatrices } from '../util/misc/matrix';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { parseTransformAttribute } from './parseTransformAttribute';\nimport { CENTER, LEFT, RIGHT, NONE, FILL, STROKE } from '../constants';\n\nexport function normalizeValue(\n attr: string,\n value: any,\n parentAttributes: Record,\n fontSize: number,\n): string | null | boolean | number[] | number {\n const isArray = Array.isArray(value);\n let parsed: number | number[];\n let ouputValue: string | null | boolean | number[] | number = value;\n if ((attr === FILL || attr === STROKE) && value === NONE) {\n ouputValue = '';\n } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === NONE) {\n ouputValue = null;\n } else {\n ouputValue = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n ouputValue = multiplyTransformMatrices(\n parentAttributes.transformMatrix,\n parseTransformAttribute(value),\n );\n } else {\n ouputValue = parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n ouputValue = value !== NONE && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n ouputValue = false;\n }\n } else if (attr === 'opacity') {\n ouputValue = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n ouputValue *= parentAttributes.opacity as number;\n }\n } else if (attr === 'textAnchor' /* text-anchor */) {\n ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER;\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = (parseUnit(value, fontSize) / fontSize) * 1000;\n } else if (attr === 'paintFirst') {\n const fillIndex = value.indexOf(FILL);\n const strokeIndex = value.indexOf(STROKE);\n ouputValue = FILL;\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n ouputValue = STROKE;\n } else if (fillIndex === -1 && strokeIndex > -1) {\n ouputValue = STROKE;\n }\n } else if (\n attr === 'href' ||\n attr === 'xlink:href' ||\n attr === 'font' ||\n attr === 'id'\n ) {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality';\n } else {\n parsed = isArray\n ? (value as string[]).map(parseUnit)\n : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed! as number) ? ouputValue : parsed!;\n}\n","import { parseUnit } from '../util/misc/svgParsing';\nimport { reFontDeclaration } from './constants';\n\n/**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\nexport function parseFontDeclaration(\n value: string,\n oStyle: Record,\n): void {\n const match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n const fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight))\n ? fontWeight\n : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n}\n","/**\n * Takes a style string and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleString(\n style: string,\n oStyle: Record,\n): void {\n style\n .replace(/;\\s*$/, '')\n .split(';')\n .forEach((chunk) => {\n if (!chunk) return;\n const [attr, value] = chunk.split(':');\n oStyle[attr.trim().toLowerCase()] = value.trim();\n });\n}\n","import { parseStyleObject } from './parseStyleObject';\nimport { parseStyleString } from './parseStyleString';\n\n/**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\nexport function parseStyleAttribute(element: HTMLElement): Record {\n const oStyle: Record = {},\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n } else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n}\n","/**\n * Takes a style object and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleObject(\n style: Record,\n oStyle: Record,\n): void {\n Object.entries(style).forEach(([prop, value]) => {\n if (value === undefined) {\n return;\n }\n oStyle[prop.toLowerCase()] = value;\n });\n}\n","import { Color } from '../color/Color';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject } from '../shapes/Object/FabricObject';\n\nconst colorAttributesMap = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity',\n};\n\n/**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\nexport function setStrokeFillOpacity(\n attributes: Record,\n): Record {\n const defaults = FabricObject.getDefaults();\n Object.entries(colorAttributesMap).forEach(([attr, colorAttr]) => {\n if (\n typeof attributes[colorAttr] === 'undefined' ||\n attributes[attr] === ''\n ) {\n return;\n }\n if (typeof attributes[attr] === 'undefined') {\n if (!defaults[attr]) {\n return;\n }\n attributes[attr] = defaults[attr];\n }\n if (attributes[attr].indexOf('url(') === 0) {\n return;\n }\n const color = new Color(attributes[attr]);\n attributes[attr] = color\n .setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2))\n .toRgba();\n });\n return attributes;\n}\n","import { DEFAULT_SVG_FONT_SIZE } from '../constants';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { cPath, fSize, svgValidParentsRegEx } from './constants';\nimport { getGlobalStylesForElement } from './getGlobalStylesForElement';\nimport { normalizeAttr } from './normalizeAttr';\nimport { normalizeValue } from './normalizeValue';\nimport { parseFontDeclaration } from './parseFontDeclaration';\nimport { parseStyleAttribute } from './parseStyleAttribute';\nimport { setStrokeFillOpacity } from './setStrokeFillOpacity';\nimport type { CSSRules } from './typedefs';\n\n/**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @param {SVGElement | HTMLElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\nexport function parseAttributes(\n element: HTMLElement | null,\n attributes: string[],\n cssRules?: CSSRules,\n): Record {\n if (!element) {\n return {};\n }\n\n let parentAttributes: Record = {},\n fontSize: number,\n parentFontSize = DEFAULT_SVG_FONT_SIZE;\n\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (\n element.parentNode &&\n svgValidParentsRegEx.test(element.parentNode.nodeName)\n ) {\n parentAttributes = parseAttributes(\n element.parentElement,\n attributes,\n cssRules,\n );\n if (parentAttributes.fontSize) {\n fontSize = parentFontSize = parseUnit(parentAttributes.fontSize);\n }\n }\n\n const ownAttributes: Record = {\n ...attributes.reduce>((memo, attr) => {\n const value = element.getAttribute(attr);\n if (value) {\n memo[attr] = value;\n }\n return memo;\n }, {}),\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ...getGlobalStylesForElement(element, cssRules),\n ...parseStyleAttribute(element),\n };\n\n if (ownAttributes[cPath]) {\n element.setAttribute(cPath, ownAttributes[cPath]);\n }\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n ownAttributes[fSize] = `${fontSize}`;\n }\n\n // this should have its own complex type\n const normalizedStyle: Record<\n string,\n string | boolean | number | number[] | null\n > = {};\n for (const attr in ownAttributes) {\n const normalizedAttr = normalizeAttr(attr);\n const normalizedValue = normalizeValue(\n normalizedAttr,\n ownAttributes[attr],\n parentAttributes,\n fontSize!,\n );\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n parseFontDeclaration(normalizedStyle.font as string, normalizedStyle);\n }\n const mergedAttrs = { ...parentAttributes, ...normalizedStyle };\n return svgValidParentsRegEx.test(element.nodeName)\n ? mergedAttrs\n : setStrokeFillOpacity(mergedAttrs);\n}\n","import { elementMatchesRule } from './elementMatchesRule';\nimport type { CSSRules } from './typedefs';\n\n/**\n * @private\n */\n\nexport function getGlobalStylesForElement(\n element: HTMLElement,\n cssRules: CSSRules = {},\n) {\n let styles: Record = {};\n for (const rule in cssRules) {\n if (elementMatchesRule(element, rule.split(' '))) {\n styles = {\n ...styles,\n ...cssRules[rule],\n };\n }\n }\n return styles;\n}\n","import { kRect } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const rectDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueRectProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedRectProps\n extends SerializedObjectProps,\n UniqueRectProps {}\n\nexport interface RectProps extends FabricObjectProps, UniqueRectProps {}\n\nconst RECT_PROPS = ['rx', 'ry'] as const;\n\nexport class Rect<\n Props extends TOptions = Partial,\n SProps extends SerializedRectProps = SerializedRectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements RectProps\n{\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Rect';\n\n static cacheProperties = [...cacheProperties, ...RECT_PROPS];\n\n static ownDefaults = rectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Rect.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Rect.ownDefaults);\n this.setOptions(options);\n this._initRxRy();\n }\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy() {\n const { rx, ry } = this;\n if (rx && !ry) {\n this.ry = rx;\n } else if (ry && !rx) {\n this.rx = ry;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const { width: w, height: h } = this;\n const x = -w / 2;\n const y = -h / 2;\n const rx = this.rx ? Math.min(this.rx, w / 2) : 0;\n const ry = this.ry ? Math.min(this.ry, h / 2) : 0;\n const isRounded = rx !== 0 || ry !== 0;\n\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded &&\n ctx.bezierCurveTo(\n x + w - kRect * rx,\n y,\n x + w,\n y + kRect * ry,\n x + w,\n y + ry,\n );\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded &&\n ctx.bezierCurveTo(\n x + w,\n y + h - kRect * ry,\n x + w - kRect * rx,\n y + h,\n x + w - rx,\n y + h,\n );\n\n ctx.lineTo(x + rx, y + h);\n isRounded &&\n ctx.bezierCurveTo(\n x + kRect * rx,\n y + h,\n x,\n y + h - kRect * ry,\n x,\n y + h - ry,\n );\n\n ctx.lineTo(x, y + ry);\n isRounded &&\n ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...RECT_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { width, height, rx, ry } = this;\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`)\n * @static\n * @memberOf Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'rx',\n 'ry',\n 'width',\n 'height',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns {@link Rect} instance from an SVG element\n * @static\n * @memberOf Rect\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n left = 0,\n top = 0,\n width = 0,\n height = 0,\n visible = true,\n ...restOfparsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n\n return new this({\n ...options,\n ...restOfparsedAttributes,\n left,\n top,\n width,\n height,\n visible: Boolean(visible && width && height),\n });\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Rect);\nclassRegistry.setSVGClass(Rect);\n","export const LAYOUT_TYPE_INITIALIZATION = 'initialization';\nexport const LAYOUT_TYPE_ADDED = 'added';\nexport const LAYOUT_TYPE_REMOVED = 'removed';\nexport const LAYOUT_TYPE_IMPERATIVE = 'imperative';\nexport const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified';\nexport const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying';\n","import { Point, ZERO } from '../../Point';\nimport type { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { multiplyTransformMatrixArray } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport {\n calcPlaneChangeMatrix,\n sendVectorToPlane,\n} from '../../util/misc/planeChange';\n\n/**\n * @returns 2 points, the tl and br corners of the non rotated bounding box of an object\n * in the {@link group} plane, taking into account objects that {@link group} is their parent\n * but also belong to the active selection.\n */\nexport const getObjectBounds = (\n destinationGroup: Group,\n object: FabricObject,\n): Point[] => {\n const {\n strokeUniform,\n strokeWidth,\n width,\n height,\n group: currentGroup,\n } = object;\n const t =\n currentGroup && currentGroup !== destinationGroup\n ? calcPlaneChangeMatrix(\n currentGroup.calcTransformMatrix(),\n destinationGroup.calcTransformMatrix(),\n )\n : null;\n const objectCenter = t\n ? object.getRelativeCenterPoint().transform(t)\n : object.getRelativeCenterPoint();\n const accountForStroke = !object['isStrokeAccountedForInDimensions']();\n const strokeUniformVector =\n strokeUniform && accountForStroke\n ? sendVectorToPlane(\n new Point(strokeWidth, strokeWidth),\n undefined,\n destinationGroup.calcTransformMatrix(),\n )\n : ZERO;\n const scalingStrokeWidth =\n !strokeUniform && accountForStroke ? strokeWidth : 0;\n const sizeVector = sizeAfterTransform(\n width + scalingStrokeWidth,\n height + scalingStrokeWidth,\n multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true),\n )\n .add(strokeUniformVector)\n .scalarDivide(2);\n return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)];\n};\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_IMPERATIVE,\n} from '../constants';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { getObjectBounds } from './utils';\n\n/**\n * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout.\n * Returning `undefined` signals the `LayoutManager` to skip the layout.\n *\n * In charge of calculating the bounding box of the passed objects.\n */\nexport abstract class LayoutStrategy {\n /**\n * override by subclass for persistence (TS does not support `static abstract`)\n */\n static type = 'strategy';\n\n /**\n * Used by the `LayoutManager` to perform layout\n * @TODO/fix: if this method is calcResult, should calc unconditionally.\n * the condition to not calc should be evaluated by the layoutManager.\n * @returns layout result **OR** `undefined` to skip layout\n */\n public calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n if (this.shouldPerformLayout(context)) {\n return this.calcBoundingBox(objects, context);\n }\n }\n\n shouldPerformLayout({ type, prevStrategy, strategy }: StrictLayoutContext) {\n return (\n type === LAYOUT_TYPE_INITIALIZATION ||\n type === LAYOUT_TYPE_IMPERATIVE ||\n (!!prevStrategy && strategy !== prevStrategy)\n );\n }\n\n shouldLayoutClipPath({ type, target: { clipPath } }: StrictLayoutContext) {\n return (\n type !== LAYOUT_TYPE_INITIALIZATION &&\n clipPath &&\n !clipPath.absolutePositioned\n );\n }\n\n getInitialSize(\n context: StrictLayoutContext & InitializationLayoutContext,\n result: Pick,\n ) {\n return result.size;\n }\n\n /**\n * Override this method to customize layout.\n */\n calcBoundingBox(\n objects: FabricObject[],\n context: StrictLayoutContext,\n ): LayoutStrategyResult | undefined {\n const { type, target } = context;\n if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) {\n return context.overrides;\n }\n if (objects.length === 0) {\n return;\n }\n const { left, top, width, height } = makeBoundingBoxFromPoints(\n objects\n .map((object) => getObjectBounds(target, object))\n .reduce((coords, curr) => coords.concat(curr), []),\n );\n const bboxSize = new Point(width, height);\n const bboxLeftTop = new Point(left, top);\n const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2));\n\n if (type === LAYOUT_TYPE_INITIALIZATION) {\n const actualSize = this.getInitialSize(context, {\n size: bboxSize,\n center: bboxCenter,\n });\n return {\n // in `initialization` we do not account for target's transformation matrix\n center: bboxCenter,\n // TODO: investigate if this is still necessary\n relativeCorrection: new Point(0, 0),\n size: actualSize,\n };\n } else {\n // we send `relativeCenter` up to group's containing plane\n const center = bboxCenter.transform(target.calcOwnMatrix());\n return {\n center,\n size: bboxSize,\n };\n }\n }\n}\n","import type { StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to fit target's objects.\n */\nexport class FitContentLayout extends LayoutStrategy {\n static readonly type = 'fit-content';\n\n /**\n * @override layout on all triggers\n * Override at will\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldPerformLayout(context: StrictLayoutContext) {\n return true;\n }\n}\n\nclassRegistry.setClass(FitContentLayout);\n","import { Point } from '../Point';\nimport {\n CENTER,\n CHANGED,\n MODIFIED,\n MODIFY_PATH,\n MODIFY_POLY,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n iMatrix,\n} from '../constants';\nimport type { Group } from '../shapes/Group';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { invertTransform } from '../util/misc/matrix';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { FitContentLayout } from './LayoutStrategies/FitContentLayout';\nimport type { LayoutStrategy } from './LayoutStrategies/LayoutStrategy';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_OBJECT_MODIFIED,\n LAYOUT_TYPE_OBJECT_MODIFYING,\n} from './constants';\nimport type {\n LayoutContext,\n LayoutResult,\n RegistrationContext,\n StrictLayoutContext,\n} from './types';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TModificationEvents } from '../EventTypeDefs';\n\nconst LAYOUT_MANAGER = 'layoutManager';\n\nexport type SerializedLayoutManager = {\n type: string;\n strategy: string;\n};\n\nexport class LayoutManager {\n private declare _prevLayoutStrategy?: LayoutStrategy;\n protected declare _subscriptions: Map;\n\n strategy: LayoutStrategy;\n\n constructor(strategy: LayoutStrategy = new FitContentLayout()) {\n this.strategy = strategy;\n this._subscriptions = new Map();\n }\n\n public performLayout(context: LayoutContext) {\n const strictContext: StrictLayoutContext = {\n bubbles: true,\n strategy: this.strategy,\n ...context,\n prevStrategy: this._prevLayoutStrategy,\n stopPropagation() {\n this.bubbles = false;\n },\n };\n\n this.onBeforeLayout(strictContext);\n\n const layoutResult = this.getLayoutResult(strictContext);\n if (layoutResult) {\n this.commitLayout(strictContext, layoutResult);\n }\n\n this.onAfterLayout(strictContext, layoutResult);\n this._prevLayoutStrategy = strictContext.strategy;\n }\n\n /**\n * Attach handlers for events that we know will invalidate the layout when\n * performed on child objects ( general transforms ).\n * Returns the disposers for later unsubscribing and cleanup\n * @param {FabricObject} object\n * @param {RegistrationContext & Partial} context\n * @returns {VoidFunction[]} disposers remove the handlers\n */\n protected attachHandlers(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ): VoidFunction[] {\n const { target } = context;\n return (\n [\n MODIFIED,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n CHANGED,\n MODIFY_POLY,\n MODIFY_PATH,\n ] as (TModificationEvents & 'modified')[]\n ).map((key) =>\n object.on(key, (e) =>\n this.performLayout(\n key === MODIFIED\n ? {\n type: LAYOUT_TYPE_OBJECT_MODIFIED,\n trigger: key,\n e,\n target,\n }\n : {\n type: LAYOUT_TYPE_OBJECT_MODIFYING,\n trigger: key,\n e,\n target,\n },\n ),\n ),\n );\n }\n\n /**\n * Subscribe an object to transform events that will trigger a layout change on the parent\n * This is important only for interactive groups.\n * @param object\n * @param context\n */\n protected subscribe(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ) {\n this.unsubscribe(object, context);\n const disposers = this.attachHandlers(object, context);\n this._subscriptions.set(object, disposers);\n }\n\n /**\n * unsubscribe object layout triggers\n */\n protected unsubscribe(\n object: FabricObject,\n _context?: RegistrationContext & Partial,\n ) {\n (this._subscriptions.get(object) || []).forEach((d) => d());\n this._subscriptions.delete(object);\n }\n\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.unsubscribe(object, context));\n }\n\n subscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.subscribe(object, context));\n }\n\n protected onBeforeLayout(context: StrictLayoutContext) {\n const { target, type } = context;\n const { canvas } = target;\n // handle layout triggers subscription\n // @TODO: gate the registration when the group is interactive\n if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) {\n this.subscribeTargets(context);\n } else if (type === LAYOUT_TYPE_REMOVED) {\n this.unsubscribeTargets(context);\n }\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:before', {\n context,\n });\n canvas &&\n canvas.fire('object:layout:before', {\n target,\n context,\n });\n\n if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) {\n const { strategy: _, ...tricklingContext } = context;\n // traverse the tree\n target.forEachObject(\n (object) =>\n (object as Group).layoutManager &&\n (object as Group).layoutManager.performLayout({\n ...tricklingContext,\n bubbles: false,\n target: object as Group,\n }),\n );\n }\n }\n\n protected getLayoutResult(\n context: StrictLayoutContext,\n ): Required | undefined {\n const { target, strategy, type } = context;\n\n const result = strategy.calcLayoutResult(context, target.getObjects());\n\n if (!result) {\n return;\n }\n\n const prevCenter =\n type === LAYOUT_TYPE_INITIALIZATION\n ? new Point()\n : target.getRelativeCenterPoint();\n\n const {\n center: nextCenter,\n correction = new Point(),\n relativeCorrection = new Point(),\n } = result;\n const offset = prevCenter\n .subtract(nextCenter)\n .add(correction)\n .transform(\n // in `initialization` we do not account for target's transformation matrix\n type === LAYOUT_TYPE_INITIALIZATION\n ? iMatrix\n : invertTransform(target.calcOwnMatrix()),\n true,\n )\n .add(relativeCorrection);\n\n return {\n result,\n prevCenter,\n nextCenter,\n offset,\n };\n }\n\n protected commitLayout(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n const {\n result: { size },\n nextCenter,\n } = layoutResult;\n // set dimensions\n target.set({ width: size.x, height: size.y });\n // layout descendants\n this.layoutObjects(context, layoutResult);\n // set position\n // in `initialization` we do not account for target's transformation matrix\n if (context.type === LAYOUT_TYPE_INITIALIZATION) {\n // TODO: what about strokeWidth?\n target.set({\n left:\n context.x ?? nextCenter.x + size.x * resolveOrigin(target.originX),\n top: context.y ?? nextCenter.y + size.y * resolveOrigin(target.originY),\n });\n } else {\n target.setPositionByOrigin(nextCenter, CENTER, CENTER);\n // invalidate\n target.setCoords();\n target.set('dirty', true);\n }\n }\n\n protected layoutObjects(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n // adjust objects to account for new center\n target.forEachObject((object) => {\n object.group === target &&\n this.layoutObject(context, layoutResult, object);\n });\n // adjust clip path to account for new center\n context.strategy.shouldLayoutClipPath(context) &&\n this.layoutObject(context, layoutResult, target.clipPath as FabricObject);\n }\n\n /**\n * @param {FabricObject} object\n * @param {Point} offset\n */\n protected layoutObject(\n context: StrictLayoutContext,\n { offset }: Required,\n object: FabricObject,\n ) {\n // TODO: this is here for cache invalidation.\n // verify if this is necessary since we have explicit\n // cache invalidation at the end of commitLayout\n object.set({\n left: object.left + offset.x,\n top: object.top + offset.y,\n });\n }\n\n protected onAfterLayout(\n context: StrictLayoutContext,\n layoutResult?: LayoutResult,\n ) {\n const {\n target,\n strategy,\n bubbles,\n prevStrategy: _,\n ...bubblingContext\n } = context;\n const { canvas } = target;\n\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:after', {\n context,\n result: layoutResult,\n });\n canvas &&\n canvas.fire('object:layout:after', {\n context,\n result: layoutResult,\n target,\n });\n\n // bubble\n const parent = target.parent;\n if (bubbles && parent?.layoutManager) {\n // add target to context#path\n (bubblingContext.path || (bubblingContext.path = [])).push(target);\n // all parents should invalidate their layout\n parent.layoutManager.performLayout({\n ...bubblingContext,\n target: parent,\n });\n }\n target.set('dirty', true);\n }\n\n dispose() {\n const { _subscriptions } = this;\n _subscriptions.forEach((disposers) => disposers.forEach((d) => d()));\n _subscriptions.clear();\n }\n\n toObject() {\n return {\n type: LAYOUT_MANAGER,\n strategy: (this.strategy.constructor as typeof LayoutStrategy).type,\n };\n }\n\n toJSON() {\n return this.toObject();\n }\n}\n\nclassRegistry.setClass(LayoutManager, LAYOUT_MANAGER);\n","import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';\nimport { createCollectionMixin } from '../Collection';\nimport type {\n TClassProperties,\n TSVGReviver,\n TOptions,\n Abortable,\n} from '../typedefs';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n} from '../util/misc/matrix';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { applyTransformToObject } from '../util/misc/objectTransforms';\nimport { FabricObject } from './Object/FabricObject';\nimport { Rect } from './Rect';\nimport { classRegistry } from '../ClassRegistry';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport { log } from '../util/internals/console';\nimport type {\n ImperativeLayoutOptions,\n LayoutBeforeEvent,\n LayoutAfterEvent,\n} from '../LayoutManager/types';\nimport { LayoutManager } from '../LayoutManager/LayoutManager';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { SerializedLayoutManager } from '../LayoutManager/LayoutManager';\nimport type { FitContentLayout } from '../LayoutManager';\n\n/**\n * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case.\n * We could have used a boolean in the constructor, as we did previously, but we think the boolean\n * would stay in the group's constructor interface and create confusion, therefore it was removed.\n * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called.\n */\nclass NoopLayoutManager extends LayoutManager {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n performLayout() {}\n}\n\nexport interface GroupEvents extends ObjectEvents, CollectionEvents {\n 'layout:before': LayoutBeforeEvent;\n 'layout:after': LayoutAfterEvent;\n}\n\nexport interface GroupOwnProps {\n subTargetCheck: boolean;\n interactive: boolean;\n}\n\nexport interface SerializedGroupProps\n extends SerializedObjectProps,\n GroupOwnProps {\n objects: SerializedObjectProps[];\n layoutManager: SerializedLayoutManager;\n}\n\nexport interface GroupProps extends FabricObjectProps, GroupOwnProps {\n layoutManager: LayoutManager;\n}\n\nexport const groupDefaultValues: Partial> = {\n strokeWidth: 0,\n subTargetCheck: false,\n interactive: false,\n};\n\n/**\n * @fires object:added\n * @fires object:removed\n * @fires layout:before\n * @fires layout:after\n */\nexport class Group\n extends createCollectionMixin(\n FabricObject,\n )\n implements GroupProps\n{\n /**\n * Used to optimize performance\n * set to `false` if you don't need contained objects to be targets of events\n * @default\n * @type boolean\n */\n declare subTargetCheck: boolean;\n\n /**\n * Used to allow targeting of object inside groups.\n * set to true if you want to select an object inside a group.\\\n * **REQUIRES** `subTargetCheck` set to true\n * This will be not removed but slowly replaced with a method setInteractive\n * that will take care of enabling subTargetCheck and necessary object events.\n * There is too much attached to group interactivity to just be evaluated by a\n * boolean in the code\n * @default\n * @deprecated\n * @type boolean\n */\n declare interactive: boolean;\n\n declare layoutManager: LayoutManager;\n\n /**\n * Used internally to optimize performance\n * Once an object is selected, instance is rendered without the selected object.\n * This way instance is cached only once for the entire interaction with the selected object.\n * @private\n */\n protected _activeObjects: FabricObject[] = [];\n\n static type = 'Group';\n\n static ownDefaults: Record = groupDefaultValues;\n private __objectSelectionTracker: (ev: ObjectEvents['selected']) => void;\n private __objectSelectionDisposer: (ev: ObjectEvents['deselected']) => void;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Group.ownDefaults,\n };\n }\n\n /**\n * Constructor\n *\n * @param {FabricObject[]} [objects] instance objects\n * @param {Object} [options] Options object\n */\n constructor(objects: FabricObject[] = [], options: Partial = {}) {\n super();\n Object.assign(this, Group.ownDefaults);\n this.setOptions(options);\n this.groupInit(objects, options);\n }\n\n /**\n * Shared code between group and active selection\n * Meant to be used by the constructor.\n */\n protected groupInit(\n objects: FabricObject[],\n options: {\n layoutManager?: LayoutManager;\n top?: number;\n left?: number;\n },\n ) {\n this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller\n\n this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(\n this,\n true,\n );\n this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(\n this,\n false,\n );\n\n this.forEachObject((object) => {\n this.enterGroup(object, false);\n });\n\n // perform initial layout\n this.layoutManager = options.layoutManager ?? new LayoutManager();\n this.layoutManager.performLayout({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: this,\n targets: [...objects],\n // @TODO remove this concept from the layout manager.\n // Layout manager will calculate the correct position,\n // group options can override it later.\n x: options.left,\n y: options.top,\n });\n }\n\n /**\n * Checks if object can enter group and logs relevant warnings\n * @private\n * @param {FabricObject} object\n * @returns\n */\n canEnterGroup(object: FabricObject) {\n if (object === this || this.isDescendantOf(object)) {\n // prevent circular object tree\n log(\n 'error',\n 'Group: circular object trees are not supported, this call has no effect',\n );\n return false;\n } else if (this._objects.indexOf(object) !== -1) {\n // is already in the objects array\n log(\n 'error',\n 'Group: duplicate objects are not supported inside group, this call has no effect',\n );\n return false;\n }\n return true;\n }\n\n /**\n * Override this method to enhance performance (for groups with a lot of objects).\n * If Overriding, be sure not pass illegal objects to group - it will break your app.\n * @private\n */\n protected _filterObjectsBeforeEnteringGroup(objects: FabricObject[]) {\n return objects.filter((object, index, array) => {\n // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates)\n return this.canEnterGroup(object) && array.indexOf(object) === index;\n });\n }\n\n /**\n * Add objects\n * @param {...FabricObject[]} objects\n */\n add(...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.add(...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {FabricObject[]} objects Object to insert\n * @param {Number} index Index to insert object at\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.insertAt(index, ...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Remove objects\n * @param {...FabricObject[]} objects\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed);\n return removed;\n }\n\n _onObjectAdded(object: FabricObject) {\n this.enterGroup(object, true);\n this.fire('object:added', { target: object });\n object.fire('added', { target: this });\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _onObjectRemoved(object: FabricObject, removeParentTransform?: boolean) {\n this.exitGroup(object, removeParentTransform);\n this.fire('object:removed', { target: object });\n object.fire('removed', { target: this });\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n this.layoutManager.performLayout({\n type,\n targets,\n target: this,\n });\n }\n\n _onStackOrderChanged() {\n this._set('dirty', true);\n }\n\n /**\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n const prev = this[key as keyof this];\n super._set(key, value);\n if (key === 'canvas' && prev !== value) {\n (this._objects || []).forEach((object) => {\n object._set(key, value);\n });\n }\n return this;\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return this.subTargetCheck;\n }\n\n /**\n * Remove all objects\n * @returns {FabricObject[]} removed objects\n */\n removeAll() {\n this._activeObjects = [];\n return this.remove(...this._objects);\n }\n\n /**\n * keeps track of the selected objects\n * @private\n */\n __objectSelectionMonitor(\n selected: T,\n {\n target: object,\n }: ObjectEvents[T extends true ? 'selected' : 'deselected'],\n ) {\n const activeObjects = this._activeObjects;\n if (selected) {\n activeObjects.push(object);\n this._set('dirty', true);\n } else if (activeObjects.length > 0) {\n const index = activeObjects.indexOf(object);\n if (index > -1) {\n activeObjects.splice(index, 1);\n this._set('dirty', true);\n }\n }\n }\n\n /**\n * @private\n * @param {boolean} watch\n * @param {FabricObject} object\n */\n _watchObject(watch: boolean, object: FabricObject) {\n // make sure we listen only once\n watch && this._watchObject(false, object);\n if (watch) {\n object.on('selected', this.__objectSelectionTracker);\n object.on('deselected', this.__objectSelectionDisposer);\n } else {\n object.off('selected', this.__objectSelectionTracker);\n object.off('deselected', this.__objectSelectionDisposer);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n object.group && object.group.remove(object);\n object._set('parent', this);\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n _enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n if (removeParentTransform) {\n // can this be converted to utils (sendObjectToPlane)?\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n invertTransform(this.calcTransformMatrix()),\n object.calcTransformMatrix(),\n ),\n );\n }\n this._shouldSetNestedCoords() && object.setCoords();\n object._set('group', this);\n object._set('canvas', this.canvas);\n this._watchObject(true, object);\n const activeObject =\n this.canvas &&\n this.canvas.getActiveObject &&\n this.canvas.getActiveObject();\n // if we are adding the activeObject in a group\n if (\n activeObject &&\n (activeObject === object || object.isDescendantOf(activeObject))\n ) {\n this._activeObjects.push(object);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n object._set('parent', undefined);\n object._set('canvas', undefined);\n }\n\n /**\n * Executes the inner fabric logic of exiting a group.\n * - Stop watching the object\n * - Remove the object from the optimization map this._activeObjects\n * - unset the group property of the object\n * @protected\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n object._set('group', undefined);\n if (!removeParentTransform) {\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n this.calcTransformMatrix(),\n object.calcTransformMatrix(),\n ),\n );\n object.setCoords();\n }\n this._watchObject(false, object);\n const index =\n this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1;\n if (index > -1) {\n this._activeObjects.splice(index, 1);\n }\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache() {\n const ownCache = FabricObject.prototype.shouldCache.call(this);\n if (ownCache) {\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n }\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow() {\n if (super.willDrawShadow()) {\n return true;\n }\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if instance or its group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache(): boolean {\n return this.ownCaching || (!!this.parent && this.parent.isOnACache());\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject(ctx: CanvasRenderingContext2D) {\n this._renderBackground(ctx);\n for (let i = 0; i < this._objects.length; i++) {\n // TODO: handle rendering edge case somehow\n if (\n this.canvas?.preserveObjectStacking &&\n this._objects[i].group !== this\n ) {\n ctx.save();\n ctx.transform(...invertTransform(this.calcTransformMatrix()));\n this._objects[i].render(ctx);\n ctx.restore();\n } else if (this._objects[i].group === this) {\n this._objects[i].render(ctx);\n }\n }\n this._drawClipPath(ctx, this.clipPath);\n }\n\n /**\n * @override\n * @return {Boolean}\n */\n setCoords() {\n super.setCoords();\n this._shouldSetNestedCoords() &&\n this.forEachObject((object) => object.setCoords());\n }\n\n triggerLayout(options: ImperativeLayoutOptions = {}) {\n this.layoutManager.performLayout({\n target: this,\n type: LAYOUT_TYPE_IMPERATIVE,\n ...options,\n });\n }\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render(ctx: CanvasRenderingContext2D) {\n this._transformDone = true;\n super.render(ctx);\n this._transformDone = false;\n }\n\n /**\n *\n * @private\n * @param {'toObject'|'toDatalessObject'} [method]\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {FabricObject[]} serialized objects\n */\n __serializeObjects(\n method: 'toObject' | 'toDatalessObject',\n propertiesToInclude?: string[],\n ) {\n const _includeDefaultValues = this.includeDefaultValues;\n return this._objects\n .filter(function (obj) {\n return !obj.excludeFromExport;\n })\n .map(function (obj) {\n const originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n const data = obj[method || 'toObject'](propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n // delete data.version;\n return data;\n });\n }\n\n /**\n * Returns object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit<\n GroupProps & TClassProperties,\n keyof SerializedGroupProps\n >,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SerializedGroupProps {\n const layoutManager = this.layoutManager.toObject();\n\n return {\n ...super.toObject([\n 'subTargetCheck',\n 'interactive',\n ...propertiesToInclude,\n ]),\n ...(layoutManager.strategy !== 'fit-content' || this.includeDefaultValues\n ? { layoutManager }\n : {}),\n objects: this.__serializeObjects(\n 'toObject',\n propertiesToInclude as string[],\n ),\n };\n }\n\n toString() {\n return `#`;\n }\n\n dispose() {\n this.layoutManager.unsubscribeTargets({\n targets: this.getObjects(),\n target: this,\n });\n this._activeObjects = [];\n this.forEachObject((object) => {\n this._watchObject(false, object);\n object.dispose();\n });\n super.dispose();\n }\n\n /**\n * @private\n */\n _createSVGBgRect(reviver?: TSVGReviver) {\n if (!this.backgroundColor) {\n return '';\n }\n const fillStroke = Rect.prototype._toSVG.call(this);\n const commons = fillStroke.indexOf('COMMON_PARTS');\n fillStroke[commons] = 'for=\"group\" ';\n const markup = fillStroke.join('');\n return reviver ? reviver(markup) : markup;\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG(reviver?: TSVGReviver) {\n const svgString = ['\\n'];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('\\n');\n return svgString;\n }\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles(): string {\n const opacity =\n typeof this.opacity !== 'undefined' && this.opacity !== 1\n ? `opacity: ${this.opacity};`\n : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].join('');\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const svgString = [];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n return this._createBaseClipPathSVGMarkup(svgString, {\n reviver,\n });\n }\n\n /**\n * @todo support loading from svg\n * @private\n * @static\n * @memberOf Group\n * @param {Object} object Object to create a group from\n * @returns {Promise}\n */\n static fromObject>(\n { type, objects = [], layoutManager, ...options }: T,\n abortable?: Abortable,\n ) {\n return Promise.all([\n enlivenObjects(objects, abortable),\n enlivenObjectEnlivables(options, abortable),\n ]).then(([objects, hydratedOptions]) => {\n const group = new this(objects, {\n ...options,\n ...hydratedOptions,\n layoutManager: new NoopLayoutManager(),\n });\n if (layoutManager) {\n const layoutClass = classRegistry.getClass(\n layoutManager.type,\n );\n const strategyClass = classRegistry.getClass(\n layoutManager.strategy,\n );\n group.layoutManager = new layoutClass(new strategyClass());\n } else {\n group.layoutManager = new LayoutManager();\n }\n group.layoutManager.subscribeTargets({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: group,\n targets: group.getObjects(),\n });\n group.setCoords();\n return group;\n });\n }\n}\n\nclassRegistry.setClass(Group);\n","import type { GroupProps } from '../../shapes/Group';\nimport { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\n\n/**\n * TODO experiment with different layout manager and svg results ( fixed fit content )\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group\n * @return {FabricObject | Group}\n */\nexport const groupSVGElements = (\n elements: FabricObject[],\n options?: Partial,\n) => {\n if (elements && elements.length === 1) {\n return elements[0];\n }\n return new Group(elements, options);\n};\n","import type { TSize } from '../../typedefs';\n\n/**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\nexport const findScaleToFit = (source: TSize, destination: TSize) =>\n Math.min(\n destination.width / source.width,\n destination.height / source.height,\n );\n\n/**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\nexport const findScaleToCover = (source: TSize, destination: TSize) =>\n Math.max(\n destination.width / source.width,\n destination.height / source.height,\n );\n","import { reNum } from '../../parser/constants';\n\nconst commaWsp = `\\\\s*,?\\\\s*`;\n\n/**\n * p for param\n * using \"bad naming\" here because it makes the regex much easier to read\n * p is a number that is preceded by an arbitary number of spaces, maybe 0,\n * a comma or not, and then possibly more spaces or not.\n */\nconst p = `${commaWsp}(${reNum})`;\n\n// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;\n\n// const reLineCommand = `(L) ?(?:${p}${p} ?)+`;\n\n// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;\n\n// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;\n\n// const reClosePathCommand = String.raw`(Z)\\s*`;\n\n// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;\n\n// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;\n\nexport const reArcCommandPoints = `${p}${p}${p}${commaWsp}([01])${commaWsp}([01])${p}${p}`;\n// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;\n\n// export const rePathCommandGroups =\n// `(?:(?:${reMoveToCommand})` +\n// `|(?:${reLineCommand})` +\n// `|(?:${reHorizontalLineCommand})` +\n// `|(?:${reVerticalLineCommand})` +\n// `|(?:${reClosePathCommand})` +\n// `|(?:${reCubicCurveCommand})` +\n// `|(?:${reCubicCurveShortcutCommand})` +\n// `|(?:${reQuadraticCurveCommand})` +\n// `|(?:${reQuadraticCurveShortcutCommand})` +\n// `|(?:${reArcCommand}))`;\n\nexport const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = >basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = >basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example Usage\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n for (let out = null; (out = regExpArcCommandPoints.exec(matchStr)); ) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n","// TODO this file needs to go away, cross browser style support is not fabricjs domain.\n\n/**\n * wrapper for setting element's style\n * @param {HTMLElement} element\n * @param {Object | string} styles\n */\nexport function setStyle(\n element: HTMLElement,\n styles: string | Record,\n) {\n const elementStyle = element.style;\n if (!elementStyle || !styles) {\n return;\n } else if (typeof styles === 'string') {\n elementStyle.cssText += ';' + styles;\n } else {\n Object.entries(styles).forEach(([property, value]) =>\n elementStyle.setProperty(property, value),\n );\n }\n}\n","import type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { sendObjectToPlane } from './planeChange';\nimport { Group } from '../../shapes/Group';\n/**\n * Merges 2 clip paths into one visually equal clip path\n *\n * **IMPORTANT**:\\\n * Does **NOT** clone the arguments, clone them proir if necessary.\n *\n * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap.\n * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible.\n *\n * In order to handle the `inverted` property we follow logic described in the following cases:\\\n * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\\\n * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\\\n * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged.\n *\n * @memberOf fabric.util\n * @param {fabric.Object} c1\n * @param {fabric.Object} c2\n * @returns {fabric.Object} merged clip path\n */\nexport const mergeClipPaths = (c1: FabricObject, c2: FabricObject) => {\n let a = c1,\n b = c2;\n if (a.inverted && !b.inverted) {\n // case (2)\n a = c2;\n b = c1;\n }\n // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane\n sendObjectToPlane(b, b.group?.calcTransformMatrix(), a.calcTransformMatrix());\n // assign the `inverted` prop to the wrapping group\n const inverted = a.inverted && b.inverted;\n if (inverted) {\n // case (1)\n a.inverted = b.inverted = false;\n }\n return new Group([a], { clipPath: b, inverted });\n};\n","/**\n * Returns random number between 2 specified ones.\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\nexport const getRandomInt = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n","import { getFabricWindow } from '../../env';\nimport { noop } from '../../constants';\nimport type { Abortable } from '../../typedefs';\nimport { SignalAbortedError } from './console';\n\ntype requestOptions = Abortable & {\n onComplete?: (xhr: XMLHttpRequest) => void;\n};\n\n/**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @deprecated this has to go away, we can use a modern browser method to do the same.\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n\nexport function request(url: string, options: requestOptions = {}) {\n const onComplete = options.onComplete || noop,\n xhr = new (getFabricWindow().XMLHttpRequest)(),\n signal = options.signal,\n abort = function () {\n xhr.abort();\n },\n removeListener = function () {\n signal && signal.removeEventListener('abort', abort);\n xhr.onerror = xhr.ontimeout = noop;\n };\n\n if (signal && signal.aborted) {\n throw new SignalAbortedError('request');\n } else if (signal) {\n signal.addEventListener('abort', abort, { once: true });\n }\n\n /** @ignore */\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4) {\n removeListener();\n onComplete(xhr);\n xhr.onreadystatechange = noop;\n }\n };\n\n xhr.onerror = xhr.ontimeout = removeListener;\n\n xhr.open('get', url, true);\n\n xhr.send();\n return xhr;\n}\n","import { CENTER, SCALE_X, SCALE_Y } from '../constants';\nimport type { FabricImage } from '../shapes/Image';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { qrDecompose } from './misc/matrix';\n\ntype FabricObjectWithTransformMatrix = FabricObject & {\n transformMatrix?: TMat2D;\n};\n\n/**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n */\nconst _assignTransformMatrixProps = (\n object: FabricObjectWithTransformMatrix,\n) => {\n if (object.transformMatrix) {\n const { scaleX, scaleY, angle, skewX } = qrDecompose(\n object.transformMatrix,\n );\n object.flipX = false;\n object.flipY = false;\n object.set(SCALE_X, scaleX);\n object.set(SCALE_Y, scaleY);\n object.angle = angle;\n object.skewX = skewX;\n object.skewY = 0;\n }\n};\n\n/**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n */\nexport const removeTransformMatrixForSvgParsing = (\n object: FabricObjectWithTransformMatrix,\n preserveAspectRatioOptions?: any,\n) => {\n let center = object._findCenterFromElement();\n if (object.transformMatrix) {\n _assignTransformMatrixProps(object);\n center = center.transform(object.transformMatrix);\n }\n delete object.transformMatrix;\n if (preserveAspectRatioOptions) {\n object.scaleX *= preserveAspectRatioOptions.scaleX;\n object.scaleY *= preserveAspectRatioOptions.scaleY;\n (object as FabricImage).cropX = preserveAspectRatioOptions.cropX;\n (object as FabricImage).cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n object.width = preserveAspectRatioOptions.width;\n object.height = preserveAspectRatioOptions.height;\n }\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n","import type { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n/**\n * Rotates `point` around `origin` with `radians`\n * @deprecated use the Point.rotate\n * @param {Point} origin The origin of the rotation\n * @param {Point} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotatePoint = (\n point: Point,\n origin: Point,\n radians: TRadian,\n): Point => point.rotate(radians, origin);\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport { createCanvasElement, setStyle } from '../../util';\nimport type { CSSDimensions } from './util';\nimport { makeElementUnselectable, setCSSDimensions } from './util';\nimport type { CanvasItem } from './StaticCanvasDOMManager';\nimport { StaticCanvasDOMManager } from './StaticCanvasDOMManager';\nimport { setCanvasDimensions } from './util';\nimport { NONE } from '../../constants';\n\nexport class CanvasDOMManager extends StaticCanvasDOMManager {\n upper: CanvasItem;\n container: HTMLDivElement;\n\n constructor(\n arg0?: string | HTMLCanvasElement,\n {\n allowTouchScrolling = false,\n containerClass = '',\n }: {\n allowTouchScrolling?: boolean;\n /**\n * @deprecated here only for backward compatibility\n */\n containerClass?: string;\n } = {},\n ) {\n super(arg0);\n const { el: lowerCanvasEl } = this.lower;\n const upperCanvasEl = this.createUpperCanvas();\n this.upper = { el: upperCanvasEl, ctx: upperCanvasEl.getContext('2d')! };\n this.applyCanvasStyle(lowerCanvasEl, {\n allowTouchScrolling,\n });\n this.applyCanvasStyle(upperCanvasEl, {\n allowTouchScrolling,\n styles: {\n position: 'absolute',\n left: '0',\n top: '0',\n },\n });\n const container = this.createContainerElement();\n container.classList.add(containerClass);\n if (lowerCanvasEl.parentNode) {\n lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl);\n }\n container.append(lowerCanvasEl, upperCanvasEl);\n this.container = container;\n }\n\n protected createUpperCanvas() {\n const { el: lowerCanvasEl } = this.lower;\n const el = createCanvasElement();\n // we assign the same classname of the lowerCanvas\n el.className = lowerCanvasEl.className;\n // but then we remove the lower-canvas specific className\n el.classList.remove('lower-canvas');\n // we add the specific upper-canvas class\n el.classList.add('upper-canvas');\n el.setAttribute('data-fabric', 'top');\n el.style.cssText = lowerCanvasEl.style.cssText;\n el.setAttribute('draggable', 'true');\n return el;\n }\n\n protected createContainerElement() {\n const container = getFabricDocument().createElement('div');\n container.setAttribute('data-fabric', 'wrapper');\n setStyle(container, {\n position: 'relative',\n });\n makeElementUnselectable(container);\n return container;\n }\n\n /**\n * @private\n * @param {HTMLCanvasElement} element canvas element to apply styles on\n */\n protected applyCanvasStyle(\n element: HTMLCanvasElement,\n options: {\n allowTouchScrolling?: boolean;\n styles?: Record;\n },\n ) {\n const { styles, allowTouchScrolling } = options;\n setStyle(element, {\n ...styles,\n 'touch-action': allowTouchScrolling ? 'manipulation' : NONE,\n });\n makeElementUnselectable(element);\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n super.setDimensions(size, retinaScaling);\n const { el, ctx } = this.upper;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial): void {\n super.setCSSDimensions(size);\n setCSSDimensions(this.upper.el, size);\n setCSSDimensions(this.container, size);\n }\n\n cleanupDOM(size: TSize) {\n const container = this.container,\n { el: lowerCanvasEl } = this.lower,\n { el: upperCanvasEl } = this.upper;\n super.cleanupDOM(size);\n container.removeChild(upperCanvasEl);\n container.removeChild(lowerCanvasEl);\n if (container.parentNode) {\n container.parentNode.replaceChild(lowerCanvasEl, container);\n }\n }\n\n dispose() {\n super.dispose();\n getEnv().dispose(this.upper.el);\n // @ts-expect-error disposing\n delete this.upper;\n // @ts-expect-error disposing\n delete this.container;\n }\n}\n","import { dragHandler } from '../controls/drag';\nimport { getActionFromCorner } from '../controls/util';\nimport { Point } from '../Point';\nimport { FabricObject } from '../shapes/Object/FabricObject';\nimport type {\n CanvasEvents,\n ModifierKey,\n TOptionalModifierKey,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport {\n addTransformToObject,\n saveObjectTransform,\n} from '../util/misc/objectTransforms';\nimport type { TCanvasSizeOptions } from './StaticCanvas';\nimport { StaticCanvas } from './StaticCanvas';\nimport { isCollection } from '../Collection';\nimport { isTransparent } from '../util/misc/isTransparent';\nimport type {\n TMat2D,\n TOriginX,\n TOriginY,\n TSize,\n TSVGReviver,\n} from '../typedefs';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { getPointer, isTouchEvent } from '../util/dom_event';\nimport type { IText } from '../shapes/IText/IText';\nimport type { BaseBrush } from '../brushes/BaseBrush';\nimport { pick } from '../util/misc/pick';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { cos, createCanvasElement, sin } from '../util';\nimport { CanvasDOMManager } from './DOMManagers/CanvasDOMManager';\nimport {\n BOTTOM,\n CENTER,\n LEFT,\n MODIFIED,\n RESIZING,\n RIGHT,\n ROTATE,\n SCALE,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CanvasOptions } from './CanvasOptions';\nimport { canvasDefaults } from './CanvasOptions';\nimport { Intersection } from '../Intersection';\nimport { isActiveSelection } from '../util/typeAssertions';\n\n/**\n * Canvas class\n * @class Canvas\n * @extends StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n *\n * @fires object:modified at the end of a transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drag:enter object drag enter\n * @fires drag:leave object drag leave\n * @fires drop:before before drop event. Prepare for the drop event (same native event).\n * @fires drop\n * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event).\n * @example\n * let a: fabric.Object, b: fabric.Object;\n * let flag = false;\n * canvas.add(a, b);\n * a.on('drop:before', opt => {\n * // we want a to accept the drop even though it's below b in the stack\n * flag = this.canDrop(opt.e);\n * });\n * b.canDrop = function(e) {\n * !flag && this.draggableTextDelegate.canDrop(e);\n * }\n * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black'));\n * a.on('drop', opt => {\n * opt.e.defaultPrevented // drop occurred\n * opt.didDrop // drop occurred on canvas\n * opt.target // drop target\n * opt.target !== a && a.set('text', 'I lost');\n * });\n * canvas.on('drop:after', opt => {\n * // inform user who won\n * if(!opt.e.defaultPrevented) {\n * // no winners\n * }\n * else if(!opt.didDrop) {\n * // my objects didn't win, some other lucky object\n * }\n * else {\n * // we have a winner it's opt.target!!\n * }\n * })\n *\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * @fires contextmenu:before\n * @fires contextmenu\n * @example\n * let handler;\n * targets.forEach(target => {\n * target.on('contextmenu:before', opt => {\n * // decide which target should handle the event before canvas hijacks it\n * if (someCaseHappens && opt.targets.includes(target)) {\n * handler = target;\n * }\n * });\n * target.on('contextmenu', opt => {\n * // do something fantastic\n * });\n * });\n * canvas.on('contextmenu', opt => {\n * if (!handler) {\n * // no one takes responsibility, it's always left to me\n * // let's show them how it's done!\n * }\n * });\n *\n */\nexport class SelectableCanvas\n extends StaticCanvas\n implements Omit\n{\n declare _objects: FabricObject[];\n\n // transform config\n declare uniformScaling: boolean;\n declare uniScaleKey: TOptionalModifierKey;\n declare centeredScaling: boolean;\n declare centeredRotation: boolean;\n declare centeredKey: TOptionalModifierKey;\n declare altActionKey: TOptionalModifierKey;\n\n // selection config\n declare selection: boolean;\n declare selectionKey: TOptionalModifierKey | ModifierKey[];\n declare altSelectionKey: TOptionalModifierKey;\n declare selectionColor: string;\n declare selectionDashArray: number[];\n declare selectionBorderColor: string;\n declare selectionLineWidth: number;\n declare selectionFullyContained: boolean;\n\n // cursors\n declare hoverCursor: CSSStyleDeclaration['cursor'];\n declare moveCursor: CSSStyleDeclaration['cursor'];\n declare defaultCursor: CSSStyleDeclaration['cursor'];\n declare freeDrawingCursor: CSSStyleDeclaration['cursor'];\n declare notAllowedCursor: CSSStyleDeclaration['cursor'];\n\n declare containerClass: string;\n\n // target find config\n declare perPixelTargetFind: boolean;\n declare targetFindTolerance: number;\n declare skipTargetFind: boolean;\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n declare isDrawingMode: boolean;\n\n declare preserveObjectStacking: boolean;\n\n // event config\n declare stopContextMenu: boolean;\n declare fireRightClick: boolean;\n declare fireMiddleClick: boolean;\n\n /**\n * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget\n * @type FabricObject[]\n */\n targets: FabricObject[] = [];\n\n /**\n * Keep track of the hovered target\n * @type FabricObject | null\n * @private\n */\n declare _hoveredTarget?: FabricObject;\n\n /**\n * hold the list of nested targets hovered\n * @type FabricObject[]\n * @private\n */\n _hoveredTargets: FabricObject[] = [];\n\n /**\n * hold the list of objects to render\n * @type FabricObject[]\n * @private\n */\n _objectsToRender?: FabricObject[];\n\n /**\n * hold a reference to a data structure that contains information\n * on the current on going transform\n * @type\n * @private\n */\n _currentTransform: Transform | null = null;\n\n /**\n * hold a reference to a data structure used to track the selection\n * box on canvas drag\n * on the current on going transform\n * x, y, deltaX and deltaY are in scene plane\n * @type\n * @private\n */\n protected _groupSelector: {\n x: number;\n y: number;\n deltaX: number;\n deltaY: number;\n } | null = null;\n\n /**\n * internal flag used to understand if the context top requires a cleanup\n * in case this is true, the contextTop will be cleared at the next render\n * @type boolean\n * @private\n */\n contextTopDirty = false;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _absolutePointer holds a reference to the pointer in fabricCanvas/design coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _absolutePointer?: Point;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _pointer holds a reference to the pointer in html coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _pointer?: Point;\n\n /**\n * During a mouse event we may need the target multiple times in multiple functions.\n * _target holds a reference to the target that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * @type {FabricObject}\n */\n protected declare _target?: FabricObject;\n\n static ownDefaults = canvasDefaults;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...SelectableCanvas.ownDefaults };\n }\n\n declare elements: CanvasDOMManager;\n get upperCanvasEl() {\n return this.elements.upper?.el;\n }\n get contextTop() {\n return this.elements.upper?.ctx;\n }\n get wrapperEl() {\n return this.elements.container;\n }\n private declare pixelFindCanvasEl: HTMLCanvasElement;\n private declare pixelFindContext: CanvasRenderingContext2D;\n\n protected declare _isCurrentlyDrawing: boolean;\n declare freeDrawingBrush?: BaseBrush;\n declare _activeObject?: FabricObject;\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new CanvasDOMManager(el, {\n allowTouchScrolling: this.allowTouchScrolling,\n containerClass: this.containerClass,\n });\n this._createCacheCanvas();\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was added\n */\n _onObjectAdded(obj: FabricObject) {\n this._objectsToRender = undefined;\n super._onObjectAdded(obj);\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was removed\n */\n _onObjectRemoved(obj: FabricObject) {\n this._objectsToRender = undefined;\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { deselected: [obj] });\n this._discardActiveObject();\n this.fire('selection:cleared', { deselected: [obj] });\n obj.fire('deselected', {\n target: obj,\n });\n }\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n super._onObjectRemoved(obj);\n }\n\n _onStackOrderChanged() {\n this._objectsToRender = undefined;\n super._onStackOrderChanged();\n }\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender(): FabricObject[] {\n const activeObject = this._activeObject;\n return !this.preserveObjectStacking && activeObject\n ? this._objects\n .filter((object) => !object.group && object !== activeObject)\n .concat(activeObject)\n : this._objects;\n }\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n this.hasLostContext = false;\n }\n !this._objectsToRender &&\n (this._objectsToRender = this._chooseObjectsToRender());\n this.renderCanvas(this.getContext(), this._objectsToRender);\n }\n\n /**\n * text selection is rendered by the active text instance during the rendering cycle\n */\n renderTopLayer(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n }\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * Does not render text selection.\n */\n renderTop() {\n const ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n // todo: how do i know if the after:render is for the top or normal contex?\n this.fire('after:render', { ctx });\n }\n\n /**\n * Set the canvas tolerance value for pixel taret find.\n * Use only integer numbers.\n * @private\n */\n setTargetFindTolerance(value: number) {\n value = Math.round(value);\n this.targetFindTolerance = value;\n const retina = this.getRetinaScaling();\n const size = Math.ceil((value * 2 + 1) * retina);\n this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size;\n this.pixelFindContext.scale(retina, retina);\n }\n\n /**\n * Returns true if object is transparent at a certain location\n * Clarification: this is `is target transparent at location X or are controls there`\n * @TODO this seems dumb that we treat controls with transparency. we can find controls\n * programmatically without painting them, the cache canvas optimization is always valid\n * @param {FabricObject} target Object to check\n * @param {Number} x Left coordinate in viewport space\n * @param {Number} y Top coordinate in viewport space\n * @return {Boolean}\n */\n isTargetTransparent(target: FabricObject, x: number, y: number): boolean {\n const tolerance = this.targetFindTolerance;\n const ctx = this.pixelFindContext;\n this.clearContext(ctx);\n ctx.save();\n ctx.translate(-x + tolerance, -y + tolerance);\n ctx.transform(...this.viewportTransform);\n const selectionBgc = target.selectionBackgroundColor;\n target.selectionBackgroundColor = '';\n target.render(ctx);\n target.selectionBackgroundColor = selectionBgc;\n ctx.restore();\n // our canvas is square, and made around tolerance.\n // so tolerance in this case also represent the center of the canvas.\n const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling());\n return isTransparent(\n ctx,\n enhancedTolerance,\n enhancedTolerance,\n enhancedTolerance,\n );\n }\n\n /**\n * takes an event and determines if selection key has been pressed\n * @private\n * @param {TPointerEvent} e Event object\n */\n _isSelectionKeyPressed(e: TPointerEvent): boolean {\n const sKey = this.selectionKey;\n if (!sKey) {\n return false;\n }\n if (Array.isArray(sKey)) {\n return !!sKey.find((key) => !!key && e[key] === true);\n } else {\n return e[sKey];\n }\n }\n\n /**\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target\n */\n _shouldClearSelection(\n e: TPointerEvent,\n target?: FabricObject,\n ): target is undefined {\n const activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return !!(\n !target ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e)) ||\n (target && !target.evented) ||\n (target && !target.selectable && activeObject && activeObject !== target)\n );\n }\n\n /**\n * This method will take in consideration a modifier key pressed and the control we are\n * about to drag, and try to guess the anchor point ( origin ) of the transormation.\n * This should be really in the realm of controls, and we should remove specific code for legacy\n * embedded actions.\n * @TODO this probably deserve discussion/rediscovery and change/refactor\n * @private\n * @deprecated\n * @param {FabricObject} target\n * @param {string} action\n * @param {boolean} altKey\n * @returns {boolean} true if the transformation should be centered\n */\n private _shouldCenterTransform(\n target: FabricObject,\n action: string,\n modifierKeyPressed: boolean,\n ) {\n if (!target) {\n return;\n }\n\n let centerTransform;\n\n if (\n action === SCALE ||\n action === SCALE_X ||\n action === SCALE_Y ||\n action === RESIZING\n ) {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === ROTATE) {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !modifierKeyPressed : modifierKeyPressed;\n }\n\n /**\n * Given the control clicked, determine the origin of the transform.\n * This is bad because controls can totally have custom names\n * should disappear before release 4.0\n * @private\n * @deprecated\n */\n _getOriginFromCorner(\n target: FabricObject,\n controlName: string,\n ): { x: TOriginX; y: TOriginY } {\n const origin = {\n x: target.originX,\n y: target.originY,\n };\n\n if (!controlName) {\n return origin;\n }\n\n // is a left control ?\n if (['ml', 'tl', 'bl'].includes(controlName)) {\n origin.x = RIGHT;\n // is a right control ?\n } else if (['mr', 'tr', 'br'].includes(controlName)) {\n origin.x = LEFT;\n }\n // is a top control ?\n if (['tl', 'mt', 'tr'].includes(controlName)) {\n origin.y = BOTTOM;\n // is a bottom control ?\n } else if (['bl', 'mb', 'br'].includes(controlName)) {\n origin.y = TOP;\n }\n return origin;\n }\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {FabricObject} target\n * @param {boolean} [alreadySelected] pass true to setup the active control\n */\n _setupCurrentTransform(\n e: TPointerEvent,\n target: FabricObject,\n alreadySelected: boolean,\n ): void {\n const pointer = target.group\n ? // transform pointer to target's containing coordinate plane\n sendPointToPlane(\n this.getScenePoint(e),\n undefined,\n target.group.calcTransformMatrix(),\n )\n : this.getScenePoint(e);\n const { key: corner = '', control } = target.getActiveControl() || {},\n actionHandler =\n alreadySelected && control\n ? control.getActionHandler(e, target, control)?.bind(control)\n : dragHandler,\n action = getActionFromCorner(alreadySelected, corner, e, target),\n altKey = e[this.centeredKey as ModifierKey],\n origin = this._shouldCenterTransform(target, action, altKey)\n ? ({ x: CENTER, y: CENTER } as const)\n : this._getOriginFromCorner(target, corner),\n /**\n * relative to target's containing coordinate plane\n * both agree on every point\n **/\n transform: Transform = {\n target: target,\n action,\n actionHandler,\n actionPerformed: false,\n corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n theta: degreesToRadians(target.angle),\n width: target.width,\n height: target.height,\n shiftKey: e.shiftKey,\n altKey,\n original: {\n ...saveObjectTransform(target),\n originX: origin.x,\n originY: origin.y,\n },\n };\n\n this._currentTransform = transform;\n\n this.fire('before:transform', {\n e,\n transform,\n });\n }\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor(value: CSSStyleDeclaration['cursor']): void {\n this.upperCanvasEl.style.cursor = value;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection(ctx: CanvasRenderingContext2D): void {\n const { x, y, deltaX, deltaY } = this._groupSelector!,\n start = new Point(x, y).transform(this.viewportTransform),\n extent = new Point(x + deltaX, y + deltaY).transform(\n this.viewportTransform,\n ),\n strokeOffset = this.selectionLineWidth / 2;\n let minX = Math.min(start.x, extent.x),\n minY = Math.min(start.y, extent.y),\n maxX = Math.max(start.x, extent.x),\n maxY = Math.max(start.y, extent.y);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n minX += strokeOffset;\n minY += strokeOffset;\n maxX -= strokeOffset;\n maxY -= strokeOffset;\n // selection border\n // @TODO: is _setLineDash still necessary on modern canvas?\n FabricObject.prototype._setLineDash.call(\n this,\n ctx,\n this.selectionDashArray,\n );\n ctx.strokeRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n /**\n * Method that determines what object we are clicking on\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @return {FabricObject | null} the target found\n */\n findTarget(e: TPointerEvent): FabricObject | undefined {\n if (this.skipTargetFind) {\n return undefined;\n }\n\n const pointer = this.getViewportPoint(e),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects();\n\n this.targets = [];\n\n if (activeObject && aObjects.length >= 1) {\n if (activeObject.findControl(pointer, isTouchEvent(e))) {\n // if we hit the corner of the active object, let's return that.\n return activeObject;\n } else if (\n aObjects.length > 1 &&\n // check pointer is over active selection and possibly perform `subTargetCheck`\n this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active selection does not select sub targets like normal groups\n return activeObject;\n } else if (\n activeObject === this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active object is not an active selection\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n const subTargets = this.targets;\n this.targets = [];\n const target = this.searchPossibleTargets(this._objects, pointer);\n if (\n e[this.altSelectionKey as ModifierKey] &&\n target &&\n target !== activeObject\n ) {\n // alt selection: select active object even though it is not the top most target\n // restore targets\n this.targets = subTargets;\n return activeObject;\n }\n return target;\n }\n }\n }\n\n return this.searchPossibleTargets(this._objects, pointer);\n }\n\n /**\n * Checks if the point is inside the object selection area including padding\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point in scene coordinates\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n private _pointIsInObjectSelectionArea(obj: FabricObject, point: Point) {\n // getCoords will already take care of group de-nesting\n let coords = obj.getCoords();\n const viewportZoom = this.getZoom();\n const padding = obj.padding / viewportZoom;\n if (padding) {\n const [tl, tr, br, bl] = coords;\n // what is the angle of the object?\n // we could use getTotalAngle, but is way easier to look at it\n // from how coords are oriented, since if something went wrong\n // at least we are consistent.\n const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x),\n cosP = cos(angleRadians) * padding,\n sinP = sin(angleRadians) * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP;\n\n coords = [\n new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP),\n new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP),\n new Point(br.x + cosPMinusSinP, br.y + cosPSinP),\n new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP),\n ];\n // in case of padding we calculate the new coords on the fly.\n // otherwise we have to maintain 2 sets of coordinates for everything.\n // we can reiterate on storing them.\n // if this is slow, for now the semplification is large and doesn't impact\n // rendering.\n // the idea behind this is that outside target check we don't need ot know\n // where those coords are\n }\n return Intersection.isPointInPolygon(point, coords);\n }\n\n /**\n * Checks point is inside the object selection condition. Either area with padding\n * or over pixels if perPixelTargetFind is enabled\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point from viewport.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget(obj: FabricObject, pointer: Point): boolean {\n if (\n obj &&\n obj.visible &&\n obj.evented &&\n this._pointIsInObjectSelectionArea(\n obj,\n sendPointToPlane(pointer, undefined, this.viewportTransform),\n )\n ) {\n if (\n (this.perPixelTargetFind || obj.perPixelTargetFind) &&\n !(obj as unknown as IText).isEditing\n ) {\n if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {FabricObject} **top most object from given `objects`** that contains pointer\n * @private\n */\n _searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n // Cache all targets where their bounding box contains point.\n let i = objects.length;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n const target = objects[i];\n if (this._checkTarget(target, pointer)) {\n if (isCollection(target) && target.subTargetCheck) {\n const subTarget = this._searchPossibleTargets(\n target._objects as FabricObject[],\n pointer,\n );\n subTarget && this.targets.push(subTarget);\n }\n return target;\n }\n }\n }\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @see {@link _searchPossibleTargets}\n * @param {FabricObject[]} [objects] objects array to look into\n * @param {Point} [pointer] coordinates from viewport to check.\n * @return {FabricObject} **top most object on screen** that contains pointer\n */\n searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n const target = this._searchPossibleTargets(objects, pointer);\n\n // if we found something in this.targets, and the group is interactive, return the innermost subTarget\n // that is still interactive\n // TODO: reverify why interactive. the target should be returned always, but selected only\n // if interactive.\n if (\n target &&\n isCollection(target) &&\n target.interactive &&\n this.targets[0]\n ) {\n /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */\n const targets = this.targets;\n for (let i = targets.length - 1; i > 0; i--) {\n const t = targets[i];\n if (!(isCollection(t) && t.interactive)) {\n // one of the subtargets was not interactive. that is the last subtarget we can return.\n // we can't dig more deep;\n return t;\n }\n }\n return targets[0];\n }\n\n return target;\n }\n\n /**\n * @returns point existing in the same plane as the {@link HTMLCanvasElement},\n * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}.\n * This means that changes to the {@link viewportTransform} do not change the values of the point\n * and it remains unchanged from the viewer's perspective.\n *\n * @example\n * const scenePoint = sendPointToPlane(\n * this.getViewportPoint(e),\n * undefined,\n * canvas.viewportTransform\n * );\n *\n */\n getViewportPoint(e: TPointerEvent) {\n if (this._pointer) {\n return this._pointer;\n }\n return this.getPointer(e, true);\n }\n\n /**\n * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in).\n * This means that changes to the {@link viewportTransform} do not change the values of the point,\n * however, from the viewer's perspective, the point is changed.\n *\n * @example\n * const viewportPoint = sendPointToPlane(\n * this.getScenePoint(e),\n * canvas.viewportTransform\n * );\n *\n */\n getScenePoint(e: TPointerEvent) {\n if (this._absolutePointer) {\n return this._absolutePointer;\n }\n return this.getPointer(e);\n }\n\n /**\n * Returns pointer relative to canvas.\n *\n * @deprecated This method is deprecated since v6 to protect you from misuse.\n * Use {@link getViewportPoint} or {@link getScenePoint} instead.\n *\n * @param {Event} e\n * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene\n * @return {Point}\n */\n getPointer(e: TPointerEvent, fromViewport = false): Point {\n const upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect();\n let pointer = getPointer(e),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0;\n\n if (!boundsWidth || !boundsHeight) {\n if (TOP in bounds && BOTTOM in bounds) {\n boundsHeight = Math.abs(bounds.top - bounds.bottom);\n }\n if (RIGHT in bounds && LEFT in bounds) {\n boundsWidth = Math.abs(bounds.right - bounds.left);\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!fromViewport) {\n pointer = sendPointToPlane(pointer, undefined, this.viewportTransform);\n }\n\n const retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n // If bounds are not available (i.e. not visible), do not apply scale.\n const cssScale =\n boundsWidth === 0 || boundsHeight === 0\n ? new Point(1, 1)\n : new Point(\n upperCanvasEl.width / boundsWidth,\n upperCanvasEl.height / boundsHeight,\n );\n\n return pointer.multiply(cssScale);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: TSize,\n options?: TCanvasSizeOptions,\n ) {\n // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract\n this._resetTransformEventData();\n super._setDimensionsImpl(dimensions, options);\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush &&\n this.freeDrawingBrush._setBrushStyles(this.contextTop);\n }\n }\n\n protected _createCacheCanvas() {\n this.pixelFindCanvasEl = createCanvasElement();\n this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', {\n willReadFrequently: true,\n })!;\n this.setTargetFindTolerance(this.targetFindTolerance);\n }\n\n /**\n * Returns context of top canvas where interactions are drawn\n * @returns {CanvasRenderingContext2D}\n */\n getTopContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns context of canvas where object selection is drawn\n * @alias\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement(): HTMLCanvasElement {\n return this.elements.upper.el;\n }\n\n /**\n * Returns currently active object\n * @return {FabricObject | null} active object\n */\n getActiveObject(): FabricObject | undefined {\n return this._activeObject;\n }\n\n /**\n * Returns an array with the current selected objects\n * @return {FabricObject[]} active objects array\n */\n getActiveObjects(): FabricObject[] {\n const active = this._activeObject;\n return isActiveSelection(active)\n ? active.getObjects()\n : active\n ? [active]\n : [];\n }\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {FabricObject[]} oldObjects old activeObject\n * @param {TPointerEvent} e mouse event triggering the selection events\n */\n _fireSelectionEvents(oldObjects: FabricObject[], e?: TPointerEvent) {\n let somethingChanged = false,\n invalidate = false;\n const objects = this.getActiveObjects(),\n added: FabricObject[] = [],\n removed: FabricObject[] = [];\n\n oldObjects.forEach((target) => {\n if (!objects.includes(target)) {\n somethingChanged = true;\n target.fire('deselected', {\n e,\n target,\n });\n removed.push(target);\n }\n });\n\n objects.forEach((target) => {\n if (!oldObjects.includes(target)) {\n somethingChanged = true;\n target.fire('selected', {\n e,\n target,\n });\n added.push(target);\n }\n });\n\n if (oldObjects.length > 0 && objects.length > 0) {\n invalidate = true;\n somethingChanged &&\n this.fire('selection:updated', {\n e,\n selected: added,\n deselected: removed,\n });\n } else if (objects.length > 0) {\n invalidate = true;\n this.fire('selection:created', {\n e,\n selected: added,\n });\n } else if (oldObjects.length > 0) {\n invalidate = true;\n this.fire('selection:cleared', {\n e,\n deselected: removed,\n });\n }\n invalidate && (this._objectsToRender = undefined);\n }\n\n /**\n * Sets given object as the only active object on canvas\n * @param {FabricObject} object Object to set as an active one\n * @param {TPointerEvent} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n setActiveObject(object: FabricObject, e?: TPointerEvent) {\n // we can't inline this, since _setActiveObject will change what getActiveObjects returns\n const currentActives = this.getActiveObjects();\n const selected = this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return selected;\n }\n\n /**\n * This is supposed to be equivalent to setActiveObject but without firing\n * any event. There is commitment to have this stay this way.\n * This is the functional part of setActiveObject.\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n _setActiveObject(object: FabricObject, e?: TPointerEvent) {\n const prevActiveObject = this._activeObject;\n if (prevActiveObject === object) {\n return false;\n }\n // after calling this._discardActiveObject, this,_activeObject could be undefined\n if (!this._discardActiveObject(e, object) && this._activeObject) {\n // refused to deselect\n return false;\n }\n if (object.onSelect({ e })) {\n return false;\n }\n\n this._activeObject = object;\n\n if (isActiveSelection(object) && prevActiveObject !== object) {\n object.set('canvas', this);\n }\n object.setCoords();\n\n return true;\n }\n\n /**\n * This is supposed to be equivalent to discardActiveObject but without firing\n * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way.\n * This is the functional part of discardActiveObject.\n * @param {Event} [e] Event (passed along when firing \"object:deselected\")\n * @param {Object} object the next object to set as active, reason why we are discarding this\n * @return {Boolean} true if the active object has been discarded\n */\n _discardActiveObject(\n e?: TPointerEvent,\n object?: FabricObject,\n ): this is { _activeObject: undefined } {\n const obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e, object })) {\n return false;\n }\n if (this._currentTransform && this._currentTransform.target === obj) {\n this.endCurrentTransform(e);\n }\n if (isActiveSelection(obj) && obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n }\n this._activeObject = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {Boolean} true if the active object has been discarded\n */\n discardActiveObject(e?: TPointerEvent): this is { _activeObject: undefined } {\n const currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n e,\n deselected: [activeObject!],\n });\n }\n const discarded = this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return discarded;\n }\n\n /**\n * End the current transform.\n * You don't usually need to call this method unless you are interrupting a user initiated transform\n * because of some other event ( a press of key combination, or something that block the user UX )\n * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event\n */\n endCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform;\n this._finalizeCurrentTransform(e);\n if (transform && transform.target) {\n // this could probably go inside _finalizeCurrentTransform\n transform.target.isMoving = false;\n }\n this._currentTransform = null;\n }\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform!,\n target = transform.target,\n options = {\n e,\n target,\n transform,\n action: transform.action,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed) {\n this.fire('object:modified', options);\n target.fire(MODIFIED, options);\n }\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n super.setViewportTransform(vpt);\n const activeObject = this._activeObject;\n if (activeObject) {\n activeObject.setCoords();\n }\n }\n\n /**\n * @override clears active selection ref and interactive canvas elements and contexts\n */\n destroy() {\n // dispose of active selection\n const activeObject = this._activeObject;\n if (isActiveSelection(activeObject)) {\n activeObject.removeAll();\n activeObject.dispose();\n }\n\n delete this._activeObject;\n\n super.destroy();\n\n // free resources\n\n // pixel find canvas\n // @ts-expect-error disposing\n this.pixelFindContext = null;\n // @ts-expect-error disposing\n this.pixelFindCanvasEl = undefined;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n // discard active object and fire events\n this.discardActiveObject();\n // make sure we clear the active object in case it refused to be discarded\n this._activeObject = undefined;\n this.clearContext(this.contextTop);\n super.clear();\n }\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls(ctx: CanvasRenderingContext2D) {\n const activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: 'toObject' | 'toDatalessObject',\n propertiesToInclude: string[],\n ): Record {\n // If the object is part of the current selection group, it should\n // be transformed appropriately\n // i.e. it should be serialised as it would appear if the selection group\n // were to be destroyed.\n const originalProperties = this._realizeGroupTransformOnObject(instance),\n object = super._toObject(instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n instance.set(originalProperties);\n return object;\n }\n\n /**\n * Realizes an object's group transformation on it\n * @private\n * @param {FabricObject} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n private _realizeGroupTransformOnObject(\n instance: FabricObject,\n ): Partial {\n const { group } = instance;\n if (group && isActiveSelection(group) && this._activeObject === group) {\n const layoutProps = [\n 'angle',\n 'flipX',\n 'flipY',\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n ] as (keyof typeof instance)[];\n const originalValues = pick(instance, layoutProps);\n addTransformToObject(instance, group.calcOwnMatrix());\n return originalValues;\n } else {\n return {};\n }\n }\n\n /**\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n // If the object is in a selection group, simulate what would happen to that\n // object when the group is deselected\n const originalProperties = this._realizeGroupTransformOnObject(instance);\n super._setSVGObject(markup, instance, reviver);\n instance.set(originalProperties);\n }\n}\n","import type { ModifierKey, TOptionalModifierKey } from '../EventTypeDefs';\nimport type { TOptions } from '../typedefs';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\n\nexport interface CanvasTransformOptions {\n /**\n * When true, objects can be transformed by one side (unproportionately)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: boolean;\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n uniScaleKey: TOptionalModifierKey;\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: boolean;\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: boolean;\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n centeredKey: TOptionalModifierKey;\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n altActionKey: TOptionalModifierKey;\n}\n\nexport interface CanvasSelectionOptions {\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: boolean;\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type ModifierKey|ModifierKey[]\n * @default\n */\n selectionKey: TOptionalModifierKey | ModifierKey[];\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|ModifierKey\n * @default\n */\n altSelectionKey: TOptionalModifierKey;\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: string;\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: number[];\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: string;\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: number;\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: boolean;\n}\n\nexport interface CanvasCursorOptions {\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n hoverCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n moveCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default default\n */\n defaultCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default crosshair\n */\n freeDrawingCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default not-allowed\n */\n notAllowedCursor: CSSStyleDeclaration['cursor'];\n}\n\nexport interface TargetFindOptions {\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: boolean;\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: number;\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: boolean;\n}\n\nexport interface CanvasEventsOptions {\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: boolean;\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: boolean;\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: boolean;\n\n /**\n * When the option is enabled, PointerEvent is used instead of TPointerEvent.\n * @type Boolean\n * @default\n */\n enablePointerEvents: boolean;\n}\n\nexport interface CanvasOptions\n extends StaticCanvasOptions,\n CanvasTransformOptions,\n CanvasSelectionOptions,\n CanvasCursorOptions,\n TargetFindOptions,\n CanvasEventsOptions {\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n * @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly\n */\n containerClass: string;\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: boolean;\n}\n\nexport type TCanvasOptions = TOptions;\n\nexport const canvasDefaults: TOptions = {\n uniformScaling: true,\n uniScaleKey: 'shiftKey',\n centeredScaling: false,\n centeredRotation: false,\n centeredKey: 'altKey',\n altActionKey: 'shiftKey',\n\n selection: true,\n selectionKey: 'shiftKey',\n selectionColor: 'rgba(100, 100, 255, 0.3)',\n selectionDashArray: [],\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n selectionLineWidth: 1,\n selectionFullyContained: false,\n\n hoverCursor: 'move',\n moveCursor: 'move',\n defaultCursor: 'default',\n freeDrawingCursor: 'crosshair',\n notAllowedCursor: 'not-allowed',\n\n perPixelTargetFind: false,\n targetFindTolerance: 0,\n skipTargetFind: false,\n\n stopContextMenu: false,\n fireRightClick: false,\n fireMiddleClick: false,\n enablePointerEvents: false,\n\n containerClass: 'canvas-container',\n\n preserveObjectStacking: false,\n};\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport type { ITextBehavior } from '../shapes/IText/ITextBehavior';\nimport { removeFromArray } from '../util/internals/removeFromArray';\nimport type { Canvas } from './Canvas';\n\n/**\n * In charge of synchronizing all interactive text instances of a canvas\n */\nexport class TextEditingManager {\n private targets: ITextBehavior[] = [];\n private declare target?: ITextBehavior;\n private __disposer: VoidFunction;\n\n constructor(canvas: Canvas) {\n const cb = () => {\n const { hiddenTextarea } =\n (canvas.getActiveObject() as ITextBehavior) || {};\n hiddenTextarea && hiddenTextarea.focus();\n };\n const el = canvas.upperCanvasEl;\n el.addEventListener('click', cb);\n this.__disposer = () => el.removeEventListener('click', cb);\n }\n\n exitTextEditing() {\n this.target = undefined;\n this.targets.forEach((target) => {\n if (target.isEditing) {\n target.exitEditing();\n }\n });\n }\n\n add(target: ITextBehavior) {\n this.targets.push(target);\n }\n\n remove(target: ITextBehavior) {\n this.unregister(target);\n removeFromArray(this.targets, target);\n }\n\n register(target: ITextBehavior) {\n this.target = target;\n }\n\n unregister(target: ITextBehavior) {\n if (target === this.target) {\n this.target = undefined;\n }\n }\n\n onMouseMove(e: TPointerEvent) {\n this.target?.isEditing && this.target.updateSelectionOnMouseMove(e);\n }\n\n clear() {\n this.targets = [];\n this.target = undefined;\n }\n\n dispose() {\n this.clear();\n this.__disposer();\n // @ts-expect-error disposing\n delete this.__disposer;\n }\n}\n","import { classRegistry } from '../ClassRegistry';\nimport { NONE } from '../constants';\nimport type {\n CanvasEvents,\n DragEventData,\n ObjectEvents,\n TPointerEvent,\n TPointerEventNames,\n Transform,\n} from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\nimport type { Group } from '../shapes/Group';\nimport type { IText } from '../shapes/IText/IText';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { isTouchEvent, stopEvent } from '../util/dom_event';\nimport { getDocumentFromElement, getWindowFromElement } from '../util/dom_misc';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { isActiveSelection } from '../util/typeAssertions';\nimport type { CanvasOptions, TCanvasOptions } from './CanvasOptions';\nimport { SelectableCanvas } from './SelectableCanvas';\nimport { TextEditingManager } from './TextEditingManager';\n\nconst addEventOptions = { passive: false } as EventListenerOptions;\n\nconst getEventPoints = (canvas: Canvas, e: TPointerEvent) => {\n const viewportPoint = canvas.getViewportPoint(e);\n const scenePoint = canvas.getScenePoint(e);\n return {\n viewportPoint,\n scenePoint,\n pointer: viewportPoint,\n absolutePointer: scenePoint,\n };\n};\n\n// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers\n// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.\n// few bytes but why give it away.\nconst addListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.addEventListener(...args);\nconst removeListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.removeEventListener(...args);\n\nconst syntheticEventConfig = {\n mouse: {\n in: 'over',\n out: 'out',\n targetIn: 'mouseover',\n targetOut: 'mouseout',\n canvasIn: 'mouse:over',\n canvasOut: 'mouse:out',\n },\n drag: {\n in: 'enter',\n out: 'leave',\n targetIn: 'dragenter',\n targetOut: 'dragleave',\n canvasIn: 'drag:enter',\n canvasOut: 'drag:leave',\n },\n} as const;\n\ntype TSyntheticEventContext = {\n mouse: { e: TPointerEvent };\n drag: DragEventData;\n};\n\nexport class Canvas extends SelectableCanvas implements CanvasOptions {\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n declare mainTouchId?: number;\n\n declare enablePointerEvents: boolean;\n\n /**\n * Holds a reference to a setTimeout timer for event synchronization\n * @type number\n * @private\n */\n private declare _willAddMouseDown: number;\n\n /**\n * Holds a reference to an object on the canvas that is receiving the drag over event.\n * @type FabricObject\n * @private\n */\n private declare _draggedoverTarget?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas from where the drag operation started\n * @type FabricObject\n * @private\n */\n private declare _dragSource?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas that is the current drop target\n * May differ from {@link _draggedoverTarget}\n * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow\n * @type FabricObject\n * @private\n */\n private declare _dropTarget: FabricObject | undefined;\n\n private _isClick: boolean;\n\n textEditingManager = new TextEditingManager(this);\n\n constructor(el?: string | HTMLCanvasElement, options: TCanvasOptions = {}) {\n super(el, options);\n // bind event handlers\n (\n [\n '_onMouseDown',\n '_onTouchStart',\n '_onMouseMove',\n '_onMouseUp',\n '_onTouchEnd',\n '_onResize',\n // '_onGesture',\n // '_onDrag',\n // '_onShake',\n // '_onLongPress',\n // '_onOrientationChange',\n '_onMouseWheel',\n '_onMouseOut',\n '_onMouseEnter',\n '_onContextMenu',\n '_onDoubleClick',\n '_onDragStart',\n '_onDragEnd',\n '_onDragProgress',\n '_onDragOver',\n '_onDragEnter',\n '_onDragLeave',\n '_onDrop',\n ] as (keyof this)[]\n ).forEach((eventHandler) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n this[eventHandler] = (this[eventHandler] as Function).bind(this);\n });\n // register event handlers\n this.addOrRemove(addListener, 'add');\n }\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n private _getEventPrefix() {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n }\n\n addOrRemove(functor: any, _eventjsFunctor: 'add' | 'remove') {\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(getWindowFromElement(canvasElement), 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove,\n addEventOptions,\n );\n functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);\n functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragstart', this._onDragStart);\n functor(canvasElement, 'dragend', this._onDragEnd);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n // eventjs[eventjsFunctor](\n // canvasElement,\n // 'orientation',\n // this._onOrientationChange\n // );\n // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n // }\n }\n\n /**\n * Removes all event listeners\n */\n removeListeners() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n private _onMouseWheel(e: MouseEvent) {\n this.__onMouseWheel(e);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onMouseOut(e: TPointerEvent) {\n const target = this._hoveredTarget;\n const shared = {\n e,\n ...getEventPoints(this, e),\n };\n this.fire('mouse:out', { ...shared, target });\n this._hoveredTarget = undefined;\n target && target.fire('mouseout', { ...shared });\n this._hoveredTargets.forEach((nestedTarget) => {\n this.fire('mouse:out', { ...shared, target: nestedTarget });\n nestedTarget && nestedTarget.fire('mouseout', { ...shared });\n });\n this._hoveredTargets = [];\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n private _onMouseEnter(e: TPointerEvent) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', {\n e,\n ...getEventPoints(this, e),\n });\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n }\n\n /**\n * supports native like text dragging\n * @private\n * @param {DragEvent} e\n */\n private _onDragStart(e: DragEvent) {\n this._isClick = false;\n const activeObject = this.getActiveObject();\n if (activeObject && activeObject.onDragStart(e)) {\n this._dragSource = activeObject;\n const options = { e, target: activeObject };\n this.fire('dragstart', options);\n activeObject.fire('dragstart', options);\n addListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n return;\n }\n stopEvent(e);\n }\n\n /**\n * First we clear top context where the effects are being rendered.\n * Then we render the effects.\n * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.\n * @private\n */\n private _renderDragEffects(\n e: DragEvent,\n source?: FabricObject,\n target?: FabricObject,\n ) {\n let dirty = false;\n // clear top context\n const dropTarget = this._dropTarget;\n if (dropTarget && dropTarget !== source && dropTarget !== target) {\n dropTarget.clearContextTop();\n dirty = true;\n }\n source?.clearContextTop();\n target !== source && target?.clearContextTop();\n // render effects\n const ctx = this.contextTop;\n ctx.save();\n ctx.transform(...this.viewportTransform);\n if (source) {\n ctx.save();\n source.transform(ctx);\n source.renderDragSourceEffect(e);\n ctx.restore();\n dirty = true;\n }\n if (target) {\n ctx.save();\n target.transform(ctx);\n target.renderDropTargetEffect(e);\n ctx.restore();\n dirty = true;\n }\n ctx.restore();\n dirty && (this.contextTopDirty = true);\n }\n\n /**\n * supports native like text dragging\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n * @private\n * @param {DragEvent} e\n */\n private _onDragEnd(e: DragEvent) {\n const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE,\n dropTarget = didDrop ? this._activeObject : undefined,\n options = {\n e,\n target: this._dragSource as FabricObject,\n subTargets: this.targets,\n dragSource: this._dragSource as FabricObject,\n didDrop,\n dropTarget: dropTarget as FabricObject,\n };\n removeListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n this.fire('dragend', options);\n this._dragSource && this._dragSource.fire('dragend', options);\n delete this._dragSource;\n // we need to call mouse up synthetically because the browser won't\n this._onMouseUp(e);\n }\n\n /**\n * fire `drag` event on canvas and drag source\n * @private\n * @param {DragEvent} e\n */\n private _onDragProgress(e: DragEvent) {\n const options = {\n e,\n target: this._dragSource as FabricObject | undefined,\n dragSource: this._dragSource as FabricObject | undefined,\n dropTarget: this._draggedoverTarget as FabricObject,\n };\n this.fire('drag', options);\n this._dragSource && this._dragSource.fire('drag', options);\n }\n\n /**\n * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.\n * Override at will\n */\n protected findDragTargets(e: DragEvent) {\n this.targets = [];\n const target = this._searchPossibleTargets(\n this._objects,\n this.getViewportPoint(e),\n );\n return {\n target,\n targets: [...this.targets],\n };\n }\n\n /**\n * prevent default to allow drop event to be fired\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets\n * @private\n * @param {DragEvent} [e] Event object fired on Event.js shake\n */\n private _onDragOver(e: DragEvent) {\n const eventType = 'dragover';\n const { target, targets } = this.findDragTargets(e);\n const dragSource = this._dragSource as FabricObject;\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource,\n canDrop: false,\n dropTarget: undefined,\n };\n let dropTarget;\n // fire on canvas\n this.fire(eventType, options);\n // make sure we fire dragenter events before dragover\n // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it\n this._fireEnterLeaveEvents(target, options);\n if (target) {\n if (target.canDrop(e)) {\n dropTarget = target;\n }\n target.fire(eventType, options);\n }\n // propagate the event to subtargets\n for (let i = 0; i < targets.length; i++) {\n const subTarget = targets[i];\n // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)\n // TODO: verify if those should loop in inverse order then?\n // what is the order of subtargets?\n if (subTarget.canDrop(e)) {\n dropTarget = subTarget;\n }\n subTarget.fire(eventType, options);\n }\n // render drag effects now that relations between source and target is clear\n this._renderDragEffects(e, dragSource, dropTarget);\n this._dropTarget = dropTarget;\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragEnter(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n };\n this.fire('dragenter', options);\n // fire dragenter on targets\n this._fireEnterLeaveEvents(target, options);\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragLeave(e: DragEvent) {\n const options = {\n e,\n target: this._draggedoverTarget,\n subTargets: this.targets,\n dragSource: this._dragSource,\n };\n this.fire('dragleave', options);\n\n // fire dragleave on targets\n this._fireEnterLeaveEvents(undefined, options);\n this._renderDragEffects(e, this._dragSource);\n this._dropTarget = undefined;\n // clear targets\n this.targets = [];\n this._hoveredTargets = [];\n }\n\n /**\n * `drop:before` is a an event that allows you to schedule logic\n * before the `drop` event. Prefer `drop` event always, but if you need\n * to run some drop-disabling logic on an event, since there is no way\n * to handle event handlers ordering, use `drop:before`\n * @private\n * @param {Event} e\n */\n private _onDrop(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = this._basicEventHandler('drop:before', {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n ...getEventPoints(this, e),\n });\n // will be set by the drop target\n options.didDrop = false;\n // will be set by the drop target, used in case options.target refuses the drop\n options.dropTarget = undefined;\n // fire `drop`\n this._basicEventHandler('drop', options);\n // inform canvas of the drop\n // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it\n // use for side effects\n this.fire('drop:after', options);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onContextMenu(e: TPointerEvent): false {\n const target = this.findTarget(e),\n subTargets = this.targets || [];\n const options = this._basicEventHandler('contextmenu:before', {\n e,\n target,\n subTargets,\n });\n // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves\n this.stopContextMenu && stopEvent(e);\n this._basicEventHandler('contextmenu', options);\n return false;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onDoubleClick(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData();\n }\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId(evt: TouchEvent | PointerEvent): number {\n const changedTouches = (evt as TouchEvent).changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return (evt as PointerEvent).pointerId;\n }\n\n return -1;\n }\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent(evt: TPointerEvent): boolean {\n if ((evt as PointerEvent).isPrimary === true) {\n return true;\n }\n if ((evt as PointerEvent).isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {\n return true;\n }\n if ((evt as TouchEvent).changedTouches) {\n return (\n (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId\n );\n }\n return true;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart(e: TouchEvent) {\n e.preventDefault();\n if (this.mainTouchId === undefined) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(canvasElement);\n addListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n addListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(\n canvasElement,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown(e: TPointerEvent) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n const doc = getDocumentFromElement(canvasElement);\n addListener(doc, `${eventTypePrefix}up`, this._onMouseUp as EventListener);\n addListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd(e: TouchEvent) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n delete this.mainTouchId;\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(() => {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(\n this.upperCanvasEl,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n this._willAddMouseDown = 0;\n }, 400) as unknown as number;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp(e: TPointerEvent) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n addListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove(e: TPointerEvent) {\n const activeObject = this.getActiveObject();\n !this.allowTouchScrolling &&\n (!activeObject ||\n // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before\n // we must not prevent the event's default behavior in order for the window to start dragging\n !activeObject.shouldStartDragging(e)) &&\n e.preventDefault &&\n e.preventDefault();\n this.__onMouseMove(e);\n }\n\n /**\n * @private\n */\n _onResize() {\n this.calcOffset();\n this._resetTransformEventData();\n }\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender(target: FabricObject | undefined) {\n const activeObject = this.getActiveObject();\n // if just one of them is available or if they are both but are different objects\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return (\n !!activeObject !== !!target ||\n (activeObject && target && activeObject !== target)\n );\n }\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'up:before');\n\n const transform = this._currentTransform;\n const isClick = this._isClick;\n const target = this._target;\n\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'up');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n let shouldRender = false;\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n if (!isClick) {\n const targetWasActive = target === this._activeObject;\n this.handleSelection(e);\n if (!shouldRender) {\n shouldRender =\n this._shouldRender(target) ||\n (!targetWasActive && target === this._activeObject);\n }\n }\n let pointer, corner;\n if (target) {\n const found = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n const { key, control } = found || {};\n corner = key;\n if (\n target.selectable &&\n target !== this._activeObject &&\n target.activeOn === 'up'\n ) {\n this.setActiveObject(target, e);\n shouldRender = true;\n } else if (control) {\n const mouseUpHandler = control.getMouseUpHandler(e, target, control);\n if (mouseUpHandler) {\n pointer = this.getScenePoint(e);\n mouseUpHandler.call(control, e, transform!, pointer.x, pointer.y);\n }\n }\n target.isMoving = false;\n }\n // if we are ending up a transform on a different control or a new object\n // fire the original mouse up from the corner that started the transform\n if (\n transform &&\n (transform.target !== target || transform.corner !== corner)\n ) {\n const originalControl =\n transform.target && transform.target.controls[transform.corner],\n originalMouseUpHandler =\n originalControl &&\n originalControl.getMouseUpHandler(\n e,\n transform.target,\n originalControl,\n );\n pointer = pointer || this.getScenePoint(e);\n originalMouseUpHandler &&\n originalMouseUpHandler.call(\n originalControl,\n e,\n transform,\n pointer.x,\n pointer.y,\n );\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up');\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = undefined);\n if (shouldRender) {\n this.requestRenderAll();\n } else if (!isClick && !(this._activeObject as IText)?.isEditing) {\n this.renderTop();\n }\n }\n\n _basicEventHandler(\n eventType: T,\n options: (CanvasEvents & ObjectEvents)[T],\n ) {\n const { target, subTargets = [] } = options as {\n target?: FabricObject;\n subTargets: FabricObject[];\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n for (let i = 0; i < subTargets.length; i++) {\n subTargets[i] !== target && subTargets[i].fire(eventType, options);\n }\n return options;\n }\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {TPointerEvent} e event from mouse\n * @param {TPointerEventNames} eventType\n */\n _handleEvent(e: TPointerEvent, eventType: T) {\n const target = this._target,\n targets = this.targets || [],\n options: CanvasEvents[`mouse:${T}`] = {\n e,\n target,\n subTargets: targets,\n ...getEventPoints(this, e),\n transform: this._currentTransform,\n ...(eventType === 'up:before' || eventType === 'up'\n ? {\n isClick: this._isClick,\n currentTarget: this.findTarget(e),\n // set by the preceding `findTarget` call\n currentSubTargets: this.targets,\n }\n : {}),\n } as CanvasEvents[`mouse:${T}`];\n this.fire(`mouse:${eventType}`, options);\n // this may be a little be more complicated of what we want to handle\n target && target.fire(`mouse${eventType}`, options);\n for (let i = 0; i < targets.length; i++) {\n targets[i] !== target && targets[i].fire(`mouse${eventType}`, options);\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode(e: TPointerEvent) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e);\n this.requestRenderAll();\n }\n // TODO: this is a scene point so it should be renamed\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });\n this._handleEvent(e, 'down');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode(e: TPointerEvent) {\n if (this._isCurrentlyDrawing) {\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseMove(pointer, {\n e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode(e: TPointerEvent) {\n const pointer = this.getScenePoint(e);\n if (this.freeDrawingBrush) {\n this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({\n e: e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n } else {\n this._isCurrentlyDrawing = false;\n }\n this._handleEvent(e, 'up');\n }\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown(e: TPointerEvent) {\n this._isClick = true;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n\n let target: FabricObject | undefined = this._target;\n\n // if right/middle click just fire events\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'down');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n let shouldRender = this._shouldRender(target);\n let grouped = false;\n if (this.handleMultiSelection(e, target)) {\n // active object might have changed while grouping\n target = this._activeObject;\n grouped = true;\n shouldRender = true;\n } else if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n // we start a group selector rectangle if\n // selection is enabled\n // and there is no target, or the following 3 conditions are satisfied:\n // target is not selectable ( otherwise we selected it )\n // target is not editing\n // target is not already selected ( otherwise we drag )\n if (\n this.selection &&\n (!target ||\n (!target.selectable &&\n !(target as IText).isEditing &&\n target !== this._activeObject))\n ) {\n const p = this.getScenePoint(e);\n this._groupSelector = {\n x: p.x,\n y: p.y,\n deltaY: 0,\n deltaX: 0,\n };\n }\n\n if (target) {\n const alreadySelected = target === this._activeObject;\n if (target.selectable && target.activeOn === 'down') {\n this.setActiveObject(target, e);\n }\n const handle = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n if (target === this._activeObject && (handle || !grouped)) {\n this._setupCurrentTransform(e, target, alreadySelected);\n const control = handle ? handle.control : undefined,\n pointer = this.getScenePoint(e),\n mouseDownHandler =\n control && control.getMouseDownHandler(e, target, control);\n mouseDownHandler &&\n mouseDownHandler.call(\n control,\n e,\n this._currentTransform!,\n pointer.x,\n pointer.y,\n );\n }\n }\n // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering\n // run before firing the `down` event to give the dev a chance to populate it themselves\n shouldRender && (this._objectsToRender = undefined);\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n shouldRender && this.requestRenderAll();\n }\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData() {\n this._target = undefined;\n this._pointer = undefined;\n this._absolutePointer = undefined;\n }\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData(e: TPointerEvent) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getViewportPoint(e);\n this._absolutePointer = sendPointToPlane(\n this._pointer,\n undefined,\n this.viewportTransform,\n );\n this._target = this._currentTransform\n ? this._currentTransform.target\n : this.findTarget(e);\n }\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove(e: TPointerEvent) {\n this._isClick = false;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'move:before');\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n const groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n const pointer = this.getScenePoint(e);\n\n groupSelector.deltaX = pointer.x - groupSelector.x;\n groupSelector.deltaY = pointer.y - groupSelector.y;\n\n this.renderTop();\n } else if (!this._currentTransform) {\n const target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(e, target);\n } else {\n this._transformObject(e);\n }\n this.textEditingManager.onMouseMove(e);\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n }\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {\n const _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target,\n oldTarget: _hoveredTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n }\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Object} data Event object fired on dragover\n * @private\n */\n _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {\n const draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target,\n oldTarget: draggedoverTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._draggedoverTarget = target;\n }\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Object} data Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents(\n type: T,\n {\n target,\n oldTarget,\n fireCanvas,\n e,\n ...data\n }: TSyntheticEventContext[T] & {\n target?: FabricObject;\n oldTarget?: FabricObject;\n fireCanvas?: boolean;\n },\n ) {\n const { targetIn, targetOut, canvasIn, canvasOut } =\n syntheticEventConfig[type];\n const targetChanged = oldTarget !== target;\n\n if (oldTarget && targetChanged) {\n const outOpt: CanvasEvents[typeof canvasOut] = {\n ...data,\n e,\n target: oldTarget,\n nextTarget: target,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasOut, outOpt);\n oldTarget.fire(targetOut, outOpt);\n }\n if (target && targetChanged) {\n const inOpt: CanvasEvents[typeof canvasIn] = {\n ...data,\n e,\n target,\n previousTarget: oldTarget,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasIn, inOpt);\n target.fire(targetIn, inOpt);\n }\n }\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n }\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject(e: TPointerEvent) {\n const scenePoint = this.getScenePoint(e),\n transform = this._currentTransform!,\n target = transform.target,\n // transform pointer to target's containing coordinate plane\n // both pointer and object should agree on every point\n localPointer = target.group\n ? sendPointToPlane(\n scenePoint,\n undefined,\n target.group.calcTransformMatrix(),\n )\n : scenePoint;\n transform.shiftKey = e.shiftKey;\n transform.altKey = !!this.centeredKey && e[this.centeredKey];\n\n this._performTransformAction(e, transform, localPointer);\n transform.actionPerformed && this.requestRenderAll();\n }\n\n /**\n * @private\n */\n _performTransformAction(\n e: TPointerEvent,\n transform: Transform,\n pointer: Point,\n ) {\n const { action, actionHandler, target } = transform;\n\n const actionPerformed =\n !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y);\n actionPerformed && target.setCoords();\n\n // this object could be created from the function in the control handlers\n if (action === 'drag' && actionPerformed) {\n transform.target.isMoving = true;\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n }\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return;\n }\n let hoverCursor = target.hoverCursor || this.hoverCursor;\n const activeSelection = isActiveSelection(this._activeObject)\n ? this._activeObject\n : null,\n // only show proper corner when group selection is not active\n corner =\n (!activeSelection || target.group !== activeSelection) &&\n // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target.findControl(this.getViewportPoint(e));\n\n if (!corner) {\n if ((target as Group).subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets\n .concat()\n .reverse()\n .map((_target) => {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n } else {\n const control = corner.control;\n this.setCursor(control.cursorStyleHandler(e, control, target));\n }\n }\n\n /**\n * ## Handles multiple selection\n * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)\n * - sets the active object in case it is not set or in case there is a single active object left under active selection.\n * ---\n * - If the active object is the active selection we add/remove `target` from it\n * - If not, add the active object and `target` to the active selection and make it the active object.\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target target of event to select/deselect\n * @returns true if grouping occurred\n */\n protected handleMultiSelection(e: TPointerEvent, target?: FabricObject) {\n const activeObject = this._activeObject;\n const isAS = isActiveSelection(activeObject);\n if (\n // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.\n !!activeObject &&\n this._isSelectionKeyPressed(e) &&\n this.selection &&\n // on top of that the user also has to hit a target that is selectable.\n !!target &&\n target.selectable &&\n // group target and active object only if they are different objects\n // else we try to find a subtarget of `ActiveSelection`\n (activeObject !== target || isAS) &&\n // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`\n // if it is then we want to remove `target` from it\n (isAS ||\n (!target.isDescendantOf(activeObject) &&\n !activeObject.isDescendantOf(target))) &&\n // target accepts selection\n !target.onSelect({ e }) &&\n // make sure we are not on top of a control\n !activeObject.getActiveControl()\n ) {\n if (isAS) {\n const prevActiveObjects = activeObject.getObjects();\n if (target === activeObject) {\n const pointer = this.getViewportPoint(e);\n target =\n // first search active objects for a target to remove\n this.searchPossibleTargets(prevActiveObjects, pointer) ||\n // if not found, search under active selection for a target to add\n // `prevActiveObjects` will be searched but we already know they will not be found\n this.searchPossibleTargets(this._objects, pointer);\n // if nothing is found bail out\n if (!target || !target.selectable) {\n return false;\n }\n }\n if (target.group === activeObject) {\n // `target` is part of active selection => remove it\n activeObject.remove(target);\n this._hoveredTarget = target;\n this._hoveredTargets = [...this.targets];\n // if after removing an object we are left with one only...\n if (activeObject.size() === 1) {\n // activate last remaining object\n // deselecting the active selection will remove the remaining object from it\n this._setActiveObject(activeObject.item(0), e);\n }\n } else {\n // `target` isn't part of active selection => add it\n activeObject.multiSelectAdd(target);\n this._hoveredTarget = activeObject;\n this._hoveredTargets = [...this.targets];\n }\n this._fireSelectionEvents(prevActiveObjects, e);\n } else {\n (activeObject as IText).exitEditing &&\n (activeObject as IText).exitEditing();\n // add the active object and the target to the active selection and set it as the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n const newActiveSelection = new klass([], {\n /**\n * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd}\n * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref\n */\n canvas: this,\n });\n newActiveSelection.multiSelectAdd(activeObject, target);\n this._hoveredTarget = newActiveSelection;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(newActiveSelection, e);\n this._fireSelectionEvents([activeObject], e);\n }\n return true;\n }\n return false;\n }\n\n /**\n * ## Handles selection\n * - selects objects that are contained in (and possibly intersecting) the selection bounding box\n * - sets the active object\n * ---\n * runs on mouse up after a mouse move\n */\n protected handleSelection(e: TPointerEvent) {\n if (!this.selection || !this._groupSelector) {\n return false;\n }\n const { x, y, deltaX, deltaY } = this._groupSelector,\n point1 = new Point(x, y),\n point2 = point1.add(new Point(deltaX, deltaY)),\n tl = point1.min(point2),\n br = point1.max(point2),\n size = br.subtract(tl);\n\n const collectedObjects = this.collectObjects(\n {\n left: tl.x,\n top: tl.y,\n width: size.x,\n height: size.y,\n },\n { includeIntersecting: !this.selectionFullyContained },\n ) as FabricObject[];\n\n const objects =\n // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down\n // should it be handled as is?\n point1.eq(point2)\n ? collectedObjects[0]\n ? [collectedObjects[0]]\n : []\n : collectedObjects.length > 1\n ? collectedObjects\n .filter((object) => !object.onSelect({ e }))\n .reverse()\n : // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case\n collectedObjects;\n\n // set active object\n if (objects.length === 1) {\n // set as active object\n this.setActiveObject(objects[0], e);\n } else if (objects.length > 1) {\n // add to active selection and make it the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n this.setActiveObject(new klass(objects, { canvas: this }), e);\n }\n\n // cleanup\n this._groupSelector = null;\n return true;\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n clear() {\n this.textEditingManager.clear();\n super.clear();\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n destroy() {\n this.removeListeners();\n this.textEditingManager.dispose();\n super.destroy();\n }\n}\n","export const linearDefaultCoords = {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n};\n\nexport const radialDefaultCoords = {\n ...linearDefaultCoords,\n r1: 0,\n r2: 0,\n};\n","/**\n *\n * @param value value to check if NaN\n * @param [valueIfNaN]\n * @returns `fallback` is `value is NaN\n */\nexport const ifNaN = (value: number, valueIfNaN?: number) => {\n return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value;\n};\n","import { ifNaN } from '../util/internals/ifNaN';\nimport { capValue } from '../util/misc/capValue';\n\nconst RE_PERCENT = /^(\\d+\\.\\d+)%|(\\d+)%$/;\n\nexport function isPercent(value: string | null) {\n return value && RE_PERCENT.test(value);\n}\n\n/**\n *\n * @param value\n * @param valueIfNaN\n * @returns ∈ [0, 1]\n */\nexport function parsePercent(\n value: string | number | null | undefined,\n valueIfNaN?: number,\n) {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string'\n ? parseFloat(value) / (isPercent(value) ? 100 : 1)\n : NaN;\n return capValue(0, ifNaN(parsed, valueIfNaN), 1);\n}\n","import { Color } from '../../color/Color';\nimport { parsePercent } from '../../parser/percent';\nimport { ifNaN } from '../../util/internals/ifNaN';\nimport type { ColorStop } from '../typedefs';\n\nconst RE_KEY_VALUE_PAIRS = /\\s*;\\s*/;\nconst RE_KEY_VALUE = /\\s*:\\s*/;\n\nfunction parseColorStop(el: SVGStopElement, multiplier: number) {\n let colorValue, opacity;\n const style = el.getAttribute('style');\n if (style) {\n const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (let i = keyValuePairs.length; i--; ) {\n const [key, value] = keyValuePairs[i]\n .split(RE_KEY_VALUE)\n .map((s) => s.trim());\n if (key === 'stop-color') {\n colorValue = value;\n } else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n const color = new Color(\n colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)',\n );\n\n return {\n offset: parsePercent(el.getAttribute('offset'), 0),\n color: color.toRgb(),\n opacity:\n ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) *\n color.getAlpha() *\n multiplier,\n };\n}\n\nexport function parseColorStops(\n el: SVGGradientElement,\n opacityAttr: string | null,\n) {\n const colorStops: ColorStop[] = [],\n colorStopEls = el.getElementsByTagName('stop'),\n multiplier = parsePercent(opacityAttr, 1);\n for (let i = colorStopEls.length; i--; ) {\n colorStops.push(parseColorStop(colorStopEls[i], multiplier));\n }\n return colorStops;\n}\n","import type { GradientType, GradientUnits } from '../typedefs';\n\nexport function parseType(el: SVGGradientElement): GradientType {\n return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT'\n ? 'linear'\n : 'radial';\n}\n\nexport function parseGradientUnits(el: SVGGradientElement): GradientUnits {\n return el.getAttribute('gradientUnits') === 'userSpaceOnUse'\n ? 'pixels'\n : 'percentage';\n}\n","import { isPercent } from '../../parser/percent';\nimport type { TSize } from '../../typedefs';\nimport type { GradientCoords, GradientType, GradientUnits } from '../typedefs';\nimport { parseGradientUnits, parseType } from './misc';\n\nfunction convertPercentUnitsToValues<\n T extends GradientType,\n K extends keyof GradientCoords,\n>(\n valuesToConvert: Record,\n { width, height, gradientUnits }: TSize & { gradientUnits: GradientUnits },\n) {\n let finalValue;\n return (Object.keys(valuesToConvert) as K[]).reduce(\n (acc, prop) => {\n const propValue = valuesToConvert[prop];\n if (propValue === 'Infinity') {\n finalValue = 1;\n } else if (propValue === '-Infinity') {\n finalValue = 0;\n } else {\n finalValue =\n typeof propValue === 'string' ? parseFloat(propValue) : propValue;\n if (typeof propValue === 'string' && isPercent(propValue)) {\n finalValue *= 0.01;\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= width;\n }\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= height;\n }\n }\n }\n }\n acc[prop] = finalValue;\n return acc;\n },\n {} as Record,\n );\n}\n\nfunction getValue(el: SVGGradientElement, key: string) {\n return el.getAttribute(key);\n}\n\nexport function parseLinearCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'x1') || 0,\n y1: getValue(el, 'y1') || 0,\n x2: getValue(el, 'x2') || '100%',\n y2: getValue(el, 'y2') || 0,\n };\n}\n\nexport function parseRadialCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%',\n y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%',\n r1: 0,\n x2: getValue(el, 'cx') || '50%',\n y2: getValue(el, 'cy') || '50%',\n r2: getValue(el, 'r') || '50%',\n };\n}\n\nexport function parseCoords(el: SVGGradientElement, size: TSize) {\n return convertPercentUnitsToValues(\n parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el),\n {\n ...size,\n gradientUnits: parseGradientUnits(el),\n },\n );\n}\n","import { Color } from '../color/Color';\nimport { iMatrix } from '../constants';\nimport { parseTransformAttribute } from '../parser/parseTransformAttribute';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { linearDefaultCoords, radialDefaultCoords } from './constants';\nimport { parseColorStops } from './parser/parseColorStops';\nimport { parseCoords } from './parser/parseCoords';\nimport { parseType, parseGradientUnits } from './parser/misc';\nimport type {\n ColorStop,\n GradientCoords,\n GradientOptions,\n GradientType,\n GradientUnits,\n SVGOptions,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { isPath } from '../util/typeAssertions';\n\n/**\n * Gradient class\n * @class Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n */\nexport class Gradient<\n S,\n T extends GradientType = S extends GradientType ? S : 'linear',\n> {\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetX: number;\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetY: number;\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n declare gradientTransform?: TMat2D;\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type GradientUnits\n * @default 'pixels'\n */\n declare gradientUnits: GradientUnits;\n\n /**\n * Gradient type linear or radial\n * @type GradientType\n * @default 'linear'\n */\n declare type: T;\n\n /**\n * Defines how the gradient is located in space and spread\n * @type GradientCoords\n */\n declare coords: GradientCoords;\n\n /**\n * Defines how many colors a gradient has and how they are located on the axis\n * defined by coords\n * @type GradientCoords\n */\n declare colorStops: ColorStop[];\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number | string\n */\n declare readonly id: string | number;\n\n static type = 'Gradient';\n\n constructor(options: GradientOptions) {\n const {\n type = 'linear' as T,\n gradientUnits = 'pixels',\n coords = {},\n colorStops = [],\n offsetX = 0,\n offsetY = 0,\n gradientTransform,\n id,\n } = options || {};\n Object.assign(this, {\n type,\n gradientUnits,\n coords: {\n ...(type === 'radial' ? radialDefaultCoords : linearDefaultCoords),\n ...coords,\n },\n colorStops,\n offsetX,\n offsetY,\n gradientTransform,\n id: id ? `${id}_${uid()}` : uid(),\n });\n }\n\n /**\n * Adds another colorStop\n * @param {Record} colorStop Object with offset and color\n * @return {Gradient} thisArg\n */\n addColorStop(colorStops: Record) {\n for (const position in colorStops) {\n const color = new Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha(),\n });\n }\n return this;\n }\n\n /**\n * Returns object representation of a gradient\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object}\n */\n toObject(propertiesToInclude?: (keyof this | string)[]) {\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: this.type,\n coords: { ...this.coords },\n colorStops: this.colorStops.map((colorStop) => ({ ...colorStop })),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform\n ? [...this.gradientTransform]\n : undefined,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {FabricObject} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG(\n object: FabricObject,\n {\n additionalTransform: preTransform,\n }: { additionalTransform?: string } = {},\n ) {\n const markup = [],\n transform = (\n this.gradientTransform\n ? this.gradientTransform.concat()\n : iMatrix.concat()\n ) as TMat2D,\n gradientUnits =\n this.gradientUnits === 'pixels'\n ? 'userSpaceOnUse'\n : 'objectBoundingBox';\n // colorStops must be sorted ascending, and guarded against deep mutations\n const colorStops = this.colorStops\n .map((colorStop) => ({ ...colorStop }))\n .sort((a, b) => {\n return a.offset - b.offset;\n });\n\n let offsetX = -this.offsetX,\n offsetY = -this.offsetY;\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n } else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n // todo what about polygon/polyline?\n if (isPath(object) && this.gradientUnits !== 'percentage') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n\n const commonAttributes = [\n `id=\"SVGID_${this.id}\"`,\n `gradientUnits=\"${gradientUnits}\"`,\n `gradientTransform=\"${\n preTransform ? preTransform + ' ' : ''\n }${matrixToSVG(transform)}\"`,\n '',\n ].join(' ');\n\n if (this.type === 'linear') {\n const { x1, y1, x2, y2 } = this.coords;\n markup.push(\n '\\n',\n );\n } else if (this.type === 'radial') {\n const { x1, y1, x2, y2, r1, r2 } = this\n .coords as GradientCoords<'radial'>;\n const needsSwap = r1 > r2;\n // svg radial gradient has just 1 radius. the biggest.\n markup.push(\n '\\n',\n );\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops.reverse(); // mutates array\n colorStops.forEach((colorStop) => {\n colorStop.offset = 1 - colorStop.offset;\n });\n }\n const minRadius = Math.min(r1, r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n const maxRadius = Math.max(r1, r2),\n percentageShift = minRadius / maxRadius;\n colorStops.forEach((colorStop) => {\n colorStop.offset += percentageShift * (1 - colorStop.offset);\n });\n }\n }\n\n colorStops.forEach(({ color, offset, opacity }) => {\n markup.push(\n '\\n',\n );\n });\n\n markup.push(\n this.type === 'linear' ? '' : '',\n '\\n',\n );\n\n return markup.join('');\n }\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasGradient {\n const { x1, y1, x2, y2, r1, r2 } = this.coords as GradientCoords<'radial'>;\n const gradient =\n this.type === 'linear'\n ? ctx.createLinearGradient(x1, y1, x2, y2)\n : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);\n\n this.colorStops.forEach(({ color, opacity, offset }) => {\n gradient.addColorStop(\n offset,\n typeof opacity !== 'undefined'\n ? new Color(color).setAlpha(opacity).toRgba()\n : color,\n );\n });\n\n return gradient;\n }\n\n static async fromObject(\n options: GradientOptions<'linear'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'radial'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'linear'> | GradientOptions<'radial'>,\n ) {\n const { colorStops, gradientTransform } = options;\n return new this({\n ...options,\n colorStops: colorStops\n ? colorStops.map((colorStop) => ({ ...colorStop }))\n : undefined,\n gradientTransform: gradientTransform ? [...gradientTransform] : undefined,\n });\n }\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link Gradient} instance from an SVG element\n * @static\n * @memberOf Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {FabricObject} instance\n * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @return {Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n *\n * @example\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n static fromElement(\n el: SVGGradientElement,\n instance: FabricObject,\n svgOptions: SVGOptions,\n ): Gradient {\n const gradientUnits = parseGradientUnits(el);\n const center = instance._findCenterFromElement();\n return new this({\n id: el.getAttribute('id') || undefined,\n type: parseType(el),\n coords: parseCoords(el, {\n width: svgOptions.viewBoxWidth || svgOptions.width,\n height: svgOptions.viewBoxHeight || svgOptions.height,\n }),\n colorStops: parseColorStops(el, svgOptions.opacity),\n gradientUnits,\n gradientTransform: parseTransformAttribute(\n el.getAttribute('gradientTransform') || '',\n ),\n ...(gradientUnits === 'pixels'\n ? {\n offsetX: instance.width / 2 - center.x,\n offsetY: instance.height / 2 - center.y,\n }\n : {\n offsetX: 0,\n offsetY: 0,\n }),\n });\n }\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Gradient, 'gradient');\nclassRegistry.setClass(Gradient, 'linear');\nclassRegistry.setClass(Gradient, 'radial');\n","import { config } from '../config';\nimport type { Abortable, TCrossOrigin, TMat2D, TSize } from '../typedefs';\nimport { ifNaN } from '../util/internals/ifNaN';\nimport { uid } from '../util/internals/uid';\nimport { loadImage } from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { toFixed } from '../util/misc/toFixed';\nimport { classRegistry } from '../ClassRegistry';\nimport type {\n PatternRepeat,\n PatternOptions,\n SerializedPatternOptions,\n} from './types';\nimport { log } from '../util/internals/console';\n\n/**\n * @see {@link http://fabricjs.com/patterns demo}\n * @see {@link http://fabricjs.com/dynamic-patterns demo}\n */\nexport class Pattern {\n static type = 'Pattern';\n\n /**\n * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern'\n * or utils like isPattern, or instance of to indentify a pattern in your code.\n * Will be removed in future versiones\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n return 'pattern';\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * @type PatternRepeat\n * @defaults\n */\n repeat: PatternRepeat = 'repeat';\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX = 0;\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY = 0;\n\n /**\n * @type TCrossOrigin\n * @default\n */\n crossOrigin: TCrossOrigin = '';\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @todo verify if using the identity matrix as default makes the rest of the code more easy\n * @type Array\n * @default\n */\n declare patternTransform?: TMat2D;\n\n /**\n * The actual pixel source of the pattern\n */\n declare source: CanvasImageSource;\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number\n */\n declare readonly id: number;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {option.source} [source] the pattern source, eventually empty or a drawable\n */\n constructor(options: PatternOptions) {\n this.id = uid();\n Object.assign(this, options);\n }\n\n /**\n * @returns true if {@link source} is an element\n */\n isImageSource(): this is { source: HTMLImageElement } {\n return (\n !!this.source && typeof (this.source as HTMLImageElement).src === 'string'\n );\n }\n\n /**\n * @returns true if {@link source} is a element\n */\n isCanvasSource(): this is { source: HTMLCanvasElement } {\n return !!this.source && !!(this.source as HTMLCanvasElement).toDataURL;\n }\n\n sourceToString(): string {\n return this.isImageSource()\n ? this.source.src\n : this.isCanvasSource()\n ? this.source.toDataURL()\n : '';\n }\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasPattern | null {\n if (\n // if the image failed to load, return, and allow rest to continue loading\n !this.source ||\n // if an image\n (this.isImageSource() &&\n (!this.source.complete ||\n this.source.naturalWidth === 0 ||\n this.source.naturalHeight === 0))\n ) {\n return null;\n }\n\n return ctx.createPattern(this.source, this.repeat)!;\n }\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object} Object representation of a pattern instance\n */\n toObject(propertiesToInclude: string[] = []): Record {\n const { repeat, crossOrigin } = this;\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: 'pattern',\n source: this.sourceToString(),\n repeat,\n crossOrigin,\n offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform\n ? [...this.patternTransform]\n : null,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n */\n toSVG({ width, height }: TSize): string {\n const { source: patternSource, repeat, id } = this,\n patternOffsetX = ifNaN(this.offsetX / width, 0),\n patternOffsetY = ifNaN(this.offsetY / height, 0),\n patternWidth =\n repeat === 'repeat-y' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetX || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).width as number) / width,\n 0,\n ),\n patternHeight =\n repeat === 'repeat-x' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetY || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).height as number) / height,\n 0,\n );\n\n return [\n ``,\n ``,\n ``,\n '',\n ].join('\\n');\n }\n /* _TO_SVG_END_ */\n\n static async fromObject(\n {\n type,\n source,\n patternTransform,\n ...otherOptions\n }: SerializedPatternOptions,\n options?: Abortable,\n ): Promise {\n const img = await loadImage(source, {\n ...options,\n crossOrigin: otherOptions.crossOrigin,\n });\n return new this({\n ...otherOptions,\n patternTransform:\n patternTransform && (patternTransform.slice(0) as TMat2D),\n source: img,\n });\n }\n}\n\nclassRegistry.setClass(Pattern);\n// kept for compatibility reason\nclassRegistry.setClass(Pattern, 'pattern');\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport type { Shadow } from '../Shadow';\nimport type { Canvas } from '../canvas/Canvas';\nimport type { TBrushEventData } from './typedefs';\n\n/**\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nexport abstract class BaseBrush {\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color = 'rgb(0, 0, 0)';\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width = 1;\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type Shadow\n * @default\n */\n shadow: Shadow | null = null;\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: CanvasLineCap = 'round';\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: CanvasLineJoin = 'round';\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit = 10;\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: number[] | null = null;\n\n /**\n * When `true`, the free drawing is limited to the whiteboard size. Default to false.\n * @type Boolean\n * @default false\n */\n\n limitedToCanvasSize = false;\n\n /**\n * @todo add type\n */\n declare canvas: Canvas;\n\n constructor(canvas: Canvas) {\n this.canvas = canvas;\n }\n\n abstract _render(): void;\n abstract onMouseDown(pointer: Point, ev: TBrushEventData): void;\n abstract onMouseMove(pointer: Point, ev: TBrushEventData): void;\n /**\n * @returns true if brush should continue blocking interaction\n */\n abstract onMouseUp(ev: TBrushEventData): boolean | void;\n\n /**\n * Sets brush styles\n * @private\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.setLineDash(this.strokeDashArray || []);\n }\n\n /**\n * Sets the transformation on given context\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @private\n */\n protected _saveAndTransform(ctx: CanvasRenderingContext2D) {\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n protected needsFullRender() {\n const color = new Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n }\n\n /**\n * Sets brush shadow styles\n * @private\n */\n protected _setShadow() {\n if (!this.shadow || !this.canvas) {\n return;\n }\n\n const canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom() * canvas.getRetinaScaling();\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n }\n\n /**\n * Removes brush shadow styles\n * @private\n */\n protected _resetShadow() {\n const ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * Check is pointer is outside canvas boundaries\n * @param {Object} pointer\n * @private\n */\n protected _isOutSideCanvas(pointer: Point) {\n return (\n pointer.x < 0 ||\n pointer.x > this.canvas.getWidth() ||\n pointer.y < 0 ||\n pointer.y > this.canvas.getHeight()\n );\n }\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { toFixed } from '../util/misc/toFixed';\nimport {\n getBoundsOfCurve,\n joinPath,\n makePathSimpler,\n parsePath,\n} from '../util/path';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type {\n TComplexPathData,\n TPathSegmentInfo,\n TSimplePathData,\n} from '../util/path/typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type {\n TBBox,\n TClassProperties,\n TSVGReviver,\n TOptions,\n} from '../typedefs';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\ninterface UniquePathProps {\n sourcePath?: string;\n path?: TSimplePathData;\n}\n\nexport interface SerializedPathProps\n extends SerializedObjectProps,\n UniquePathProps {}\n\nexport interface PathProps extends FabricObjectProps, UniquePathProps {}\n\nexport interface IPathBBox extends TBBox {\n left: number;\n top: number;\n pathOffset: Point;\n}\n\nexport class Path<\n Props extends TOptions = Partial,\n SProps extends SerializedPathProps = SerializedPathProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Array of path points\n * @type Array\n * @default\n */\n declare path: TSimplePathData;\n\n declare pathOffset: Point;\n\n declare sourcePath?: string;\n\n declare segmentsInfo?: TPathSegmentInfo[];\n\n static type = 'Path';\n\n static cacheProperties = [...cacheProperties, 'path', 'fillRule'];\n\n /**\n * Constructor\n * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Partial} [options] Options object\n * @return {Path} thisArg\n */\n constructor(\n path: TComplexPathData | string,\n // todo: evaluate this spread here\n { path: _, left, top, ...options }: Partial = {},\n ) {\n super();\n Object.assign(this, Path.ownDefaults);\n this.setOptions(options);\n this._setPath(path || [], true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box\n * @returns {Point} top left position of the bounding box, useful for complementary positioning\n */\n _setPath(path: TComplexPathData | string, adjustPosition?: boolean) {\n this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));\n this.setBoundingBox(adjustPosition);\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = this._calcBoundsFromPath();\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands(ctx: CanvasRenderingContext2D) {\n const l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (const command of this.path) {\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n ctx.lineTo(command[1] + l, command[2] + t);\n break;\n\n case 'M': // moveTo, absolute\n ctx.moveTo(command[1] + l, command[2] + t);\n break;\n\n case 'C': // bezierCurveTo, absolute\n ctx.bezierCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n command[5] + l,\n command[6] + t,\n );\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n );\n break;\n\n case 'Z':\n ctx.closePath();\n break;\n }\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render(ctx: CanvasRenderingContext2D) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns string representation of an instance\n * @return {string} string representation of an instance\n */\n toString() {\n return `#`;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n path: this.path.map((pathCmd) => pathCmd.slice()),\n };\n }\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n delete o.path;\n o.sourcePath = this.sourcePath;\n }\n return o;\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const path = joinPath(this.path, config.NUM_FRACTION_DIGITS);\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @return the path command's translate transform attribute\n */\n _getOffsetTransform() {\n const digits = config.NUM_FRACTION_DIGITS;\n return ` translate(${toFixed(-this.pathOffset.x, digits)}, ${toFixed(\n -this.pathOffset.y,\n digits,\n )})`;\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n })\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n });\n }\n\n /**\n * Returns number representation of an instance complexity\n * @return {number} complexity of this instance\n */\n complexity() {\n return this.path.length;\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { width, height, pathOffset } = this._calcDimensions();\n this.set({ width, height, pathOffset });\n // using pathOffset because it match the use case.\n // if pathOffset change here we need to use left + width/2 , top + height/2\n adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER);\n }\n\n _calcBoundsFromPath(): TBBox {\n const bounds: XY[] = [];\n let subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0; // current y\n\n for (const command of this.path) {\n // current instruction\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n x = command[1];\n y = command[2];\n bounds.push({ x: subpathStartX, y: subpathStartY }, { x, y });\n break;\n\n case 'M': // moveTo, absolute\n x = command[1];\n y = command[2];\n subpathStartX = x;\n subpathStartY = y;\n break;\n\n case 'C': // bezierCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[3],\n command[4],\n command[5],\n command[6],\n ),\n );\n x = command[5];\n y = command[6];\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[1],\n command[2],\n command[3],\n command[4],\n ),\n );\n x = command[3];\n y = command[4];\n break;\n\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n }\n return makeBoundingBoxFromPoints(bounds);\n }\n\n /**\n * @private\n */\n _calcDimensions(): IPathBBox {\n const bbox = this._calcBoundsFromPath();\n\n return {\n ...bbox,\n pathOffset: new Point(\n bbox.left + bbox.width / 2,\n bbox.top + bbox.height / 2,\n ),\n };\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`)\n * @static\n * @memberOf Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'd'];\n\n /**\n * Creates an instance of Path from an object\n * @static\n * @memberOf Path\n * @param {Object} object\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'path',\n });\n }\n\n /**\n * Creates an instance of Path from an SVG element\n * @static\n * @memberOf Path\n * @param {HTMLElement} element to parse\n * @param {Partial} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Partial,\n cssRules?: CSSRules,\n ) {\n const { d, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(d, {\n ...parsedAttributes,\n ...options,\n // we pass undefined to instruct the constructor to position the object using the bbox\n left: undefined,\n top: undefined,\n });\n }\n}\n\nclassRegistry.setClass(Path);\nclassRegistry.setSVGClass(Path);\n\n/* _FROM_SVG_START_ */\n","import type { ModifierKey, TEvent } from '../EventTypeDefs';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Path } from '../shapes/Path';\nimport { getSmoothPathFromPoints, joinPath } from '../util/path';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\n/**\n * @private\n * @param {TSimplePathData} pathData SVG path commands\n * @returns {boolean}\n */\nfunction isEmptySVGPath(pathData: TSimplePathData): boolean {\n return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0';\n}\n\nexport class PencilBrush extends BaseBrush {\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate = 0.4;\n\n /**\n * Draws a straight line between last recorded point to current pointer\n * Used for `shift` functionality\n *\n * @type boolean\n * @default false\n */\n drawStraightLine = false;\n\n /**\n * The event modifier key that makes the brush draw a straight line.\n * If `null` or 'none' or any other string that is not a modifier key the feature is disabled.\n * @type {ModifierKey | undefined | null}\n */\n straightLineKey: ModifierKey | undefined | null = 'shiftKey';\n\n private declare _points: Point[];\n private declare _hasStraightLine: boolean;\n private declare oldEnd?: Point;\n\n constructor(canvas: Canvas) {\n super(canvas);\n this._points = [];\n this._hasStraightLine = false;\n }\n\n needsFullRender() {\n return super.needsFullRender() || this._hasStraightLine;\n }\n\n static drawSegment(ctx: CanvasRenderingContext2D, p1: Point, p2: Point) {\n const midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._addPoint(pointer);\n this._render();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this._addPoint(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n } else {\n const points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = PencilBrush.drawSegment(\n ctx,\n points[length - 2],\n points[length - 1],\n );\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp({ e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return true;\n }\n this.drawStraightLine = false;\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n }\n\n /**\n * @private\n * @param {Point} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing(pointer: Point) {\n this._reset();\n this._addPoint(pointer);\n this.canvas.contextTop.moveTo(pointer.x, pointer.y);\n }\n\n /**\n * @private\n * @param {Point} point Point to be added to points array\n */\n _addPoint(point: Point) {\n if (\n this._points.length > 1 &&\n point.eq(this._points[this._points.length - 1])\n ) {\n return false;\n }\n if (this.drawStraightLine && this._points.length > 1) {\n this._hasStraightLine = true;\n this._points.pop();\n }\n this._points.push(point);\n return true;\n }\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset() {\n this._points = [];\n this._setBrushStyles(this.canvas.contextTop);\n this._setShadow();\n this._hasStraightLine = false;\n }\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n * @param {CanvasRenderingContext2D} [ctx]\n */\n _render(ctx: CanvasRenderingContext2D = this.canvas.contextTop) {\n let p1 = this._points[0],\n p2 = this._points[1];\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n const width = this.width / 1000;\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (let i = 1; i < this._points.length; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n PencilBrush.drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * Converts points to SVG path\n * @param {Point[]} points Array of points\n * @return {TSimplePathData} SVG path commands\n */\n convertPointsToSVGPath(points: Point[]): TSimplePathData {\n const correction = this.width / 1000;\n return getSmoothPathFromPoints(points, correction);\n }\n\n /**\n * Creates a Path object to add on canvas\n * @param {TSimplePathData} pathData Path data\n * @return {Path} Path to add on canvas\n */\n createPath(pathData: TSimplePathData): Path {\n const path = new Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new Shadow(this.shadow);\n }\n\n return path;\n }\n\n /**\n * Decimate points array with the decimate value\n */\n decimatePoints(points: Point[], distance: number) {\n if (points.length <= 2) {\n return points;\n }\n let lastPoint = points[0],\n cDistance;\n const zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n l = points.length - 1,\n newPoints = [lastPoint];\n for (let i = 1; i < l - 1; i++) {\n cDistance =\n Math.pow(lastPoint.x - points[i].x, 2) +\n Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n // Add the last point from the original line to the end of the array.\n // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point.\n newPoints.push(points[l]);\n return newPoints;\n }\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new Path object\n * and add it to the canvas.\n */\n _finalizeAndAddPath() {\n const ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n const pathData = this.convertPointsToSVGPath(this._points);\n if (isEmptySVGPath(pathData)) {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n const path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', { path: path });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n}\n","import type { ObjectEvents } from '../EventTypeDefs';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { cos } from '../util/misc/cos';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { sin } from '../util/misc/sin';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { CSSRules } from '../parser/typedefs';\nimport { SCALE_X, SCALE_Y } from '../constants';\n\ninterface UniqueCircleProps {\n /**\n * Radius of this circle\n * @type Number\n * @default 0\n */\n radius: number;\n\n /**\n * Angle for the start of the circle, in degrees.\n * @type TDegree 0 - 359\n * @default 0\n */\n startAngle: number;\n\n /**\n * Angle for the end of the circle, in degrees\n * @type TDegree 1 - 360\n * @default 360\n */\n endAngle: number;\n\n /**\n * Orientation for the direction of the circle.\n * Setting to true will switch the arc of the circle to traverse from startAngle to endAngle in a counter-clockwise direction.\n * Note: this will only change how the circle is drawn, and does not affect rotational transformation.\n * @default false\n */\n counterClockwise: boolean;\n}\n\nexport interface SerializedCircleProps\n extends SerializedObjectProps,\n UniqueCircleProps {}\n\nexport interface CircleProps extends FabricObjectProps, UniqueCircleProps {}\n\nconst CIRCLE_PROPS = [\n 'radius',\n 'startAngle',\n 'endAngle',\n 'counterClockwise',\n] as const;\n\nexport const circleDefaultValues: Partial> = {\n radius: 0,\n startAngle: 0,\n endAngle: 360,\n counterClockwise: false,\n};\n\nexport class Circle<\n Props extends TOptions = Partial,\n SProps extends SerializedCircleProps = SerializedCircleProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueCircleProps\n{\n declare radius: number;\n declare startAngle: number;\n declare endAngle: number;\n declare counterClockwise: boolean;\n\n static type = 'Circle';\n\n static cacheProperties = [...cacheProperties, ...CIRCLE_PROPS];\n\n static ownDefaults = circleDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Circle.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Circle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n degreesToRadians(this.startAngle),\n degreesToRadians(this.endAngle),\n this.counterClockwise,\n );\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX(): number {\n return this.get('radius') * this.get(SCALE_X);\n }\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY(): number {\n return this.get('radius') * this.get(SCALE_Y);\n }\n\n /**\n * Sets radius of an object (and updates width accordingly)\n */\n setRadius(value: number) {\n this.radius = value;\n this.set({ width: value * 2, height: value * 2 });\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]);\n }\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n const angle = (this.endAngle - this.startAngle) % 360;\n\n if (angle === 0) {\n return [\n '\\n',\n ];\n } else {\n const { radius } = this;\n const start = degreesToRadians(this.startAngle),\n end = degreesToRadians(this.endAngle),\n startX = cos(start) * radius,\n startY = sin(start) * radius,\n endX = cos(end) * radius,\n endY = sin(end) * radius,\n largeFlag = angle > 180 ? 1 : 0,\n sweepFlag = this.counterClockwise ? 0 : 1;\n return [\n `\\n',\n ];\n }\n }\n /* _TO_SVG_END_ */\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement})\n * @static\n * @memberOf Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n static ATTRIBUTE_NAMES = ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES];\n\n /**\n * Returns {@link Circle} instance from an SVG element\n * @static\n * @memberOf Circle\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Partial Circle object to default missing properties on the element.\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ): Promise {\n const {\n left = 0,\n top = 0,\n radius = 0,\n ...otherParsedAttributes\n } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n ) as Partial;\n\n // this probably requires to be fixed for default origins not being top/left.\n\n return new this({\n ...otherParsedAttributes,\n radius,\n left: left - radius,\n top: top - radius,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * @todo how do we declare this??\n */\n static fromObject>(object: T) {\n return super._fromObject(object);\n }\n}\n\nclassRegistry.setClass(Circle);\nclassRegistry.setSVGClass(Circle);\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Circle } from '../shapes/Circle';\nimport { Group } from '../shapes/Group';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { CircleBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\nexport class CircleBrush extends BaseBrush {\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width = 10;\n\n declare points: CircleBrushPoint[];\n\n constructor(canvas: Canvas) {\n super(canvas);\n this.points = [];\n }\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Point} pointer\n */\n drawDot(pointer: Point) {\n const point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n }\n\n dot(ctx: CanvasRenderingContext2D, point: CircleBrushPoint) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Invoked on mouse down\n */\n onMouseDown(pointer: Point) {\n this.points = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n }\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render() {\n const ctx = this.canvas.contextTop,\n points = this.points;\n this._saveAndTransform(ctx);\n for (let i = 0; i < points.length; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n } else {\n this.drawDot(pointer);\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const circles: Circle[] = [];\n\n for (let i = 0; i < this.points.length; i++) {\n const point = this.points[i],\n circle = new Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: CENTER,\n originY: CENTER,\n fill: point.fill,\n });\n\n this.shadow && (circle.shadow = new Shadow(this.shadow));\n\n circles.push(circle);\n }\n const group = new Group(circles, { canvas: this.canvas });\n\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n /**\n * @param {Object} pointer\n * @return {Point} Just added pointer point\n */\n addPoint({ x, y }: Point) {\n const pointerPoint: CircleBrushPoint = {\n x,\n y,\n radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba(),\n };\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n}\n","import type { Point } from '../Point';\nimport { Group } from '../shapes/Group';\nimport { Shadow } from '../Shadow';\nimport { Rect } from '../shapes/Rect';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { SprayBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\n/**\n *\n * @param rects\n * @returns\n */\nfunction getUniqueRects(rects: Rect[]) {\n const uniqueRects: Record = {};\n const uniqueRectsArray: Rect[] = [];\n\n for (let i = 0, key: string; i < rects.length; i++) {\n key = `${rects[i].left}${rects[i].top}`;\n if (!uniqueRects[key]) {\n uniqueRects[key] = true;\n uniqueRectsArray.push(rects[i]);\n }\n }\n\n return uniqueRectsArray;\n}\n\nexport class SprayBrush extends BaseBrush {\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width = 10;\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density = 20;\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth = 1;\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance = 1;\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity = false;\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping = true;\n\n private declare sprayChunks: SprayBrushPoint[][];\n\n private declare sprayChunk: SprayBrushPoint[];\n\n /**\n * Constructor\n * @param {Canvas} canvas\n * @return {SprayBrush} Instance of a spray brush\n */\n constructor(canvas: Canvas) {\n super(canvas);\n this.sprayChunks = [];\n this.sprayChunk = [];\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point) {\n this.sprayChunks = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const rects: Rect[] = [];\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n const sprayChunk = this.sprayChunks[i];\n for (let j = 0; j < sprayChunk.length; j++) {\n const chunck = sprayChunk[j];\n const rect = new Rect({\n width: chunck.width,\n height: chunck.width,\n left: chunck.x + 1,\n top: chunck.y + 1,\n originX: CENTER,\n originY: CENTER,\n fill: this.color,\n });\n rects.push(rect);\n }\n }\n\n const group = new Group(\n this.optimizeOverlapping ? getUniqueRects(rects) : rects,\n {\n objectCaching: true,\n subTargetCheck: false,\n interactive: false,\n },\n );\n this.shadow && group.set('shadow', new Shadow(this.shadow));\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n renderChunck(sprayChunck: SprayBrushPoint[]) {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < sprayChunck.length; i++) {\n const point = sprayChunck[i];\n ctx.globalAlpha = point.opacity;\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n }\n\n /**\n * Render all spray chunks\n */\n _render() {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n this.renderChunck(this.sprayChunks[i]);\n }\n ctx.restore();\n }\n\n /**\n * @param {Point} pointer\n */\n addSprayChunk(pointer: Point) {\n this.sprayChunk = [];\n const radius = this.width / 2;\n\n for (let i = 0; i < this.density; i++) {\n this.sprayChunk.push({\n x: getRandomInt(pointer.x - radius, pointer.x + radius),\n y: getRandomInt(pointer.y - radius, pointer.y + radius),\n width: this.dotWidthVariance\n ? getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance,\n )\n : this.dotWidth,\n opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1,\n });\n }\n\n this.sprayChunks.push(this.sprayChunk);\n }\n}\n","import { Pattern } from '../Pattern';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { Canvas } from '../canvas/Canvas';\nimport { PencilBrush } from './PencilBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\nexport class PatternBrush extends PencilBrush {\n declare source?: CanvasImageSource;\n\n constructor(canvas: Canvas) {\n super(canvas);\n }\n\n getPatternSrc() {\n const dotWidth = 20,\n dotDistance = 5,\n patternCanvas = createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n if (patternCtx) {\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(\n dotWidth / 2,\n dotWidth / 2,\n dotWidth / 2,\n 0,\n Math.PI * 2,\n false,\n );\n patternCtx.closePath();\n patternCtx.fill();\n }\n return patternCanvas;\n }\n\n /**\n * Creates \"pattern\" instance property\n * @param {CanvasRenderingContext2D} ctx\n */\n getPattern(ctx: CanvasRenderingContext2D) {\n return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat');\n }\n\n /**\n * Sets brush styles\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n super._setBrushStyles(ctx);\n const pattern = this.getPattern(ctx);\n pattern && (ctx.strokeStyle = pattern);\n }\n\n /**\n * Creates path\n */\n createPath(pathData: TSimplePathData) {\n const path = super.createPath(pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new Pattern({\n source: this.source || this.getPatternSrc(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y,\n });\n return path;\n }\n}\n","import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\n// @TODO this code is terrible and Line should be a special case of polyline.\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineProps {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineProps {}\n\nexport class Line<\n Props extends TOptions = Partial,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueLineProps\n{\n /**\n * x value or first line edge\n * @type number\n * @default\n */\n declare x1: number;\n\n /**\n * y value or first line edge\n * @type number\n * @default\n */\n declare y1: number;\n\n /**\n * x value or second line edge\n * @type number\n * @default\n */\n declare x2: number;\n\n /**\n * y value or second line edge\n * @type number\n * @default\n */\n declare y2: number;\n\n static type = 'Line';\n\n static cacheProperties = [...cacheProperties, ...coordProps];\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {Line} thisArg\n */\n constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) {\n super();\n Object.assign(this, Line.ownDefaults);\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight() {\n const { x1, y1, x2, y2 } = this;\n this.width = Math.abs(x2 - x1);\n this.height = Math.abs(y2 - y1);\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ]);\n const position = new Point(left + width / 2, top + height / 2);\n this.setPositionByOrigin(position, CENTER, CENTER);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineProps)) {\n // this doesn't make sense very much, since setting x1 when top or left\n // are already set, is just going to show a strange result since the\n // line will move way more than the developer expect.\n // in fabric5 it worked only when the line didn't have extra transformations,\n // in fabric6 too. With extra transform they behave bad in different ways.\n // This needs probably a good rework or a tutorial if you have to create a dynamic line\n this._setWidthHeight();\n }\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n } else {\n ctx.strokeStyle = this.stroke ?? ctx.fillStyle;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n }\n\n /**\n * Recalculates line points given width and height\n * Those points are simply placed around the center,\n * This is not useful outside internal render functions and svg output\n * Is not meant to be for the developer.\n * @private\n */\n calcLinePoints(): UniqueLineProps {\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1,\n yMult = _y1 <= _y2 ? -1 : 1,\n x1 = (xMult * width) / 2,\n y1 = (yMult * height) / 2,\n x2 = (xMult * -width) / 2,\n y2 = (yMult * -height) / 2;\n\n return {\n x1,\n x2,\n y1,\n y2,\n };\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})\n * @static\n * @memberOf Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n /**\n * Returns Line instance from an SVG element\n * @static\n * @memberOf Line\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Line instance from an object representation\n * @static\n * @memberOf Line\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>({\n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject(\n {\n ...object,\n points: [x1, y1, x2, y2],\n },\n {\n extraParam: 'points',\n },\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n","import { classRegistry } from '../ClassRegistry';\nimport { FabricObject } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { TClassProperties, TOptions } from '../typedefs';\nimport type { ObjectEvents } from '../EventTypeDefs';\n\nexport const triangleDefaultValues: Partial> = {\n width: 100,\n height: 100,\n};\n\nexport class Triangle<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n static type = 'Triangle';\n\n static ownDefaults = triangleDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...Triangle.ownDefaults };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Triangle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = `${-widthBy2} ${heightBy2},0 ${-heightBy2},${widthBy2} ${heightBy2}`;\n return [''];\n }\n}\n\nclassRegistry.setClass(Triangle);\nclassRegistry.setSVGClass(Triangle);\n","import { SCALE_X, SCALE_Y, twoMathPi } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const ellipseDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueEllipseProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedEllipseProps\n extends SerializedObjectProps,\n UniqueEllipseProps {}\n\nexport interface EllipseProps extends FabricObjectProps, UniqueEllipseProps {}\n\nconst ELLIPSE_PROPS = ['rx', 'ry'] as const;\n\nexport class Ellipse<\n Props extends TOptions = Partial,\n SProps extends SerializedEllipseProps = SerializedEllipseProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements EllipseProps\n{\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Ellipse';\n\n static cacheProperties = [...cacheProperties, ...ELLIPSE_PROPS];\n\n static ownDefaults = ellipseDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Ellipse.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Ellipse.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {Ellipse} thisArg\n */\n _set(key: string, value: any) {\n super._set(key, value);\n switch (key) {\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n }\n return this;\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx() {\n return this.get('rx') * this.get(SCALE_X);\n }\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy() {\n return this.get('ry') * this.get(SCALE_Y);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, twoMathPi, false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement})\n * @static\n * @memberOf Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry'];\n\n /**\n * Returns {@link Ellipse} instance from an SVG element\n * @static\n * @memberOf Ellipse\n * @param {HTMLElement} element Element to parse\n * @return {Ellipse}\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n return new this(parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Ellipse);\nclassRegistry.setSVGClass(Ellipse);\n","import type { XY } from '../Point';\n\n/**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\nexport function parsePointsAttribute(points: string | null): XY[] {\n // points attribute is required and must not be empty\n if (!points) {\n return [];\n }\n\n // replace commas with whitespace and remove bookending whitespace\n const pointsSplit: string[] = points.replace(/,/g, ' ').trim().split(/\\s+/);\n\n const parsedPoints = [];\n\n for (let i = 0; i < pointsSplit.length; i += 2) {\n parsedPoints.push({\n x: parseFloat(pointsSplit[i]),\n y: parseFloat(pointsSplit[i + 1]),\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n return parsedPoints;\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { parsePointsAttribute } from '../parser/parsePointsAttribute';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { calcDimensionsMatrix, transformPoint } from '../util/misc/matrix';\nimport { projectStrokeOnPoints } from '../util/misc/projectStroke';\nimport type { TProjectStrokeOnPointsOptions } from '../util/misc/projectStroke/types';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport {\n CENTER,\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const polylineDefaultValues: Partial> = {\n /**\n * @deprecated transient option soon to be removed in favor of a different design\n */\n exactBoundingBox: false,\n};\n\nexport interface SerializedPolylineProps extends SerializedObjectProps {\n points: XY[];\n}\n\nexport class Polyline<\n Props extends TOptions = Partial,\n SProps extends SerializedPolylineProps = SerializedPolylineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Points array\n * @type Array\n * @default\n */\n declare points: XY[];\n\n /**\n * WARNING: Feature in progress\n * Calculate the exact bounding box taking in account strokeWidth on acute angles\n * this will be turned to true by default on fabric 6.0\n * maybe will be left in as an optimization since calculations may be slow\n * @deprecated transient option soon to be removed in favor of a different design\n * @type Boolean\n * @default false\n */\n declare exactBoundingBox: boolean;\n\n private declare initialized: true | undefined;\n\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polyline';\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Polyline.ownDefaults,\n };\n }\n\n /**\n * A list of properties that if changed trigger a recalculation of dimensions\n * @todo check if you really need to recalculate for all cases\n */\n static layoutProperties: (keyof Polyline)[] = [\n SKEW_X,\n SKEW_Y,\n 'strokeLineCap',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'strokeWidth',\n 'strokeUniform',\n 'points',\n ];\n\n declare pathOffset: Point;\n\n declare strokeOffset: Point;\n\n static cacheProperties = [...cacheProperties, 'points'];\n\n strokeDiff: Point;\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {Polyline} thisArg\n * @example\n * var poly = new Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n constructor(points: XY[] = [], options: Props = {} as Props) {\n super();\n Object.assign(this, Polyline.ownDefaults);\n this.setOptions(options);\n this.points = points;\n const { left, top } = options;\n this.initialized = true;\n this.setBoundingBox(true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n protected isOpen() {\n return true;\n }\n\n private _projectStrokeOnPoints(options: TProjectStrokeOnPointsOptions) {\n return projectStrokeOnPoints(this.points, options, this.isOpen());\n }\n\n /**\n * Calculate the polygon bounding box\n * @private\n */\n _calcDimensions(options?: Partial) {\n options = {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeUniform: this.strokeUniform,\n strokeWidth: this.strokeWidth,\n ...(options || {}),\n };\n const points = this.exactBoundingBox\n ? this._projectStrokeOnPoints(\n options as TProjectStrokeOnPointsOptions,\n ).map((projection) => projection.projectedPoint)\n : this.points;\n if (points.length === 0) {\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n pathOffset: new Point(),\n strokeOffset: new Point(),\n strokeDiff: new Point(),\n };\n }\n const bbox = makeBoundingBoxFromPoints(points),\n // Remove scale effect, since it's applied after\n matrix = calcDimensionsMatrix({ ...options, scaleX: 1, scaleY: 1 }),\n bboxNoStroke = makeBoundingBoxFromPoints(\n this.points.map((p) => transformPoint(p, matrix, true)),\n ),\n scale = new Point(this.scaleX, this.scaleY);\n let offsetX = bbox.left + bbox.width / 2,\n offsetY = bbox.top + bbox.height / 2;\n if (this.exactBoundingBox) {\n offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX));\n // Order of those assignments is important.\n // offsetY relies on offsetX being already changed by the line above\n offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY));\n }\n\n return {\n ...bbox,\n pathOffset: new Point(offsetX, offsetY),\n strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top)\n .subtract(new Point(bbox.left, bbox.top))\n .multiply(scale),\n strokeDiff: new Point(bbox.width, bbox.height)\n .subtract(new Point(bboxNoStroke.width, bboxNoStroke.height))\n .multiply(scale),\n };\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = makeBoundingBoxFromPoints(this.points);\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { left, top, width, height, pathOffset, strokeOffset, strokeDiff } =\n this._calcDimensions();\n this.set({ width, height, pathOffset, strokeOffset, strokeDiff });\n adjustPosition &&\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER,\n );\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return this.exactBoundingBox;\n }\n\n /**\n * @override stroke is taken in account in size\n */\n _getNonTransformedDimensions() {\n return this.exactBoundingBox\n ? // TODO: fix this\n new Point(this.width, this.height)\n : super._getNonTransformedDimensions();\n }\n\n /**\n * @override stroke and skewing are taken into account when projecting stroke on points,\n * therefore we don't want the default calculation to account for skewing as well.\n * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion.\n *\n * @private\n */\n _getTransformedDimensions(options: any = {}) {\n if (this.exactBoundingBox) {\n let size: Point;\n /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because\n the stroke projections are affected.\n When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on\n projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/\n if (\n Object.keys(options).some(\n (key) =>\n this.strokeUniform ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof TProjectStrokeOnPointsOptions,\n ),\n )\n ) {\n const { width, height } = this._calcDimensions(options);\n size = new Point(options.width ?? width, options.height ?? height);\n } else {\n size = new Point(\n options.width ?? this.width,\n options.height ?? this.height,\n );\n }\n return size.multiply(\n new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY),\n );\n } else {\n return super._getTransformedDimensions(options);\n }\n }\n\n /**\n * Recalculates dimensions when changing skew and scale\n * @private\n */\n _set(key: string, value: any) {\n const changed = this.initialized && this[key as keyof this] !== value;\n const output = super._set(key, value);\n if (\n this.exactBoundingBox &&\n changed &&\n (((key === SCALE_X || key === SCALE_Y) &&\n this.strokeUniform &&\n (this.constructor as typeof Polyline).layoutProperties.includes(\n 'strokeUniform',\n )) ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof Polyline,\n ))\n ) {\n this.setDimensions();\n }\n return output;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n points: this.points.map(({ x, y }) => ({ x, y })),\n };\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const points = [],\n diffX = this.pathOffset.x,\n diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n\n for (let i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS),\n ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS),\n ' ',\n );\n }\n return [\n `<${\n (this.constructor as typeof Polyline).type.toLowerCase() as\n | 'polyline'\n | 'polygon'\n } `,\n 'COMMON_PARTS',\n `points=\"${points.join('')}\" />\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (let i = 0; i < len; i++) {\n const point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n !this.isOpen() && ctx.closePath();\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity(): number {\n return this.points.length;\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement})\n * @static\n * @memberOf Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES];\n\n /**\n * Returns Polyline instance from an SVG element\n * @static\n * @memberOf Polyline\n * @param {HTMLElement} element Element to parser\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const points = parsePointsAttribute(element.getAttribute('points')),\n // we omit left and top to instruct the constructor to position the object using the bbox\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { left, top, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(points, {\n ...parsedAttributes,\n ...options,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Polyline instance from an object representation\n * @static\n * @memberOf Polyline\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'points',\n });\n }\n}\n\nclassRegistry.setClass(Polyline);\nclassRegistry.setSVGClass(Polyline);\n","import { classRegistry } from '../ClassRegistry';\nimport { Polyline, polylineDefaultValues } from './Polyline';\n\nexport class Polygon extends Polyline {\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polygon';\n\n protected isOpen() {\n return false;\n }\n}\n\nclassRegistry.setClass(Polygon);\nclassRegistry.setSVGClass(Polygon);\n","import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { TOptions } from '../../typedefs';\nimport { FabricObject } from '../Object/FabricObject';\nimport { styleProperties } from './constants';\nimport type { StylePropertiesType } from './constants';\nimport type { FabricText } from './Text';\nimport { pick } from '../../util';\nimport { pickBy } from '../../util/misc/pick';\n\nexport type CompleteTextStyleDeclaration = Pick<\n FabricText,\n StylePropertiesType\n>;\n\nexport type TextStyleDeclaration = Partial;\n\nexport type TextStyle = {\n [line: number | string]: { [char: number | string]: TextStyleDeclaration };\n};\n\nexport abstract class StyledText<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n declare abstract styles: TextStyle;\n protected declare abstract _textLines: string[][];\n protected declare _forceClearCache: boolean;\n static _styleProperties: Readonly = styleProperties;\n abstract get2DCursorLocation(\n selectionStart: number,\n skipWrapping?: boolean,\n ): { charIndex: number; lineIndex: number };\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex?: number): boolean {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex?: number): boolean {\n if (!this.styles) {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (const p1 in obj) {\n // eslint-disable-next-line\n for (const p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return false;\n }\n const obj = this.styles;\n let stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0;\n for (const p1 in obj) {\n letterCount = 0;\n for (const p2 in obj[p1]) {\n const styleObject = obj[p1][p2] || {},\n stylePropertyHasBeenSet = styleObject[property] !== undefined;\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property as keyof this]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (let i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n // @ts-expect-error conspiracy theory of TS\n this[property as keyof this] = stylePropertyValue;\n this.removeStyle(property);\n }\n }\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return;\n }\n const obj = this.styles;\n let line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n }\n\n private _extendStyles(index: number, style: TextStyleDeclaration): void {\n const { lineIndex, charIndex } = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex);\n }\n\n const newStyle = pickBy(\n {\n // first create a new object that is a merge of existing and new\n ...this._getStyleDeclaration(lineIndex, charIndex),\n ...style,\n // use the predicate to discard undefined values\n },\n (value) => value !== undefined,\n );\n\n // finally assign to the old position the new style\n this._setStyleDeclaration(lineIndex, charIndex, newStyle);\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number,\n endIndex?: number,\n complete?: boolean,\n ): TextStyleDeclaration[] {\n const styles: TextStyleDeclaration[] = [];\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n }\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition(position: number, complete?: boolean) {\n const { lineIndex, charIndex } = this.get2DCursorLocation(position);\n return complete\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex)\n : this._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} styles Styles object\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1\n */\n setSelectionStyles(styles: object, startIndex: number, endIndex?: number) {\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n }\n\n /**\n * Get a reference, not a clone, to the style object for a given character,\n * if no style is set for a line or char, return a new empty object.\n * This is tricky and confusing because when you get an empty object you can't\n * determine if it is a reference or a new one.\n * @TODO this should always return a reference or always a clone or undefined when necessary.\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n const lineStyle = this.styles && this.styles[lineIndex];\n return lineStyle ? lineStyle[charIndex] ?? {} : {};\n }\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): CompleteTextStyleDeclaration {\n return {\n // @ts-expect-error readonly\n ...pick(this, (this.constructor as typeof StyledText)._styleProperties),\n ...this._getStyleDeclaration(lineIndex, charIndex),\n } as CompleteTextStyleDeclaration;\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n this.styles[lineIndex][charIndex] = style;\n }\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n delete this.styles[lineIndex][charIndex];\n }\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n return !!this.styles[lineIndex];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n this.styles[lineIndex] = {};\n }\n\n protected _deleteLineStyle(lineIndex: number) {\n delete this.styles[lineIndex];\n }\n}\n","import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number,\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n },\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t',\n textSpans.join(''),\n '\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number,\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height,\n ),\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number,\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex),\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `${escapeXml(char)}`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset,\n ),\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number,\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number,\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean,\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ],\n )\n .join(' ');\n }\n}\n","import { cache } from '../../cache';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, STROKE } from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type {\n CompleteTextStyleDeclaration,\n TextStyle,\n TextStyleDeclaration,\n} from './StyledText';\nimport { StyledText } from './StyledText';\nimport { SHARED_ATTRIBUTES } from '../../parser/attributes';\nimport { parseAttributes } from '../../parser/parseAttributes';\nimport type {\n Abortable,\n TCacheCanvasDimensions,\n TClassProperties,\n TFiller,\n TOptions,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { graphemeSplit } from '../../util/lang_string';\nimport { createCanvasElement } from '../../util/misc/dom';\nimport type { TextStyleArray } from '../../util/misc/textStyles';\nimport {\n hasStyleChanged,\n stylesFromArray,\n stylesToArray,\n} from '../../util/misc/textStyles';\nimport { getPathSegmentsInfo, getPointOnPath } from '../../util/path';\nimport { cacheProperties } from '../Object/FabricObject';\nimport type { Path } from '../Path';\nimport { TextSVGExportMixin } from './TextSVGExportMixin';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { StylePropertiesType } from './constants';\nimport {\n additionalProps,\n textDefaultValues,\n textLayoutProperties,\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from './constants';\nimport { CENTER, LEFT, RIGHT, TOP, BOTTOM } from '../../constants';\nimport { isFiller } from '../../util/typeAssertions';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { CSSRules } from '../../parser/typedefs';\n\nlet measuringContext: CanvasRenderingContext2D | null;\n\n/**\n * Return a context for measurement of text string.\n * if created it gets stored for reuse\n */\nfunction getMeasuringContext() {\n if (!measuringContext) {\n const canvas = createCanvasElement();\n canvas.width = canvas.height = 0;\n measuringContext = canvas.getContext('2d');\n }\n return measuringContext;\n}\n\nexport type TPathSide = 'left' | 'right';\n\nexport type TPathAlign = 'baseline' | 'center' | 'ascender' | 'descender';\n\nexport type TextLinesInfo = {\n lines: string[];\n graphemeLines: string[][];\n graphemeText: string[];\n _unwrappedLines: string[][];\n};\n\n/**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * Override to customize measuring\n */\nexport type GraphemeBBox = {\n width: number;\n height: number;\n kernedWidth: number;\n left: number;\n deltaY: number;\n renderLeft?: number;\n renderTop?: number;\n angle?: number;\n};\n\n// @TODO this is not complete\ninterface UniqueTextProps {\n charSpacing: number;\n lineHeight: number;\n fontSize: number;\n fontWeight: string | number;\n fontFamily: string;\n fontStyle: string;\n pathSide: TPathSide;\n pathAlign: TPathAlign;\n underline: boolean;\n overline: boolean;\n linethrough: boolean;\n textAlign: string;\n direction: CanvasDirection;\n path?: Path;\n}\n\nexport interface SerializedTextProps\n extends SerializedObjectProps,\n UniqueTextProps {\n styles: TextStyleArray | TextStyle;\n}\n\nexport interface TextProps extends FabricObjectProps, UniqueTextProps {\n styles: TextStyle;\n}\n\n/**\n * Text class\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n */\nexport class FabricText<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends StyledText\n implements UniqueTextProps\n{\n /**\n * Properties that requires a text layout recalculation when changed\n * @type string[]\n * @protected\n */\n static textLayoutProperties: string[] = textLayoutProperties;\n\n /**\n * @private\n */\n declare _reNewline: RegExp;\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpacesAndTabs: RegExp;\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpaceAndTab: RegExp;\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reWords: RegExp;\n\n declare text: string;\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n declare fontSize: number;\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n declare fontWeight: string | number;\n\n /**\n * Font family\n * @type String\n * @default\n */\n declare fontFamily: string;\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n declare underline: boolean;\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n declare overline: boolean;\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n declare linethrough: boolean;\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n declare textAlign: string;\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n declare fontStyle: string;\n\n /**\n * Line height\n * @type Number\n * @default\n */\n declare lineHeight: number;\n\n /**\n * Superscript schema object (minimum overlap)\n */\n declare superscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (upwards)\n * @default -0.35\n */\n baseline: number;\n };\n\n /**\n * Subscript schema object (minimum overlap)\n */\n declare subscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (downwards)\n * @default 0.11\n */\n baseline: number;\n };\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n declare textBackgroundColor: string;\n\n declare styles: TextStyle;\n\n /**\n * Path that the text should follow.\n * since 4.6.0 the path will be drawn automatically.\n * if you want to make the path visible, give it a stroke and strokeWidth or fill value\n * if you want it to be hidden, assign visible = false to the path.\n * This feature is in BETA, and SVG import/export is not yet supported.\n * @type Path\n * @example\n * const textPath = new Text('Text on a path', {\n * top: 150,\n * left: 150,\n * textAlign: 'center',\n * charSpacing: -50,\n * path: new Path('M 0 0 C 50 -100 150 -100 200 0', {\n * strokeWidth: 1,\n * visible: false\n * }),\n * pathSide: 'left',\n * pathStartOffset: 0\n * });\n * @default\n */\n declare path?: Path;\n\n /**\n * Offset amount for text path starting position\n * Only used when text has a path\n * @type Number\n * @default\n */\n declare pathStartOffset: number;\n\n /**\n * Which side of the path the text should be drawn on.\n * Only used when text has a path\n * @type {TPathSide} 'left|right'\n * @default\n */\n declare pathSide: TPathSide;\n\n /**\n * How text is aligned to the path. This property determines\n * the perpendicular position of each character relative to the path.\n * (one of \"baseline\", \"center\", \"ascender\", \"descender\")\n * This feature is in BETA, and its behavior may change\n * @type TPathAlign\n * @default\n */\n declare pathAlign: TPathAlign;\n\n /**\n * @private\n */\n declare _fontSizeFraction: number;\n\n /**\n * @private\n */\n declare offsets: { underline: number; linethrough: number; overline: number };\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n declare _fontSizeMult: number;\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n declare charSpacing: number;\n\n /**\n * Baseline shift, styles only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n declare deltaY: number;\n\n /**\n * WARNING: EXPERIMENTAL. NOT SUPPORTED YET\n * determine the direction of the text.\n * This has to be set manually together with textAlign and originX for proper\n * experience.\n * some interesting link for the future\n * https://www.w3.org/International/questions/qa-bidi-unicode-controls\n * @since 4.5.0\n * @type {CanvasDirection} 'ltr|rtl'\n * @default\n */\n declare direction: CanvasDirection;\n\n /**\n * contains characters bounding boxes\n * This variable is considered to be protected.\n * But for how mixins are implemented right now, we can't leave it private\n * @protected\n */\n __charBounds: GraphemeBBox[][] = [];\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n declare CACHE_FONT_SIZE: number;\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n declare MIN_TEXT_WIDTH: number;\n\n /**\n * contains the the text of the object, divided in lines as they are displayed\n * on screen. Wrapping will divide the text independently of line breaks\n * @type {string[]}\n * @default\n */\n declare textLines: string[];\n\n /**\n * same as textlines, but each line is an array of graphemes as split by splitByGrapheme\n * @type {string[]}\n * @default\n */\n declare _textLines: string[][];\n\n declare _unwrappedTextLines: string[][];\n declare _text: string[];\n declare cursorWidth: number;\n declare __lineHeights: number[];\n declare __lineWidths: number[];\n declare initialized?: true;\n\n static cacheProperties = [...cacheProperties, ...additionalProps];\n\n static ownDefaults = textDefaultValues;\n\n static type = 'Text';\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...FabricText.ownDefaults };\n }\n\n constructor(text: string, options?: Props) {\n super();\n Object.assign(this, FabricText.ownDefaults);\n this.setOptions(options);\n if (!this.styles) {\n this.styles = {};\n }\n this.text = text;\n this.initialized = true;\n if (this.path) {\n this.setPathInfo();\n }\n this.initDimensions();\n this.setCoords();\n }\n\n /**\n * If text has a path, it will add the extra information needed\n * for path and text calculations\n */\n setPathInfo() {\n const path = this.path;\n if (path) {\n path.segmentsInfo = getPathSegmentsInfo(path.path);\n }\n }\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText(): TextLinesInfo {\n const newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n }\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions() {\n this._splitText();\n this._clearCache();\n this.dirty = true;\n if (this.path) {\n this.width = this.path.width;\n this.height = this.path.height;\n } else {\n this.width =\n this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n this.height = this.calcTextHeight();\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n }\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces() {\n let diffSpace,\n currentLineWidth,\n numberOfSpaces,\n accumulatedSpace,\n line,\n charBound,\n spaces;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n if (\n this.textAlign !== JUSTIFY &&\n (i === len - 1 || this.isEndOfWrapping(i))\n ) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (\n currentLineWidth < this.width &&\n (spaces = this.textLines[i].match(this._reSpacesAndTabs))\n ) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (let j = 0; j <= line.length; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n } else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n return lineIndex === this._textLines.length - 1;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always 1 for text and Itext. Textbox has its own implementation\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1;\n missingNewlineOffset(_lineIndex: number): 1 {\n return 1;\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor\n * @param {Number} selectionStart\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(selectionStart: number, skipWrapping?: boolean) {\n const lines = skipWrapping ? this._unwrappedTextLines : this._textLines;\n let i: number;\n for (i = 0; i < lines.length; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart,\n };\n }\n selectionStart -=\n lines[i].length + this.missingNewlineOffset(i, skipWrapping);\n }\n return {\n lineIndex: i - 1,\n charIndex:\n lines[i - 1].length < selectionStart\n ? lines[i - 1].length\n : selectionStart,\n };\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString(): string {\n return `#`;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const dims = super._getCacheCanvasDimensions();\n const fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const path = this.path;\n path && !path.isNotVisible() && path._render(ctx);\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n }\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles(\n ctx: CanvasRenderingContext2D,\n charStyle?: any,\n forMeasuring?: boolean,\n ) {\n ctx.textBaseline = 'alphabetic';\n if (this.path) {\n switch (this.pathAlign) {\n case CENTER:\n ctx.textBaseline = 'middle';\n break;\n case 'ascender':\n ctx.textBaseline = TOP;\n break;\n case 'descender':\n ctx.textBaseline = BOTTOM;\n break;\n }\n }\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n }\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of Text object\n */\n calcTextWidth(): number {\n let maxWidth = this.getLineWidth(0);\n\n for (let i = 1, len = this._textLines.length; i < len; i++) {\n const currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n }\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: string[],\n left: number,\n top: number,\n lineIndex: number,\n ) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n }\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground(ctx: CanvasRenderingContext2D) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n const originalFill = ctx.fillStyle,\n leftOffset = this._getLeftOffset();\n let lineTopOffset = this._getTopOffset();\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (\n !this.textBackgroundColor &&\n !this.styleHas('textBackgroundColor', i)\n ) {\n lineTopOffset += heightOfLine;\n continue;\n }\n const jlen = this._textLines[i].length;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxWidth = 0;\n let boxStart = 0;\n let drawStart;\n let currentColor;\n let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < jlen; j++) {\n // at this point charbox are either standard or full with pathInfo if there is a path.\n const charBox = this.__charBounds[i][j] as Required;\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (this.path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillStyle = currentColor;\n currentColor &&\n ctx.fillRect(\n -charBox.width / 2,\n (-heightOfLine / this.lineHeight) * (1 - this._fontSizeFraction),\n charBox.width,\n heightOfLine / this.lineHeight,\n );\n ctx.restore();\n } else if (currentColor !== lastColor) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = lastColor;\n lastColor &&\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor && !this.path) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar(\n _char: string,\n charStyle: CompleteTextStyleDeclaration,\n previousChar: string | undefined,\n prevCharStyle: CompleteTextStyleDeclaration | Record,\n ) {\n const fontCache = cache.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n couple = previousChar + _char,\n stylesAreEqual =\n previousChar &&\n fontDeclaration === this._getFontDeclaration(prevCharStyle),\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE;\n let width: number | undefined,\n coupleWidth: number | undefined,\n previousWidth: number | undefined,\n kernedWidth: number | undefined;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth!;\n }\n if (\n width === undefined ||\n previousWidth === undefined ||\n coupleWidth === undefined\n ) {\n const ctx = getMeasuringContext()!;\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n // safe to use the non-null since if undefined we defined it before.\n kernedWidth = coupleWidth - previousWidth!;\n }\n }\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth! * fontMultiplier,\n };\n }\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar(line: number, _char: number): number {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n }\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n */\n measureLine(lineIndex: number) {\n const lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n }\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine(lineIndex: number) {\n let width = 0,\n prevGrapheme: string | undefined,\n graphemeInfo: GraphemeBBox | undefined;\n\n const reverse = this.pathSide === RIGHT,\n path = this.path,\n line = this._textLines[lineIndex],\n llength = line.length,\n lineBounds = new Array(llength);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (let i = 0; i < llength; i++) {\n const grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[llength] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize,\n deltaY: 0,\n } as GraphemeBBox;\n if (path && path.segmentsInfo) {\n let positionInPath = 0;\n const totalPathLength =\n path.segmentsInfo[path.segmentsInfo.length - 1].length;\n switch (this.textAlign) {\n case LEFT:\n positionInPath = reverse ? totalPathLength - width : 0;\n break;\n case CENTER:\n positionInPath = (totalPathLength - width) / 2;\n break;\n case RIGHT:\n positionInPath = reverse ? 0 : totalPathLength - width;\n break;\n //todo - add support for justify\n }\n positionInPath += this.pathStartOffset * (reverse ? -1 : 1);\n for (\n let i = reverse ? llength - 1 : 0;\n reverse ? i >= 0 : i < llength;\n reverse ? i-- : i++\n ) {\n graphemeInfo = lineBounds[i];\n if (positionInPath > totalPathLength) {\n positionInPath %= totalPathLength;\n } else if (positionInPath < 0) {\n positionInPath += totalPathLength;\n }\n // it would probably much faster to send all the grapheme position for a line\n // and calculate path position/angle at once.\n this._setGraphemeOnPath(positionInPath, graphemeInfo);\n positionInPath += graphemeInfo.kernedWidth;\n }\n }\n return { width: width, numOfSpaces: 0 };\n }\n\n /**\n * Calculate the angle and the left,top position of the char that follow a path.\n * It appends it to graphemeInfo to be reused later at rendering\n * @private\n * @param {Number} positionInPath to be measured\n * @param {GraphemeBBox} graphemeInfo current grapheme box information\n * @param {Object} startingPoint position of the point\n */\n _setGraphemeOnPath(positionInPath: number, graphemeInfo: GraphemeBBox) {\n const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,\n path = this.path!;\n\n // we are at currentPositionOnPath. we want to know what point on the path is.\n const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo)!;\n graphemeInfo.renderLeft = info.x - path.pathOffset.x;\n graphemeInfo.renderTop = info.y - path.pathOffset.y;\n graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0);\n }\n\n /**\n *\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n * @returns {GraphemeBBox} grapheme bbox\n */\n _getGraphemeBox(\n grapheme: string,\n lineIndex: number,\n charIndex: number,\n prevGrapheme?: string,\n skipLeft?: boolean,\n ): GraphemeBBox {\n const style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1)\n : {},\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle);\n let kernedWidth = info.kernedWidth,\n width = info.width,\n charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n const box: GraphemeBBox = {\n width,\n left: 0,\n height: style.fontSize,\n kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n const previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left =\n previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n }\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine(lineIndex: number): number {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n // char 0 is measured before the line cycle because it needs to char\n // emptylines\n let maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return (this.__lineHeights[lineIndex] =\n maxHeight * this.lineHeight * this._fontSizeMult);\n }\n\n /**\n * Calculate text box height\n */\n calcTextHeight() {\n let lineHeight,\n height = 0;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;\n }\n return height;\n }\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset(): number {\n return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;\n }\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset(): number {\n return -this.height / 2;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon(\n ctx: CanvasRenderingContext2D,\n method: 'fillText' | 'strokeText',\n ) {\n ctx.save();\n let lineHeights = 0;\n const left = this._getLeftOffset(),\n top = this._getTopOffset();\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i,\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill && !this.styleHas(FILL)) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke(ctx: CanvasRenderingContext2D) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n }\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: Array,\n left: number,\n top: number,\n lineIndex: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n path = this.path,\n shortCut =\n !isJustify &&\n this.charSpacing === 0 &&\n this.isEmptyStyles(lineIndex) &&\n !path,\n isLtr = this.direction === 'ltr',\n sign = this.direction === 'ltr' ? 1 : -1,\n // this was changed in the PR #7674\n // currentDirection = ctx.canvas.getAttribute('dir');\n currentDirection = ctx.direction;\n\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n drawingLeft;\n\n ctx.save();\n if (currentDirection !== this.direction) {\n ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');\n ctx.direction = isLtr ? 'ltr' : 'rtl';\n ctx.textAlign = isLtr ? LEFT : RIGHT;\n }\n top -= (lineHeight * this._fontSizeFraction) / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top);\n ctx.restore();\n return;\n }\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing || path;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i] as Required;\n if (boxWidth === 0) {\n left += sign * (charBox.kernedWidth - charBox.width);\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, false);\n }\n if (timeToRender) {\n if (path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n -boxWidth / 2,\n 0,\n );\n ctx.restore();\n } else {\n drawingLeft = left;\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n drawingLeft,\n top,\n );\n }\n charsToRender = '';\n actualStyle = nextStyle;\n left += sign * boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {TFiller} filler a fabric gradient instance\n * @return {CanvasPattern} a pattern to use as fill/stroke style\n */\n _applyPatternGradientTransformText(filler: TFiller) {\n const pCanvas = createCanvasElement(),\n // TODO: verify compatibility with strokeUniform\n width = this.width + this.strokeWidth,\n height = this.height + this.strokeWidth,\n pCtx = pCanvas.getContext('2d')!;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.fillStyle = filler.toLive(pCtx)!;\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fill();\n return pCtx.createPattern(pCanvas, 'no-repeat')!;\n }\n\n handleFiller(\n ctx: CanvasRenderingContext2D,\n property: `${T}Style`,\n filler: TFiller | string,\n ): { offsetX: number; offsetY: number } {\n let offsetX: number, offsetY: number;\n if (isFiller(filler)) {\n if (\n (filler as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n offsetX = -this.width / 2;\n offsetY = -this.height / 2;\n ctx.translate(offsetX, offsetY);\n ctx[property] = this._applyPatternGradientTransformText(filler);\n return { offsetX, offsetY };\n } else {\n // is a simple gradient or pattern\n ctx[property] = filler.toLive(ctx)!;\n return this._applyPatternGradientTransform(ctx, filler);\n }\n } else {\n // is a color\n ctx[property] = filler;\n }\n return { offsetX: 0, offsetY: 0 };\n }\n\n /**\n * This function prepare the canvas for a stroke style, and stroke and strokeWidth\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined\n * @returns\n */\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n {\n stroke,\n strokeWidth,\n }: Pick,\n ) {\n ctx.lineWidth = strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineDashOffset = this.strokeDashOffset;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n return this.handleFiller(ctx, 'strokeStyle', stroke!);\n }\n\n /**\n * This function prepare the canvas for a ill style, and fill\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with ill defined\n * @returns\n */\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n return this.handleFiller(ctx, 'fillStyle', fill!);\n }\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n lineIndex: number,\n charIndex: number,\n _char: string,\n left: number,\n top: number,\n ) {\n const decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke =\n method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n ctx.save();\n\n ctx.font = this._getFontDeclaration(fullDecl);\n\n if (decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl.deltaY) {\n top += decl.deltaY;\n }\n\n if (shouldFill) {\n const fillOffsets = this._setFillStyles(ctx, fullDecl);\n ctx.fillText(\n _char,\n left - fillOffsets.offsetX,\n top - fillOffsets.offsetY,\n );\n }\n\n if (shouldStroke) {\n const strokeOffsets = this._setStrokeStyles(ctx, fullDecl);\n ctx.strokeText(\n _char,\n left - strokeOffsets.offsetX,\n top - strokeOffsets.offsetY,\n );\n }\n\n ctx.restore();\n }\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSuperscript(start: number, end: number) {\n this._setScript(start, end, this.superscript);\n }\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSubscript(start: number, end: number) {\n this._setScript(start, end, this.subscript);\n }\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n */\n protected _setScript(\n start: number,\n end: number,\n schema: {\n size: number;\n baseline: number;\n },\n ) {\n const loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(\n loc.lineIndex,\n loc.charIndex,\n 'fontSize',\n ),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline,\n };\n this.setSelectionStyles(style, start, end);\n }\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset(lineIndex: number): number {\n const lineWidth = this.getLineWidth(lineIndex),\n lineDiff = this.width - lineWidth,\n textAlign = this.textAlign,\n direction = this.direction,\n isEndOfWrapping = this.isEndOfWrapping(lineIndex);\n let leftOffset = 0;\n if (\n textAlign === JUSTIFY ||\n (textAlign === JUSTIFY_CENTER && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_RIGHT && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_LEFT && !isEndOfWrapping)\n ) {\n return 0;\n }\n if (textAlign === CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === RIGHT) {\n leftOffset = lineDiff;\n }\n if (textAlign === JUSTIFY_CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === JUSTIFY_RIGHT) {\n leftOffset = lineDiff;\n }\n if (direction === 'rtl') {\n if (\n textAlign === RIGHT ||\n textAlign === JUSTIFY ||\n textAlign === JUSTIFY_RIGHT\n ) {\n leftOffset = 0;\n } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) {\n leftOffset = -lineDiff;\n } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) {\n leftOffset = -lineDiff / 2;\n }\n }\n return leftOffset;\n }\n\n /**\n * @private\n */\n _clearCache() {\n this._forceClearCache = false;\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n }\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth(lineIndex: number): number {\n if (this.__lineWidths[lineIndex] !== undefined) {\n return this.__lineWidths[lineIndex];\n }\n\n const { width } = this.measureLine(lineIndex);\n this.__lineWidths[lineIndex] = width;\n return width;\n }\n\n _getWidthOfCharSpacing() {\n if (this.charSpacing !== 0) {\n return (this.fontSize * this.charSpacing) / 1000;\n }\n return 0;\n }\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the character number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt(\n lineIndex: number,\n charIndex: number,\n property: T,\n ): this[T] {\n const charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n return (charStyle[property] ?? this[property]) as this[T];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration(\n ctx: CanvasRenderingContext2D,\n type: 'underline' | 'linethrough' | 'overline',\n ) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n let topOffset = this._getTopOffset();\n const leftOffset = this._getLeftOffset(),\n path = this.path,\n charSpacing = this._getWidthOfCharSpacing(),\n offsetY = this.offsets[type];\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n const line = this._textLines[i];\n const maxHeight = heightOfLine / this.lineHeight;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxStart = 0;\n let boxWidth = 0;\n let lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n let lastFill = this.getValueOfPropertyAt(i, 0, FILL);\n let currentDecoration;\n let currentFill;\n const top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n let size = this.getHeightOfChar(i, 0);\n let dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n const charBox = this.__charBounds[i][j] as Required;\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, FILL);\n const currentSize = this.getHeightOfChar(i, j);\n const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if (path && currentDecoration && currentFill) {\n ctx.save();\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillRect(\n -charBox.kernedWidth / 2,\n offsetY * currentSize + currentDy,\n charBox.kernedWidth,\n this.fontSize / 15,\n );\n ctx.restore();\n } else if (\n (currentDecoration !== lastDecoration ||\n currentFill !== lastFill ||\n currentSize !== size ||\n currentDy !== dy) &&\n boxWidth > 0\n ) {\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n if (lastDecoration && lastFill) {\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth,\n this.fontSize / 15,\n );\n }\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = currentSize;\n dy = currentDy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentFill as string;\n currentDecoration &&\n currentFill &&\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15,\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration(\n {\n fontFamily = this.fontFamily,\n fontStyle = this.fontStyle,\n fontWeight = this.fontWeight,\n fontSize = this.fontSize,\n }: Partial<\n Pick<\n TextStyleDeclaration,\n 'fontFamily' | 'fontStyle' | 'fontWeight' | 'fontSize'\n >\n > = {},\n forMeasuring?: boolean,\n ): string {\n const parsedFontFamily =\n fontFamily.includes(\"'\") ||\n fontFamily.includes('\"') ||\n fontFamily.includes(',') ||\n FabricText.genericFonts.includes(fontFamily.toLowerCase())\n ? fontFamily\n : `\"${fontFamily}\"`;\n return [\n fontStyle,\n fontWeight,\n `${forMeasuring ? this.CACHE_FONT_SIZE : fontSize}px`,\n parsedFontFamily,\n ].join(' ');\n }\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n if (!this.visible) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n if (this._forceClearCache) {\n this.initDimensions();\n }\n super.render(ctx);\n }\n\n /**\n * Override this method to customize grapheme splitting\n * @todo the util `graphemeSplit` needs to be injectable in some way.\n * is more comfortable to inject the correct util rather than having to override text\n * in the middle of the prototype chain\n * @param {string} value\n * @returns {string[]} array of graphemes\n */\n graphemeSplit(value: string): string[] {\n return graphemeSplit(value);\n }\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns Lines in the text\n */\n _splitTextIntoLines(text: string): TextLinesInfo {\n const lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'];\n let newText: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n newLines[i] = this.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines,\n };\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject([...additionalProps, ...propertiesToInclude] as K[]),\n styles: stylesToArray(this.styles, this.text),\n ...(this.path ? { path: this.path.toObject() } : {}),\n };\n }\n\n set(key: string | any, value?: any) {\n const { textLayoutProperties } = this.constructor as typeof FabricText;\n super.set(key, value);\n let needsDims = false;\n let isAddingPath = false;\n if (typeof key === 'object') {\n for (const _key in key) {\n if (_key === 'path') {\n this.setPathInfo();\n }\n needsDims = needsDims || textLayoutProperties.includes(_key);\n isAddingPath = isAddingPath || _key === 'path';\n }\n } else {\n needsDims = textLayoutProperties.includes(key);\n isAddingPath = key === 'path';\n }\n if (isAddingPath) {\n this.setPathInfo();\n }\n if (needsDims && this.initialized) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity(): number {\n return 1;\n }\n\n static genericFonts = [\n 'sans-serif',\n 'serif',\n 'cursive',\n 'fantasy',\n 'monospace',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})\n * @static\n * @memberOf Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'font-family',\n 'font-style',\n 'font-weight',\n 'font-size',\n 'letter-spacing',\n 'text-decoration',\n 'text-anchor',\n );\n\n /**\n * Returns FabricText instance from an SVG element (not yet implemented)\n * @static\n * @memberOf Text\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n FabricText.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n const {\n textAnchor = LEFT as typeof LEFT | typeof CENTER | typeof RIGHT,\n textDecoration = '',\n dx = 0,\n dy = 0,\n top = 0,\n left = 0,\n fontSize = DEFAULT_SVG_FONT_SIZE,\n strokeWidth = 1,\n ...restOfOptions\n } = { ...options, ...parsedAttributes };\n\n const textContent = (element.textContent || '')\n .replace(/^\\s+|\\s+$|\\n+/g, '')\n .replace(/\\s+/g, ' ');\n\n // this code here is probably the usual issue for SVG center find\n // this can later looked at again and probably removed.\n\n const text = new this(textContent, {\n left: left + dx,\n top: top + dy,\n underline: textDecoration.includes('underline'),\n overline: textDecoration.includes('overline'),\n linethrough: textDecoration.includes('line-through'),\n // we initialize this as 0\n strokeWidth: 0,\n fontSize,\n ...restOfOptions,\n }),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff =\n (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff;\n\n let offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (textAnchor === CENTER) {\n offX = text.getScaledWidth() / 2;\n }\n if (textAnchor === RIGHT) {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top:\n text.top -\n (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) /\n text.lineHeight,\n strokeWidth,\n });\n return text;\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns FabricText instance from an object representation\n * @param {Object} object plain js Object to create an instance from\n * @returns {Promise}\n */\n static fromObject<\n T extends TOptions,\n S extends FabricText,\n >(object: T) {\n return this._fromObject(\n {\n ...object,\n styles: stylesFromArray(object.styles || {}, object.text),\n },\n {\n extraParam: 'text',\n },\n );\n }\n}\n\napplyMixins(FabricText, [TextSVGExportMixin]);\nclassRegistry.setClass(FabricText);\nclassRegistry.setSVGClass(FabricText);\n","import type {\n DragEventData,\n DropEventData,\n TPointerEvent,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { IText } from './IText';\nimport { setStyle } from '../../util/dom_style';\nimport { cloneStyles } from '../../util/internals/cloneStyles';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, NONE } from '../../constants';\n\n/**\n * #### Dragging IText/Textbox Lifecycle\n * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection}\n * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection\n * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session\n * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur\n * - canvas fires relevant drag events that are handled by the handlers defined in this scope\n * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior\n * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown`\n */\nexport class DraggableTextDelegate {\n readonly target: IText;\n private __mouseDownInPlace = false;\n private __dragStartFired = false;\n private __isDraggingOver = false;\n private __dragStartSelection?: {\n selectionStart: number;\n selectionEnd: number;\n };\n private __dragImageDisposer?: VoidFunction;\n private _dispose?: () => void;\n\n constructor(target: IText) {\n this.target = target;\n const disposers = [\n this.target.on('dragenter', this.dragEnterHandler.bind(this)),\n this.target.on('dragover', this.dragOverHandler.bind(this)),\n this.target.on('dragleave', this.dragLeaveHandler.bind(this)),\n this.target.on('dragend', this.dragEndHandler.bind(this)),\n this.target.on('drop', this.dropHandler.bind(this)),\n ];\n this._dispose = () => {\n disposers.forEach((d) => d());\n this._dispose = undefined;\n };\n }\n\n isPointerOverSelection(e: TPointerEvent) {\n const target = this.target;\n const newSelection = target.getSelectionStartFromPointer(e);\n return (\n target.isEditing &&\n newSelection >= target.selectionStart &&\n newSelection <= target.selectionEnd &&\n target.selectionStart < target.selectionEnd\n );\n }\n\n /**\n * @public override this method to disable dragging and default to mousedown logic\n */\n start(e: TPointerEvent) {\n return (this.__mouseDownInPlace = this.isPointerOverSelection(e));\n }\n\n /**\n * @public override this method to disable dragging without discarding selection\n */\n isActive() {\n return this.__mouseDownInPlace;\n }\n\n /**\n * Ends interaction and sets cursor in case of a click\n * @returns true if was active\n */\n end(e: TPointerEvent) {\n const active = this.isActive();\n if (active && !this.__dragStartFired) {\n // mousedown has been blocked since `active` is true => cursor has not been set.\n // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection.\n // meaning this is actually a click, `active` is a false positive.\n this.target.setCursorByClick(e);\n this.target.initDelayedCursor(true);\n }\n this.__mouseDownInPlace = false;\n this.__dragStartFired = false;\n this.__isDraggingOver = false;\n return active;\n }\n\n getDragStartSelection() {\n return this.__dragStartSelection;\n }\n\n /**\n * Override to customize the drag image\n * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage\n */\n setDragImage(\n e: DragEvent,\n {\n selectionStart,\n selectionEnd,\n }: {\n selectionStart: number;\n selectionEnd: number;\n },\n ) {\n const target = this.target;\n const canvas = target.canvas!;\n const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1);\n const boundaries = target._getCursorBoundaries(selectionStart);\n const selectionPosition = new Point(\n boundaries.left + boundaries.leftOffset,\n boundaries.top + boundaries.topOffset,\n ).multiply(flipFactor);\n const pos = selectionPosition.transform(target.calcTransformMatrix());\n const pointer = canvas.getScenePoint(e);\n const diff = pointer.subtract(pos);\n const retinaScaling = target.getCanvasRetinaScaling();\n const bbox = target.getBoundingRect();\n const correction = pos.subtract(new Point(bbox.left, bbox.top));\n const vpt = canvas.viewportTransform;\n const offset = correction.add(diff).transform(vpt, true);\n // prepare instance for drag image snapshot by making all non selected text invisible\n const bgc = target.backgroundColor;\n const styles = cloneStyles(target.styles);\n target.backgroundColor = '';\n const styleOverride = {\n stroke: 'transparent',\n fill: 'transparent',\n textBackgroundColor: 'transparent',\n };\n target.setSelectionStyles(styleOverride, 0, selectionStart);\n target.setSelectionStyles(styleOverride, selectionEnd, target.text.length);\n target.dirty = true;\n const dragImage = target.toCanvasElement({\n enableRetinaScaling: canvas.enableRetinaScaling,\n viewportTransform: true,\n });\n // restore values\n target.backgroundColor = bgc;\n target.styles = styles;\n target.dirty = true;\n // position drag image offscreen\n setStyle(dragImage, {\n position: 'fixed',\n left: `${-dragImage.width}px`,\n border: NONE,\n width: `${dragImage.width / retinaScaling}px`,\n height: `${dragImage.height / retinaScaling}px`,\n });\n this.__dragImageDisposer && this.__dragImageDisposer();\n this.__dragImageDisposer = () => {\n dragImage.remove();\n };\n getDocumentFromElement(\n (e.target || this.target.hiddenTextarea)! as HTMLElement,\n ).body.appendChild(dragImage);\n e.dataTransfer?.setDragImage(dragImage, offset.x, offset.y);\n }\n\n /**\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source\n */\n onDragStart(e: DragEvent): boolean {\n this.__dragStartFired = true;\n const target = this.target;\n const active = this.isActive();\n if (active && e.dataTransfer) {\n const selection = (this.__dragStartSelection = {\n selectionStart: target.selectionStart,\n selectionEnd: target.selectionEnd,\n });\n const value = target._text\n .slice(selection.selectionStart, selection.selectionEnd)\n .join('');\n const data = { text: target.text, value, ...selection };\n e.dataTransfer.setData('text/plain', value);\n e.dataTransfer.setData(\n 'application/fabric',\n JSON.stringify({\n value: value,\n styles: target.getSelectionStyles(\n selection.selectionStart,\n selection.selectionEnd,\n true,\n ),\n }),\n );\n e.dataTransfer.effectAllowed = 'copyMove';\n this.setDragImage(e, data);\n }\n target.abortCursorAnimation();\n return active;\n }\n\n /**\n * use {@link targetCanDrop} to respect overriding\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target\n */\n canDrop(e: DragEvent): boolean {\n if (\n this.target.editable &&\n !this.target.getActiveControl() &&\n !e.defaultPrevented\n ) {\n if (this.isActive() && this.__dragStartSelection) {\n // drag source trying to drop over itself\n // allow dropping only outside of drag start selection\n const index = this.target.getSelectionStartFromPointer(e);\n const dragStartSelection = this.__dragStartSelection;\n return (\n index < dragStartSelection.selectionStart ||\n index > dragStartSelection.selectionEnd\n );\n }\n return true;\n }\n return false;\n }\n\n /**\n * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly\n */\n protected targetCanDrop(e: DragEvent) {\n return this.target.canDrop(e);\n }\n\n dragEnterHandler({ e }: DragEventData) {\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n }\n }\n\n dragOverHandler(ev: DragEventData) {\n const { e } = ev;\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n } else if (this.__isDraggingOver && !canDrop) {\n // drop state has changed\n this.__isDraggingOver = false;\n }\n if (this.__isDraggingOver) {\n // can be dropped, inform browser\n e.preventDefault();\n // inform event subscribers\n ev.canDrop = true;\n ev.dropTarget = this.target;\n }\n }\n\n dragLeaveHandler() {\n if (this.__isDraggingOver || this.isActive()) {\n this.__isDraggingOver = false;\n }\n }\n\n /**\n * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer}\n * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop\n */\n dropHandler(ev: DropEventData) {\n const { e } = ev;\n const didDrop = e.defaultPrevented;\n this.__isDraggingOver = false;\n // inform browser that the drop has been accepted\n e.preventDefault();\n let insert = e.dataTransfer?.getData('text/plain');\n if (insert && !didDrop) {\n const target = this.target;\n const canvas = target.canvas!;\n let insertAt = target.getSelectionStartFromPointer(e);\n const { styles } = (\n e.dataTransfer!.types.includes('application/fabric')\n ? JSON.parse(e.dataTransfer!.getData('application/fabric'))\n : {}\n ) as { styles: TextStyleDeclaration[] };\n const trailing = insert[Math.max(0, insert.length - 1)];\n const selectionStartOffset = 0;\n // drag and drop in same instance\n if (this.__dragStartSelection) {\n const selectionStart = this.__dragStartSelection.selectionStart;\n const selectionEnd = this.__dragStartSelection.selectionEnd;\n if (insertAt > selectionStart && insertAt <= selectionEnd) {\n insertAt = selectionStart;\n } else if (insertAt > selectionEnd) {\n insertAt -= selectionEnd - selectionStart;\n }\n target.removeChars(selectionStart, selectionEnd);\n // prevent `dragend` from handling event\n delete this.__dragStartSelection;\n }\n // remove redundant line break\n if (\n target._reNewline.test(trailing) &&\n (target._reNewline.test(target._text[insertAt]) ||\n insertAt === target._text.length)\n ) {\n insert = insert.trimEnd();\n }\n // inform subscribers\n ev.didDrop = true;\n ev.dropTarget = target;\n // finalize\n target.insertChars(insert, styles, insertAt);\n // can this part be moved in an outside event? andrea to check.\n canvas.setActiveObject(target);\n target.enterEditing(e);\n target.selectionStart = Math.min(\n insertAt + selectionStartOffset,\n target._text.length,\n );\n target.selectionEnd = Math.min(\n target.selectionStart + insert.length,\n target._text.length,\n );\n target.hiddenTextarea!.value = target.text;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n target.fire(CHANGED, {\n index: insertAt + selectionStartOffset,\n action: 'drop',\n });\n canvas.fire('text:changed', { target });\n canvas.contextTopDirty = true;\n canvas.requestRenderAll();\n }\n }\n\n /**\n * fired only on the drag source after drop (if occurred)\n * handle changes to the drag source in case of a drop on another object or a cancellation\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n */\n dragEndHandler({ e }: DragEventData) {\n if (this.isActive() && this.__dragStartFired) {\n // once the drop event finishes we check if we need to change the drag source\n // if the drag source received the drop we bail out since the drop handler has already handled logic\n if (this.__dragStartSelection) {\n const target = this.target;\n const canvas = this.target.canvas!;\n const { selectionStart, selectionEnd } = this.__dragStartSelection;\n const dropEffect = e.dataTransfer?.dropEffect || NONE;\n if (dropEffect === NONE) {\n // pointer is back over selection\n target.selectionStart = selectionStart;\n target.selectionEnd = selectionEnd;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n } else {\n target.clearContextTop();\n if (dropEffect === 'move') {\n target.removeChars(selectionStart, selectionEnd);\n target.selectionStart = target.selectionEnd = selectionStart;\n target.hiddenTextarea &&\n (target.hiddenTextarea.value = target.text);\n target._updateTextarea();\n target.fire(CHANGED, {\n index: selectionStart,\n action: 'dragend',\n });\n canvas.fire('text:changed', { target });\n canvas.requestRenderAll();\n }\n target.exitEditing();\n }\n }\n }\n\n this.__dragImageDisposer && this.__dragImageDisposer();\n delete this.__dragImageDisposer;\n delete this.__dragStartSelection;\n this.__isDraggingOver = false;\n }\n\n dispose() {\n this._dispose && this._dispose();\n }\n}\n","import type {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends FabricText {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean,\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n },\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1),\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n this.canvas.fire('text:editing:entered', {\n target: this as unknown as IText,\n e,\n });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[],\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text,\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value,\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight,\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight,\n ),\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire(MODIFIED);\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true,\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration },\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle,\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength,\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start,\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number,\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\n","import { config } from '../../config';\nimport { getFabricDocument, getEnv } from '../../env';\nimport { capValue } from '../../util/misc/capValue';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextBehavior } from './ITextBehavior';\nimport type { TKeyMapIText } from './constants';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\nimport type { IText } from './IText';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\n\nexport abstract class ITextKeyBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextBehavior {\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behavior for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the IText or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = Object.assign({}, this.keysMap);\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\n */\n declare keysMap: TKeyMapIText;\n\n declare keysMapRtl: TKeyMapIText;\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n declare ctrlKeysMapUp: TKeyMapIText;\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n declare ctrlKeysMapDown: TKeyMapIText;\n\n declare hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * DOM container to append the hiddenTextarea.\n * An alternative to attaching to the document.body.\n * Useful to reduce laggish redraw of the full document.body tree and\n * also with modals event capturing that won't let the textarea take focus.\n * @type HTMLElement\n * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare fromPaste: boolean;\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea() {\n const doc =\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument();\n const textarea = doc.createElement('textarea');\n Object.entries({\n autocapitalize: 'off',\n autocorrect: 'off',\n autocomplete: 'off',\n spellcheck: 'false',\n 'data-fabric': 'textarea',\n wrap: 'off',\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\n const { top, left, fontSize } = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\n\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\n\n Object.entries({\n blur: 'blur',\n keydown: 'onKeyDown',\n keyup: 'onKeyUp',\n input: 'onInput',\n copy: 'copy',\n cut: 'copy',\n paste: 'paste',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate',\n compositionend: 'onCompositionEnd',\n } as Record).map(([eventName, handler]) =>\n textarea.addEventListener(\n eventName,\n (this[handler] as EventListener).bind(this),\n ),\n );\n this.hiddenTextarea = textarea;\n }\n\n /**\n * Override this method to customize cursor behavior on textbox blur\n */\n blur() {\n this.abortCursorAnimation();\n }\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {KeyboardEvent} e Event object\n */\n onKeyDown(e: KeyboardEvent) {\n if (!this.isEditing) {\n return;\n }\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\n if (e.keyCode in keyMap) {\n // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n }\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {KeyboardEvent} e Event object\n */\n onKeyUp(e: KeyboardEvent) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n }\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\n const fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n const updateAndFire = () => {\n this.updateFromTextArea();\n this.fire(CHANGED);\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this as unknown as IText });\n this.canvas.requestRenderAll();\n }\n };\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n updateAndFire();\n return;\n }\n // decisions about style changes.\n const nextText = this._splitTextIntoLines(\n this.hiddenTextarea.value,\n ).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd;\n let copiedStyle: TextStyleDeclaration[] | undefined,\n removedText,\n charDiff = nextCharCount - charCount,\n removeFrom,\n removeTo;\n\n const textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value,\n );\n const backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(\n selectionStart,\n selectionStart - charDiff,\n );\n }\n }\n const insertedText = nextText.slice(\n textareaSelection.selectionEnd - charDiff,\n textareaSelection.selectionEnd,\n );\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(\n selectionStart,\n selectionStart + 1,\n false,\n );\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(\n () =>\n // this return an array of references, but that is fine since we are\n // copying the style later.\n copiedStyle![0],\n );\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differences between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n const { copyPasteData } = getEnv();\n if (\n fromPaste &&\n insertedText.join('') === copyPasteData.copiedText &&\n !config.disableStyleCopyPaste\n ) {\n copiedStyle = copyPasteData.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n updateAndFire();\n }\n\n /**\n * Composition start\n */\n onCompositionStart() {\n this.inCompositionMode = true;\n }\n\n /**\n * Composition end\n */\n onCompositionEnd() {\n this.inCompositionMode = false;\n }\n\n onCompositionUpdate({ target }: CompositionEvent) {\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\n this.compositionStart = selectionStart;\n this.compositionEnd = selectionEnd;\n this.updateTextareaPosition();\n }\n\n /**\n * Copies selected text\n */\n copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n const { copyPasteData } = getEnv();\n copyPasteData.copiedText = this.getSelectedText();\n if (!config.disableStyleCopyPaste) {\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\n this.selectionStart,\n this.selectionEnd,\n true,\n );\n } else {\n copyPasteData.copiedTextStyle = undefined;\n }\n this._copyDone = true;\n }\n\n /**\n * Pastes text\n */\n paste() {\n this.fromPaste = true;\n }\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n }\n\n /**\n * Gets start offset of a selection\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (\n lineIndex === this._textLines.length - 1 ||\n e.metaKey ||\n e.keyCode === 34\n ) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return (\n textAfterCursor.length +\n indexOnOtherLine +\n 1 +\n this.missingNewlineOffset(lineIndex)\n );\n }\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n }\n\n /**\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return (\n -this._textLines[lineIndex - 1].length +\n indexOnOtherLine -\n textBeforeCursor.length +\n (1 - missingNewlineOffset)\n );\n }\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine(lineIndex: number, width: number) {\n const line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n let widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n const leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n }\n\n /**\n * Moves cursor down\n * @param {KeyboardEvent} e Event object\n */\n moveCursorDown(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n }\n\n /**\n * Moves cursor up\n * @param {KeyboardEvent} e Event object\n */\n moveCursorUp(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n }\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\n const offset = this[`get${direction}CursorOffset`](\n e,\n this._selectionDirection === RIGHT,\n );\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n const max = this.text.length;\n this.selectionStart = capValue(0, this.selectionStart, max);\n this.selectionEnd = capValue(0, this.selectionEnd, max);\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift(offset: number) {\n const newSelection =\n this._selectionDirection === LEFT\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(\n this.selectionStart,\n this.selectionEnd,\n newSelection,\n );\n return offset !== 0;\n }\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift(offset: number) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n }\n\n /**\n * Moves cursor left\n * @param {KeyboardEvent} e Event object\n */\n moveCursorLeft(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n }\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n *\n * @todo refactor not to use method name composition\n */\n _move(\n e: KeyboardEvent,\n prop: 'selectionStart' | 'selectionEnd',\n direction: 'Left' | 'Right',\n ): boolean {\n let newValue: number | undefined;\n if (e.altKey) {\n newValue = this[`findWordBoundary${direction}`](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this[`findLineBoundary${direction}`](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n return false;\n }\n\n /**\n * @private\n */\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Left');\n }\n\n /**\n * @private\n */\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Right');\n }\n\n /**\n * Moves cursor left without keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\n let change = true;\n this._selectionDirection = LEFT;\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (\n this.selectionEnd === this.selectionStart &&\n this.selectionStart !== 0\n ) {\n change = this._moveLeft(e, 'selectionStart');\n }\n this.selectionEnd = this.selectionStart;\n return change;\n }\n\n /**\n * Moves cursor left while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === RIGHT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = LEFT;\n return this._moveLeft(e, 'selectionStart');\n }\n }\n\n /**\n * Moves cursor right\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRight(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n }\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\n const actionName = `moveCursor${direction}${\n e.shiftKey ? 'WithShift' : 'WithoutShift'\n }` as const;\n this._currentCursorOpacity = 1;\n if (this[actionName](e)) {\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor right while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorRightWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === LEFT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = RIGHT;\n return this._moveRight(e, 'selectionEnd');\n }\n }\n\n /**\n * Moves cursor right without keeping selection\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRightWithoutShift(e: KeyboardEvent) {\n let changed = true;\n this._selectionDirection = RIGHT;\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n }\n}\n","import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { stopEvent } from '../../util/dom_event';\nimport { invertTransform } from '../../util/misc/matrix';\nimport { DraggableTextDelegate } from './DraggableTextDelegate';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextKeyBehavior } from './ITextKeyBehavior';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\n\n/**\n * `LEFT_CLICK === 0`\n */\nconst notALeftClick = (e: Event) => !!(e as MouseEvent).button;\n\nexport abstract class ITextClickBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextKeyBehavior {\n private declare __lastSelected: boolean;\n private declare __lastClickTime: number;\n private declare __lastLastClickTime: number;\n private declare __lastPointer: XY | Record;\n private declare __newClickTime: number;\n\n protected draggableTextDelegate: DraggableTextDelegate;\n\n initBehavior() {\n // Initializes event handlers related to cursor or selection\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n this.on('mouseup', this.mouseUpHandler);\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n\n // Initializes \"dbclick\" event handler\n this.__lastClickTime = +new Date();\n // for triple click\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n\n // @ts-expect-error in reality it is an IText instance\n this.draggableTextDelegate = new DraggableTextDelegate(this);\n\n super.initBehavior();\n }\n\n /**\n * If this method returns true a mouse move operation over a text selection\n * will not prevent the native mouse event allowing the browser to start a drag operation.\n * shouldStartDragging can be read 'do not prevent default for mouse move event'\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns\n */\n shouldStartDragging() {\n return this.draggableTextDelegate.isActive();\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drag source,\n * @see also {@link DraggableTextDelegate#isActive}\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns {boolean} should handle event\n */\n onDragStart(e: DragEvent) {\n return this.draggableTextDelegate.onDragStart(e);\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drop target\n */\n canDrop(e: DragEvent) {\n return this.draggableTextDelegate.canDrop(e);\n }\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown(options: TPointerEventInfo) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n const newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastSelected = this.selected && !this.getActiveControl();\n }\n\n isTripleClick(newPointer: XY) {\n return (\n this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y\n );\n }\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler({ e }: TPointerEventInfo) {\n if (\n !this.canvas ||\n !this.editable ||\n notALeftClick(e) ||\n this.getActiveControl()\n ) {\n return;\n }\n\n if (this.draggableTextDelegate.start(e)) {\n return;\n }\n\n this.canvas.textEditingManager.register(this);\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore({ e }: TPointerEventInfo) {\n if (!this.canvas || !this.editable || notALeftClick(e)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n }\n\n /**\n * standard handler for mouse up, overridable\n * @private\n */\n mouseUpHandler({ e, transform }: TPointerEventInfo) {\n const didDrag = this.draggableTextDelegate.end(e);\n if (this.canvas) {\n this.canvas.textEditingManager.unregister(this);\n\n const activeObject = this.canvas._activeObject;\n if (activeObject && activeObject !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n if (\n !this.editable ||\n (this.group && !this.group.interactive) ||\n (transform && transform.actionPerformed) ||\n notALeftClick(e) ||\n didDrag\n ) {\n return;\n }\n\n if (this.__lastSelected && !this.getActiveControl()) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\n }\n } else {\n this.selected = true;\n }\n }\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {TPointerEvent} e Event object\n */\n setCursorByClick(e: TPointerEvent) {\n const newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {TPointerEvent} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer(e: TPointerEvent): number {\n const mouseOffset = this.canvas!.getScenePoint(e)\n .transform(invertTransform(this.calcTransformMatrix()))\n .add(new Point(-this._getLeftOffset(), -this._getTopOffset()));\n let height = 0,\n charIndex = 0,\n lineIndex = 0;\n\n for (let i = 0; i < this._textLines.length; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i);\n lineIndex = i;\n if (i > 0) {\n charIndex +=\n this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex));\n let width = lineLeftOffset;\n const charLength = this._textLines[lineIndex].length;\n const chars = this.__charBounds[lineIndex];\n for (let j = 0; j < charLength; j++) {\n // i removed something about flipX here, check.\n const charWidth = chars[j].kernedWidth;\n const widthAfter = width + charWidth;\n if (mouseOffset.x <= widthAfter) {\n // if the pointer is closer to the end of the char we increment charIndex\n // in order to position the cursor after the char\n if (\n Math.abs(mouseOffset.x - widthAfter) <=\n Math.abs(mouseOffset.x - width)\n ) {\n charIndex++;\n }\n break;\n }\n width = widthAfter;\n charIndex++;\n }\n\n return Math.min(\n // if object is horizontally flipped, mirror cursor location from the end\n this.flipX ? charLength - charIndex : charIndex,\n this._text.length,\n );\n }\n}\n","export type TKeyMapIText = Record<\n KeyboardEvent['keyCode'],\n CursorHandlingMethods\n>;\n\nexport type CursorHandlingMethods =\n | 'moveCursorUp'\n | 'moveCursorDown'\n | 'moveCursorLeft'\n | 'moveCursorRight'\n | 'exitEditing'\n | 'copy'\n | 'cut'\n | 'selectAll';\n\nconst MOVE_CURSOR_UP: CursorHandlingMethods = 'moveCursorUp';\nconst MOVE_CURSOR_DOWN: CursorHandlingMethods = 'moveCursorDown';\nconst MOVE_CURSOR_LEFT: CursorHandlingMethods = 'moveCursorLeft';\nconst MOVE_CURSOR_RIGHT: CursorHandlingMethods = 'moveCursorRight';\nconst EXIT_EDITING: CursorHandlingMethods = 'exitEditing';\n\n// @TODO look into import { Key } from 'ts-key-enum';\n// and transition from keyCode to Key\n// also reduce string duplication\nexport const keysMap: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_RIGHT,\n 36: MOVE_CURSOR_LEFT,\n 37: MOVE_CURSOR_LEFT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_RIGHT,\n 40: MOVE_CURSOR_DOWN,\n};\n\nexport const keysMapRtl: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_LEFT,\n 36: MOVE_CURSOR_RIGHT,\n 37: MOVE_CURSOR_RIGHT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_LEFT,\n 40: MOVE_CURSOR_DOWN,\n};\n\n/**\n * For functionalities on keyUp + ctrl || cmd\n */\nexport const ctrlKeysMapUp: TKeyMapIText = {\n 67: 'copy',\n // there was a reason this wasn't deleted. for now leave it here\n 88: 'cut',\n};\n\n/**\n * For functionalities on keyDown + ctrl || cmd\n */\nexport const ctrlKeysMapDown: TKeyMapIText = {\n 65: 'selectAll',\n};\n","import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, FILL, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions = Partial,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends ITextClickBehavior\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number,\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean,\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean,\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean,\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean,\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number,\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, FILL) as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight,\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true),\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries,\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight,\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, FILL);\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n","import type { TClassProperties, TOptions } from '../typedefs';\nimport { IText } from './IText/IText';\nimport { classRegistry } from '../ClassRegistry';\nimport { createTextboxDefaultControls } from '../controls/commonControls';\nimport { JUSTIFY } from './Text/constants';\nimport type { TextStyleDeclaration } from './Text/StyledText';\nimport type { SerializedITextProps, ITextProps } from './IText/IText';\nimport type { ITextEvents } from './IText/ITextBehavior';\nimport type { TextLinesInfo } from './Text/Text';\nimport type { Control } from '../controls/Control';\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textboxDefaultValues: Partial> = {\n minWidth: 20,\n dynamicMinWidth: 2,\n lockScalingFlip: true,\n noScaleCache: false,\n _wordJoiners: /[ \\t\\r]/,\n splitByGrapheme: false,\n};\n\nexport type GraphemeData = {\n wordsData: {\n word: string[];\n width: number;\n }[][];\n largestWordWidth: number;\n};\n\nexport type StyleMap = Record;\n\n// @TODO this is not complete\ninterface UniqueTextboxProps {\n minWidth: number;\n splitByGrapheme: boolean;\n dynamicMinWidth: number;\n _wordJoiners: RegExp;\n}\n\nexport interface SerializedTextboxProps\n extends SerializedITextProps,\n Pick {}\n\nexport interface TextboxProps extends ITextProps, UniqueTextboxProps {}\n\n/**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n */\nexport class Textbox<\n Props extends TOptions = Partial,\n SProps extends SerializedTextboxProps = SerializedTextboxProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends IText\n implements UniqueTextboxProps\n{\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n declare minWidth: number;\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n declare dynamicMinWidth: number;\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japanese\n * @type Boolean\n * @since 2.6.0\n */\n declare splitByGrapheme: boolean;\n\n declare _wordJoiners: RegExp;\n\n declare _styleMap: StyleMap;\n\n declare isWrapping: boolean;\n\n static type = 'Textbox';\n\n static textLayoutProperties = [...IText.textLayoutProperties, 'width'];\n\n static ownDefaults = textboxDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Textbox.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...Textbox.ownDefaults, ...options } as Props);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults object\n */\n static createControls(): { controls: Record } {\n return { controls: createTextboxDefaultControls() };\n }\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions() {\n if (!this.initialized) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n }\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap(textInfo: TextLinesInfo): StyleMap {\n let realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0;\n const map: StyleMap = {};\n\n for (let i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n } else if (\n !this.splitByGrapheme &&\n this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) &&\n i > 0\n ) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n }\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex: number): boolean {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return super.styleHas(property, lineIndex);\n }\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex: number): boolean {\n if (!this.styles) {\n return true;\n }\n let offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset: number,\n shouldLimit = false;\n const map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n const p2Number = parseInt(p2, 10);\n if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset!)) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n /**\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (!map) {\n return {};\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return super._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n const map = this._styleMap[lineIndex];\n super._setStyleDeclaration(map.line, map.offset + charIndex, style);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n const map = this._styleMap[lineIndex];\n super._deleteStyleDeclaration(map.line, map.offset + charIndex);\n }\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n const map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n const map = this._styleMap[lineIndex];\n super._setLineStyle(map.line);\n }\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText(lines: string[], desiredWidth: number): string[][] {\n this.isWrapping = true;\n // extract all thewords and the widths to optimally wrap lines.\n const data = this.getGraphemeDataForRender(lines);\n const wrapped: string[][] = [];\n for (let i = 0; i < data.wordsData.length; i++) {\n wrapped.push(...this._wrapLine(i, desiredWidth, data));\n }\n this.isWrapping = false;\n return wrapped;\n }\n\n /**\n * For each line of text terminated by an hard line stop,\n * measure each word width and extract the largest word from all.\n * The returned words here are the one that at the end will be rendered.\n * @param {string[]} lines the lines we need to measure\n *\n */\n getGraphemeDataForRender(lines: string[]): GraphemeData {\n const splitByGrapheme = this.splitByGrapheme,\n infix = splitByGrapheme ? '' : ' ';\n\n let largestWordWidth = 0;\n\n const data = lines.map((line, lineIndex) => {\n let offset = 0;\n const wordsOrGraphemes = splitByGrapheme\n ? this.graphemeSplit(line)\n : this.wordSplit(line);\n\n if (wordsOrGraphemes.length === 0) {\n return [{ word: [], width: 0 }];\n }\n\n return wordsOrGraphemes.map((word: string) => {\n // if using splitByGrapheme words are already in graphemes.\n const graphemeArray = splitByGrapheme\n ? [word]\n : this.graphemeSplit(word);\n const width = this._measureWord(graphemeArray, lineIndex, offset);\n largestWordWidth = Math.max(width, largestWordWidth);\n offset += graphemeArray.length + infix.length;\n return { word: graphemeArray, width };\n });\n });\n\n return {\n wordsData: data,\n largestWordWidth,\n };\n }\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * It gets called when charBounds are not available yet.\n * Override if necessary\n * Use with {@link Textbox#wordSplit}\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n */\n _measureWord(word: string[], lineIndex: number, charOffset = 0): number {\n let width = 0,\n prevGrapheme;\n const skipLeft = true;\n for (let i = 0, len = word.length; i < len; i++) {\n const box = this._getGraphemeBox(\n word[i],\n lineIndex,\n i + charOffset,\n prevGrapheme,\n skipLeft,\n );\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n }\n\n /**\n * Override this method to customize word splitting\n * Use with {@link Textbox#_measureWord}\n * @param {string} value\n * @returns {string[]} array of words\n */\n wordSplit(value: string): string[] {\n return value.split(this._wordJoiners);\n }\n\n /**\n * Wraps a line of text using the width of the Textbox as desiredWidth\n * and leveraging the known width o words from GraphemeData\n * @private\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {GraphemeData} graphemeData an object containing all the lines' words width.\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine(\n lineIndex: number,\n desiredWidth: number,\n { largestWordWidth, wordsData }: GraphemeData,\n reservedSpace = 0,\n ): string[][] {\n const additionalSpace = this._getWidthOfCharSpacing(),\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n infix = splitByGrapheme ? '' : ' ';\n\n let lineWidth = 0,\n line: string[] = [],\n // spaces in different languages?\n offset = 0,\n infixWidth = 0,\n lineJustStarted = true;\n\n desiredWidth -= reservedSpace;\n\n const maxWidth = Math.max(\n desiredWidth,\n largestWordWidth,\n this.dynamicMinWidth,\n );\n // layout words\n const data = wordsData[lineIndex];\n offset = 0;\n let i;\n for (i = 0; i < data.length; i++) {\n const { word, width: wordWidth } = data[i];\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n if (lineWidth > maxWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = splitByGrapheme\n ? 0\n : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n }\n\n i && graphemeLines.push(line);\n\n // TODO: this code is probably not necessary anymore.\n // it can be moved out of this function since largestWordWidth is now\n // known in advance\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n return graphemeLines;\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * This is important only for splitByGrapheme at the end of wrapping.\n * If we are not wrapping the offset is always 1\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1 {\n if (this.splitByGrapheme && !skipWrapping) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n }\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines(text: string) {\n const newText = super._splitTextIntoLines(text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (let i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n }\n\n getMinWidth() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n }\n\n _removeExtraneousStyles() {\n const linesToKeep = new Map();\n for (const prop in this._styleMap) {\n const propNumber = parseInt(prop, 10);\n if (this._textLines[propNumber]) {\n const lineIndex = this._styleMap[prop].line;\n linesToKeep.set(`${lineIndex}`, true);\n }\n }\n for (const prop in this.styles) {\n if (!linesToKeep.has(prop)) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([\n 'minWidth',\n 'splitByGrapheme',\n ...propertiesToInclude,\n ] as K[]) as Pick & SProps;\n }\n}\n\nclassRegistry.setClass(Textbox);\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport { sendPointToPlane } from '../../util/misc/planeChange';\nimport type { LayoutStrategyResult, StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { getObjectBounds } from './utils';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to match the clip path bounding box.\n */\nexport class ClipPathLayout extends LayoutStrategy {\n static readonly type = 'clip-path';\n\n shouldPerformLayout(context: StrictLayoutContext): boolean {\n return !!context.target.clipPath && super.shouldPerformLayout(context);\n }\n\n shouldLayoutClipPath() {\n return false;\n }\n\n calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n const { target } = context;\n const { clipPath, group } = target;\n if (!clipPath || !this.shouldPerformLayout(context)) {\n return;\n }\n // TODO: remove stroke calculation from this case\n const { width, height } = makeBoundingBoxFromPoints(\n getObjectBounds(target, clipPath as FabricObject),\n );\n const size = new Point(width, height);\n if (clipPath.absolutePositioned) {\n // we want the center point to exist in group's containing plane\n const clipPathCenter = sendPointToPlane(\n clipPath.getRelativeCenterPoint(),\n undefined,\n group ? group.calcTransformMatrix() : undefined,\n );\n return {\n center: clipPathCenter,\n size,\n };\n } else {\n // we want the center point to exist in group's containing plane, so we send it upwards\n const clipPathCenter = clipPath\n .getRelativeCenterPoint()\n .transform(target.calcOwnMatrix(), true);\n if (this.shouldPerformLayout(context)) {\n // the clip path is positioned relative to the group's center which is affected by the bbox\n // so we first calculate the bbox\n const { center = new Point(), correction = new Point() } =\n this.calcBoundingBox(objects, context) || {};\n return {\n center: center.add(clipPathCenter),\n correction: correction.subtract(clipPathCenter),\n size,\n };\n } else {\n return {\n center: target.getRelativeCenterPoint().add(clipPathCenter),\n size,\n };\n }\n }\n }\n}\n\nclassRegistry.setClass(ClipPathLayout);\n","import { Point } from '../../Point';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will keep target's initial size.\n */\nexport class FixedLayout extends LayoutStrategy {\n static readonly type = 'fixed';\n\n /**\n * @override respect target's initial size\n */\n getInitialSize(\n { target }: StrictLayoutContext & InitializationLayoutContext,\n { size }: Pick,\n ): Point {\n return new Point(target.width || size.x, target.height || size.y);\n }\n}\n\nclassRegistry.setClass(FixedLayout);\n","import { LayoutManager } from './LayoutManager';\nimport type { RegistrationContext, StrictLayoutContext } from './types';\nimport type { Group } from '../shapes/Group';\n\n/**\n * Today the LayoutManager class also takes care of subscribing event handlers\n * to update the group layout when the group is interactive and a transform is applied\n * to a child object.\n * The ActiveSelection is never interactive, but it could contain objects from\n * groups that are.\n * The standard LayoutManager would subscribe the children of the activeSelection to\n * perform layout changes to the active selection itself, what we need instead is that\n * the transformation applied to the active selection will trigger changes to the\n * original group of the children ( the one referenced under the parent property )\n * This subclass of the LayoutManager has a single duty to fill the gap of this difference.`\n */\nexport class ActiveSelectionLayoutManager extends LayoutManager {\n subscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n parent.layoutManager.subscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n\n /**\n * unsubscribe from parent only if all its children were deselected\n */\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const selectedObjects = activeSelection.getObjects();\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n !selectedObjects.some((object) => object.parent === parent) &&\n parent.layoutManager.unsubscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n}\n","import type { ControlRenderingStyleOverride } from '../controls/controlRendering';\nimport { classRegistry } from '../ClassRegistry';\nimport type { GroupProps } from './Group';\nimport { Group } from './Group';\nimport type { FabricObject } from './Object/FabricObject';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { TClassProperties } from '../typedefs';\nimport { log } from '../util/internals/console';\nimport { ActiveSelectionLayoutManager } from '../LayoutManager/ActiveSelectionLayoutManager';\n\nexport type MultiSelectionStacking = 'canvas-stacking' | 'selection-order';\n\nexport interface ActiveSelectionOptions extends GroupProps {\n multiSelectionStacking: MultiSelectionStacking;\n}\n\nconst activeSelectionDefaultValues: Partial> =\n {\n multiSelectionStacking: 'canvas-stacking',\n };\n\n/**\n * Used by Canvas to manage selection.\n *\n * @example\n * class MyActiveSelection extends ActiveSelection {\n * ...\n * }\n *\n * // override the default `ActiveSelection` class\n * classRegistry.setClass(MyActiveSelection)\n */\nexport class ActiveSelection extends Group {\n static type = 'ActiveSelection';\n\n static ownDefaults: Record = activeSelectionDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...ActiveSelection.ownDefaults };\n }\n\n /**\n * The ActiveSelection needs to use the ActiveSelectionLayoutManager\n * or selections on interactive groups may be broken\n */\n declare layoutManager: ActiveSelectionLayoutManager;\n\n /**\n * controls how selected objects are added during a multiselection event\n * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order\n * - `selection-order` adds the selected object to the top of the stack,\n * meaning that the stack is ordered by the order in which objects were selected\n * @default `canvas-stacking`\n */\n declare multiSelectionStacking: MultiSelectionStacking;\n\n constructor(\n objects: FabricObject[] = [],\n options: Partial = {},\n ) {\n super();\n Object.assign(this, ActiveSelection.ownDefaults);\n this.setOptions(options);\n const { left, top, layoutManager } = options;\n this.groupInit(objects, {\n left,\n top,\n layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(),\n });\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return true;\n }\n\n /**\n * @private\n * @override we don't want the selection monitor to be active\n */\n __objectSelectionMonitor() {\n // noop\n }\n\n /**\n * Adds objects with respect to {@link multiSelectionStacking}\n * @param targets object to add to selection\n */\n multiSelectAdd(...targets: FabricObject[]) {\n if (this.multiSelectionStacking === 'selection-order') {\n this.add(...targets);\n } else {\n // respect object stacking as it is on canvas\n // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf`\n targets.forEach((target) => {\n const index = this._objects.findIndex((obj) => obj.isInFrontOf(target));\n const insertAt =\n index === -1\n ? // `target` is in front of all other objects\n this.size()\n : index;\n this.insertAt(insertAt, target);\n });\n }\n }\n\n /**\n * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree\n */\n canEnterGroup(object: FabricObject) {\n if (\n this.getObjects().some(\n (o) => o.isDescendantOf(object) || object.isDescendantOf(o),\n )\n ) {\n // prevent circular object tree\n log(\n 'error',\n 'ActiveSelection: circular object trees are not supported, this call has no effect',\n );\n return false;\n }\n\n return super.canEnterGroup(object);\n }\n\n /**\n * Change an object so that it can be part of an active selection.\n * this method is called by multiselectAdd from canvas code.\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n // This condition check that the object has currently a group, and the group\n // is also its parent, meaning that is not in an active selection, but is\n // in a normal group.\n if (object.parent && object.parent === object.group) {\n // Disconnect the object from the group functionalities, but keep the ref parent intact\n // for later re-enter\n object.parent._exitGroup(object);\n // in this case the object is probably inside an active selection.\n } else if (object.group && object.parent !== object.group) {\n // in this case group.remove will also clear the old parent reference.\n object.group.remove(object);\n }\n // enter the active selection from a render perspective\n // the object will be in the objects array of both the ActiveSelection and the Group\n // but referenced in the group's _activeObjects so that it won't be rendered twice.\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * we want objects to retain their canvas ref when exiting instance\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n // return to parent\n object.parent && object.parent._enterGroup(object, true);\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n super._onAfterObjectsChange(type, targets);\n const groups = new Set();\n targets.forEach((object) => {\n const { parent } = object;\n parent && groups.add(parent);\n });\n if (type === LAYOUT_TYPE_REMOVED) {\n // invalidate groups' layout and mark as dirty\n groups.forEach((group) => {\n group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets);\n });\n } else {\n // mark groups as dirty\n groups.forEach((group) => {\n group._set('dirty', true);\n });\n }\n }\n\n /**\n * @override remove all objects\n */\n onDeselect() {\n this.removeAll();\n return false;\n }\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString() {\n return `#`;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache() {\n return false;\n }\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache() {\n return false;\n }\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride?: ControlRenderingStyleOverride,\n childrenOverride?: ControlRenderingStyleOverride,\n ) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n const options = {\n hasControls: false,\n ...childrenOverride,\n forActiveSelection: true,\n };\n for (let i = 0; i < this._objects.length; i++) {\n this._objects[i]._renderControls(ctx, options);\n }\n super._renderControls(ctx, styleOverride);\n ctx.restore();\n }\n}\n\nclassRegistry.setClass(ActiveSelection);\nclassRegistry.setClass(ActiveSelection, 'activeSelection');\n","/**\n * Canvas 2D filter backend.\n */\nimport type { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TPipelineResources } from './typedefs';\n\nexport class Canvas2dFilterBackend {\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters(\n filters: BaseFilter>[],\n sourceElement: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n targetCanvas: HTMLCanvasElement,\n ): T2DPipelineState | void {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const pipelineState: T2DPipelineState = {\n sourceWidth,\n sourceHeight,\n imageData,\n originalEl: sourceElement,\n originalImageData,\n canvasEl: targetCanvas,\n ctx,\n filterBackend: this,\n };\n filters.forEach((filter) => {\n filter.applyTo(pipelineState);\n });\n const { imageData: imageDataPostFilter } = pipelineState;\n if (\n imageDataPostFilter.width !== sourceWidth ||\n imageDataPostFilter.height !== sourceHeight\n ) {\n targetCanvas.width = imageDataPostFilter.width;\n targetCanvas.height = imageDataPostFilter.height;\n }\n ctx.putImageData(imageDataPostFilter, 0, 0);\n return pipelineState;\n }\n}\n","import { config } from '../config';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n TWebGLPipelineState,\n TProgramCache,\n TTextureCache,\n TPipelineResources,\n} from './typedefs';\nimport type { BaseFilter } from './BaseFilter';\n\nexport class WebGLFilterBackend {\n declare tileSize: number;\n\n /**\n * Define ...\n **/\n aPosition: Float32Array = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n\n /**\n * If GLPut data is the fastest operation, or if forced, this buffer will be used\n * to transfer the data back in the 2d logic\n **/\n declare imageBuffer?: ArrayBuffer;\n\n declare canvas: HTMLCanvasElement;\n\n /**\n * The Webgl context that will execute the operations for filtering\n **/\n declare gl: WebGLRenderingContext;\n\n /**\n * Keyed map for shader cache\n **/\n declare programCache: TProgramCache;\n\n /**\n * Keyed map for texture cache\n **/\n declare textureCache: TTextureCache;\n\n /**\n * Contains GPU info for debug\n **/\n declare gpuInfo: any;\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n constructor({ tileSize = config.textureSize } = {}) {\n this.tileSize = tileSize;\n this.setupGLContext(tileSize, tileSize);\n this.captureGPUInfo();\n }\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext(width: number, height: number): void {\n this.dispose();\n this.createWebGLCanvas(width, height);\n }\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas(width: number, height: number): void {\n const canvas = createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n const glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false,\n },\n gl = canvas.getContext('webgl', glOptions) as WebGLRenderingContext;\n\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n }\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {TexImageSource} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters(\n filters: BaseFilter>[],\n source: TexImageSource,\n width: number,\n height: number,\n targetCanvas: HTMLCanvasElement,\n cacheKey?: string,\n ): TWebGLPipelineState | undefined {\n const gl = this.gl;\n const ctx = targetCanvas.getContext('2d');\n if (!gl || !ctx) {\n return;\n }\n let cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n const pipelineState: TWebGLPipelineState = {\n originalWidth:\n (source as HTMLImageElement).width ||\n // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state?\n (source as HTMLImageElement).originalWidth ||\n 0,\n originalHeight:\n (source as HTMLImageElement).height ||\n // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state?\n (source as HTMLImageElement).originalHeight ||\n 0,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n ),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture:\n cachedTexture ||\n this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n )!,\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas,\n };\n const tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach((filter: any) => {\n filter && filter.applyTo(pipelineState);\n });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n }\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose() {\n if (this.canvas) {\n // we are disposing, we don't care about the fact\n // that the canvas shouldn't be null.\n // @ts-expect-error disposing\n this.canvas = null;\n // @ts-expect-error disposing\n this.gl = null;\n }\n this.clearWebGLCaches();\n }\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches() {\n this.programCache = {};\n this.textureCache = {};\n }\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the texture to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {number} width The width to initialize the texture at.\n * @param {number} height The height to initialize the texture.\n * @param {TexImageSource} textureImageSource A source for the texture data.\n * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture.\n * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR\n * @returns {WebGLTexture}\n */\n createTexture(\n gl: WebGLRenderingContext,\n width: number,\n height: number,\n textureImageSource?: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ) {\n const {\n NEAREST,\n TEXTURE_2D,\n RGBA,\n UNSIGNED_BYTE,\n CLAMP_TO_EDGE,\n TEXTURE_MAG_FILTER,\n TEXTURE_MIN_FILTER,\n TEXTURE_WRAP_S,\n TEXTURE_WRAP_T,\n } = gl;\n const texture = gl.createTexture();\n gl.bindTexture(TEXTURE_2D, texture);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n RGBA,\n UNSIGNED_BYTE,\n textureImageSource,\n );\n } else {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n width,\n height,\n 0,\n RGBA,\n UNSIGNED_BYTE,\n null,\n );\n }\n return texture;\n }\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture(\n uniqueId: string,\n textureImageSource: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ): WebGLTexture | null {\n const { textureCache } = this;\n if (textureCache[uniqueId]) {\n return textureCache[uniqueId];\n } else {\n const texture = this.createTexture(\n this.gl,\n (textureImageSource as HTMLImageElement).width,\n (textureImageSource as HTMLImageElement).height,\n textureImageSource,\n filter,\n );\n if (texture) {\n textureCache[uniqueId] = texture;\n }\n return texture;\n }\n }\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey(cacheKey: string) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2D(gl: WebGLRenderingContext, pipelineState: TWebGLPipelineState) {\n const glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n const sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(\n glCanvas,\n 0,\n sourceY,\n targetCanvas.width,\n targetCanvas.height,\n 0,\n 0,\n targetCanvas.width,\n targetCanvas.height,\n );\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2DPutImageData(\n this: Required,\n gl: WebGLRenderingContext,\n pipelineState: TWebGLPipelineState,\n ) {\n const targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n if (!ctx) {\n return;\n }\n const u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n const imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n }\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n const gl = this.gl,\n gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n const ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n }\n}\n\nfunction resizeCanvasIfNeeded(pipelineState: TWebGLPipelineState): void {\n const targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width,\n height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n","import { config } from '../config';\nimport { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { Canvas2dFilterBackend } from './Canvas2dFilterBackend';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\n\nexport type FilterBackend = WebGLFilterBackend | Canvas2dFilterBackend;\n\nlet filterBackend: FilterBackend;\n\n/**\n * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend\n */\nexport function initFilterBackend(): FilterBackend {\n const { WebGLProbe } = getEnv();\n WebGLProbe.queryWebGL(createCanvasElement());\n if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) {\n return new WebGLFilterBackend({ tileSize: config.textureSize });\n } else {\n return new Canvas2dFilterBackend();\n }\n}\n\n/**\n * Get the current fabricJS filter backend or initialize one if not available yet\n * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior),\n * pass `false` to get the backend ref without mutating it\n */\nexport function getFilterBackend(strict = true): FilterBackend {\n if (!filterBackend && strict) {\n filterBackend = initFilterBackend();\n }\n return filterBackend;\n}\n\nexport function setFilterBackend(backend: FilterBackend) {\n filterBackend = backend;\n}\n","import { getFabricDocument, getEnv } from '../env';\nimport type { BaseFilter } from '../filters/BaseFilter';\nimport { getFilterBackend } from '../filters/FilterBackend';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type {\n TClassProperties,\n TCrossOrigin,\n TSize,\n Abortable,\n TOptions,\n} from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { findScaleToCover, findScaleToFit } from '../util/misc/findScaleTo';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n loadImage,\n} from '../util/misc/objectEnlive';\nimport { parsePreserveAspectRatioAttribute } from '../util/misc/svgParsing';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { WebGLFilterBackend } from '../filters/WebGLFilterBackend';\nimport { FILL, NONE } from '../constants';\nimport { getDocumentFromElement } from '../util/dom_misc';\nimport type { CSSRules } from '../parser/typedefs';\nimport type { Resize } from '../filters/Resize';\nimport type { TCachedFabricObject } from './Object/Object';\nimport { log } from '../util/internals/console';\n\n// @todo Would be nice to have filtering code not imported directly.\n\nexport type ImageSource =\n | HTMLImageElement\n | HTMLVideoElement\n | HTMLCanvasElement;\n\ninterface UniqueImageProps {\n srcFromAttribute: boolean;\n minimumScaleTrigger: number;\n cropX: number;\n cropY: number;\n imageSmoothing: boolean;\n filters: BaseFilter>[];\n resizeFilter?: Resize;\n}\n\nexport const imageDefaultValues: Partial> = {\n strokeWidth: 0,\n srcFromAttribute: false,\n minimumScaleTrigger: 0.5,\n cropX: 0,\n cropY: 0,\n imageSmoothing: true,\n};\n\nexport interface SerializedImageProps extends SerializedObjectProps {\n src: string;\n crossOrigin: TCrossOrigin;\n filters: any[];\n resizeFilter?: any;\n cropX: number;\n cropY: number;\n}\n\nexport interface ImageProps extends FabricObjectProps, UniqueImageProps {}\n\nconst IMAGE_PROPS = ['cropX', 'cropY'] as const;\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n */\nexport class FabricImage<\n Props extends TOptions = Partial,\n SProps extends SerializedImageProps = SerializedImageProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements ImageProps\n{\n /**\n * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default false\n */\n declare srcFromAttribute: boolean;\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleX = 1;\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleY = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingX = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingY = 1;\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n declare minimumScaleTrigger: number;\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n declare cacheKey: string;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropX: number;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropY: number;\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n declare imageSmoothing: boolean;\n\n declare preserveAspectRatio: string;\n\n protected declare src: string;\n\n declare filters: BaseFilter>[];\n declare resizeFilter: Resize;\n\n declare _element: ImageSource;\n declare _filteredEl?: HTMLCanvasElement;\n declare _originalElement: ImageSource;\n\n static type = 'Image';\n\n static cacheProperties = [...cacheProperties, ...IMAGE_PROPS];\n\n static ownDefaults = imageDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...FabricImage.ownDefaults,\n };\n }\n /**\n * Constructor\n * Image can be initialized with any canvas drawable or a string.\n * The string should be a url and will be loaded as an image.\n * Canvas and Image element work out of the box, while videos require extra code to work.\n * Please check video element events for seeking.\n * @param {ImageSource | string} element Image element\n * @param {Object} [options] Options object\n */\n constructor(elementId: string, options?: Props);\n constructor(element: ImageSource, options?: Props);\n constructor(arg0: ImageSource | string, options?: Props) {\n super();\n this.filters = [];\n Object.assign(this, FabricImage.ownDefaults);\n this.setOptions(options);\n this.cacheKey = `texture${uid()}`;\n this.setElement(\n typeof arg0 === 'string'\n ? ((\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument()\n ).getElementById(arg0) as ImageSource)\n : arg0,\n options,\n );\n }\n\n /**\n * Returns image element which this instance if based on\n */\n getElement() {\n return this._element;\n }\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Partial} [size] Options object\n */\n setElement(element: ImageSource, size: Partial = {}) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._element = element;\n this._originalElement = element;\n this._setWidthHeight(size);\n element.classList.add(FabricImage.CSS_CANVAS);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal filters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n }\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture(key: string) {\n const backend = getFilterBackend(false);\n if (backend instanceof WebGLFilterBackend) {\n backend.evictCachesForKey(key);\n }\n }\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose() {\n super.dispose();\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._cacheContext = null;\n (\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'] as const\n ).forEach((elementKey) => {\n const el = this[elementKey];\n el && getEnv().dispose(el);\n // @ts-expect-error disposing\n this[elementKey] = undefined;\n });\n }\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin(): string | null {\n return (\n this._originalElement &&\n ((this._originalElement as any).crossOrigin || null)\n );\n }\n\n /**\n * Returns original size of an image\n */\n getOriginalSize() {\n const element = this.getElement() as any;\n if (!element) {\n return {\n width: 0,\n height: 0,\n };\n }\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height,\n };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n const w = this.width / 2,\n h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const filters: Record[] = [];\n this.filters.forEach((filterObj) => {\n filterObj && filters.push(filterObj.toObject());\n });\n return {\n ...super.toObject([...IMAGE_PROPS, ...propertiesToInclude]),\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters,\n ...(this.resizeFilter\n ? { resizeFilter: this.resizeFilter.toObject() }\n : {}),\n };\n }\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height.\n * @return {Boolean}\n */\n hasCrop() {\n return (\n !!this.cropX ||\n !!this.cropY ||\n this.width < this._element.width ||\n this.height < this._element.height\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @return {string[]} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const imageMarkup: string[] = [],\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2;\n let svgString: string[] = [],\n strokeSvg: string[] = [],\n clipPath = '',\n imageRendering = '';\n if (!element) {\n return [];\n }\n if (this.hasCrop()) {\n const clipPathId = uid();\n svgString.push(\n '\\n',\n '\\t\\n',\n '\\n',\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n if (!this.imageSmoothing) {\n imageRendering = ' image-rendering=\"optimizeSpeed\"';\n }\n imageMarkup.push(\n '\\t element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n }\" width=\"${\n element.width || (element as HTMLImageElement).naturalWidth\n }\" height=\"${\n element.height || (element as HTMLImageElement).naturalHeight\n }\"${imageRendering}${clipPath}>\\n`,\n );\n\n if (this.stroke || this.strokeDashArray) {\n const origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n `\\t\\n`,\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== FILL) {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n }\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc(filtered?: boolean): string {\n const element = filtered ? this._element : this._originalElement;\n if (element) {\n if ((element as HTMLCanvasElement).toDataURL) {\n return (element as HTMLCanvasElement).toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src') || '';\n } else {\n return (element as HTMLImageElement).src;\n }\n } else {\n return this.src || '';\n }\n }\n\n /**\n * Alias for getSrc\n * @param filtered\n * @deprecated\n */\n getSvgSrc(filtered?: boolean) {\n return this.getSrc(filtered);\n }\n\n /**\n * Loads and sets source of an image\\\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n * @param {String} src Source string (URL)\n * @param {LoadImageOptions} [options] Options object\n */\n setSrc(src: string, { crossOrigin, signal }: LoadImageOptions = {}) {\n return loadImage(src, { crossOrigin, signal }).then((img) => {\n typeof crossOrigin !== 'undefined' && this.set({ crossOrigin });\n this.setElement(img);\n });\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString() {\n return `#`;\n }\n\n applyResizeFilters() {\n const filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.x,\n scaleY = objectScale.y,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n const canvasEl = createCanvasElement(),\n sourceWidth = elementToFilter.width,\n sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n getFilterBackend().applyFilters(\n [filter],\n elementToFilter,\n sourceWidth,\n sourceHeight,\n this._element,\n );\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n }\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n */\n applyFilters(\n filters: BaseFilter>[] = this.filters || [],\n ) {\n filters = filters.filter((filter) => filter && !filter.isNeutralState());\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(`${this.cacheKey}_filtered`);\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n // this is unsafe and needs to be rethinkend\n this._filteredEl = undefined;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return;\n }\n\n const imgElement = this._originalElement,\n sourceWidth =\n (imgElement as HTMLImageElement).naturalWidth || imgElement.width,\n sourceHeight =\n (imgElement as HTMLImageElement).naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the _element a reference to _originalElement\n // we need to create a new element to host the filtered pixels\n const canvasEl = createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n } else if (this._filteredEl) {\n // if the _element is it own element,\n // and we also have a _filteredEl, then we clean up _filteredEl\n // and we assign it to _element.\n // in this way we invalidate the eventual old resize filtered element\n this._element = this._filteredEl;\n this._filteredEl\n .getContext('2d')!\n .clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n getFilterBackend().applyFilters(\n filters,\n this._originalElement,\n sourceWidth,\n sourceHeight,\n this._element as HTMLCanvasElement,\n );\n if (\n this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height\n ) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY =\n this._element.height / this._originalElement.height;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(\n this: TCachedFabricObject,\n ctx: CanvasRenderingContext2D,\n ) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n super.drawCacheOnCanvas(ctx);\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache() {\n return this.needsItsOwnCache();\n }\n\n _renderFill(ctx: CanvasRenderingContext2D) {\n const elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n const scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n // crop values cannot be lesser than 0.\n cropX = Math.max(this.cropX, 0),\n cropY = Math.max(this.cropY, 0),\n elWidth =\n (elementToDraw as HTMLImageElement).naturalWidth || elementToDraw.width,\n elHeight =\n (elementToDraw as HTMLImageElement).naturalHeight ||\n elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = Math.min(w * scaleX, elWidth - sX),\n sH = Math.min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = Math.min(w, elWidth / scaleX - cropX),\n maxDestH = Math.min(h, elHeight / scaleY - cropY);\n\n elementToDraw &&\n ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n }\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize() {\n const scale = this.getTotalObjectScaling();\n return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY;\n }\n\n /**\n * @private\n * @deprecated unused\n */\n _resetWidthHeight() {\n this.set(this.getOriginalSize());\n }\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n */\n _setWidthHeight({ width, height }: Partial = {}) {\n const size = this.getOriginalSize();\n this.width = width || size.width;\n this.height = height || size.height;\n }\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n */\n parsePreserveAspectRatioAttribute() {\n const pAR = parsePreserveAspectRatioAttribute(\n this.preserveAspectRatio || '',\n ),\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = { width: pWidth, height: pHeight };\n let rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset;\n\n if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX,\n scaleY,\n offsetLeft,\n offsetTop,\n cropX,\n cropY,\n };\n }\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n static CSS_CANVAS = 'canvas-img';\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'width',\n 'height',\n 'preserveAspectRatio',\n 'xlink:href',\n 'crossOrigin',\n 'image-rendering',\n ];\n\n /**\n * Creates an instance of FabricImage from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n { filters: f, resizeFilter: rf, src, crossOrigin, type, ...object }: T,\n options?: Abortable,\n ) {\n return Promise.all([\n loadImage(src!, { ...options, crossOrigin }),\n f && enlivenObjects>(f, options),\n // TODO: redundant - handled by enlivenObjectEnlivables\n rf && enlivenObjects>([rf], options),\n enlivenObjectEnlivables(object, options),\n ]).then(([el, filters = [], [resizeFilter] = [], hydratedProps = {}]) => {\n return new this(el, {\n ...object,\n // TODO: this creates a difference between image creation and restoring from JSON\n src,\n filters,\n resizeFilter,\n ...hydratedProps,\n });\n });\n }\n\n /**\n * Creates an instance of Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {LoadImageOptions} [options] Options object\n * @returns {Promise}\n */\n static fromURL>(\n url: string,\n { crossOrigin = null, signal }: LoadImageOptions = {},\n imageOptions?: T,\n ): Promise {\n return loadImage(url, { crossOrigin, signal }).then(\n (img) => new this(img, imageOptions),\n );\n }\n\n /**\n * Returns {@link FabricImage} instance from an SVG element\n * @static\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} callback Callback to execute when Image object is created\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable = {},\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return this.fromURL(\n parsedAttributes['xlink:href'],\n options,\n parsedAttributes,\n ).catch((err) => {\n log('log', 'Unable to parse Image', err);\n return null;\n });\n }\n}\n\nclassRegistry.setClass(FabricImage);\nclassRegistry.setSVGClass(FabricImage);\n","import { svgNS } from './constants';\nimport {\n parsePreserveAspectRatioAttribute,\n parseUnit,\n} from '../util/misc/svgParsing';\nimport { svgViewBoxElementsRegEx, reViewBoxAttrValue } from './constants';\nimport { NONE } from '../constants';\n\nexport type ParsedViewboxTransform = Partial<{\n width: number;\n height: number;\n minX: number;\n minY: number;\n viewBoxWidth: number;\n viewBoxHeight: number;\n}>;\n\n/**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\nexport function applyViewboxTransform(\n element: Element,\n): ParsedViewboxTransform {\n if (!svgViewBoxElementsRegEx.test(element.nodeName)) {\n return {};\n }\n const viewBoxAttr: string | null = element.getAttribute('viewBox');\n let scaleX = 1;\n let scaleY = 1;\n let minX = 0;\n let minY = 0;\n let matrix;\n let el;\n const widthAttr = element.getAttribute('width');\n const heightAttr = element.getAttribute('height');\n const x = element.getAttribute('x') || 0;\n const y = element.getAttribute('y') || 0;\n const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr);\n const missingViewBox = !goodViewbox;\n const missingDimAttr =\n !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%';\n\n let translateMatrix = '';\n let widthDiff = 0;\n let heightDiff = 0;\n\n if (missingViewBox) {\n if (\n (x || y) &&\n element.parentNode &&\n element.parentNode.nodeName !== '#document'\n ) {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (missingViewBox && missingDimAttr) {\n return {\n width: 0,\n height: 0,\n };\n }\n\n const parsedDim: ParsedViewboxTransform = {\n width: 0,\n height: 0,\n };\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr!);\n parsedDim.height = parseUnit(heightAttr!);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n\n const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue)!;\n minX = -parseFloat(pasedViewBox[1]);\n minY = -parseFloat(pasedViewBox[2]);\n const viewBoxWidth = parseFloat(pasedViewBox[3]);\n const viewBoxHeight = parseFloat(pasedViewBox[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n const preserveAspectRatio = parsePreserveAspectRatioAttribute(\n element.getAttribute('preserveAspectRatio') || '',\n );\n if (preserveAspectRatio.alignX !== NONE) {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY;\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (\n scaleX === 1 &&\n scaleY === 1 &&\n minX === 0 &&\n minY === 0 &&\n x === 0 &&\n y === 0\n ) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode!.nodeName !== '#document') {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n }\n\n matrix =\n translateMatrix +\n ' matrix(' +\n scaleX +\n ' 0' +\n ' 0 ' +\n scaleY +\n ' ' +\n (minX * scaleX + widthDiff) +\n ' ' +\n (minY * scaleY + heightDiff) +\n ') ';\n // seems unused.\n // parsedDim.viewboxTransform = parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n}\n","export const getTagName = (node: Element) => node.tagName.replace('svg:', '');\n","import { svgInvalidAncestors } from './constants';\nimport { getSvgRegex } from './getSvgRegex';\nimport { getTagName } from './getTagName';\n\nconst svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n\nexport function hasInvalidAncestor(element: Element) {\n let _element: Element | null = element;\n while (_element && (_element = _element.parentElement)) {\n if (\n _element &&\n _element.nodeName &&\n svgInvalidAncestorsRegEx.test(getTagName(_element)) &&\n !_element.getAttribute('instantiated_by_use')\n ) {\n return true;\n }\n }\n return false;\n}\n","export function getMultipleNodes(\n doc: Document,\n nodeNames: string[],\n): Element[] {\n let nodeName,\n nodeArray: Element[] = [],\n nodeList,\n i,\n len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagNameNS(\n 'http://www.w3.org/2000/svg',\n nodeName,\n );\n nodeArray = nodeArray.concat(Array.from(nodeList));\n }\n return nodeArray;\n}\n","const gradientsAttrs = [\n 'gradientTransform',\n 'x1',\n 'x2',\n 'y1',\n 'y2',\n 'gradientUnits',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n];\nconst xlinkAttr = 'xlink:href';\n\nexport function recursivelyParseGradientsXlink(\n doc: Document,\n gradient: Element,\n) {\n const xLink = gradient.getAttribute(xlinkAttr)?.slice(1) || '',\n referencedGradient = doc.getElementById(xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient as Element);\n }\n if (referencedGradient) {\n gradientsAttrs.forEach((attr) => {\n const value = referencedGradient.getAttribute(attr);\n if (!gradient.hasAttribute(attr) && value) {\n gradient.setAttribute(attr, value);\n }\n });\n if (!gradient.children.length) {\n const referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n }\n gradient.removeAttribute(xlinkAttr);\n}\n","import { getMultipleNodes } from './getMultipleNodes';\nimport { recursivelyParseGradientsXlink } from './recursivelyParseGradientsXlink';\n\nconst tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient',\n];\n\n/**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\nexport function getGradientDefs(\n doc: Document,\n): Record {\n const elList = getMultipleNodes(doc, tagArray);\n const gradientDefs: Record = {};\n let j = elList.length;\n while (j--) {\n const el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n const id = el.getAttribute('id');\n if (id) {\n gradientDefs[id] = el as SVGGradientElement;\n }\n }\n return gradientDefs;\n}\n","import type { CSSRules } from './typedefs';\n\n/**\n * Returns CSS rules for a given SVG document\n * @param {HTMLElement} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\nexport function getCSSRules(doc: Document) {\n const styles = doc.getElementsByTagName('style');\n let i;\n let len;\n const allRules: CSSRules = {};\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n const styleContents = (styles[i].textContent || '').replace(\n // remove comments\n /\\/\\*[\\s\\S]*?\\*\\//g,\n '',\n );\n\n if (styleContents.trim() === '') {\n continue;\n }\n // recovers all the rule in this form `body { style code... }`\n // rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n styleContents\n .split('}')\n // remove empty rules and remove everything if we didn't split in at least 2 pieces\n .filter((rule, index, array) => array.length > 1 && rule.trim())\n // at this point we have hopefully an array of rules `body { style code... `\n .forEach((rule) => {\n // if there is more than one opening bracket and the rule starts with '@', it is likely\n // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below\n // can not handle it.\n if (\n (rule.match(/{/g) || []).length > 1 &&\n rule.trim().startsWith('@')\n ) {\n return;\n }\n\n const match = rule.split('{'),\n ruleObj: Record = {},\n declaration = match[1].trim(),\n propertyValuePairs = declaration.split(';').filter(function (pair) {\n return pair.trim();\n });\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n const pair = propertyValuePairs[i].split(':'),\n property = pair[0].trim(),\n value = pair[1].trim();\n ruleObj[property] = value;\n }\n rule = match[0].trim();\n rule.split(',').forEach((_rule) => {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n allRules[_rule] = {\n ...(allRules[_rule] || {}),\n ...ruleObj,\n };\n });\n });\n }\n return allRules;\n}\n","import { Gradient } from '../gradient/Gradient';\nimport { Group } from '../shapes/Group';\nimport { FabricImage } from '../shapes/Image';\nimport { classRegistry } from '../ClassRegistry';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../util/misc/matrix';\nimport { removeTransformMatrixForSvgParsing } from '../util/transform_matrix_removal';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { Point } from '../Point';\nimport { CENTER, FILL, STROKE } from '../constants';\nimport { getGradientDefs } from './getGradientDefs';\nimport { getCSSRules } from './getCSSRules';\nimport type { LoadImageOptions } from '../util';\nimport type { CSSRules, TSvgReviverCallback } from './typedefs';\nimport type { ParsedViewboxTransform } from './applyViewboxTransform';\nimport type { SVGOptions } from '../gradient';\nimport { getTagName } from './getTagName';\nimport { parseTransformAttribute } from './parseTransformAttribute';\n\nconst findTag = (el: Element) =>\n classRegistry.getSVGClass(getTagName(el).toLowerCase());\n\ntype StorageType = {\n fill: SVGGradientElement;\n stroke: SVGGradientElement;\n clipPath: Element[];\n};\n\ntype NotParsedFabricObject = FabricObject & {\n fill: string;\n stroke: string;\n clipPath?: string;\n clipRule?: CanvasFillRule;\n};\n\nexport class ElementsParser {\n declare elements: Element[];\n declare options: LoadImageOptions & ParsedViewboxTransform;\n declare reviver?: TSvgReviverCallback;\n declare regexUrl: RegExp;\n declare doc: Document;\n declare clipPaths: Record;\n declare gradientDefs: Record;\n declare cssRules: CSSRules;\n\n constructor(\n elements: Element[],\n options: LoadImageOptions & ParsedViewboxTransform,\n reviver: TSvgReviverCallback | undefined,\n doc: Document,\n clipPaths: Record,\n ) {\n this.elements = elements;\n this.options = options;\n this.reviver = reviver;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n this.clipPaths = clipPaths;\n this.gradientDefs = getGradientDefs(doc);\n this.cssRules = getCSSRules(doc);\n }\n\n parse(): Promise> {\n return Promise.all(\n this.elements.map((element) => this.createObject(element)),\n );\n }\n\n async createObject(el: Element): Promise {\n const klass = findTag(el);\n if (klass) {\n const obj: NotParsedFabricObject = await klass.fromElement(\n el,\n this.options,\n this.cssRules,\n );\n this.resolveGradient(obj, el, FILL);\n this.resolveGradient(obj, el, STROKE);\n if (obj instanceof FabricImage && obj._originalElement) {\n removeTransformMatrixForSvgParsing(\n obj,\n obj.parsePreserveAspectRatioAttribute(),\n );\n } else {\n removeTransformMatrixForSvgParsing(obj);\n }\n await this.resolveClipPath(obj, el);\n this.reviver && this.reviver(el, obj);\n return obj;\n }\n return null;\n }\n\n extractPropertyDefinition(\n obj: NotParsedFabricObject,\n property: 'fill' | 'stroke' | 'clipPath',\n storage: Record,\n ): StorageType[typeof property] | undefined {\n const value = obj[property]!,\n regex = this.regexUrl;\n if (!regex.test(value)) {\n return undefined;\n }\n // verify: can we remove the 'g' flag? and remove lastIndex changes?\n regex.lastIndex = 0;\n // we passed the regex test, so we know is not null;\n const id = regex.exec(value)![1];\n regex.lastIndex = 0;\n // @todo fix this\n return storage[id];\n }\n\n resolveGradient(\n obj: NotParsedFabricObject,\n el: Element,\n property: 'fill' | 'stroke',\n ) {\n const gradientDef = this.extractPropertyDefinition(\n obj,\n property,\n this.gradientDefs,\n ) as SVGGradientElement;\n if (gradientDef) {\n const opacityAttr = el.getAttribute(property + '-opacity');\n const gradient = Gradient.fromElement(gradientDef, obj, {\n ...this.options,\n opacity: opacityAttr,\n } as SVGOptions);\n obj.set(property, gradient);\n }\n }\n\n // TODO: resolveClipPath could be run once per clippath with minor work per object.\n // is a refactor that i m not sure is worth on this code\n async resolveClipPath(obj: NotParsedFabricObject, usingElement: Element) {\n const clipPathElements = this.extractPropertyDefinition(\n obj,\n 'clipPath',\n this.clipPaths,\n ) as Element[];\n if (clipPathElements) {\n const objTransformInv = invertTransform(obj.calcTransformMatrix());\n const clipPathTag = clipPathElements[0].parentElement!;\n let clipPathOwner = usingElement;\n while (\n clipPathOwner.parentElement &&\n clipPathOwner.getAttribute('clip-path') !== obj.clipPath\n ) {\n clipPathOwner = clipPathOwner.parentElement;\n }\n // move the clipPath tag as sibling to the real element that is using it\n clipPathOwner.parentElement!.appendChild(clipPathTag!);\n\n // this multiplication order could be opposite.\n // but i don't have an svg to test it\n // at the first SVG that has a transform on both places and is misplaced\n // try to invert this multiplication order\n const finalTransform = parseTransformAttribute(\n `${clipPathOwner.getAttribute('transform') || ''} ${\n clipPathTag.getAttribute('originalTransform') || ''\n }`,\n );\n\n clipPathTag.setAttribute(\n 'transform',\n `matrix(${finalTransform.join(',')})`,\n );\n\n const container = await Promise.all(\n clipPathElements.map((clipPathElement) => {\n return findTag(clipPathElement)\n .fromElement(clipPathElement, this.options, this.cssRules)\n .then((enlivedClippath: NotParsedFabricObject) => {\n removeTransformMatrixForSvgParsing(enlivedClippath);\n enlivedClippath.fillRule = enlivedClippath.clipRule!;\n delete enlivedClippath.clipRule;\n return enlivedClippath;\n });\n }),\n );\n const clipPath =\n container.length === 1 ? container[0] : new Group(container);\n const gTransform = multiplyTransformMatrices(\n objTransformInv,\n clipPath.calcTransformMatrix(),\n );\n if (clipPath.clipPath) {\n await this.resolveClipPath(clipPath, clipPathOwner);\n }\n const { scaleX, scaleY, angle, skewX, translateX, translateY } =\n qrDecompose(gTransform);\n clipPath.set({\n flipX: false,\n flipY: false,\n });\n clipPath.set({\n scaleX,\n scaleY,\n angle,\n skewX,\n skewY: 0,\n });\n clipPath.setPositionByOrigin(\n new Point(translateX, translateY),\n CENTER,\n CENTER,\n );\n obj.clipPath = clipPath;\n } else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n return;\n }\n }\n}\n","import { applyViewboxTransform } from './applyViewboxTransform';\nimport { svgValidTagNamesRegEx } from './constants';\nimport { hasInvalidAncestor } from './hasInvalidAncestor';\nimport { parseUseDirectives } from './parseUseDirectives';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { ElementsParser } from './elements_parser';\nimport { log, SignalAbortedError } from '../util/internals/console';\nimport { getTagName } from './getTagName';\n\nconst isValidSvgTag = (el: Element) =>\n svgValidTagNamesRegEx.test(getTagName(el));\n\nexport const createEmptyResponse = (): SVGParsingOutput => ({\n objects: [],\n elements: [],\n options: {},\n allElements: [],\n});\n\n/**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {HTMLElement} doc SVG document to parse\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {SVGParsingOutput}\n * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n */\nexport async function parseSVGDocument(\n doc: Document,\n reviver?: TSvgReviverCallback,\n { crossOrigin, signal }: LoadImageOptions = {},\n): Promise {\n if (signal && signal.aborted) {\n log('log', new SignalAbortedError('parseSVGDocument'));\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n }\n const documentElement = doc.documentElement;\n parseUseDirectives(doc);\n\n const descendants = Array.from(documentElement.getElementsByTagName('*')),\n options = {\n ...applyViewboxTransform(documentElement),\n crossOrigin,\n signal,\n };\n\n const elements = descendants.filter((el) => {\n applyViewboxTransform(el);\n return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n if (!elements || (elements && !elements.length)) {\n return {\n ...createEmptyResponse(),\n options,\n allElements: descendants,\n };\n }\n const localClipPaths: Record = {};\n descendants\n .filter((el) => getTagName(el) === 'clipPath')\n .forEach((el) => {\n el.setAttribute('originalTransform', el.getAttribute('transform') || '');\n const id = el.getAttribute('id')!;\n localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(\n (el) => isValidSvgTag(el),\n );\n });\n\n // Precedence of rules: style > class > attribute\n const elementParser = new ElementsParser(\n elements,\n options,\n reviver,\n doc,\n localClipPaths,\n );\n\n const instances = await elementParser.parse();\n\n return {\n objects: instances,\n elements,\n options,\n allElements: descendants,\n };\n}\n","import { svgNS } from './constants';\nimport { getMultipleNodes } from './getMultipleNodes';\nimport { applyViewboxTransform } from './applyViewboxTransform';\nimport { parseStyleString } from './parseStyleString';\n\nexport function parseUseDirectives(doc: Document) {\n const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);\n const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];\n\n for (const useElement of nodelist) {\n const useAttributes: NamedNodeMap = useElement.attributes;\n\n const useAttrMap: Record = {};\n for (const attr of useAttributes) {\n attr.value && (useAttrMap[attr.name] = attr.value);\n }\n\n const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);\n\n if (xlink === '') {\n return;\n }\n const referencedElement = doc.getElementById(xlink);\n if (referencedElement === null) {\n // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink\n return;\n }\n let clonedOriginal = referencedElement.cloneNode(true) as Element;\n\n const originalAttributes: NamedNodeMap = clonedOriginal.attributes;\n\n const originalAttrMap: Record = {};\n for (const attr of originalAttributes) {\n attr.value && (originalAttrMap[attr.name] = attr.value);\n }\n\n // Transform attribute needs to be merged in a particular way\n const { x = 0, y = 0, transform = '' } = useAttrMap;\n const currentTrans = `${transform} ${\n originalAttrMap.transform || ''\n } translate(${x}, ${y})`;\n\n applyViewboxTransform(clonedOriginal);\n\n if (/^svg$/i.test(clonedOriginal.nodeName)) {\n // if is an SVG, create a group and apply all the attributes on top of it\n const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');\n Object.entries(originalAttrMap).forEach(([name, value]) =>\n el3.setAttributeNS(svgNS, name, value),\n );\n el3.append(...clonedOriginal.childNodes);\n clonedOriginal = el3;\n }\n\n for (const attr of useAttributes) {\n if (!attr) {\n continue;\n }\n const { name, value } = attr;\n if (skipAttributes.includes(name)) {\n continue;\n }\n\n if (name === 'style') {\n // when use has a style, merge the two styles, with the ref being priority (not use)\n // priority is by feature. an attribute for fill on the original element\n // will overwrite the fill in style or attribute for tha use\n const styleRecord: Record = {};\n parseStyleString(value!, styleRecord);\n // cleanup styleRecord from attributes of original\n Object.entries(originalAttrMap).forEach(([name, value]) => {\n styleRecord[name] = value;\n });\n // now we can put in the style of the original that will overwrite the original attributes\n parseStyleString(originalAttrMap.style || '', styleRecord);\n const mergedStyles = Object.entries(styleRecord)\n .map((entry) => entry.join(':'))\n .join(';');\n clonedOriginal.setAttribute(name, mergedStyles);\n } else {\n // set the attribute from use element only if the original does not have it already\n !originalAttrMap[name] && clonedOriginal.setAttribute(name, value!);\n }\n }\n\n clonedOriginal.setAttribute('transform', currentTrans);\n clonedOriginal.setAttribute('instantiated_by_use', '1');\n clonedOriginal.removeAttribute('id');\n useElement.parentNode!.replaceChild(clonedOriginal, useElement);\n }\n}\n","import { getFabricWindow } from '../env';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { parseSVGDocument } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\n\n/**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string representing the svg\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromString(\n string: string,\n reviver?: TSvgReviverCallback,\n options?: LoadImageOptions,\n): Promise {\n const parser = new (getFabricWindow().DOMParser)(),\n // should we use `image/svg+xml` here?\n doc = parser.parseFromString(string.trim(), 'text/xml');\n return parseSVGDocument(doc, reviver, options);\n}\n","import { request } from '../util/internals/dom_request';\nimport { parseSVGDocument, createEmptyResponse } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\n\n/**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {string} url where the SVG is\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromURL(\n url: string,\n reviver?: TSvgReviverCallback,\n options: LoadImageOptions = {},\n): Promise {\n // need to handle error properly\n return new Promise((resolve, reject) => {\n const onComplete = (r: XMLHttpRequest) => {\n const xml = r.responseXML;\n if (xml) {\n resolve(xml);\n }\n reject();\n };\n\n request(url.replace(/^\\n\\s*/, '').trim(), {\n onComplete,\n signal: options.signal,\n });\n })\n .then((parsedDoc) => parseSVGDocument(parsedDoc, reviver, options))\n .catch(() => {\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n });\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Polyline } from '../shapes/Polyline';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { MODIFY_POLY } from '../constants';\n\nconst ACTION_NAME: TModificationEvents = MODIFY_POLY;\n\ntype TTransformAnchor = Transform & { pointIndex: number };\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nexport const createPolyPositionHandler = (pointIndex: number) => {\n return function (dim: Point, finalMatrix: TMat2D, polyObject: Polyline) {\n const { points, pathOffset } = polyObject;\n return new Point(points[pointIndex])\n .subtract(pathOffset)\n .transform(\n multiplyTransformMatrices(\n polyObject.getViewportTransform(),\n polyObject.calcTransformMatrix(),\n ),\n );\n };\n};\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nexport const polyActionHandler = (\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) => {\n const { target, pointIndex } = transform;\n const poly = target as Polyline;\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n poly.calcOwnMatrix(),\n );\n\n poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);\n poly.setDimensions();\n\n return true;\n};\n\n/**\n * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.\n */\nexport const factoryPolyActionHandler = (\n pointIndex: number,\n fn: TransformActionHandler,\n) => {\n return function (\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n ) {\n const poly = transform.target as Polyline,\n anchorPoint = new Point(\n poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1],\n ),\n anchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix()),\n actionPerformed = fn(eventData, { ...transform, pointIndex }, x, y);\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n poly.left -= diff.x;\n poly.top -= diff.y;\n\n return actionPerformed;\n };\n};\n\nexport const createPolyActionHandler = (pointIndex: number) =>\n wrapWithFireEvent(\n ACTION_NAME,\n factoryPolyActionHandler(pointIndex, polyActionHandler),\n );\n\nexport function createPolyControls(\n poly: Polyline,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n numOfControls: number,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n arg0: number | Polyline,\n options: Partial = {},\n) {\n const controls = {} as Record;\n for (\n let idx = 0;\n idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length);\n idx++\n ) {\n controls[`p${idx}`] = new Control({\n actionName: ACTION_NAME,\n positionHandler: createPolyPositionHandler(idx),\n actionHandler: createPolyActionHandler(idx),\n ...options,\n });\n }\n return controls;\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Path } from '../shapes/Path';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport type { TSimpleParseCommandType } from '../util/path/typedefs';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\nconst ACTION_NAME: TModificationEvents = 'modifyPath' as const;\n\ntype TTransformAnchor = Transform;\n\nexport type PathPointControlStyle = {\n controlFill?: string;\n controlStroke?: string;\n connectionDashArray?: number[];\n};\n\nconst calcPathPointPosition = (\n pathObject: Path,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n const command = path[commandIndex];\n return new Point(\n (command[pointIndex] as number) - pathOffset.x,\n (command[pointIndex + 1] as number) - pathOffset.y,\n ).transform(\n multiplyTransformMatrices(\n pathObject.getViewportTransform(),\n pathObject.calcTransformMatrix(),\n ),\n );\n};\n\nconst movePathPoint = (\n pathObject: Path,\n x: number,\n y: number,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n\n const anchorCommand =\n path[(commandIndex > 0 ? commandIndex : path.length) - 1];\n const anchorPoint = new Point(\n anchorCommand[pointIndex] as number,\n anchorCommand[pointIndex + 1] as number,\n );\n\n const anchorPointInParentPlane = anchorPoint\n .subtract(pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n pathObject.calcOwnMatrix(),\n );\n\n path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;\n path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;\n pathObject.setDimensions();\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(pathObject.pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n pathObject.left -= diff.x;\n pathObject.top -= diff.y;\n pathObject.set('dirty', true);\n return true;\n};\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nfunction pathPositionHandler(\n this: PathPointControl,\n dim: Point,\n finalMatrix: TMat2D,\n pathObject: Path,\n) {\n const { commandIndex, pointIndex } = this;\n return calcPathPointPosition(pathObject, commandIndex, pointIndex);\n}\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nfunction pathActionHandler(\n this: PathPointControl,\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) {\n const { target } = transform;\n const { commandIndex, pointIndex } = this;\n const actionPerformed = movePathPoint(\n target as Path,\n x,\n y,\n commandIndex,\n pointIndex,\n );\n if (actionPerformed) {\n fireEvent(this.actionName as TModificationEvents, {\n ...commonEventInfo(eventData, transform, x, y),\n commandIndex,\n pointIndex,\n });\n }\n return actionPerformed;\n}\n\nconst indexFromPrevCommand = (previousCommandType: TSimpleParseCommandType) =>\n previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;\n\nclass PathPointControl extends Control {\n declare commandIndex: number;\n declare pointIndex: number;\n declare controlFill: string;\n declare controlStroke: string;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const overrides: ControlRenderingStyleOverride = {\n ...styleOverride,\n cornerColor: this.controlFill,\n cornerStrokeColor: this.controlStroke,\n transparentCorners: !this.controlFill,\n };\n super.render(ctx, left, top, overrides, fabricObject);\n }\n}\n\nclass PathControlPointControl extends PathPointControl {\n declare connectionDashArray?: number[];\n declare connectToCommandIndex: number;\n declare connectToPointIndex: number;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n this: PathControlPointControl,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const { path } = fabricObject;\n const {\n commandIndex,\n pointIndex,\n connectToCommandIndex,\n connectToPointIndex,\n } = this;\n ctx.save();\n ctx.strokeStyle = this.controlStroke;\n if (this.connectionDashArray) {\n ctx.setLineDash(this.connectionDashArray);\n }\n const [commandType] = path[commandIndex];\n const point = calcPathPointPosition(\n fabricObject,\n connectToCommandIndex,\n connectToPointIndex,\n );\n\n if (commandType === 'Q') {\n // one control point connects to 2 points\n const point2 = calcPathPointPosition(\n fabricObject,\n commandIndex,\n pointIndex + 2,\n );\n ctx.moveTo(point2.x, point2.y);\n ctx.lineTo(left, top);\n } else {\n ctx.moveTo(left, top);\n }\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n ctx.restore();\n\n super.render(ctx, left, top, styleOverride, fabricObject);\n }\n}\n\nconst createControl = (\n commandIndexPos: number,\n pointIndexPos: number,\n isControlPoint: boolean,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n },\n connectToCommandIndex?: number,\n connectToPointIndex?: number,\n) =>\n new (isControlPoint ? PathControlPointControl : PathPointControl)({\n commandIndex: commandIndexPos,\n pointIndex: pointIndexPos,\n actionName: ACTION_NAME,\n positionHandler: pathPositionHandler,\n actionHandler: pathActionHandler,\n connectToCommandIndex,\n connectToPointIndex,\n ...options,\n ...(isControlPoint ? options.controlPointStyle : options.pointStyle),\n } as Partial);\n\nexport function createPathControls(\n path: Path,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n } = {},\n): Record {\n const controls = {} as Record;\n let previousCommandType: TSimpleParseCommandType = 'M';\n path.path.forEach((command, commandIndex) => {\n const commandType = command[0];\n\n if (commandType !== 'Z') {\n controls[`c_${commandIndex}_${commandType}`] = createControl(\n commandIndex,\n command.length - 2,\n false,\n options,\n );\n }\n switch (commandType) {\n case 'C':\n controls[`c_${commandIndex}_C_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex - 1,\n indexFromPrevCommand(previousCommandType),\n );\n controls[`c_${commandIndex}_C_CP_2`] = createControl(\n commandIndex,\n 3,\n true,\n options,\n commandIndex,\n 5,\n );\n break;\n case 'Q':\n controls[`c_${commandIndex}_Q_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex,\n 3,\n );\n break;\n }\n previousCommandType = commandType;\n });\n return controls;\n}\n","import { getFabricWindow } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\n\nexport const isWebGLPipelineState = (\n options: TWebGLPipelineState | T2DPipelineState,\n): options is TWebGLPipelineState => {\n return (options as TWebGLPipelineState).webgl !== undefined;\n};\n\n/**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * drawImage should be faster, but is also bugged for a small combination of old hardware\n * and drivers.\n * putImageData is faster than drawImage for that specific operation.\n */\nexport const isPutImageFaster = (width: number, height: number): boolean => {\n const targetCanvas = createCanvasElement();\n const sourceCanvas = createCanvasElement();\n const gl = sourceCanvas.getContext('webgl')!;\n // eslint-disable-next-line no-undef\n const imageBuffer = new ArrayBuffer(width * height * 4);\n\n const testContext = {\n imageBuffer: imageBuffer,\n } as unknown as Required;\n const testPipelineState = {\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas,\n } as unknown as TWebGLPipelineState;\n let startTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2D.call(\n testContext,\n gl,\n testPipelineState,\n );\n const drawImageTime = getFabricWindow().performance.now() - startTime;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(\n testContext,\n gl,\n testPipelineState,\n );\n const putImageDataTime = getFabricWindow().performance.now() - startTime;\n\n return drawImageTime > putImageDataTime;\n};\n","export const highPsourceCode = `precision highp float`;\n\nexport const identityFragmentShader = `\n ${highPsourceCode};\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }`;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }`;\n","import { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n T2DPipelineState,\n TWebGLAttributeLocationMap,\n TWebGLPipelineState,\n TWebGLProgramCacheItem,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport {\n highPsourceCode,\n identityFragmentShader,\n vertexSource,\n} from './shaders/baseFilter';\nimport type { Abortable } from '../typedefs';\nimport { FabricError } from '../util/internals/console';\n\nconst regex = new RegExp(highPsourceCode, 'g');\n\nexport class BaseFilter<\n Name extends string,\n OwnProps extends Record = object,\n> {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n get type(): Name {\n return (this.constructor as typeof BaseFilter).type as Name;\n }\n\n /**\n * The class type. Used to identify which class this is.\n * This is used for serialization purposes and internally it can be used\n * to identify classes. As a developer you could use `instance of Class`\n * but to avoid importing all the code and blocking tree shaking we try\n * to avoid doing that.\n */\n static type = 'BaseFilter';\n\n /**\n * Contains the uniform locations for the fragment shader.\n * uStepW and uStepH are handled by the BaseFilter, each filter class\n * needs to specify all the one that are needed\n */\n static uniformLocations: string[] = [];\n\n declare static defaults: Record;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor({\n type,\n ...options\n }: { type?: never } & Partial & Record = {}) {\n Object.assign(\n this,\n (this.constructor as typeof BaseFilter).defaults,\n options,\n );\n }\n\n protected getFragmentSource(): string {\n return identityFragmentShader;\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram(\n gl: WebGLRenderingContext,\n fragmentSource: string = this.getFragmentSource(),\n vertexSource: string = this.getVertexSource(),\n ) {\n const {\n WebGLProbe: { GLPrecision = 'highp' },\n } = getEnv();\n if (GLPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(\n regex,\n highPsourceCode.replace('highp', GLPrecision),\n );\n }\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n const program = gl.createProgram();\n\n if (!vertexShader || !fragmentShader || !program) {\n throw new FabricError(\n 'Vertex, fragment shader or program creation error',\n );\n }\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n vertexShader,\n )}`,\n );\n }\n\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n fragmentShader,\n )}`,\n );\n }\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new FabricError(\n `Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}`,\n );\n }\n\n const uniformLocations = this.getUniformLocations(gl, program) || {};\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n\n return {\n program,\n attributeLocations: this.getAttributeLocations(gl, program),\n uniformLocations,\n };\n }\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLAttributeLocationMap {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n }\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLUniformLocationMap {\n const locations = (this.constructor as unknown as typeof BaseFilter)\n .uniformLocations;\n\n const uniformLocations: Record = {};\n for (let i = 0; i < locations.length; i++) {\n uniformLocations[locations[i]] = gl.getUniformLocation(\n program,\n locations[i],\n );\n }\n return uniformLocations;\n }\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData(\n gl: WebGLRenderingContext,\n attributeLocations: Record,\n aPositionData: Float32Array,\n ) {\n const attributeLocation = attributeLocations.aPosition;\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n }\n\n _setupFrameBuffer(options: TWebGLPipelineState) {\n const gl = options.context;\n if (options.passes > 1) {\n const width = options.destinationWidth;\n const height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(\n gl,\n width,\n height,\n );\n }\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n options.targetTexture,\n 0,\n );\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n }\n\n _swapTextures(options: TWebGLPipelineState) {\n options.passes--;\n options.pass++;\n const temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n }\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isNeutralState(options?: any): boolean {\n return false;\n }\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(_options: T2DPipelineState): void {\n // override by subclass\n }\n\n /**\n * Returns a string that represent the current selected shader code for the filter.\n * Used to force recompilation when parameters change or to retrieve the shader from cache\n * @type string\n **/\n getCacheKey(): string {\n return this.type;\n }\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n * @return {WebGLProgram} the compiled program shader\n */\n retrieveShader(options: TWebGLPipelineState): TWebGLProgramCacheItem {\n const key = this.getCacheKey();\n if (!options.programCache[key]) {\n options.programCache[key] = this.createProgram(options.context);\n }\n return options.programCache[key];\n }\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context;\n const shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n bindAdditionalTexture(\n gl: WebGLRenderingContext,\n texture: WebGLTexture,\n textureUnit: number,\n ) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n }\n\n unbindAdditionalTexture(gl: WebGLRenderingContext, textureUnit: number) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n }\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program.\n * @param {Object} _uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData(\n _gl: WebGLRenderingContext,\n _uniformLocations: TWebGLUniformLocationMap,\n ): void {\n // override by subclass\n }\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer(options: T2DPipelineState) {\n if (!options.helpLayer) {\n const helpLayer = createCanvasElement();\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n }\n\n /**\n * Returns object representation of an instance\n * It will automatically export the default values of a filter,\n * stored in the static defaults property.\n * @return {Object} Object representation of an instance\n */\n toObject(): { type: Name } & OwnProps {\n const defaultKeys = Object.keys(\n (this.constructor as typeof BaseFilter).defaults || {},\n ) as (keyof OwnProps)[];\n\n return {\n type: this.type,\n ...defaultKeys.reduce((acc, key) => {\n acc[key] = this[\n key as keyof this\n ] as unknown as (typeof acc)[typeof key];\n return acc;\n }, {} as OwnProps),\n };\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n static async fromObject(\n { type, ...filterOptions }: Record,\n _options: Abortable,\n ): Promise> {\n return new this(filterOptions);\n }\n}\n","export const blendColorFragmentSource = {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen:\n 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion:\n 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: `\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n `,\n tint: `\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n `,\n} as const;\n","import { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { blendColorFragmentSource } from './shaders/blendColor';\n\nexport type TBlendMode =\n | 'multiply'\n | 'add'\n | 'difference'\n | 'screen'\n | 'subtract'\n | 'darken'\n | 'lighten'\n | 'overlay'\n | 'exclusion'\n | 'tint';\n\ntype BlendColorOwnProps = {\n color: string;\n mode: TBlendMode;\n alpha: number;\n};\n\nexport const blendColorDefaultValues: BlendColorOwnProps = {\n color: '#F95C63',\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Color Blend filter class\n * @example\n * const filter = new BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendColor extends BaseFilter<'BlendColor', BlendColorOwnProps> {\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n * @type String\n * @default\n **/\n declare color: BlendColorOwnProps['color'];\n\n /**\n * Blend mode for the filter: one of multiply, add, difference, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n * @type String\n * @default\n **/\n declare mode: BlendColorOwnProps['mode'];\n /**\n * alpha value. represent the strength of the blend color operation.\n * @type Number\n * @default\n **/\n declare alpha: BlendColorOwnProps['alpha'];\n\n static defaults = blendColorDefaultValues;\n\n static type = 'BlendColor';\n\n static uniformLocations = ['uColor'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n protected getFragmentSource(): string {\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ${blendColorFragmentSource[this.mode]}\n }\n }\n `;\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const source = new Color(this.color).getSource();\n const tr = source[0] * this.alpha;\n const tg = source[1] * this.alpha;\n const tb = source[2] * this.alpha;\n const alpha1 = 1 - this.alpha;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n break;\n case 'screen':\n data[i] = 255 - ((255 - r) * (255 - tr)) / 255;\n data[i + 1] = 255 - ((255 - g) * (255 - tg)) / 255;\n data[i + 2] = 255 - ((255 - b) * (255 - tb)) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] =\n tr < 128\n ? (2 * r * tr) / 255\n : 255 - (2 * (255 - r) * (255 - tr)) / 255;\n data[i + 1] =\n tg < 128\n ? (2 * g * tg) / 255\n : 255 - (2 * (255 - g) * (255 - tg)) / 255;\n data[i + 2] =\n tb < 128\n ? (2 * b * tb) / 255\n : 255 - (2 * (255 - b) * (255 - tb)) / 255;\n break;\n case 'exclusion':\n data[i] = tr + r - (2 * tr * r) / 255;\n data[i + 1] = tg + g - (2 * tg * g) / 255;\n data[i + 2] = tb + b - (2 * tb * b) / 255;\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource();\n source[0] = (this.alpha * source[0]) / 255;\n source[1] = (this.alpha * source[1]) / 255;\n source[2] = (this.alpha * source[2]) / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n }\n}\n\nclassRegistry.setClass(BlendColor);\n","import type { TBlendImageMode } from '../BlendImage';\n\nexport const fragmentSource: Record = {\n multiply: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n `,\n mask: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n `,\n} as const;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n ` as const;\n","import { FabricImage } from '../shapes/Image';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport type { WebGLFilterBackend } from './WebGLFilterBackend';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource, vertexSource } from './shaders/blendImage';\n\nexport type TBlendImageMode = 'multiply' | 'mask';\n\ntype BlendImageOwnProps = {\n mode: TBlendImageMode;\n alpha: number;\n};\n\nexport const blendImageDefaultValues: BlendImageOwnProps = {\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Image Blend filter class\n * @example\n * const filter = new filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendImage extends BaseFilter<'BlendImage', BlendImageOwnProps> {\n /**\n * Image to make the blend operation with.\n **/\n declare image: FabricImage;\n\n /**\n * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will\n * multiply the values of each channel (R, G, B, and A) of the filter image by\n * their corresponding values in the base image. 'mask' will only look at the\n * alpha channel of the filter image, and apply those values to the base\n * image's alpha channel.\n * @type String\n * @default\n **/\n declare mode: BlendImageOwnProps['mode'];\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n declare alpha: BlendImageOwnProps['alpha'];\n\n static type = 'BlendImage';\n\n static defaults = blendImageDefaultValues;\n\n static uniformLocations = ['uTransformMatrix', 'uImage'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource(): string {\n return fragmentSource[this.mode];\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture!, gl.TEXTURE1);\n super.applyToWebGL(options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n }\n\n createTexture(backend: WebGLFilterBackend, image: FabricImage) {\n return backend.getCachedTexture(image.cacheKey, image.getElement());\n }\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix() {\n const image = this.image,\n { width, height } = image.getElement();\n return [\n 1 / image.scaleX,\n 0,\n 0,\n 0,\n 1 / image.scaleY,\n 0,\n -image.left / width,\n -image.top / height,\n 1,\n ];\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({\n imageData: { data, width, height },\n filterBackend: { resources },\n }: T2DPipelineState) {\n const image = this.image;\n if (!resources.blendImage) {\n resources.blendImage = createCanvasElement();\n }\n const canvas1 = resources.blendImage;\n const context = canvas1.getContext('2d')!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(\n image.scaleX,\n 0,\n 0,\n image.scaleY,\n image.left,\n image.top,\n );\n context.drawImage(image.getElement(), 0, 0, width, height);\n const blendData = context.getImageData(0, 0, width, height).data;\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n const tr = blendData[i];\n const tg = blendData[i + 1];\n const tb = blendData[i + 2];\n const ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n data[i + 3] = (a * ta) / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n }\n\n /**\n * Returns object representation of an instance\n * TODO: Handle the possibility of missing image better.\n * As of now a BlendImage filter without image can't be used with fromObject\n * @return {Object} Object representation of an instance\n */\n toObject(): {\n type: 'BlendImage';\n image: ReturnType;\n } & BlendImageOwnProps {\n return {\n ...super.toObject(),\n image: this.image && this.image.toObject(),\n };\n }\n\n /**\n * Create filter instance from an object representation\n * @static\n * @param {object} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static async fromObject(\n { type, image, ...filterOptions }: Record,\n options: { signal: AbortSignal },\n ): Promise> {\n return FabricImage.fromObject(image, options).then(\n (enlivedImage) =>\n new this({ ...filterOptions, image: enlivedImage }) as BlendImage,\n );\n }\n}\n\nclassRegistry.setClass(BlendImage);\n","import { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n TWebGLPipelineState,\n T2DPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/blur';\n\ntype BlurOwnProps = {\n blur: number;\n};\n\nexport const blurDefaultValues: BlurOwnProps = {\n blur: 0,\n};\n\n/**\n * Blur filter class\n * @example\n * const filter = new Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Blur extends BaseFilter<'Blur', BlurOwnProps> {\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range between 0 and 1.\n * @type Number\n * @default\n */\n declare blur: BlurOwnProps['blur'];\n\n declare horizontal: boolean;\n declare aspectRatio: number;\n\n static type = 'Blur';\n\n static defaults = blurDefaultValues;\n\n static uniformLocations = ['uDelta'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(options: T2DPipelineState) {\n options.imageData = this.simpleBlur(options);\n }\n\n simpleBlur({\n ctx,\n imageData,\n filterBackend: { resources },\n }: T2DPipelineState) {\n const { width, height } = imageData;\n if (!resources.blurLayer1) {\n resources.blurLayer1 = createCanvasElement();\n resources.blurLayer2 = createCanvasElement();\n }\n const canvas1 = resources.blurLayer1!;\n const canvas2 = resources.blurLayer2!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n const ctx1 = canvas1.getContext('2d')!,\n ctx2 = canvas2.getContext('2d')!,\n nSamples = 15,\n blur = this.blur * 0.06 * 0.5;\n let random, percent, j, i;\n\n // load first canvas\n ctx1.putImageData(imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n ctx.drawImage(canvas1, 0, 0);\n const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.uDelta, delta);\n }\n\n isNeutralState() {\n return this.blur === 0;\n }\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta() {\n let blurScale = 1;\n const delta = [0, 0];\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n const blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n return delta;\n }\n}\n\nclassRegistry.setClass(Blur);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n ` as const;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/brightness';\n\ntype BrightnessOwnProps = {\n brightness: number;\n};\n\nexport const brightnessDefaultValues: BrightnessOwnProps = {\n brightness: 0,\n};\n\n/**\n * Brightness filter class\n * @example\n * const filter = new Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Brightness extends BaseFilter<'Brightness', BrightnessOwnProps> {\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n declare brightness: BrightnessOwnProps['brightness'];\n\n static type = 'Brightness';\n\n static defaults = brightnessDefaultValues;\n\n static uniformLocations = ['uBrightness'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const brightness = Math.round(this.brightness * 255);\n for (let i = 0; i < data.length; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n }\n\n isNeutralState() {\n return this.brightness === 0;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n }\n}\n\nclassRegistry.setClass(Brightness);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TMatColorMatrix,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/colorMatrix';\n\ntype ColorMatrixOwnProps = {\n matrix: TMatColorMatrix;\n colorsOnly: boolean;\n};\n\nexport const colorMatrixDefaultValues: ColorMatrixOwnProps = {\n matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\n colorsOnly: true,\n};\n\n/**\n * Color Matrix filter class\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo}\n * @example Kodachrome filter\n * const filter = new ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class ColorMatrix<\n Name extends string = 'ColorMatrix',\n OwnProps extends object = ColorMatrixOwnProps,\n> extends BaseFilter {\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n declare matrix: ColorMatrixOwnProps['matrix'];\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario\n * to save some calculation\n * @type Boolean\n * @default true\n */\n declare colorsOnly: ColorMatrixOwnProps['colorsOnly'];\n\n static type = 'ColorMatrix';\n\n static defaults = colorMatrixDefaultValues;\n\n static uniformLocations = ['uColorMatrix', 'uConstants'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n m = this.matrix,\n colorsOnly = this.colorsOnly;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n } else {\n const a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] =\n r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] =\n r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const m = this.matrix,\n matrix = [\n m[0],\n m[1],\n m[2],\n m[3],\n m[5],\n m[6],\n m[7],\n m[8],\n m[10],\n m[11],\n m[12],\n m[13],\n m[15],\n m[16],\n m[17],\n m[18],\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n }\n\n toObject() {\n return {\n ...super.toObject(),\n matrix: [...this.matrix] as TMatColorMatrix,\n };\n }\n}\n\nclassRegistry.setClass(ColorMatrix);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }`;\n","import { ColorMatrix } from './ColorMatrix';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TMatColorMatrix } from './typedefs';\n\ntype FixedFiltersOwnProps = {\n colorsOnly: boolean;\n};\n\nexport function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) {\n const newClass = class extends ColorMatrix {\n static type = key;\n\n static defaults = {\n colorsOnly: false,\n matrix,\n };\n\n //@ts-expect-error TS wants matrix to be exported.\n toObject(): { type: string } & FixedFiltersOwnProps {\n return { type: this.type, colorsOnly: this.colorsOnly };\n }\n };\n classRegistry.setClass(newClass, key);\n return newClass as typeof ColorMatrix;\n}\n\nexport const Brownie = createColorMatrixFilter(\n 'Brownie',\n [\n 0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449,\n 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Vintage = createColorMatrixFilter(\n 'Vintage',\n [\n 0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0,\n 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Kodachrome = createColorMatrixFilter(\n 'Kodachrome',\n [\n 1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0,\n 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Technicolor = createColorMatrixFilter(\n 'Technicolor',\n [\n 1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0,\n -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Polaroid = createColorMatrixFilter(\n 'Polaroid',\n [\n 1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016,\n 1.483, 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Sepia = createColorMatrixFilter(\n 'Sepia',\n [\n 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131,\n 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const BlackWhite = createColorMatrixFilter(\n 'BlackWhite',\n [\n 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0,\n 1, 0,\n ],\n);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLPipelineState } from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\n\ntype ComposedOwnProps = {\n subFilters: BaseFilter[];\n};\n\n/**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\nexport class Composed extends BaseFilter<'Composed', ComposedOwnProps> {\n /**\n * A non sparse array of filters to apply\n */\n declare subFilters: ComposedOwnProps['subFilters'];\n\n static type = 'Composed';\n\n constructor(\n options: { subFilters?: BaseFilter[] } & Record<\n string,\n any\n > = {},\n ) {\n super(options);\n this.subFilters = options.subFilters || [];\n }\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n options.passes += this.subFilters.length - 1;\n }\n this.subFilters.forEach((filter) => {\n filter.applyTo(options);\n });\n }\n\n /**\n * Serialize this filter into JSON.\n * @returns {Object} A JSON representation of this filter.\n */\n //@ts-expect-error TS doesn't like this toObject\n toObject(): {\n type: 'Composed';\n subFilters: ReturnType['toObject']>[];\n } {\n return {\n type: this.type,\n subFilters: this.subFilters.map((filter) => filter.toObject()),\n };\n }\n\n isNeutralState() {\n return !this.subFilters.some((filter) => !filter.isNeutralState());\n }\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n * @static\n * @param {oject} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject(\n object: Record,\n options: { signal: AbortSignal },\n ): Promise {\n return Promise.all(\n ((object.subFilters || []) as BaseFilter[]).map(\n (filter) =>\n classRegistry\n .getClass(filter.type)\n .fromObject(filter, options),\n ),\n ).then(\n (enlivedFilters) => new this({ subFilters: enlivedFilters }) as Composed,\n );\n }\n}\n\nclassRegistry.setClass(Composed);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/constrast';\n\ntype ContrastOwnProps = {\n contrast: number;\n};\n\nexport const contrastDefaultValues: ContrastOwnProps = {\n contrast: 0,\n};\n\n/**\n * Contrast filter class\n * @example\n * const filter = new Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Contrast extends BaseFilter<'Contrast', ContrastOwnProps> {\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n declare contrast: ContrastOwnProps['contrast'];\n\n static type = 'Contrast';\n\n static defaults = contrastDefaultValues;\n\n static uniformLocations = ['uContrast'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n isNeutralState() {\n return this.contrast === 0;\n }\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const contrast = Math.floor(this.contrast * 255),\n contrastF = (259 * (contrast + 255)) / (255 * (259 - contrast));\n\n for (let i = 0; i < data.length; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n }\n}\n\nclassRegistry.setClass(Contrast);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }`;\n","export const fragmentSource = {\n Convolute_3_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_3_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_5_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_5_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_7_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_7_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_9_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_9_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/convolute';\n\nexport type ConvoluteOwnProps = {\n opaque: boolean;\n matrix: number[];\n};\n\nexport const convoluteDefaultValues: ConvoluteOwnProps = {\n opaque: false,\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n};\n\n/**\n * Adapted from html5rocks article\n * @example Sharpen filter\n * const filter = new Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Blur filter\n * const filter = new Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter\n * const filter = new Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter with opaqueness\n * const filter = new Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Convolute extends BaseFilter<'Convolute', ConvoluteOwnProps> {\n /*\n * Opaque value (true/false)\n */\n declare opaque: ConvoluteOwnProps['opaque'];\n\n /*\n * matrix for the filter, max 9x9\n */\n declare matrix: ConvoluteOwnProps['matrix'];\n\n static type = 'Convolute';\n\n static defaults = convoluteDefaultValues;\n\n static uniformLocations = ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize'];\n\n getCacheKey() {\n return `${this.type}_${Math.sqrt(this.matrix.length)}_${\n this.opaque ? 1 : 0\n }` as keyof typeof fragmentSource;\n }\n\n getFragmentSource() {\n return fragmentSource[this.getCacheKey()];\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0;\n let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n }\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject() {\n return {\n ...super.toObject(),\n opaque: this.opaque,\n matrix: [...this.matrix],\n };\n }\n}\n\nclassRegistry.setClass(Convolute);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/gamma';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nconst GAMMA = 'Gamma' as const;\n\nexport type GammaInput = [number, number, number];\n\nexport type GammaOwnProps = {\n gamma: GammaInput;\n};\n\nexport const gammaDefaultValues: GammaOwnProps = {\n gamma: [1, 1, 1],\n};\n\n/**\n * Gamma filter class\n * @example\n * const filter = new Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Gamma extends BaseFilter {\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n declare gamma: GammaOwnProps['gamma'];\n declare rgbValues?: {\n r: Uint8Array;\n g: Uint8Array;\n b: Uint8Array;\n };\n\n static type = GAMMA;\n\n static defaults = gammaDefaultValues;\n\n static uniformLocations = ['uGamma'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n constructor(options: { gamma?: GammaInput } = {}) {\n super(options);\n this.gamma =\n options.gamma ||\n ((\n this.constructor as typeof Gamma\n ).defaults.gamma.concat() as GammaInput);\n }\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const gamma = this.gamma,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2];\n\n if (!this.rgbValues) {\n this.rgbValues = {\n r: new Uint8Array(256),\n g: new Uint8Array(256),\n b: new Uint8Array(256),\n };\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n const rgb = this.rgbValues;\n for (let i = 0; i < 256; i++) {\n rgb.r[i] = Math.pow(i / 255, rInv) * 255;\n rgb.g[i] = Math.pow(i / 255, gInv) * 255;\n rgb.b[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (let i = 0; i < data.length; i += 4) {\n data[i] = rgb.r[data[i]];\n data[i + 1] = rgb.g[data[i + 1]];\n data[i + 2] = rgb.b[data[i + 2]];\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n }\n\n isNeutralState() {\n const { gamma } = this;\n return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1;\n }\n\n toObject(): { type: typeof GAMMA; gamma: GammaInput } {\n return {\n type: GAMMA,\n gamma: this.gamma.concat() as GammaInput,\n };\n }\n}\n\nclassRegistry.setClass(Gamma);\n","import type { TGrayscaleMode } from '../Grayscale';\n\nexport const fragmentSource: Record = {\n average: `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n `,\n lightness: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n luminosity: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/grayscale';\n\nexport type TGrayscaleMode = 'average' | 'lightness' | 'luminosity';\n\ntype GrayscaleOwnProps = {\n mode: TGrayscaleMode;\n};\n\nexport const grayscaleDefaultValues: GrayscaleOwnProps = {\n mode: 'average',\n};\n\n/**\n * Grayscale image filter class\n * @example\n * const filter = new Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Grayscale extends BaseFilter<'Grayscale', GrayscaleOwnProps> {\n declare mode: TGrayscaleMode;\n\n static type = 'Grayscale';\n\n static defaults = grayscaleDefaultValues;\n\n static uniformLocations = ['uMode'];\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0, value: number; i < data.length; i += 4) {\n switch (this.mode) {\n case 'average':\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n break;\n case 'lightness':\n value =\n (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) /\n 2;\n break;\n case 'luminosity':\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n break;\n }\n\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n }\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource() {\n return fragmentSource[this.mode];\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n }\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState() {\n return false;\n }\n}\n\nclassRegistry.setClass(Grayscale);\n","import { cos } from '../util/misc/cos';\nimport { sin } from '../util/misc/sin';\nimport { ColorMatrix } from './ColorMatrix';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\n\nexport type HueRotationOwnProps = {\n rotation: number;\n};\n\nexport const hueRotationDefaultValues: HueRotationOwnProps = {\n rotation: 0,\n};\n\n/**\n * HueRotation filter class\n * @example\n * const filter = new HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class HueRotation extends ColorMatrix<\n 'HueRotation',\n HueRotationOwnProps\n> {\n /**\n * HueRotation value, from -1 to 1.\n */\n declare rotation: HueRotationOwnProps['rotation'];\n\n static type = 'HueRotation';\n\n static defaults = hueRotationDefaultValues;\n\n calculateMatrix() {\n const rad = this.rotation * Math.PI,\n cosine = cos(rad),\n sine = sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sine,\n OneMinusCos = 1 - cosine;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\n this.matrix[0] = cosine + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cosine + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cosine + aThird * OneMinusCos;\n }\n\n isNeutralState() {\n return this.rotation === 0;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n this.calculateMatrix();\n super.applyTo(options);\n }\n\n //@ts-expect-error TS and classes with different methods\n toObject(): { type: 'HueRotation'; rotation: number } {\n return {\n type: this.type,\n rotation: this.rotation,\n };\n }\n}\n\nclassRegistry.setClass(HueRotation);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/invert';\n\nexport type InvertOwnProps = {\n alpha: boolean;\n invert: boolean;\n};\n\nexport const invertDefaultValues: InvertOwnProps = {\n alpha: false,\n invert: true,\n};\n\n/**\n * @example\n * const filter = new Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Invert extends BaseFilter<'Invert', InvertOwnProps> {\n /**\n * Invert also alpha.\n * @param {Boolean} alpha\n * @default\n **/\n declare alpha: InvertOwnProps['alpha'];\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n declare invert: InvertOwnProps['invert'];\n\n static type = 'Invert';\n\n static defaults = invertDefaultValues;\n\n static uniformLocations = ['uInvert', 'uAlpha'];\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0; i < data.length; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n\n if (this.alpha) {\n data[i + 3] = 255 - data[i + 3];\n }\n }\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState() {\n return !this.invert;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1i(uniformLocations.uInvert, Number(this.invert));\n gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha));\n }\n}\n\nclassRegistry.setClass(Invert);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/noise';\n\nexport type NoiseOwnProps = {\n noise: number;\n};\n\nexport const noiseDefaultValues: NoiseOwnProps = {\n noise: 0,\n};\n\n/**\n * Noise filter class\n * @example\n * const filter = new Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Noise extends BaseFilter<'Noise', NoiseOwnProps> {\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n declare noise: NoiseOwnProps['noise'];\n\n static type = 'Noise';\n\n static defaults = noiseDefaultValues;\n\n static uniformLocations = ['uNoise', 'uSeed'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const noise = this.noise;\n for (let i = 0; i < data.length; i += 4) {\n const rand = (0.5 - Math.random()) * noise;\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n }\n\n isNeutralState() {\n return this.noise === 0;\n }\n}\n\nclassRegistry.setClass(Noise);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/pixelate';\n\nexport type PixelateOwnProps = {\n blocksize: number;\n};\n\nexport const pixelateDefaultValues: PixelateOwnProps = {\n blocksize: 4,\n};\n\n/**\n * Pixelate filter class\n * @example\n * const filter = new Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Pixelate extends BaseFilter<'Pixelate', PixelateOwnProps> {\n declare blocksize: PixelateOwnProps['blocksize'];\n\n static type = 'Pixelate';\n\n static defaults = pixelateDefaultValues;\n\n static uniformLocations = ['uBlocksize'];\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data, width, height } }: T2DPipelineState) {\n for (let i = 0; i < height; i += this.blocksize) {\n for (let j = 0; j < width; j += this.blocksize) {\n const index = i * 4 * width + j * 4;\n const r = data[index];\n const g = data[index + 1];\n const b = data[index + 2];\n const a = data[index + 3];\n\n for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) {\n for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) {\n const index = _i * 4 * width + _j * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n }\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState() {\n return this.blocksize === 1;\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n }\n}\n\nclassRegistry.setClass(Pixelate);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n`;\n","import { classRegistry } from '../ClassRegistry';\nimport { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport { fragmentShader } from './shaders/removeColor';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nexport type RemoveColorOwnProps = {\n color: string;\n distance: number;\n useAlpha: boolean;\n};\n\nexport const removeColorDefaultValues: RemoveColorOwnProps = {\n color: '#FFFFFF',\n distance: 0.02,\n useAlpha: false,\n};\n\n/**\n * Remove white filter class\n * @example\n * const filter = new RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class RemoveColor extends BaseFilter<\n 'RemoveColor',\n RemoveColorOwnProps\n> {\n /**\n * Color to remove, in any format understood by {@link Color}.\n * @param {String} type\n * @default\n */\n declare color: RemoveColorOwnProps['color'];\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n declare distance: RemoveColorOwnProps['distance'];\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n declare useAlpha: RemoveColorOwnProps['useAlpha'];\n\n static type = 'RemoveColor';\n\n static defaults = removeColorDefaultValues;\n\n static uniformLocations = ['uLow', 'uHigh'];\n\n getFragmentSource() {\n return fragmentShader;\n }\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const distance = this.distance * 255,\n source = new Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n if (\n r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]\n ) {\n data[i + 3] = 0;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource(),\n distance = this.distance,\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1,\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1,\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n }\n}\n\nclassRegistry.setClass(RemoveColor);\n","export const fragmentShader = `\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { XY } from '../Point';\n\nexport type TResizeType = 'bilinear' | 'hermite' | 'sliceHack' | 'lanczos';\n\nexport type ResizeOwnProps = {\n resizeType: TResizeType;\n scaleX: number;\n scaleY: number;\n lanczosLobes: number;\n};\n\nexport const resizeDefaultValues: ResizeOwnProps = {\n resizeType: 'hermite',\n scaleX: 1,\n scaleY: 1,\n lanczosLobes: 3,\n};\n\ntype ResizeDuring2DResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n};\n\ntype ResizeDuringWEBGLResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n horizontal: boolean;\n width: number;\n height: number;\n taps: number[];\n tempScale: number;\n dH: number;\n dW: number;\n};\n\n/**\n * Resize image filter class\n * @example\n * const filter = new Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Resize extends BaseFilter<'Resize', ResizeOwnProps> {\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @default\n */\n declare resizeType: ResizeOwnProps['resizeType'];\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n declare scaleX: ResizeOwnProps['scaleX'];\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n declare scaleY: ResizeOwnProps['scaleY'];\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n declare lanczosLobes: ResizeOwnProps['lanczosLobes'];\n\n static type = 'Resize';\n\n static defaults = resizeDefaultValues;\n\n static uniformLocations = ['uDelta', 'uTaps'];\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n this: ResizeDuringWEBGLResize,\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform2fv(\n uniformLocations.uDelta,\n this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height],\n );\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n }\n\n getFilterWindow(this: ResizeDuringWEBGLResize) {\n const scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n }\n\n getCacheKey(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return `${this.type}_${filterWindow}`;\n }\n\n getFragmentSource(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return this.generateShader(filterWindow);\n }\n\n getTaps(this: ResizeDuringWEBGLResize) {\n const lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n }\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader(filterWindow: number) {\n const offsets = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = `${i}.0 * uDelta`;\n }\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[${filterWindow}];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ${offsets\n .map(\n (offset, i) => `\n color += texture2D(uTexture, vTexCoord + ${offset}) * uTaps[${i}] + texture2D(uTexture, vTexCoord - ${offset}) * uTaps[${i}];\n sum += 2.0 * uTaps[${i}];\n `,\n )\n .join('\\n')}\n gl_FragColor = color / sum;\n }\n `;\n }\n\n applyToForWebgl(this: ResizeDuringWEBGLResize, options: TWebGLPipelineState) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n super.applyTo(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n super.applyTo(options);\n options.sourceHeight = options.destinationHeight;\n }\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n (this as unknown as ResizeDuringWEBGLResize).applyToForWebgl(options);\n } else {\n (this as unknown as ResizeDuring2DResize).applyTo2d(options);\n }\n }\n\n isNeutralState() {\n return this.scaleX === 1 && this.scaleY === 1;\n }\n\n lanczosCreate(lobes: number) {\n return (x: number) => {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.1920929e-7 && x > -1.1920929e-7) {\n return 1.0;\n }\n x *= Math.PI;\n const xx = x / lobes;\n return ((Math.sin(x) / x) * Math.sin(xx)) / xx;\n };\n }\n\n applyTo2d(this: ResizeDuring2DResize, options: T2DPipelineState) {\n const imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n const oW = imageData.width;\n const oH = imageData.height;\n const dW = Math.round(oW * scaleX);\n const dH = Math.round(oH * scaleY);\n let newData: ImageData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n } else {\n // this should never trigger, is here just for safety net.\n newData = new ImageData(dW, dH);\n }\n options.imageData = newData;\n }\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo(\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const imageData = options.imageData;\n const mult = 0.5;\n let doneW = false;\n let doneH = false;\n let stepW = oW * mult;\n let stepH = oH * mult;\n const resources = options.filterBackend.resources;\n let sX = 0;\n let sY = 0;\n const dX = oW;\n let dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = createCanvasElement();\n }\n const tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n const ctx = tmpCanvas.getContext('2d')!;\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = Math.floor(dW);\n dH = Math.floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < Math.floor(stepW * mult)) {\n stepW = Math.floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n if (dH < Math.floor(stepH * mult)) {\n stepH = Math.floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n }\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ): ImageData {\n function process(u: number): ImageData {\n let v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = Math.floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = Math.floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = Math.floor(1000 * Math.abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = Math.floor(1000 * Math.abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(\n Math.sqrt(\n Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2),\n ) / 1000,\n );\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n } else {\n return destImg;\n }\n }\n\n const srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = Math.ceil((ratioX * this.lanczosLobes) / 2),\n range2Y = Math.ceil((ratioY * this.lanczosLobes) / 2),\n cacheLanc: Record> = {},\n center: XY = { x: 0, y: 0 },\n icenter: XY = { x: 0, y: 0 };\n\n return process(0);\n }\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n let a;\n let b;\n let c;\n let d;\n let x;\n let y;\n let i;\n let j;\n let xDiff;\n let yDiff;\n let chnl;\n let color;\n let offset = 0;\n let origPix;\n const ratioX = this.rcpScaleX;\n const ratioY = this.rcpScaleY;\n const w4 = 4 * (oW - 1);\n const img = options.imageData;\n const pixels = img.data;\n const destImage = options.ctx.createImageData(dW, dH);\n const destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = Math.floor(ratioX * j);\n y = Math.floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color =\n a * (1 - xDiff) * (1 - yDiff) +\n b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) +\n d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n }\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = Math.ceil(ratioW / 2),\n ratioHHalf = Math.ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n for (let j = 0; j < dH; j++) {\n for (let i = 0; i < dW; i++) {\n const x2 = (i + j * dW) * 4;\n let weight = 0;\n let weights = 0;\n let weightsAlpha = 0;\n let gxR = 0;\n let gxG = 0;\n let gxB = 0;\n let gxA = 0;\n const centerY = (j + 0.5) * ratioH;\n for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW,\n w0 = dy * dy;\n for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf;\n const w = Math.sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = (weight * data[dx + 3]) / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n }\n}\n\nclassRegistry.setClass(Resize);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/saturation';\n\nexport type SaturationOwnProps = {\n saturation: number;\n};\n\nexport const saturationDefaultValues: SaturationOwnProps = {\n saturation: 0,\n};\n\n/**\n * Saturate filter class\n * @example\n * const filter = new Saturation({\n * saturation: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Saturation extends BaseFilter<'Saturation', SaturationOwnProps> {\n /**\n * Saturation value, from -1 to 1.\n * Increases/decreases the color saturation.\n * A value of 0 has no effect.\n *\n * @param {Number} saturation\n * @default\n */\n declare saturation: SaturationOwnProps['saturation'];\n\n static type = 'Saturation';\n\n static defaults = saturationDefaultValues;\n\n static uniformLocations = ['uSaturation'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.saturation;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n }\n\n isNeutralState() {\n return this.saturation === 0;\n }\n}\n\nclassRegistry.setClass(Saturation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/vibrance';\n\nexport type VibranceOwnProps = {\n vibrance: number;\n};\n\nexport const vibranceDefaultValues: VibranceOwnProps = {\n vibrance: 0,\n};\n\n/**\n * Vibrance filter class\n * @example\n * const filter = new Vibrance({\n * vibrance: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Vibrance extends BaseFilter<'Vibrance', VibranceOwnProps> {\n /**\n * Vibrance value, from -1 to 1.\n * Increases/decreases the saturation of more muted colors with less effect on saturated colors.\n * A value of 0 has no effect.\n *\n * @param {Number} vibrance\n * @default\n */\n declare vibrance: VibranceOwnProps['vibrance'];\n\n static type = 'Vibrance';\n\n static defaults = vibranceDefaultValues;\n\n static uniformLocations = ['uVibrance'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.vibrance;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;\n const amt = ((Math.abs(max - avg) * 2) / 255) * adjust;\n data[i] += max !== data[i] ? (max - data[i]) * amt : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uVibrance, -this.vibrance);\n }\n\n isNeutralState() {\n return this.vibrance === 0;\n }\n}\n\nclassRegistry.setClass(Vibrance);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n`;\n"],"names":["BaseConfiguration","constructor","_defineProperty","this","window","devicePixelRatio","config","super","configure","arguments","length","undefined","Object","assign","addFonts","paths","fontPaths","_objectSpread","removeFonts","forEach","fontFamily","clearFonts","restoreDefaults","keys","defaults","reduce","acc","key","log","severity","_len","optionalParams","Array","_key","console","FabricError","Error","message","options","concat","SignalAbortedError","context","GLProbe","WebGLProbe","testPrecision","gl","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","queryWebGL","canvas","getContext","maxTextureSize","getParameter","MAX_TEXTURE_SIZE","GLPrecision","find","getExtension","loseContext","isSupported","textureSize","copyPasteData","env","setEnv","value","getEnv","document","isTouchSupported","navigator","maxTouchPoints","dispose","getFabricDocument","getFabricWindow","getDevicePixelRatio","_config$devicePixelRa","Math","max","cache","getFontCache","_ref","fontStyle","fontWeight","toLowerCase","charWidthsCache","fontCache","cacheKey","clearFontCache","limitDimsByArea","ar","perfLimitSizeTotal","roughWidth","sqrt","floor","VERSION","noop","halfPI","PI","twoMathPi","PiBy180","iMatrix","freeze","DEFAULT_SVG_FONT_SIZE","kRect","CENTER","LEFT","TOP","BOTTOM","RIGHT","NONE","reNewline","MOVING","SCALING","ROTATING","ROTATE","SKEWING","RESIZING","MODIFY_POLY","MODIFY_PATH","CHANGED","SCALE","SCALE_X","SCALE_Y","SKEW_X","SKEW_Y","FILL","STROKE","MODIFIED","JSON","SVG","classRegistry","Map","has","classType","getClass","get","setClass","classConstructor","set","type","getSVGClass","SVGTagName","setSVGClass","runningAnimations","remove","index","indexOf","splice","cancelAll","animations","animation","abort","cancelByCanvas","filter","_animation$target","target","cancelByTarget","Observable","on","arg0","handler","__eventListeners","entries","eventName","off","push","once","disposers","_ref2","d","disposer","args","call","_removeEventListener","eventListener","_ref3","fire","_this$__eventListener","listenersForEvent","i","removeFromArray","array","idx","cos","angle","abs","sin","angleSlice","sign","Point","y","x","add","that","addEquals","scalarAdd","scalar","scalarAddEquals","subtract","subtractEquals","scalarSubtract","scalarSubtractEquals","multiply","scalarMultiply","scalarMultiplyEquals","divide","scalarDivide","scalarDivideEquals","eq","lt","lte","gt","gte","lerp","t","min","distanceFrom","dx","dy","midPointFrom","toString","setXY","setX","setY","setFromPoint","swap","clone","rotate","radians","origin","ZERO","sinus","cosinus","p","transform","ignoreOffset","isCollection","fabricObject","isArray","_objects","createCollectionMixin","Base","Collection","_onObjectAdded","object","_onObjectRemoved","_onStackOrderChanged","objects","size","insertAt","_len2","_key2","removed","_len3","_key3","forEachObject","callback","getObjects","_len4","types","_key4","o","isType","item","isEmpty","contains","deep","includes","some","obj","complexity","memo","current","sendObjectToBack","unshift","bringObjectToFront","sendObjectBackwards","intersecting","newIdx","findNewLowerIndex","bringObjectForward","findNewUpperIndex","moveObjectTo","isOverlapping","collectObjects","left","top","width","height","includeIntersecting","tl","br","selectable","visible","intersectsWithRect","isContainedWithinRect","containsPoint","CommonMethods","_setOptions","prop","_setObject","_set","toggle","property","requestAnimFrame","requestAnimationFrame","cancelAnimFrame","handle","cancelAnimationFrame","id","uid","createCanvasElement","element","createElement","createImage","toDataURL","canvasEl","format","quality","degreesToRadians","degrees","radiansToDegrees","isIdentityMatrix","mat","every","transformPoint","invertTransform","a","r","multiplyTransformMatrices","b","is2x2","multiplyTransformMatrixArray","matrices","reduceRight","product","curr","calcPlaneRotation","atan2","qrDecompose","denom","pow","scaleX","scaleY","skewX","skewY","translateX","translateY","createTranslateMatrix","createRotateMatrix","angleRadiant","cosValue","sinValue","createScaleMatrix","angleToSkew","tan","createSkewXMatrix","skewValue","createSkewYMatrix","calcDimensionsMatrix","flipX","flipY","matrix","composeMatrix","scaleMatrix","loadImage","url","signal","crossOrigin","Promise","resolve","reject","aborted","img","err","src","addEventListener","done","onload","onerror","removeEventListener","enlivenObjects","reviver","instances","all","map","fromObject","then","fabricInstance","catch","error","instance","finally","enlivenObjectEnlivables","serializedObject","promises","values","enlived","pick","source","pickBy","predicate","ColorNameMap","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","hue2rgb","q","rgb2Hsl","g","maxValue","minValue","h","s","l","round","fromAlphaToFloat","parseFloat","endsWith","hexify","toUpperCase","padStart","greyAverage","avg","Color","color","setSource","_source","_tryParsingColor","sourceFromHex","sourceFromRgb","sourceFromHsl","isUnrecognised","getSource","toRgb","toRgba","join","toHsl","toHsla","toHex","toHexa","slice","getAlpha","setAlpha","alpha","toGrayscale","toBlackWhite","threshold","average","bOrW","overlayWith","otherColor","otherSource","R","G","B","fromRgb","fromRgba","match","parsedValue","fromHsl","fromHsla","parseAngletoDegrees","fromHex","expandedValue","split","hex","hexCouple","parseInt","lowercase","numeric","toFixed","number","fractionDigits","Number","parseUnit","fontSize","unit","exec","dpi","DPI","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","alignX","alignY","align","meetOrSlice","matrixToSVG","NUM_FRACTION_DIGITS","colorPropToSVG","colorValue","opacityValue","inlineStyle","toLive","opacity","isFiller","filler","isSerializableFiller","toObject","isPattern","offsetX","isTextObject","_renderText","isActiveSelection","getScrollLeftTop","doc","getDocumentFromElement","elementLoop","docElement","documentElement","body","scrollLeft","scrollTop","parentNode","host","nodeType","style","position","el","ownerDocument","getWindowFromElement","_el$ownerDocument","defaultView","setCanvasDimensions","ctx","retinaScaling","setAttribute","scale","setCSSDimensions","makeElementUnselectable","onselectstart","userSelect","StaticCanvasDOMManager","createLowerCanvas","lower","getElementById","hasAttribute","_originalCanvasStyle","cssText","classList","cleanupDOM","removeAttribute","setDimensions","calcOffset","_getWindowFromElement","offset","elemStyle","getComputedStyle","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","box","docElem","getBoundingClientRect","scrollLeftTop","clientLeft","clientTop","getElementOffset","staticCanvasDefaults","backgroundVpt","backgroundColor","overlayVpt","overlayColor","includeDefaultValues","svgViewportTransformation","renderOnAddRemove","skipOffscreen","enableRetinaScaling","imageSmoothingEnabled","controlsAboveOverlay","allowTouchScrolling","viewportTransform","StaticCanvas","lowerCanvasEl","_this$elements$lower","elements","contextContainer","_this$elements$lower2","getDefaults","ownDefaults","initElements","_setDimensionsImpl","skipControlsDrawing","calcViewportBoundaries","requestRenderAll","setCoords","getRetinaScaling","_offset","getWidth","getHeight","setWidth","setHeight","dimensions","cssOnly","backstoreOnly","hasLostContext","getZoom","setViewportTransform","vpt","zoomToPoint","point","before","newPoint","after","setZoom","absolutePan","relativePan","getElement","clearContext","clearRect","clear","backgroundImage","overlayImage","renderAll","cancelRequestedRender","destroyed","renderCanvas","renderAndReset","nextRenderHandle","disposed","iVpt","vptCoords","tr","bl","drawControls","_ctx","v","path","clipPath","patternQuality","_renderBackground","save","_renderObjects","restore","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","__cleanupTask","globalCompositeOperation","zoomX","zoomY","drawImage","_cacheCanvas","cacheTranslationX","cacheTranslationY","len","render","_renderBackgroundOrOverlay","fill","needsVpt","isAFiller","beginPath","moveTo","lineTo","closePath","fillStyle","offsetY","m","gradientTransform","patternTransform","getCenter","getCenterPoint","centerObjectH","_centerObject","centerObjectV","centerObject","viewportCenterObject","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","center","toDatalessJSON","propertiesToInclude","toDatalessObject","_toObjectMethod","toJSON","methodName","clipPathData","excludeFromExport","_toObject","version","__serializeBgOverlay","originalValue","data","bgImage","bgColor","background","overlay","toSVG","markup","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","optViewBox","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","additionalTransform","fontList","styles","styleRow","fontListMarkup","_setSVGObject","bgOrOverlay","repeat","finalWidth","finalHeight","loadFromJSON","json","serialized","parse","enlivedMap","properties","cloneWithoutData","multiplier","finalMultiplier","toCanvasElement","scaledWidth","scaledHeight","zoom","originalWidth","originalHeight","originalSkipControlsDrawing","newZoom","vp","newVp","originalRetina","objectsToRender","task","destroy","kill","touchEvents","getPointer","event","scroll","_evt","touchProp","changedTouches","getTouchInfo","clientX","clientY","isTouchEvent","pointerType","stopEvent","e","preventDefault","stopPropagation","makeBoundingBoxFromPoints","points","addTransformToObject","applyTransformToObject","calcOwnMatrix","_qrDecompose","otherOptions","_objectWithoutProperties","_excluded","setPositionByOrigin","resetObjectTransform","saveObjectTransform","sizeAfterTransform","dimX","dimY","bbox","calcPlaneChangeMatrix","from","sendPointToPlane","to","sendVectorToPlane","sendObjectToPlane","fireEvent","_target$canvas","originOffset","bottom","right","resolveOrigin","originValue","NOT_ALLOWED_CURSOR","isTransformCentered","originX","originY","invertOrigin","isLocked","lockingKey","commonEventInfo","eventData","pointer","findCornerQuadrant","control","cornerAngle","getTotalAngle","getLocalPoint","corner","controls","padding","localPoint","getRelativeCenterPoint","translateToGivenOrigin","normalizePoint","dragHandler","newLeft","newTop","moveX","moveY","FabricObjectSVGExportMixin","getSvgStyles","skipShadow","fillRule","strokeWidth","strokeDashArray","strokeDashOffset","strokeLineCap","strokeLineJoin","strokeMiterLimit","visibility","getSvgFilter","stroke","shadow","getSvgCommons","getSvgTransform","full","calcTransformMatrix","svgTransform","_toSVG","_reviver","_createBaseSVGMarkup","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","withShadow","styleInfo","shadowInfo","vectorEffect","strokeUniform","absoluteClipPath","absolutePositioned","clipPathMarkup","addPaintOrder","paintFirst","getSvgRegex","arr","RegExp","reNum","String","raw","_templateObject","_taggedTemplateLiteral","svgNS","reFontDeclaration","attributesMap","cx","cy","display","fSize","cPath","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgValidParentsRegEx","reViewBoxAttrValue","unitVectorX","zero","rotateVector","vector","createVector","magnitude","calcAngleBetweenVectors","crossProduct","dotProduct","calcVectorRotation","getUnitVector","getOrthonormalVector","counterClockwise","isBetweenVectors","AxB","AxT","BxT","shadowOffsetRegex","reOffsetsAndBlur","Shadow","parseShadow","shadowStr","blur","replace","fBoxX","fBoxY","affectStroke","nonScaling","capValue","stateProperties","cacheProperties","fabricObjectDefaultValues","minScaleLimit","objectCaching","inverted","centeredRotation","centeredScaling","dirty","normalize","c","asin","elastic","defaultEasing","easeOutBounce","easeInBounce","easeInCirc","easeInCubic","easeInElastic","normA","normS","normP","easeInExpo","easeInOutBounce","easeInOutCirc","easeInOutCubic","easeInOutElastic","normC","easeInOutExpo","easeInOutQuad","easeInOutQuart","easeInOutQuint","easeInOutSine","easeInQuad","easeInQuart","easeInQuint","easeInSine","easeOutCirc","easeOutCubic","easeOutElastic","easeOutExpo","easeOutQuad","easeOutQuart","easeOutQuint","easeOutSine","defaultAbort","AnimationBase","startValue","byValue","duration","delay","easing","onStart","onChange","onComplete","tick","bind","_onStart","_onChange","_onComplete","_abort","endValue","calculate","state","_state","isDone","start","firstTick","timestamp","startTime","Date","register","setTimeout","durationMs","boundDurationMs","durationProgress","valueProgress","unregister","ValueAnimation","timeElapsed","ArrayAnimation","defaultColorEasing","wrapColorCallback","rgba","ColorAnimation","startColor","endColor","animate","isArrayAnimation","animateColor","Intersection","status","append","isPointContained","T","A","infinite","AB","isPointInPolygon","other","hits","inter","intersectSegmentSegment","intersectLineLine","a1","a2","b1","b2","aInfinite","bInfinite","a2xa1x","a2ya1y","b2xb1x","b2yb1y","a1xb1x","a1yb1y","uaT","ubT","uB","ua","ub","segmentsCoincide","intersectSegmentLine","s1","s2","l1","l2","intersectLinePolygon","result","intersectSegmentPolygon","intersectPolygonPolygon","points1","points2","coincidences","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","ObjectGeometry","getX","getXY","getY","getRelativeX","setRelativeX","getRelativeY","setRelativeY","relativePosition","getRelativeXY","group","setRelativeXY","isStrokeAccountedForInDimensions","getCoords","aCoords","calcACoords","coords","intersectsWithObject","intersection","isContainedWithinObject","getBoundingRect","isOnScreen","isPartiallyOnScreen","getScaledWidth","_getTransformedDimensions","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","getCanvasRetinaScaling","_this$canvas","getViewportTransform","_this$canvas2","rotateMatrix","tMatrix","finalMatrix","dim","w","transformMatrixKey","skipGroup","prefix","matrixCache","ownMatrixCache","_getNonTransformedDimensions","_calculateCurrentDimensions","dimOptions","preScalingStrokeValue","postScalingStrokeValue","finalDimensions","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","translateToOriginPoint","relCenter","getPointByOrigin","pos","_getLeftTopCoords","FabricObject","name","setOptions","_createCacheCanvas","_cacheContext","_updateCacheCanvas","_limitCacheSize","dims","maxCacheSideLimit","minCacheSideLimit","limX","limY","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","minCacheSize","dimensionsChanged","zoomChanged","drawingWidth","drawingHeight","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","getHeightOfLine","ceil","setTransform","translate","needFullTransform","contextTop","getObjectScaling","retina","getObjectOpacity","_constrainScale","isChanged","parent","isNotVisible","_setupCompositeOperation","drawSelectionBackground","_setOpacity","_setShadow","drawCacheOnCanvas","_removeCacheCanvas","drawObject","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","isOnACache","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_render","_drawClipPath","skipCanvas","fillRect","_removeShadow","globalAlpha","_setStrokeStyles","decl","lineWidth","lineCap","lineDashOffset","lineJoin","miterLimit","gradientUnits","_applyPatternForTransformedGradient","strokeStyle","_applyPatternGradientTransform","_setFillStyles","_setLineDash","dashArray","setLineDash","sx","sy","multX","multY","scaling","shadowColor","shadowBlur","browserShadowBlurConstant","shadowOffsetX","shadowOffsetY","_renderPaintInOrder","_renderStroke","_renderFill","_pCtx$createPattern","pCanvas","pCtx","createPattern","_findCenterFromElement","objectForm","cloneAsImage","origParams","originalGroup","originalShadow","canvasProvider","withoutTransform","withoutShadow","boundingRect","shadowOffset","originalCanvas","setOnGroup","animatable","_animate","propIsColor","colorProperties","animationOptions","isDescendantOf","getAncestors","ancestors","findCommonAncestors","fork","otherFork","common","otherAncestors","ancestor","j","hasCommonAncestors","commonAncestors","isInFrontOf","ancestorData","firstCommonAncestor","headOfFork","pop","headOfOtherFork","thisIndex","otherIndex","propertiesToSerialize","customProperties","toFixedBound","val","_removeDefaultValues","baseValues","getPrototypeOf","baseValue","_fromObject","serializedObjectOptions","_ref4","extraParam","_excluded2","enlivedObjectOptions","wrapWithFireEvent","actionHandler","extraEventInfo","actionPerformed","wrapWithFixedAnchor","centerPoint","constraint","changeWidth","changeObjectWidth","strokePadding","oldWidth","newWidth","renderCircleControl","styleOverride","xSize","sizeX","cornerSize","ySize","sizeY","transparentCorners","cornerStrokeColor","myLeft","myTop","cornerColor","arc","renderSquareControl","xSizeBy2","ySizeBy2","strokeRect","Control","shouldActivate","controlKey","_fabricObject$canvas","getActiveObject","isControlVisible","getActionHandler","getMouseDownHandler","mouseDownHandler","getMouseUpHandler","mouseUpHandler","cursorStyleHandler","cursorStyle","getActionName","actionName","getVisibility","_fabricObject$_contro","_fabricObject$_contro2","_controlsVisibility","setVisibility","positionHandler","currentControl","calcCornerCoords","objectCornerSize","centerX","centerY","isTouch","touchSizeX","touchSizeY","cornerStyle","rotationStyleHandler","lockRotation","rotationWithSnapping","rotateObjectWithSnapping","ex","ey","theta","pivotPoint","lastAngle","curAngle","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","hasRotated","scaleIsProportional","uniformIsToggled","uniScaleKey","uniformScaling","scalingIsForbidden","by","scaleProportionally","lockX","lockY","scaleMap","scaleCursorStyleHandler","n","scaleObject","signX","signY","gestureScale","distance","original","oldScaleX","oldScaleY","scalingEqually","scaleObjectFromCorner","scalingX","scaleObjectX","scalingY","scaleObjectY","AXIS_KEYS","counterAxis","skew","lockSkewing","flip","skewMap","skewCursorStyleHandler","skewHandler","axis","originKey","lockSkewingKey","skewKey","flipKey","counterOriginKey","counterFlipKey","counterOriginFactor","skewingSide","finalHandler","skewingBefore","skewingStart","shearingStart","shearing","skewing","atan","changed","dimBefore","dimAfter","compensationFactor","skewObject","skewHandlerX","skewHandlerY","isAltAction","altActionKey","scaleOrSkewActionName","isAlternative","scaleSkewCursorStyleHandler","scalingXOrSkewingY","scalingYOrSkewingX","createObjectDefaultControls","ml","mr","mb","mt","mtr","withConnection","createResizeControls","createTextboxDefaultControls","InteractiveFabricObject","createControls","targetCanvas","noScaleCache","_currentTransform","action","startsWith","getActiveControl","__corner","coord","oCoords","findControl","forTouch","hasControls","cornerEntries","touchCorner","calcOCoords","rMatrix","positionMatrix","startMatrix","transformOptions","forEachControl","_calcCornerCoords","touchCornerSize","fn","selectionBackgroundColor","_activeObject","wh","strokeBorders","_drawBorders","borderColor","borderDashArray","drawControlsConnectingLines","_renderControls","hasBorders","styleOptions","shouldDrawBorders","shouldDrawControls","borderScaleFactor","isMoving","borderOpacityWhenMoving","drawBorders","forActiveSelection","shouldStroke","cornerDashArray","setControlVisible","setControlsVisibility","clearContextTop","restoreManually","onDeselect","_options","onSelect","shouldStartDragging","_e","onDragStart","canDrop","renderDragSourceEffect","renderDropTargetEffect","applyMixins","derivedCtor","constructors","baseCtor","getOwnPropertyNames","prototype","defineProperty","getOwnPropertyDescriptor","create","lockMovementX","lockMovementY","lockScalingX","lockScalingY","lockSkewingX","lockSkewingY","lockScalingFlip","evented","perPixelTargetFind","activeOn","hoverCursor","moveCursor","isTransparent","tolerance","getImageData","StrokeProjectionsBase","strokeProjectionMagnitude","strokeUniformScalar","createSideVector","projectOrthogonally","applySkew","calcOrthogonalProjection","isSkewed","scaleUnitVector","unitVector","zeroVector","StrokeLineJoinProjections","getOrthogonalRotationFactor","vector1","vector2","C","AC","bisector","orthogonalProjection","correctSide","projectBevel","projections","projectMiter","hypotUnitScalar","miterVector","projectRoundNoSkew","startCircle","endCircle","projectRoundWithSkew","circleRadius","newY","furthestY","newX","furthestX","projectRound","isStraightLine","newOrigin","proj0","proj1","comparisonVector","isProj0Start","projectPoints","project","originPoint","projectedPoint","StrokeLineCapProjections","projectButt","projection","projectSquare","strokePointingOut","projectedA","projectStrokeOnPoints","openPath","reduced","findIndexRight","cloneStyles","newObj","keyInner","escapeXml","string","graphemeSplit","textstring","graphemes","chr","getWholeChar","str","code","charCodeAt","isNaN","charAt","next","prev","firstLetterOnly","hasStyleChanged","prevStyle","thisStyle","forTextSpans","textBackgroundColor","deltaY","overline","underline","linethrough","stylesToArray","text","textLines","stylesArray","charIndex","chars","end","stylesFromArray","stylesObject","styleIndex","SHARED_ATTRIBUTES","selectorMatches","selector","nodeName","classNames","getAttribute","azAz","matcher","splitClassNames","elementMatchesRule","selectors","parentMatching","firstMatching","parentElement","doesSomeParentMatch","normalizeAttr","attr","_attributesMap","regex","cleanupSvgAttribute","attributeValue","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_templateObject6","transforms","transformList","_templateObject7","reTransformList","reTransform","reTransformAll","parseTransformAttribute","test","matchAll","transformMatch","matchedParams","operation","rawArgs","arg1","arg2","arg3","arg4","arg5","arg","normalizeValue","parentAttributes","parsed","ouputValue","transformMatrix","fillIndex","strokeIndex","parseFontDeclaration","oStyle","lineHeight","parseStyleString","chunk","parseStyleAttribute","parseStyleObject","colorAttributesMap","parseAttributes","attributes","cssRules","parentFontSize","ownAttributes","rule","getGlobalStylesForElement","normalizedStyle","normalizedAttr","normalizedValue","font","mergedAttrs","colorAttr","setStrokeFillOpacity","RECT_PROPS","Rect","_initRxRy","rx","ry","isRounded","bezierCurveTo","fromElement","_parseAttributes","ATTRIBUTE_NAMES","restOfparsedAttributes","Boolean","LAYOUT_TYPE_INITIALIZATION","LAYOUT_TYPE_ADDED","LAYOUT_TYPE_REMOVED","LAYOUT_TYPE_IMPERATIVE","getObjectBounds","destinationGroup","currentGroup","objectCenter","accountForStroke","strokeUniformVector","scalingStrokeWidth","sizeVector","LayoutStrategy","calcLayoutResult","shouldPerformLayout","calcBoundingBox","prevStrategy","strategy","shouldLayoutClipPath","getInitialSize","overrides","bboxSize","bboxCenter","actualSize","relativeCorrection","FitContentLayout","LAYOUT_MANAGER","LayoutManager","_subscriptions","performLayout","strictContext","bubbles","_prevLayoutStrategy","onBeforeLayout","layoutResult","getLayoutResult","commitLayout","onAfterLayout","attachHandlers","trigger","subscribe","unsubscribe","_context","delete","unsubscribeTargets","targets","subscribeTargets","tricklingContext","layoutManager","prevCenter","nextCenter","correction","_context$x","_context$y","layoutObjects","layoutObject","_","bubblingContext","NoopLayoutManager","Group","groupInit","_options$layoutManage","__objectSelectionTracker","__objectSelectionMonitor","__objectSelectionDisposer","enterGroup","canEnterGroup","_filterObjectsBeforeEnteringGroup","allowedObjects","_onAfterObjectsChange","removeParentTransform","exitGroup","_shouldSetNestedCoords","subTargetCheck","removeAll","_activeObjects","selected","activeObjects","_watchObject","watch","_enterGroup","activeObject","_exitGroup","ownCache","preserveObjectStacking","triggerLayout","__serializeObjects","method","_includeDefaultValues","originalDefaults","_createSVGBgRect","fillStroke","commons","svgString","bg","abortable","hydratedOptions","layoutClass","strategyClass","interactive","findScaleToFit","destination","findScaleToCover","commaWsp","reArcCommandPoints","repeatedCommands","M","segmentToBezier","theta1","theta2","cosTh","sinTh","cx1","cy1","mT","fromX","fromY","costh1","sinth1","costh2","sinth2","toX","toY","calcVectorAngle","ux","uy","vx","vy","ta","tb","getBoundsOfCurve","begx","begy","cp1x","cp1y","cp2x","cp2y","endx","endy","argsString","cachesBoundsOfCurve","boundsOfCurveCache","tvalues","bounds","b2ac","sqrtb2ac","t1","t2","jlen","iterator","getPointOnCubicBezierIterator","fromArcToBeziers","fx","fy","rot","large","sweep","tx","ty","segsNorm","arcToSegments","rotateX","root","sinTheta","px","py","rx2","ry2","py2","px2","pl","_rx","_ry","mTheta","dtheta","segments","mDelta","th3","makePathSimpler","x1","y1","destinationPath","previous","controlX","controlY","parsedCommand","converted","calcLineLength","x2","y2","pct","c1","c2","CB2","c3","CB3","c4","CB4","QB1","QB2","QB3","getTangentCubicIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","qb1","qb2","qb3","tangentX","tangentY","getPointOnQuadraticBezierIterator","getTangentQuadraticIterator","invT","pathIterator","tempP","tmpLen","perc","findPercentageForDistance","segInfo","nextLen","nextStep","lastPerc","angleFinder","getPathSegmentsInfo","tempInfo","totalLength","info","basicInfo","command","destX","destY","getPointOnPath","infos","segPercent","segment","rePathCmdAll","regExpArcCommandPoints","reMyNum","commandLengths","parsePath","pathString","_pathString$match","chain","matchStr","commandLetter","commandLength","paramArr","lastIndex","out","newCommand","transformedCommand","getSmoothPathFromPoints","p1","p2","multSignX","multSignY","manyPoints","midPoint","joinPath","pathData","setStyle","elementStyle","setProperty","getRandomInt","random","request","xhr","removeListener","ontimeout","onreadystatechange","readyState","open","send","removeTransformMatrixForSvgParsing","preserveAspectRatioOptions","_assignTransformMatrixProps","cropX","cropY","offsetLeft","offsetTop","_newCanvas$getContext","newCanvas","getRegularPolygonPath","numVertexes","radius","interiorAngle","rotationAdjustment","rad","commonAttributes","groupSVGElements","mergeClipPaths","_b$group","removeTransformFromObject","finalTransform","rotatePoint","transformPath","pathOffset","pathSegment","newSegment","CanvasDOMManager","containerClass","upperCanvasEl","createUpperCanvas","upper","applyCanvasStyle","container","createContainerElement","replaceChild","className","removeChild","SelectableCanvas","_this$elements$upper","_this$elements$upper2","wrapperEl","_objectsToRender","deselected","_discardActiveObject","_hoveredTarget","_hoveredTargets","_chooseObjectsToRender","contextTopDirty","_groupSelector","isDrawingMode","renderTopLayer","_isCurrentlyDrawing","freeDrawingBrush","selection","_drawSelection","renderTop","setTargetFindTolerance","targetFindTolerance","pixelFindCanvasEl","pixelFindContext","isTargetTransparent","selectionBgc","enhancedTolerance","_isSelectionKeyPressed","sKey","selectionKey","_shouldClearSelection","getActiveObjects","_shouldCenterTransform","modifierKeyPressed","centerTransform","_getOriginFromCorner","controlName","_setupCurrentTransform","alreadySelected","_control$getActionHan","getScenePoint","getActionFromCorner","altKey","centeredKey","lastX","lastY","shiftKey","setCursor","cursor","deltaX","extent","strokeOffset","selectionLineWidth","minX","minY","maxX","maxY","selectionColor","selectionBorderColor","selectionDashArray","findTarget","skipTargetFind","getViewportPoint","aObjects","searchPossibleTargets","subTargets","altSelectionKey","_pointIsInObjectSelectionArea","viewportZoom","angleRadians","cosP","sinP","cosPSinP","cosPMinusSinP","_checkTarget","isEditing","_searchPossibleTargets","subTarget","_pointer","_absolutePointer","fromViewport","boundsWidth","boundsHeight","cssScale","_resetTransformEventData","_setBrushStyles","willReadFrequently","getTopContext","getSelectionContext","getSelectionElement","active","_fireSelectionEvents","oldObjects","somethingChanged","invalidate","added","setActiveObject","currentActives","_setActiveObject","prevActiveObject","endCurrentTransform","discardActiveObject","discarded","_finalizeCurrentTransform","_scaling","originalProperties","_realizeGroupTransformOnObject","originalValues","selectionFullyContained","defaultCursor","freeDrawingCursor","notAllowedCursor","stopContextMenu","fireRightClick","fireMiddleClick","enablePointerEvents","TextEditingManager","cb","hiddenTextarea","focus","__disposer","exitTextEditing","exitEditing","onMouseMove","_this$target","updateSelectionOnMouseMove","addEventOptions","passive","getEventPoints","viewportPoint","scenePoint","absolutePointer","addListener","syntheticEventConfig","mouse","in","targetIn","targetOut","canvasIn","canvasOut","drag","Canvas","eventHandler","addOrRemove","_getEventPrefix","functor","_eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","removeListeners","_onMouseUp","_onTouchEnd","__onMouseWheel","shared","nestedTarget","_isClick","_dragSource","_onDragProgress","_renderDragEffects","dropTarget","_dropTarget","didDrop","dataTransfer","dropEffect","dragSource","_draggedoverTarget","findDragTargets","eventType","_fireEnterLeaveEvents","_basicEventHandler","_cacheTransformEventData","_handleEvent","getPointerId","evt","identifier","pointerId","_isMainEvent","isPrimary","touches","mainTouchId","__onMouseDown","__onMouseUp","_willAddMouseDown","clearTimeout","__onMouseMove","_shouldRender","_this$_activeObject","isClick","_target","button","_onMouseUpInDrawingMode","shouldRender","targetWasActive","handleSelection","found","originalControl","originalMouseUpHandler","_setCursorFromEvent","currentTarget","currentSubTargets","_onMouseDownInDrawingMode","onMouseDown","_onMouseMoveInDrawingMode","onMouseUp","grouped","handleMultiSelection","groupSelector","_transformObject","_fireOverOutEvents","textEditingManager","fireSyntheticInOutEvents","oldTarget","fireCanvas","draggedoverTarget","targetChanged","outOpt","nextTarget","inOpt","previousTarget","localPointer","_performTransformAction","activeSelection","reverse","isAS","prevActiveObjects","multiSelectAdd","newActiveSelection","point1","point2","collectedObjects","klass","linearDefaultCoords","radialDefaultCoords","ifNaN","valueIfNaN","RE_PERCENT","isPercent","parsePercent","NaN","RE_KEY_VALUE_PAIRS","RE_KEY_VALUE","parseColorStop","keyValuePairs","parseColorStops","opacityAttr","colorStops","colorStopEls","getElementsByTagName","parseType","parseGradientUnits","getValue","parseCoords","valuesToConvert","finalValue","propValue","convertPercentUnitsToValues","parseLinearCoords","parseRadialCoords","Gradient","addColorStop","colorStop","preTransform","sort","_renderPathCommands","needsSwap","minRadius","percentageShift","gradient","createLinearGradient","createRadialGradient","svgOptions","viewBoxWidth","viewBoxHeight","Pattern","isImageSource","isCanvasSource","sourceToString","complete","naturalWidth","naturalHeight","patternSource","patternOffsetX","patternOffsetY","patternWidth","patternHeight","BaseBrush","_saveAndTransform","needsFullRender","_resetShadow","_isOutSideCanvas","Path","_setPath","adjustPosition","setBoundingBox","_calcBoundsFromPath","quadraticCurveTo","pathCmd","sourcePath","_getOffsetTransform","digits","_calcDimensions","subpathStartX","subpathStartY","parsedAttributes","PencilBrush","_points","_hasStraightLine","drawSegment","drawStraightLine","straightLineKey","_prepareForDrawing","_addPoint","limitedToCanvasSize","oldEnd","_finalizeAndAddPath","_reset","convertPointsToSVGPath","createPath","decimatePoints","cDistance","lastPoint","adjustedDistance","newPoints","decimate","isEmptySVGPath","CIRCLE_PROPS","Circle","setRadius","startAngle","endAngle","getRadiusX","getRadiusY","startX","startY","endX","endY","largeFlag","sweepFlag","CircleBrush","drawDot","addPoint","dot","originalRenderOnAddRemove","circles","circle","pointerPoint","SprayBrush","sprayChunks","sprayChunk","addSprayChunk","renderChunck","rects","chunck","rect","optimizeOverlapping","uniqueRects","uniqueRectsArray","getUniqueRects","sprayChunck","density","dotWidthVariance","dotWidth","randomOpacity","PatternBrush","getPatternSrc","patternCanvas","patternCtx","getPattern","pattern","topLeft","coordProps","Line","_setWidthHeight","calcLinePoints","origStrokeStyle","_this$stroke","_x1","_x2","_y1","_y2","xMult","yMult","Triangle","widthBy2","heightBy2","ELLIPSE_PROPS","Ellipse","getRx","getRy","parsePointsAttribute","pointsSplit","parsedPoints","polylineDefaultValues","exactBoundingBox","Polyline","initialized","isOpen","_projectStrokeOnPoints","strokeDiff","bboxNoStroke","layoutProperties","_options$width","_options$height","_options$width2","_options$height2","output","diffX","diffY","Polygon","fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","textDefaultValues","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER","StyledText","isEmptyStyles","lineIndex","line","p3","styleHas","cleanStyle","letterCount","stylePropertyValue","stylesCount","allStyleObjectPropertiesMatch","graphemeCount","styleObject","_textLines","removeStyle","lineNum","charNum","_extendStyles","get2DCursorLocation","_getLineStyle","_setLineStyle","newStyle","_getStyleDeclaration","_setStyleDeclaration","getSelectionStyles","startIndex","endIndex","getStyleAtPosition","getCompleteStyleDeclaration","setSelectionStyles","_forceClearCache","_lineStyle$charIndex","lineStyle","_styleProperties","_deleteStyleDeclaration","_deleteLineStyle","multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","svgColor","createSVGRect","measuringContext","FabricText","setPathInfo","initDimensions","segmentsInfo","_splitText","newLines","_splitTextIntoLines","lines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","calcTextHeight","enlargeSpaces","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","charBound","spaces","isEndOfWrapping","getLineWidth","__charBounds","kernedWidth","missingNewlineOffset","_lineIndex","selectionStart","skipWrapping","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","leftOffset","_getLeftOffset","lineTopOffset","_getTopOffset","heightOfLine","lineLeftOffset","_getLineLeftOffset","drawStart","currentColor","boxWidth","boxStart","lastColor","getValueOfPropertyAt","charBox","renderLeft","_measureChar","_char","previousChar","prevCharStyle","fontDeclaration","couple","stylesAreEqual","fontMultiplier","coupleWidth","previousWidth","getMeasuringContext","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","prevGrapheme","graphemeInfo","llength","lineBounds","grapheme","_getGraphemeBox","positionInPath","totalPathLength","_setGraphemeOnPath","numOfSpaces","centerPosition","skipLeft","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","isJustify","shortCut","isLtr","currentDirection","actualStyle","nextStyle","timeToRender","drawingLeft","charsToRender","_renderChar","_applyPatternGradientTransformText","handleFiller","fullDecl","shouldFill","fillOffsets","fillText","strokeOffsets","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","lineDiff","__lineWidths","_charStyle$property","topOffset","currentDecoration","currentFill","lastDecoration","lastFill","currentSize","currentDy","parsedFontFamily","genericFonts","newLine","newText","needsDims","isAddingPath","_options$parsedAttrib","textAnchor","textDecoration","restOfOptions","textContent","textHeightScaleFactor","scaledDiff","textHeight","offX","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textBgRects","textSpans","getSvgTextDecoration","textTopOffset","textLeftOffset","lineOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","fillStyles","dySpan","_getSVGLineTopOffset","lastHeight","useWhiteSpace","decoration","DraggableTextDelegate","dragEnterHandler","dragOverHandler","dragLeaveHandler","dragEndHandler","dropHandler","_dispose","isPointerOverSelection","newSelection","getSelectionStartFromPointer","selectionEnd","__mouseDownInPlace","isActive","__dragStartFired","setCursorByClick","initDelayedCursor","__isDraggingOver","getDragStartSelection","__dragStartSelection","setDragImage","_e$dataTransfer","flipFactor","boundaries","_getCursorBoundaries","diff","bgc","dragImage","border","__dragImageDisposer","appendChild","setData","stringify","effectAllowed","abortCursorAnimation","editable","defaultPrevented","dragStartSelection","targetCanDrop","ev","_e$dataTransfer2","insert","getData","trailing","selectionStartOffset","removeChars","trimEnd","insertChars","enterEditing","_updateTextarea","_e$dataTransfer3","reNonWord","ITextBehavior","initBehavior","_tick","_onTickComplete","_animateCursor","toValue","_currentCursorOpacity","renderCursorOrSelection","_currentTickState","cursorDuration","_this$_currentTickCom","_currentTickCompleteState","restart","cursorDelay","shouldClear","cursorAnimation","restartCursorIfNeeded","selectAll","_fireSelectionChanged","getSelectedText","findWordBoundaryLeft","startFrom","_reSpace","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","selectWord","newSelectionStart","newSelectionEnd","selectLine","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","activeElement","currentStart","currentEnd","__selectionStartOnMouseDown","editingBorderColor","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","fromGraphemeToStringSelection","cursorOffsetCache","inCompositionMode","updateTextareaPosition","updateFromTextArea","textarea","_calcTextareaPosition","desiredPosition","compositionStart","cursorLocation","charHeight","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","_exitEditing","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","styleObj","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","_selectionDirection","ITextKeyBehavior","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","hiddenTextareaContainer","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","onKeyDown","keyMap","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","updateAndFire","nextText","charCount","nextCharCount","removedText","removeFrom","removeTo","charDiff","textareaSelection","backDelete","copiedText","disableStyleCopyPaste","copiedTextStyle","onCompositionStart","onCompositionEnd","onCompositionUpdate","compositionEnd","_getWidthBeforeCursor","bound","widthBeforeCursor","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","getUpCursorOffset","textBeforeCursor","charWidth","foundMatch","widthOfCharsOnLine","indexOnLine","leftEdge","rightEdge","offsetFromLeftEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","newValue","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","moveCursorRightWithShift","moveCursorRightWithoutShift","notALeftClick","ITextClickBehavior","_mouseDownHandler","_mouseDownHandlerBefore","doubleClickHandler","tripleClickHandler","__lastClickTime","__lastLastClickTime","__lastPointer","draggableTextDelegate","__newClickTime","newPointer","isTripleClick","__lastSelected","didDrag","mouseOffset","charLength","widthAfter","MOVE_CURSOR_UP","MOVE_CURSOR_DOWN","MOVE_CURSOR_LEFT","MOVE_CURSOR_RIGHT","EXIT_EDITING","iTextDefaultValues","cursorColor","caching","IText","setSelectionStart","_updateAndFire","setSelectionEnd","renderCursor","renderSelection","skipCaching","_getCursorBoundariesOffsets","__getCursorBoundariesOffsets","renderCursorAt","_renderCursor","_renderSelection","dragSelection","startLine","endLine","startChar","endChar","realLineHeight","boxEnd","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","cursorPosition","Textbox","dynamicMinWidth","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","splitByGrapheme","isWrapping","nextOffset","nextLineIndex","shouldLimit","mapNextLine","p2Number","_wrapText","desiredWidth","getGraphemeDataForRender","wrapped","wordsData","_wrapLine","infix","largestWordWidth","wordsOrGraphemes","wordSplit","word","graphemeArray","_measureWord","charOffset","_wordJoiners","reservedSpace","additionalSpace","infixWidth","lineJustStarted","wordWidth","getMinWidth","minWidth","linesToKeep","propNumber","ClipPathLayout","clipPathCenter","FixedLayout","ActiveSelectionLayoutManager","parents","Set","selectedObjects","ActiveSelection","multiSelectionStacking","findIndex","groups","childrenOverride","Canvas2dFilterBackend","applyFilters","filters","sourceElement","sourceWidth","sourceHeight","pipelineState","imageData","originalEl","originalImageData","filterBackend","applyTo","imageDataPostFilter","putImageData","WebGLFilterBackend","tileSize","Float32Array","setupGLContext","captureGPUInfo","createWebGLCanvas","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","destinationWidth","destinationHeight","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","aPosition","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","dWidth","dHeight","resizeCanvasIfNeeded","copyGLTo2D","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","NEAREST","RGBA","UNSIGNED_BYTE","CLAMP_TO_EDGE","TEXTURE_MAG_FILTER","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","texture","texParameteri","texImage2D","uniqueId","evictCachesForKey","glCanvas","sourceY","copyGLTo2DPutImageData","numBytes","u8","Uint8Array","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","imgData","ImageData","gpuInfo","renderer","vendor","ext","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","initFilterBackend","enableGLFiltering","getFilterBackend","setFilterBackend","backend","IMAGE_PROPS","FabricImage","setElement","_element","removeTexture","_originalElement","CSS_CANVAS","resizeFilter","applyResizeFilters","elementKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","imageMarkup","strokeSvg","imageRendering","imageSmoothing","getSvgSrc","origFill","filtered","srcFromAttribute","setSrc","minimumScale","minimumScaleTrigger","elementToFilter","_filteredEl","_filterScalingX","_filterScalingY","_lastScaleX","_lastScaleY","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","pAR","preserveAspectRatio","pWidth","pHeight","rWidth","rHeight","f","rf","hydratedProps","fromURL","imageOptions","applyViewboxTransform","viewBoxAttr","widthAttr","heightAttr","missingViewBox","missingDimAttr","translateMatrix","widthDiff","heightDiff","parsedDim","pasedViewBox","createElementNS","firstChild","getTagName","node","tagName","svgInvalidAncestorsRegEx","getMultipleNodes","nodeNames","nodeList","nodeArray","getElementsByTagNameNS","gradientsAttrs","xlinkAttr","recursivelyParseGradientsXlink","_gradient$getAttribut","xLink","referencedGradient","children","referenceClone","cloneNode","tagArray","getCSSRules","allRules","styleContents","ruleObj","propertyValuePairs","pair","_rule","findTag","ElementsParser","clipPaths","regexUrl","gradientDefs","elList","getGradientDefs","createObject","resolveGradient","resolveClipPath","extractPropertyDefinition","storage","gradientDef","usingElement","clipPathElements","objTransformInv","clipPathTag","clipPathOwner","clipPathElement","enlivedClippath","clipRule","gTransform","isValidSvgTag","createEmptyResponse","allElements","async","parseSVGDocument","nodelist","skipAttributes","useElement","useAttributes","useAttrMap","xlink","href","referencedElement","clonedOriginal","originalAttributes","originalAttrMap","currentTrans","el3","setAttributeNS","childNodes","styleRecord","mergedStyles","entry","parseUseDirectives","descendants","hasInvalidAncestor","localClipPaths","elementParser","loadSVGFromString","parseFromString","loadSVGFromURL","xml","responseXML","parsedDoc","ACTION_NAME","createPolyPositionHandler","pointIndex","polyObject","polyActionHandler","poly","mouseLocalPosition","factoryPolyActionHandler","anchorPoint","anchorPointInParentPlane","createPolyActionHandler","calcPathPointPosition","pathObject","commandIndex","pathPositionHandler","pathActionHandler","movePathPoint","anchorCommand","PathPointControl","controlFill","controlStroke","PathControlPointControl","connectToCommandIndex","connectToPointIndex","connectionDashArray","commandType","createControl","commandIndexPos","pointIndexPos","isControlPoint","controlPointStyle","pointStyle","previousCommandType","indexFromPrevCommand","isWebGLPipelineState","isPutImageFaster","testContext","ArrayBuffer","testPipelineState","performance","now","drawImageTime","highPsourceCode","identityFragmentShader","BaseFilter","getFragmentSource","getVertexSource","createProgram","vertexSource","vertexShader","VERTEX_SHADER","program","getShaderInfoLog","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","attributeLocations","getAttributeLocations","getAttribLocation","locations","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","finish","_swapTextures","temp","applyToWebGL","applyTo2d","getCacheKey","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","_gl","_uniformLocations","createHelpLayer","helpLayer","defaultKeys","blendColorFragmentSource","screen","difference","lighten","darken","exclusion","tint","BlendColor","mode","tg","alpha1","uniform4fv","uColor","mask","BlendImage","image","TEXTURE1","calculateMatrix","resources","blendImage","canvas1","blendData","uniform1i","uImage","uniformMatrix3fv","uTransformMatrix","filterOptions","enlivedImage","Blur","aspectRatio","horizontal","simpleBlur","blurLayer1","blurLayer2","canvas2","ctx1","ctx2","nSamples","percent","newImageData","delta","chooseRightDelta","uniform2fv","uDelta","blurScale","Brightness","brightness","uBrightness","ColorMatrix","colorsOnly","constants","uniformMatrix4fv","uColorMatrix","uConstants","createColorMatrixFilter","_Class","newClass","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","Composed","subFilters","enlivedFilters","Contrast","contrast","contrastF","uContrast","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","Convolute","opaque","weights","side","halfSide","sw","sh","createImageData","dst","alphaFac","dstOff","scx","scy","srcOff","wt","uniform1fv","uMatrix","GAMMA","Gamma","gamma","rInv","gInv","bInv","rgbValues","rgb","uniform3fv","uGamma","lightness","luminosity","Grayscale","uMode","HueRotation","rotation","cosine","sine","aThird","aThirdSqtSin","OneMinusCos","Invert","invert","uInvert","uAlpha","Noise","noise","rand","uNoise","uSeed","Pixelate","blocksize","_i","_j","uBlocksize","RemoveColor","lowC","highC","uLow","uHigh","useAlpha","Resize","uTaps","taps","getFilterWindow","tempScale","lanczosLobes","filterWindow","generateShader","getTaps","lobeFunction","lanczosCreate","applyToForWebgl","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","oW","oH","newData","resizeType","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","mult","doneW","doneH","stepW","stepH","dX","dY","tmpCanvas","srcData","destImg","destData","lanczos","ratioX","ratioY","rcpRatioX","rcpRatioY","range2X","range2Y","cacheLanc","icenter","process","u","weight","fX","fY","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","yy","w0","Saturation","adjust","saturation","uSaturation","Vibrance","vibrance","amt","uVibrance"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs new file mode 100644 index 00000000000..a974d7fb8f8 --- /dev/null +++ b/dist/index.mjs @@ -0,0 +1,27954 @@ +function _defineProperty(e, r, t) { + return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[r] = t, e; +} +function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; +} +function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; +} +function _objectWithoutProperties(e, t) { + if (null == e) return {}; + var o, + r, + i = _objectWithoutPropertiesLoose(e, t); + if (Object.getOwnPropertySymbols) { + var n = Object.getOwnPropertySymbols(e); + for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); + } + return i; +} +function _objectWithoutPropertiesLoose(r, e) { + if (null == r) return {}; + var t = {}; + for (var n in r) if ({}.hasOwnProperty.call(r, n)) { + if (e.indexOf(n) >= 0) continue; + t[n] = r[n]; + } + return t; +} +function _taggedTemplateLiteral(e, t) { + return t || (t = e.slice(0)), Object.freeze(Object.defineProperties(e, { + raw: { + value: Object.freeze(t) + } + })); +} +function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); +} +function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; +} + +class BaseConfiguration { + constructor() { + /** + * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, + * which is unitless and not rendered equally across browsers. + * + * Values that work quite well (as of October 2017) are: + * - Chrome: 1.5 + * - Edge: 1.75 + * - Firefox: 0.9 + * - Safari: 0.95 + * + * @since 2.0.0 + * @type Number + * @default 1 + */ + _defineProperty(this, "browserShadowBlurConstant", 1); + /** + * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. + */ + _defineProperty(this, "DPI", 96); + /** + * Device Pixel Ratio + * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html + */ + _defineProperty(this, "devicePixelRatio", typeof window !== 'undefined' ? window.devicePixelRatio : 1); + // eslint-disable-line no-restricted-globals + /** + * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "perfLimitSizeTotal", 2097152); + /** + * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "maxCacheSideLimit", 4096); + /** + * Lowest pixel limit for cache canvases, set at 256PX + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "minCacheSideLimit", 256); + /** + * When 'true', style information is not retained when copy/pasting text, making + * pasted text use destination style. + * Defaults to 'false'. + * @type Boolean + * @default + * @deprecated + */ + _defineProperty(this, "disableStyleCopyPaste", false); + /** + * Enable webgl for filtering picture is available + * A filtering backend will be initialized, this will both take memory and + * time since a default 2048x2048 canvas will be created for the gl context + * @since 2.0.0 + * @type Boolean + * @default + */ + _defineProperty(this, "enableGLFiltering", true); + /** + * if webgl is enabled and available, textureSize will determine the size + * of the canvas backend + * + * In order to support old hardware set to `2048` to avoid OOM + * + * @since 2.0.0 + * @type Number + * @default + */ + _defineProperty(this, "textureSize", 4096); + /** + * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on + * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true + * this has to be set before instantiating the filtering backend ( before filtering the first image ) + * @type Boolean + * @default false + */ + _defineProperty(this, "forceGLPutImageData", false); + /** + * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better + * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from + * the curve is very hard to hit any cache. + * Enable only if you know why it could be useful. + * Candidate for removal/simplification + * @default false + */ + _defineProperty(this, "cachesBoundsOfCurve", false); + /** + * Map of font files + * Map of font files + */ + _defineProperty(this, "fontPaths", {}); + /** + * Defines the number of fraction digits to use when serializing object values. + * Used in exporting methods (`toObject`, `toJSON`, `toSVG`) + * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. + */ + _defineProperty(this, "NUM_FRACTION_DIGITS", 4); + } +} +class Configuration extends BaseConfiguration { + constructor(config) { + super(); + this.configure(config); + } + configure() { + let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + Object.assign(this, config); + } + + /** + * Map of font files + */ + addFonts() { + let paths = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.fontPaths = _objectSpread2(_objectSpread2({}, this.fontPaths), paths); + } + removeFonts() { + let fontFamilys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + fontFamilys.forEach(fontFamily => { + delete this.fontPaths[fontFamily]; + }); + } + clearFonts() { + this.fontPaths = {}; + } + restoreDefaults(keys) { + const defaults = new BaseConfiguration(); + const config = (keys === null || keys === void 0 ? void 0 : keys.reduce((acc, key) => { + acc[key] = defaults[key]; + return acc; + }, {})) || defaults; + this.configure(config); + } +} +const config = new Configuration(); + +const log = function (severity) { + for (var _len = arguments.length, optionalParams = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + optionalParams[_key - 1] = arguments[_key]; + } + return ( + // eslint-disable-next-line no-restricted-syntax + console[severity]('fabric', ...optionalParams) + ); +}; +class FabricError extends Error { + constructor(message, options) { + super("fabric: ".concat(message), options); + } +} +class SignalAbortedError extends FabricError { + constructor(context) { + super("".concat(context, " 'options.signal' is in 'aborted' state")); + } +} + +class GLProbe {} + +/** + * Lazy initialize WebGL constants + */ +class WebGLProbe extends GLProbe { + /** + * Tests if webgl supports certain precision + * @param {WebGL} Canvas WebGL context to test on + * @param {GLPrecision} Precision to test can be any of following + * @returns {Boolean} Whether the user's browser WebGL supports given precision. + */ + testPrecision(gl, precision) { + const fragmentSource = "precision ".concat(precision, " float;\nvoid main(){}"); + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + if (!fragmentShader) { + return false; + } + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS); + } + + /** + * query browser for WebGL + */ + queryWebGL(canvas) { + const gl = canvas.getContext('webgl'); + if (gl) { + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.GLPrecision = ['highp', 'mediump', 'lowp'].find(precision => this.testPrecision(gl, precision)); + gl.getExtension('WEBGL_lose_context').loseContext(); + log('log', "WebGL: max texture size ".concat(this.maxTextureSize)); + } + } + isSupported(textureSize) { + return !!this.maxTextureSize && this.maxTextureSize >= textureSize; + } +} + +/* eslint-disable no-restricted-globals */ +const copyPasteData = {}; +const getEnv$1 = () => { + return { + document, + window, + isTouchSupported: 'ontouchstart' in window || 'ontouchstart' in document || window && window.navigator && window.navigator.maxTouchPoints > 0, + WebGLProbe: new WebGLProbe(), + dispose() { + // noop + }, + copyPasteData + }; +}; + +/** + * This file is consumed by fabric. + * The `./node` and `./browser` files define the env variable that is used by this module. + * The `./browser` module is defined to be the default env and doesn't set the env at all. + * This is done in order to support isomorphic usage for browser and node applications + * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env. + */ + +let env; + +/** + * Sets the environment variables used by fabric.\ + * This is exposed for special cases, such as configuring a test environment, and should be used with care. + * + * **CAUTION**: Must be called before using the package. + * + * @example + * Passing `window` and `document` objects to fabric (in case they are mocked or something) + * import { getEnv, setEnv } from 'fabric'; + * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in. + * setEnv({ ...getEnv(), window, document }); + * // done with setup, using fabric is now safe + */ +const setEnv = value => { + env = value; +}; + +/** + * In order to support SSR we **MUST** access the browser env only after the window has loaded + */ +const getEnv = () => env || (env = getEnv$1()); +const getFabricDocument = () => getEnv().document; +const getFabricWindow = () => getEnv().window; + +/** + * @returns the config value if defined, fallbacks to the environment value + */ +const getDevicePixelRatio = () => { + var _config$devicePixelRa; + return Math.max((_config$devicePixelRa = config.devicePixelRatio) !== null && _config$devicePixelRa !== void 0 ? _config$devicePixelRa : getFabricWindow().devicePixelRatio, 1); +}; + +class Cache { + constructor() { + /** + * Cache of widths of chars in text rendering. + */ + _defineProperty(this, "charWidthsCache", {}); + /** + * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it. + * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing + * you do not get any speed benefit and you get a big object in memory. + * The object was a private variable before, while now is appended to the lib so that you have access to it and you + * can eventually clear it. + * It was an internal variable, is accessible since version 2.3.4 + */ + _defineProperty(this, "boundsOfCurveCache", {}); + } + /** + * @return {Object} reference to cache + */ + getFontCache(_ref) { + let { + fontFamily, + fontStyle, + fontWeight + } = _ref; + fontFamily = fontFamily.toLowerCase(); + if (!this.charWidthsCache[fontFamily]) { + this.charWidthsCache[fontFamily] = {}; + } + const fontCache = this.charWidthsCache[fontFamily]; + const cacheKey = "".concat(fontStyle.toLowerCase(), "_").concat((fontWeight + '').toLowerCase()); + if (!fontCache[cacheKey]) { + fontCache[cacheKey] = {}; + } + return fontCache[cacheKey]; + } + + /** + * Clear char widths cache for the given font family or all the cache if no + * fontFamily is specified. + * Use it if you know you are loading fonts in a lazy way and you are not waiting + * for custom fonts to load properly when adding text objects to the canvas. + * If a text object is added when its own font is not loaded yet, you will get wrong + * measurement and so wrong bounding boxes. + * After the font cache is cleared, either change the textObject text content or call + * initDimensions() to trigger a recalculation + * @param {String} [fontFamily] font family to clear + */ + clearFontCache(fontFamily) { + fontFamily = (fontFamily || '').toLowerCase(); + if (!fontFamily) { + this.charWidthsCache = {}; + } else if (this.charWidthsCache[fontFamily]) { + delete this.charWidthsCache[fontFamily]; + } + } + + /** + * Given current aspect ratio, determines the max width and height that can + * respect the total allowed area for the cache. + * @param {number} ar aspect ratio + * @return {number[]} Limited dimensions X and Y + */ + limitDimsByArea(ar) { + const { + perfLimitSizeTotal + } = config; + const roughWidth = Math.sqrt(perfLimitSizeTotal * ar); + // we are not returning a point on purpose, to avoid circular dependencies + // this is an internal utility + return [Math.floor(roughWidth), Math.floor(perfLimitSizeTotal / roughWidth)]; + } +} +const cache = new Cache(); + +var version = "6.4.2"; + +// use this syntax so babel plugin see this import here +const VERSION = version; +// eslint-disable-next-line @typescript-eslint/no-empty-function +function noop() {} +const halfPI = Math.PI / 2; +const twoMathPi = Math.PI * 2; +const PiBy180 = Math.PI / 180; +const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]); +const DEFAULT_SVG_FONT_SIZE = 16; +const ALIASING_LIMIT = 2; + +/* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */ +const kRect = 1 - 0.5522847498; +const CENTER = 'center'; +const LEFT = 'left'; +const TOP = 'top'; +const BOTTOM = 'bottom'; +const RIGHT = 'right'; +const NONE = 'none'; +const reNewline = /\r?\n/; +const MOVING = 'moving'; +const SCALING = 'scaling'; +const ROTATING = 'rotating'; +const ROTATE = 'rotate'; +const SKEWING = 'skewing'; +const RESIZING = 'resizing'; +const MODIFY_POLY = 'modifyPoly'; +const MODIFY_PATH = 'modifyPath'; +const CHANGED = 'changed'; +const SCALE = 'scale'; +const SCALE_X = 'scaleX'; +const SCALE_Y = 'scaleY'; +const SKEW_X = 'skewX'; +const SKEW_Y = 'skewY'; +const FILL = 'fill'; +const STROKE = 'stroke'; +const MODIFIED = 'modified'; + +/* + * This Map connects the objects type value with their + * class implementation. It used from any object to understand which are + * the classes to enlive when requesting a object.type = 'path' for example. + * Objects uses it for clipPath, Canvas uses it for everything. + * This is necessary for generic code to run and enlive instances from serialized representation. + * You can customize which classes get enlived from SVG parsing using this classRegistry. + * The Registry start empty and gets filled in depending which files you import. + * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from + * different sources you will need to import all fabric because you may need all classes. + */ + +const JSON$1 = 'json'; +const SVG = 'svg'; +class ClassRegistry { + constructor() { + this[JSON$1] = new Map(); + this[SVG] = new Map(); + } + has(classType) { + return this[JSON$1].has(classType); + } + getClass(classType) { + const constructor = this[JSON$1].get(classType); + if (!constructor) { + throw new FabricError("No class registered for ".concat(classType)); + } + return constructor; + } + setClass(classConstructor, classType) { + if (classType) { + this[JSON$1].set(classType, classConstructor); + } else { + this[JSON$1].set(classConstructor.type, classConstructor); + // legacy + // @TODO: needs to be removed in fabric 7 or 8 + this[JSON$1].set(classConstructor.type.toLowerCase(), classConstructor); + } + } + getSVGClass(SVGTagName) { + return this[SVG].get(SVGTagName); + } + setSVGClass(classConstructor, SVGTagName) { + this[SVG].set(SVGTagName !== null && SVGTagName !== void 0 ? SVGTagName : classConstructor.type.toLowerCase(), classConstructor); + } +} +const classRegistry = new ClassRegistry(); + +/** + * Array holding all running animations + */ +class AnimationRegistry extends Array { + /** + * Remove a single animation using an animation context + * @param {AnimationBase} context + */ + remove(context) { + const index = this.indexOf(context); + index > -1 && this.splice(index, 1); + } + + /** + * Cancel all running animations on the next frame + */ + cancelAll() { + const animations = this.splice(0); + animations.forEach(animation => animation.abort()); + return animations; + } + + /** + * Cancel all running animations attached to a canvas on the next frame + * @param {StaticCanvas} canvas + */ + cancelByCanvas(canvas) { + if (!canvas) { + return []; + } + const animations = this.filter(animation => { + var _animation$target; + return animation.target === canvas || typeof animation.target === 'object' && ((_animation$target = animation.target) === null || _animation$target === void 0 ? void 0 : _animation$target.canvas) === canvas; + }); + animations.forEach(animation => animation.abort()); + return animations; + } + + /** + * Cancel all running animations for target on the next frame + * @param target + */ + cancelByTarget(target) { + if (!target) { + return []; + } + const animations = this.filter(animation => animation.target === target); + animations.forEach(animation => animation.abort()); + return animations; + } +} +const runningAnimations = new AnimationRegistry(); + +/** + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} + * @see {@link http://fabricjs.com/events|Events demo} + */ +class Observable { + constructor() { + _defineProperty(this, "__eventListeners", {}); + } + /** + * Observes specified event + * @alias on + * @param {string} eventName Event name (eg. 'after:render') + * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function that receives a notification when an event of the specified type occurs + * @return {Function} disposer + */ + on(arg0, handler) { + if (!this.__eventListeners) { + this.__eventListeners = {}; + } + if (typeof arg0 === 'object') { + // one object with key/value pairs was passed + Object.entries(arg0).forEach(_ref => { + let [eventName, handler] = _ref; + this.on(eventName, handler); + }); + return () => this.off(arg0); + } else if (handler) { + const eventName = arg0; + if (!this.__eventListeners[eventName]) { + this.__eventListeners[eventName] = []; + } + this.__eventListeners[eventName].push(handler); + return () => this.off(eventName, handler); + } else { + // noop + return () => false; + } + } + + /** + * Observes specified event **once** + * @alias once + * @param {string} eventName Event name (eg. 'after:render') + * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function that receives a notification when an event of the specified type occurs + * @return {Function} disposer + */ + + once(arg0, handler) { + if (typeof arg0 === 'object') { + // one object with key/value pairs was passed + const disposers = []; + Object.entries(arg0).forEach(_ref2 => { + let [eventName, handler] = _ref2; + disposers.push(this.once(eventName, handler)); + }); + return () => disposers.forEach(d => d()); + } else if (handler) { + const disposer = this.on(arg0, function onceHandler() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + handler.call(this, ...args); + disposer(); + }); + return disposer; + } else { + // noop + return () => false; + } + } + + /** + * @private + * @param {string} eventName + * @param {Function} [handler] + */ + _removeEventListener(eventName, handler) { + if (!this.__eventListeners[eventName]) { + return; + } + if (handler) { + const eventListener = this.__eventListeners[eventName]; + const index = eventListener.indexOf(handler); + index > -1 && eventListener.splice(index, 1); + } else { + this.__eventListeners[eventName] = []; + } + } + + /** + * Unsubscribe all event listeners for eventname. + * Do not use this pattern. You could kill internal fabricJS events. + * We know we should have protected events for internal flows, but we don't have yet + * @deprecated + * @param {string} eventName event name (eg. 'after:render') + */ + + /** + * unsubscribe an event listener + * @param {string} eventName event name (eg. 'after:render') + * @param {TEventCallback} handler event listener to unsubscribe + */ + + /** + * unsubscribe event listeners + * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + */ + + /** + * unsubscribe all event listeners + */ + + off(arg0, handler) { + if (!this.__eventListeners) { + return; + } + + // remove all key/value pairs (event name -> event handler) + if (typeof arg0 === 'undefined') { + for (const eventName in this.__eventListeners) { + this._removeEventListener(eventName); + } + } + // one object with key/value pairs was passed + else if (typeof arg0 === 'object') { + Object.entries(arg0).forEach(_ref3 => { + let [eventName, handler] = _ref3; + this._removeEventListener(eventName, handler); + }); + } else { + this._removeEventListener(arg0, handler); + } + } + + /** + * Fires event with an optional options object + * @param {String} eventName Event name to fire + * @param {Object} [options] Options object + */ + fire(eventName, options) { + var _this$__eventListener; + if (!this.__eventListeners) { + return; + } + const listenersForEvent = (_this$__eventListener = this.__eventListeners[eventName]) === null || _this$__eventListener === void 0 ? void 0 : _this$__eventListener.concat(); + if (listenersForEvent) { + for (let i = 0; i < listenersForEvent.length; i++) { + listenersForEvent[i].call(this, options || {}); + } + } + } +} + +/** + * Removes value from an array. + * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` + * @param {Array} array + * @param {*} value + * @return {Array} original array + */ +const removeFromArray = (array, value) => { + const idx = array.indexOf(value); + if (idx !== -1) { + array.splice(idx, 1); + } + return array; +}; + +/** + * Calculate the cos of an angle, avoiding returning floats for known results + * This function is here just to avoid getting 0.999999999999999 when dealing + * with numbers that are really 1 or 0. + * @param {TRadian} angle the angle + * @return {Number} the cosin value for angle. + */ +const cos = angle => { + if (angle === 0) { + return 1; + } + const angleSlice = Math.abs(angle) / halfPI; + switch (angleSlice) { + case 1: + case 3: + return 0; + case 2: + return -1; + } + return Math.cos(angle); +}; + +/** + * Calculate the cos of an angle, avoiding returning floats for known results + * This function is here just to avoid getting 0.999999999999999 when dealing + * with numbers that are really 1 or 0. + * @param {TRadian} angle the angle + * @return {Number} the sin value for angle. + */ +const sin = angle => { + if (angle === 0) { + return 0; + } + const angleSlice = angle / halfPI; + const value = Math.sign(angle); + switch (angleSlice) { + case 1: + return value; + case 2: + return 0; + case 3: + return -value; + } + return Math.sin(angle); +}; + +/** + * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com) + */ +class Point { + constructor() { + let arg0 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + if (typeof arg0 === 'object') { + this.x = arg0.x; + this.y = arg0.y; + } else { + this.x = arg0; + this.y = y; + } + } + + /** + * Adds another point to this one and returns another one + * @param {XY} that + * @return {Point} new Point instance with added values + */ + add(that) { + return new Point(this.x + that.x, this.y + that.y); + } + + /** + * Adds another point to this one + * @param {XY} that + * @return {Point} thisArg + * @chainable + * @deprecated + */ + addEquals(that) { + this.x += that.x; + this.y += that.y; + return this; + } + + /** + * Adds value to this point and returns a new one + * @param {Number} scalar + * @return {Point} new Point with added value + */ + scalarAdd(scalar) { + return new Point(this.x + scalar, this.y + scalar); + } + + /** + * Adds value to this point + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarAddEquals(scalar) { + this.x += scalar; + this.y += scalar; + return this; + } + + /** + * Subtracts another point from this point and returns a new one + * @param {XY} that + * @return {Point} new Point object with subtracted values + */ + subtract(that) { + return new Point(this.x - that.x, this.y - that.y); + } + + /** + * Subtracts another point from this point + * @param {XY} that + * @return {Point} thisArg + * @chainable + * @deprecated + */ + subtractEquals(that) { + this.x -= that.x; + this.y -= that.y; + return this; + } + + /** + * Subtracts value from this point and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarSubtract(scalar) { + return new Point(this.x - scalar, this.y - scalar); + } + + /** + * Subtracts value from this point + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarSubtractEquals(scalar) { + this.x -= scalar; + this.y -= scalar; + return this; + } + + /** + * Multiplies this point by another value and returns a new one + * @param {XY} that + * @return {Point} + */ + multiply(that) { + return new Point(this.x * that.x, this.y * that.y); + } + + /** + * Multiplies this point by a value and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarMultiply(scalar) { + return new Point(this.x * scalar, this.y * scalar); + } + + /** + * Multiplies this point by a value + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarMultiplyEquals(scalar) { + this.x *= scalar; + this.y *= scalar; + return this; + } + + /** + * Divides this point by another and returns a new one + * @param {XY} that + * @return {Point} + */ + divide(that) { + return new Point(this.x / that.x, this.y / that.y); + } + + /** + * Divides this point by a value and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarDivide(scalar) { + return new Point(this.x / scalar, this.y / scalar); + } + + /** + * Divides this point by a value + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarDivideEquals(scalar) { + this.x /= scalar; + this.y /= scalar; + return this; + } + + /** + * Returns true if this point is equal to another one + * @param {XY} that + * @return {Boolean} + */ + eq(that) { + return this.x === that.x && this.y === that.y; + } + + /** + * Returns true if this point is less than another one + * @param {XY} that + * @return {Boolean} + */ + lt(that) { + return this.x < that.x && this.y < that.y; + } + + /** + * Returns true if this point is less than or equal to another one + * @param {XY} that + * @return {Boolean} + */ + lte(that) { + return this.x <= that.x && this.y <= that.y; + } + + /** + * Returns true if this point is greater another one + * @param {XY} that + * @return {Boolean} + */ + gt(that) { + return this.x > that.x && this.y > that.y; + } + + /** + * Returns true if this point is greater than or equal to another one + * @param {XY} that + * @return {Boolean} + */ + gte(that) { + return this.x >= that.x && this.y >= that.y; + } + + /** + * Returns new point which is the result of linear interpolation with this one and another one + * @param {XY} that + * @param {Number} t , position of interpolation, between 0 and 1 default 0.5 + * @return {Point} + */ + lerp(that) { + let t = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.5; + t = Math.max(Math.min(1, t), 0); + return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); + } + + /** + * Returns distance from this point and another one + * @param {XY} that + * @return {Number} + */ + distanceFrom(that) { + const dx = this.x - that.x, + dy = this.y - that.y; + return Math.sqrt(dx * dx + dy * dy); + } + + /** + * Returns the point between this point and another one + * @param {XY} that + * @return {Point} + */ + midPointFrom(that) { + return this.lerp(that); + } + + /** + * Returns a new point which is the min of this and another one + * @param {XY} that + * @return {Point} + */ + min(that) { + return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); + } + + /** + * Returns a new point which is the max of this and another one + * @param {XY} that + * @return {Point} + */ + max(that) { + return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); + } + + /** + * Returns string representation of this point + * @return {String} + */ + toString() { + return "".concat(this.x, ",").concat(this.y); + } + + /** + * Sets x/y of this point + * @param {Number} x + * @param {Number} y + * @chainable + */ + setXY(x, y) { + this.x = x; + this.y = y; + return this; + } + + /** + * Sets x of this point + * @param {Number} x + * @chainable + */ + setX(x) { + this.x = x; + return this; + } + + /** + * Sets y of this point + * @param {Number} y + * @chainable + */ + setY(y) { + this.y = y; + return this; + } + + /** + * Sets x/y of this point from another point + * @param {XY} that + * @chainable + */ + setFromPoint(that) { + this.x = that.x; + this.y = that.y; + return this; + } + + /** + * Swaps x/y of this point and another point + * @param {XY} that + */ + swap(that) { + const x = this.x, + y = this.y; + this.x = that.x; + this.y = that.y; + that.x = x; + that.y = y; + } + + /** + * return a cloned instance of the point + * @return {Point} + */ + clone() { + return new Point(this.x, this.y); + } + + /** + * Rotates `point` around `origin` with `radians` + * @static + * @memberOf fabric.util + * @param {XY} origin The origin of the rotation + * @param {TRadian} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ + rotate(radians) { + let origin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ZERO; + // TODO benchmark and verify the add and subtract how much cost + // and then in case early return if no origin is passed + const sinus = sin(radians), + cosinus = cos(radians); + const p = this.subtract(origin); + const rotated = new Point(p.x * cosinus - p.y * sinus, p.x * sinus + p.y * cosinus); + return rotated.add(origin); + } + + /** + * Apply transform t to point p + * @static + * @memberOf fabric.util + * @param {TMat2D} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {Point} The transformed point + */ + transform(t) { + let ignoreOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return new Point(t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]), t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5])); + } +} +const ZERO = new Point(0, 0); + +const isCollection = fabricObject => { + return !!fabricObject && Array.isArray(fabricObject._objects); +}; +function createCollectionMixin(Base) { + class Collection extends Base { + constructor() { + super(...arguments); + /** + * @type {FabricObject[]} + * @TODO needs to end up in the constructor too + */ + _defineProperty(this, "_objects", []); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onObjectAdded(object) { + // subclasses should override this method + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onObjectRemoved(object) { + // subclasses should override this method + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onStackOrderChanged(object) { + // subclasses should override this method + } + + /** + * Adds objects to collection + * Objects should be instances of (or inherit from) FabricObject + * @param {...FabricObject[]} objects to add + * @returns {number} new array length + */ + add() { + for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { + objects[_key] = arguments[_key]; + } + const size = this._objects.push(...objects); + objects.forEach(object => this._onObjectAdded(object)); + return size; + } + + /** + * Inserts an object into collection at specified index + * @param {number} index Index to insert object at + * @param {...FabricObject[]} objects Object(s) to insert + * @returns {number} new array length + */ + insertAt(index) { + for (var _len2 = arguments.length, objects = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + objects[_key2 - 1] = arguments[_key2]; + } + this._objects.splice(index, 0, ...objects); + objects.forEach(object => this._onObjectAdded(object)); + return this._objects.length; + } + + /** + * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * @private + * @param {...FabricObject[]} objects objects to remove + * @returns {FabricObject[]} removed objects + */ + remove() { + const array = this._objects, + removed = []; + for (var _len3 = arguments.length, objects = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + objects[_key3] = arguments[_key3]; + } + objects.forEach(object => { + const index = array.indexOf(object); + // only call onObjectRemoved if an object was actually removed + if (index !== -1) { + array.splice(index, 1); + removed.push(object); + this._onObjectRemoved(object); + } + }); + return removed; + } + + /** + * Executes given function for each object in this group + * A simple shortcut for getObjects().forEach, before es6 was more complicated, + * now is just a shortcut. + * @param {Function} callback + * Callback invoked with current object as first argument, + * index - as second and an array of all objects - as third. + */ + forEachObject(callback) { + this.getObjects().forEach((object, index, objects) => callback(object, index, objects)); + } + + /** + * Returns an array of children objects of this instance + * @param {...String} [types] When specified, only objects of these types are returned + * @return {Array} + */ + getObjects() { + for (var _len4 = arguments.length, types = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + types[_key4] = arguments[_key4]; + } + if (types.length === 0) { + return [...this._objects]; + } + return this._objects.filter(o => o.isType(...types)); + } + + /** + * Returns object at specified index + * @param {Number} index + * @return {Object} object at index + */ + item(index) { + return this._objects[index]; + } + + /** + * Returns true if collection contains no objects + * @return {Boolean} true if collection is empty + */ + isEmpty() { + return this._objects.length === 0; + } + + /** + * Returns a size of a collection (i.e: length of an array containing its objects) + * @return {Number} Collection size + */ + size() { + return this._objects.length; + } + + /** + * Returns true if collection contains an object.\ + * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons** + * instead of `a.contains(b)` use `b.isDescendantOf(a)` + * @param {Object} object Object to check against + * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` + * @return {Boolean} `true` if collection contains an object + */ + contains(object, deep) { + if (this._objects.includes(object)) { + return true; + } else if (deep) { + return this._objects.some(obj => obj instanceof Collection && obj.contains(object, true)); + } + return false; + } + + /** + * Returns number representation of a collection complexity + * @return {Number} complexity + */ + complexity() { + return this._objects.reduce((memo, current) => { + memo += current.complexity ? current.complexity() : 0; + return memo; + }, 0); + } + + /** + * Moves an object or the objects of a multiple selection + * to the bottom of the stack of drawn objects + * @param {fabric.Object} object Object to send to back + * @returns {boolean} true if change occurred + */ + sendObjectToBack(object) { + if (!object || object === this._objects[0]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.unshift(object); + this._onStackOrderChanged(object); + return true; + } + + /** + * Moves an object or the objects of a multiple selection + * to the top of the stack of drawn objects + * @param {fabric.Object} object Object to send + * @returns {boolean} true if change occurred + */ + bringObjectToFront(object) { + if (!object || object === this._objects[this._objects.length - 1]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.push(object); + this._onStackOrderChanged(object); + return true; + } + + /** + * Moves an object or a selection down in stack of drawn objects + * An optional parameter, `intersecting` allows to move the object in behind + * the first intersecting object. Where intersection is calculated with + * bounding box. If no intersection is found, there will not be change in the + * stack. + * @param {fabric.Object} object Object to send + * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object + * @returns {boolean} true if change occurred + */ + sendObjectBackwards(object, intersecting) { + if (!object) { + return false; + } + const idx = this._objects.indexOf(object); + if (idx !== 0) { + // if object is not on the bottom of stack + const newIdx = this.findNewLowerIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this._onStackOrderChanged(object); + return true; + } + return false; + } + + /** + * Moves an object or a selection up in stack of drawn objects + * An optional parameter, intersecting allows to move the object in front + * of the first intersecting object. Where intersection is calculated with + * bounding box. If no intersection is found, there will not be change in the + * stack. + * @param {fabric.Object} object Object to send + * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object + * @returns {boolean} true if change occurred + */ + bringObjectForward(object, intersecting) { + if (!object) { + return false; + } + const idx = this._objects.indexOf(object); + if (idx !== this._objects.length - 1) { + // if object is not on top of stack (last item in an array) + const newIdx = this.findNewUpperIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this._onStackOrderChanged(object); + return true; + } + return false; + } + + /** + * Moves an object to specified level in stack of drawn objects + * @param {fabric.Object} object Object to send + * @param {number} index Position to move to + * @returns {boolean} true if change occurred + */ + moveObjectTo(object, index) { + if (object === this._objects[index]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.splice(index, 0, object); + this._onStackOrderChanged(object); + return true; + } + findNewLowerIndex(object, idx, intersecting) { + let newIdx; + if (intersecting) { + newIdx = idx; + // traverse down the stack looking for the nearest intersecting object + for (let i = idx - 1; i >= 0; --i) { + if (object.isOverlapping(this._objects[i])) { + newIdx = i; + break; + } + } + } else { + newIdx = idx - 1; + } + return newIdx; + } + findNewUpperIndex(object, idx, intersecting) { + let newIdx; + if (intersecting) { + newIdx = idx; + // traverse up the stack looking for the nearest intersecting object + for (let i = idx + 1; i < this._objects.length; ++i) { + if (object.isOverlapping(this._objects[i])) { + newIdx = i; + break; + } + } + } else { + newIdx = idx + 1; + } + return newIdx; + } + + /** + * Given a bounding box, return all the objects of the collection that are contained in the bounding box. + * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well. + * This is meant to work with selection. Is not a generic method. + * @param {TBBox} bbox a bounding box in scene coordinates + * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting + * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise + */ + collectObjects(_ref) { + let { + left, + top, + width, + height + } = _ref; + let { + includeIntersecting = true + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const objects = [], + tl = new Point(left, top), + br = tl.add(new Point(width, height)); + + // we iterate reverse order to collect top first in case of click. + for (let i = this._objects.length - 1; i >= 0; i--) { + const object = this._objects[i]; + if (object.selectable && object.visible && (includeIntersecting && object.intersectsWithRect(tl, br) || object.isContainedWithinRect(tl, br) || includeIntersecting && object.containsPoint(tl) || includeIntersecting && object.containsPoint(br))) { + objects.push(object); + } + } + return objects; + } + } + + // https://github.com/microsoft/TypeScript/issues/32080 + return Collection; +} + +class CommonMethods extends Observable { + /** + * Sets object's properties from options, for initialization only + * @protected + * @param {Object} [options] Options object + */ + _setOptions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + for (const prop in options) { + this.set(prop, options[prop]); + } + } + + /** + * @private + */ + _setObject(obj) { + for (const prop in obj) { + this._set(prop, obj[prop]); + } + } + + /** + * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. + * @param {String|Object} key Property name or object (if object, iterate over the object properties) + * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) + */ + set(key, value) { + if (typeof key === 'object') { + this._setObject(key); + } else { + this._set(key, value); + } + return this; + } + _set(key, value) { + this[key] = value; + } + + /** + * Toggles specified property from `true` to `false` or from `false` to `true` + * @param {String} property Property to toggle + */ + toggle(property) { + const value = this.get(property); + if (typeof value === 'boolean') { + this.set(property, !value); + } + return this; + } + + /** + * Basic getter + * @param {String} property Property name + * @return {*} value of a property + */ + get(property) { + return this[property]; + } +} + +function requestAnimFrame(callback) { + return getFabricWindow().requestAnimationFrame(callback); +} +function cancelAnimFrame(handle) { + return getFabricWindow().cancelAnimationFrame(handle); +} + +let id = 0; +const uid = () => id++; + +/** + * Creates canvas element + * @return {CanvasElement} initialized canvas element + */ +const createCanvasElement = () => { + const element = getFabricDocument().createElement('canvas'); + if (!element || typeof element.getContext === 'undefined') { + throw new FabricError('Failed to create `canvas` element'); + } + return element; +}; + +/** + * Creates image element (works on client and node) + * @return {HTMLImageElement} HTML image element + */ +const createImage = () => getFabricDocument().createElement('img'); + +/** + * Creates a canvas element that is a copy of another and is also painted + * @param {CanvasElement} canvas to copy size and content of + * @return {CanvasElement} initialized canvas element + */ +const copyCanvasElement = canvas => { + var _newCanvas$getContext; + const newCanvas = createCanvasElement(); + newCanvas.width = canvas.width; + newCanvas.height = canvas.height; + (_newCanvas$getContext = newCanvas.getContext('2d')) === null || _newCanvas$getContext === void 0 || _newCanvas$getContext.drawImage(canvas, 0, 0); + return newCanvas; +}; + +/** + * since 2.6.0 moved from canvas instance to utility. + * possibly useless + * @param {CanvasElement} canvasEl to copy size and content of + * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too + * @param {Number} quality <= 1 and > 0 + * @return {String} data url + */ +const toDataURL = (canvasEl, format, quality) => canvasEl.toDataURL("image/".concat(format), quality); +const isHTMLCanvas = canvas => { + return !!canvas && canvas.getContext !== undefined; +}; + +/** + * Transforms degrees to radians. + * @param {TDegree} degrees value in degrees + * @return {TRadian} value in radians + */ +const degreesToRadians = degrees => degrees * PiBy180; + +/** + * Transforms radians to degrees. + * @param {TRadian} radians value in radians + * @return {TDegree} value in degrees + */ +const radiansToDegrees = radians => radians / PiBy180; + +const isIdentityMatrix = mat => mat.every((value, index) => value === iMatrix[index]); + +/** + * Apply transform t to point p + * @deprecated use {@link Point#transform} + * @param {Point | XY} p The point to transform + * @param {Array} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {Point} The transformed point + */ +const transformPoint = (p, t, ignoreOffset) => new Point(p).transform(t, ignoreOffset); + +/** + * Invert transformation t + * @param {Array} t The transform + * @return {Array} The inverted transform + */ +const invertTransform = t => { + const a = 1 / (t[0] * t[3] - t[1] * t[2]), + r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0], + { + x, + y + } = new Point(t[4], t[5]).transform(r, true); + r[4] = -x; + r[5] = -y; + return r; +}; + +/** + * Multiply matrix A by matrix B to nest transformations + * @param {TMat2D} a First transformMatrix + * @param {TMat2D} b Second transformMatrix + * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices + * @return {TMat2D} The product of the two transform matrices + */ +const multiplyTransformMatrices = (a, b, is2x2) => [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]]; + +/** + * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it + * + * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))` + * + * @param matrices an array of matrices + * @param [is2x2] flag to multiply matrices as 2x2 matrices + * @returns the multiplication product + */ +const multiplyTransformMatrixArray = (matrices, is2x2) => matrices.reduceRight((product, curr) => curr && product ? multiplyTransformMatrices(curr, product, is2x2) : curr || product, undefined) || iMatrix.concat(); +const calcPlaneRotation = _ref => { + let [a, b] = _ref; + return Math.atan2(b, a); +}; + +/** + * Decomposes standard 2x3 matrix into transform components + * @param {TMat2D} a transformMatrix + * @return {Object} Components of transform + */ +const qrDecompose = a => { + const angle = calcPlaneRotation(a), + denom = Math.pow(a[0], 2) + Math.pow(a[1], 2), + scaleX = Math.sqrt(denom), + scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, + skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom); + return { + angle: radiansToDegrees(angle), + scaleX, + scaleY, + skewX: radiansToDegrees(skewX), + skewY: 0, + translateX: a[4] || 0, + translateY: a[5] || 0 + }; +}; + +/** + * Generate a translation matrix + * + * A translation matrix in the form of + * [ 1 0 x ] + * [ 0 1 y ] + * [ 0 0 1 ] + * + * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details + * + * @param {number} x translation on X axis + * @param {number} [y] translation on Y axis + * @returns {TMat2D} matrix + */ +const createTranslateMatrix = function (x) { + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return [1, 0, 0, 1, x, y]; +}; + +/** + * Generate a rotation matrix around around a point (x,y), defaulting to (0,0) + * + * A matrix in the form of + * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x] + * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y] + * [0 0 1 ] + * + * + * @param {TDegree} angle rotation in degrees + * @param {XY} [pivotPoint] pivot point to rotate around + * @returns {TMat2D} matrix + */ +function createRotateMatrix() { + let { + angle = 0 + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let { + x = 0, + y = 0 + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const angleRadiant = degreesToRadians(angle), + cosValue = cos(angleRadiant), + sinValue = sin(angleRadiant); + return [cosValue, sinValue, -sinValue, cosValue, x ? x - (cosValue * x - sinValue * y) : 0, y ? y - (sinValue * x + cosValue * y) : 0]; +} + +/** + * Generate a scale matrix around the point (0,0) + * + * A matrix in the form of + * [x 0 0] + * [0 y 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale + * + * @param {number} x scale on X axis + * @param {number} [y] scale on Y axis + * @returns {TMat2D} matrix + */ +const createScaleMatrix = function (x) { + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + return [x, 0, 0, y, 0, 0]; +}; +const angleToSkew = angle => Math.tan(degreesToRadians(angle)); + +/** + * Generate a skew matrix for the X axis + * + * A matrix in the form of + * [1 x 0] + * [0 1 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx + * + * @param {TDegree} skewValue translation on X axis + * @returns {TMat2D} matrix + */ +const createSkewXMatrix = skewValue => [1, 0, angleToSkew(skewValue), 1, 0, 0]; + +/** + * Generate a skew matrix for the Y axis + * + * A matrix in the form of + * [1 0 0] + * [y 1 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy + * + * @param {TDegree} skewValue translation on Y axis + * @returns {TMat2D} matrix + */ +const createSkewYMatrix = skewValue => [1, angleToSkew(skewValue), 0, 1, 0, 0]; + +/** + * Returns a transform matrix starting from an object of the same kind of + * the one returned from qrDecompose, useful also if you want to calculate some + * transformations from an object that is not enlived yet. + * is called DimensionsTransformMatrix because those properties are the one that influence + * the size of the resulting box of the object. + * @param {Object} options + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Boolean} [options.flipX] + * @param {Boolean} [options.flipY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @return {Number[]} transform matrix + */ +const calcDimensionsMatrix = _ref2 => { + let { + scaleX = 1, + scaleY = 1, + flipX = false, + flipY = false, + skewX = 0, + skewY = 0 + } = _ref2; + let matrix = createScaleMatrix(flipX ? -scaleX : scaleX, flipY ? -scaleY : scaleY); + if (skewX) { + matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true); + } + if (skewY) { + matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true); + } + return matrix; +}; + +/** + * Returns a transform matrix starting from an object of the same kind of + * the one returned from qrDecompose, useful also if you want to calculate some + * transformations from an object that is not enlived yet + * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs + * @param {Object} options + * @param {Number} [options.angle] + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Boolean} [options.flipX] + * @param {Boolean} [options.flipY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @param {Number} [options.translateX] + * @param {Number} [options.translateY] + * @return {Number[]} transform matrix + */ +const composeMatrix = options => { + const { + translateX = 0, + translateY = 0, + angle = 0 + } = options; + let matrix = createTranslateMatrix(translateX, translateY); + if (angle) { + matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ + angle + })); + } + const scaleMatrix = calcDimensionsMatrix(options); + if (!isIdentityMatrix(scaleMatrix)) { + matrix = multiplyTransformMatrices(matrix, scaleMatrix); + } + return matrix; +}; + +/** + * Loads image element from given url and resolve it, or catch. + * @param {String} url URL representing an image + * @param {LoadImageOptions} [options] image loading options + * @returns {Promise} the loaded image. + */ +const loadImage = function (url) { + let { + signal, + crossOrigin = null + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise(function (resolve, reject) { + if (signal && signal.aborted) { + return reject(new SignalAbortedError('loadImage')); + } + const img = createImage(); + let abort; + if (signal) { + abort = function (err) { + img.src = ''; + reject(err); + }; + signal.addEventListener('abort', abort, { + once: true + }); + } + const done = function () { + img.onload = img.onerror = null; + abort && (signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', abort)); + resolve(img); + }; + if (!url) { + done(); + return; + } + img.onload = done; + img.onerror = function () { + abort && (signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', abort)); + reject(new FabricError("Error loading ".concat(img.src))); + }; + crossOrigin && (img.crossOrigin = crossOrigin); + img.src = url; + }); +}; +/** + * @TODO type this correctly. + * Creates corresponding fabric instances from their object representations + * @param {Object[]} objects Objects to enliven + * @param {EnlivenObjectOptions} [options] + * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements, + * called after each fabric object created. + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ +const enlivenObjects = function (objects) { + let { + signal, + reviver = noop + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise((resolve, reject) => { + const instances = []; + signal && signal.addEventListener('abort', reject, { + once: true + }); + Promise.all(objects.map(obj => classRegistry.getClass(obj.type).fromObject(obj, { + signal + }).then(fabricInstance => { + reviver(obj, fabricInstance); + instances.push(fabricInstance); + return fabricInstance; + }))).then(resolve).catch(error => { + // cleanup + instances.forEach(instance => { + instance.dispose && instance.dispose(); + }); + reject(error); + }).finally(() => { + signal && signal.removeEventListener('abort', reject); + }); + }); +}; + +/** + * Creates corresponding fabric instances residing in an object, e.g. `clipPath` + * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path ) + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise>} the input object with enlived values + */ +const enlivenObjectEnlivables = function (serializedObject) { + let { + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise((resolve, reject) => { + const instances = []; + signal && signal.addEventListener('abort', reject, { + once: true + }); + // enlive every possible property + const promises = Object.values(serializedObject).map(value => { + if (!value) { + return value; + } + /** + * clipPath or shadow or gradient or text on a path or a pattern, + * or the backgroundImage or overlayImage of canvas + * If we have a type and there is a classe registered for it, we enlive it. + * If there is no class registered for it we return the value as is + * */ + if (value.type && classRegistry.has(value.type)) { + return enlivenObjects([value], { + signal + }).then(_ref => { + let [enlived] = _ref; + instances.push(enlived); + return enlived; + }); + } + return value; + }); + const keys = Object.keys(serializedObject); + Promise.all(promises).then(enlived => { + return enlived.reduce((acc, instance, index) => { + acc[keys[index]] = instance; + return acc; + }, {}); + }).then(resolve).catch(error => { + // cleanup + instances.forEach(instance => { + instance.dispose && instance.dispose(); + }); + reject(error); + }).finally(() => { + signal && signal.removeEventListener('abort', reject); + }); + }); +}; + +/** + * Populates an object with properties of another object + * @param {Object} source Source object + * @param {string[]} properties Properties names to include + * @returns object populated with the picked keys + */ +const pick = function (source) { + let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + return keys.reduce((o, key) => { + if (key in source) { + o[key] = source[key]; + } + return o; + }, {}); +}; +const pickBy = (source, predicate) => { + return Object.keys(source).reduce((o, key) => { + if (predicate(source[key], key, source)) { + o[key] = source[key]; + } + return o; + }, {}); +}; + +/** + * Map of the 148 color names with HEX code + * @see: https://www.w3.org/TR/css3-color/#svg-color + */ +const ColorNameMap = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aqua: '#0FF', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000', + blanchedalmond: '#FFEBCD', + blue: '#00F', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#0FF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgrey: '#A9A9A9', + darkgreen: '#006400', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + fuchsia: '#F0F', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + gray: '#808080', + grey: '#808080', + green: '#008000', + greenyellow: '#ADFF2F', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgray: '#D3D3D3', + lightgrey: '#D3D3D3', + lightgreen: '#90EE90', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#789', + lightslategrey: '#789', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + lime: '#0F0', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#F0F', + maroon: '#800000', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + navy: '#000080', + oldlace: '#FDF5E6', + olive: '#808000', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + purple: '#800080', + rebeccapurple: '#639', + red: '#F00', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + silver: '#C0C0C0', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + teal: '#008080', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + white: '#FFF', + whitesmoke: '#F5F5F5', + yellow: '#FF0', + yellowgreen: '#9ACD32' +}; + +/** + * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`) + * Also matching rgba(r g b / a) as per new specs + * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb + * Formal syntax at the time of writing: + * = + * rgb( [ | none ]{3} [ / [ | none ] ]? ) | + * rgb( [ | none ]{3} [ / [ | none ] ]? ) + * = | + * + * For learners this is how you can read this regex + * Regular expression for matching an rgba or rgb CSS color value + * + * /^ # Beginning of the string + * rgba? # "rgb" or "rgba" + * \(\s* # Opening parenthesis and optional whitespace + * (\d{0,3} # 0 to three digits R channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the first color component + * %? # Optional percent sign after the first color component + * \s* # Optional whitespace + * [\s|,] # Separator between color components can be a space or comma + * \s* # Optional whitespace + * (\d{0,3} # 0 to three digits G channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the second color component + * %? # Optional percent sign after the second color component + * \s* # Optional whitespace + * [\s|,] # Separator between color components can be a space or comma + * \s* # Optional whitespace + * (\d{0,3} # 0 to three digits B channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the third color component + * %? # Optional percent sign after the third color component + * \s* # Optional whitespace + * (?: # Beginning of non-capturing group for alpha value + * \s* # Optional whitespace + * [,/] # Comma or slash separator for alpha value + * \s* # Optional whitespace + * (\d{0,3} # Zero to three digits + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for alpha value + * %? # Optional percent sign after alpha value + * \s* # Optional whitespace + * )? # End of non-capturing group for alpha value (optional) + * \) # Closing parenthesis + * $ # End of the string + * + * The alpha channel can be in the format 0.4 .7 or 1 or 73% + * + * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color. + * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us + */ +const reRGBa = () => /^rgba?\(\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d{0,3}(?:\.\d+)?%?)\s*)?\)$/i; + +/** + * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) + * Also matching rgba(r g b / a) as per new specs + * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl + * Formal syntax at the time of writing: + * = + * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? ) + * + * = + * | + * + * + * = + * | + * + * + * For learners this is how you can read this regex + * Regular expression for matching an hsla or hsl CSS color value + * + * /^hsla?\( // Matches the beginning of the string and the opening parenthesis of "hsl" or "hsla" + * \s* // Matches any whitespace characters (space, tab, etc.) zero or more times + * (\d{0,3} // Hue: 0 to three digits - start capture in a group + * (?:\.\d+)? // Hue: Optional (non capture group) decimal with one or more digits. + * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad + * ) // Hue: End capture group + * \s* // Matches any whitespace characters zero or more times + * [\s|,] // Matches a space, tab or comma + * \s* // Matches any whitespace characters zero or more times + * (\d{0,3} // Saturation: 0 to three digits - start capture in a group + * (?:\.\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group + * %?) // Saturation: match optional % character and end capture group + * \s* // Matches any whitespace characters zero or more times + * [\s|,] // Matches a space, tab or comma + * \s* // Matches any whitespace characters zero or more times + * (\d{0,3} // Lightness: 0 to three digits - start capture in a group + * (?:\.\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group + * %?) // Lightness: match % character and end capture group + * \s* // Matches any whitespace characters zero or more times + * (?: // Alpha: Begins a non-capturing group for the alpha value + * \s* // Matches any whitespace characters zero or more times + * [,/] // Matches a comma or forward slash + * \s* // Matches any whitespace characters zero or more times + * (\d*(?:\.\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group + * \s* // Matches any whitespace characters zero or more times + * )? // Makes the alpha value group optional + * \) // Matches the closing parenthesis + * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode + * + * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color. + * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us. + */ +const reHSLa = () => /^hsla?\(\s*([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d*(?:\.\d+)?%?)\s*)?\)$/i; + +/** + * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff) + */ +const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i; + +/** + * @param {Number} p + * @param {Number} q + * @param {Number} t + * @return {Number} + */ +const hue2rgb = (p, q, t) => { + if (t < 0) { + t += 1; + } + if (t > 1) { + t -= 1; + } + if (t < 1 / 6) { + return p + (q - p) * 6 * t; + } + if (t < 1 / 2) { + return q; + } + if (t < 2 / 3) { + return p + (q - p) * (2 / 3 - t) * 6; + } + return p; +}; + +/** + * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson} + * @param {Number} r Red color value + * @param {Number} g Green color value + * @param {Number} b Blue color value + * @param {Number} a Alpha color value pass through + * @return {TRGBColorSource} Hsl color + */ +const rgb2Hsl = (r, g, b, a) => { + r /= 255; + g /= 255; + b /= 255; + const maxValue = Math.max(r, g, b), + minValue = Math.min(r, g, b); + let h, s; + const l = (maxValue + minValue) / 2; + if (maxValue === minValue) { + h = s = 0; // achromatic + } else { + const d = maxValue - minValue; + s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue); + switch (maxValue) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a]; +}; +const fromAlphaToFloat = function () { + let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '1'; + return parseFloat(value) / (value.endsWith('%') ? 100 : 1); +}; + +/** + * Convert a value in the inclusive range [0, 255] to hex + */ +const hexify = value => Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0'); + +/** + * Calculate the grey average value for rgb and pass through alpha + */ +const greyAverage = _ref => { + let [r, g, b, a = 1] = _ref; + const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11); + return [avg, avg, avg, a]; +}; + +/** + * @class Color common color operations + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors} + */ +class Color { + /** + * + * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list + */ + constructor(color) { + _defineProperty(this, "isUnrecognised", false); + if (!color) { + // we default to black as canvas does + this.setSource([0, 0, 0, 1]); + } else if (color instanceof Color) { + this.setSource([...color._source]); + } else if (Array.isArray(color)) { + const [r, g, b, a = 1] = color; + this.setSource([r, g, b, a]); + } else { + this.setSource(this._tryParsingColor(color)); + } + } + + /** + * @private + * @param {string} [color] Color value to parse + * @returns {TRGBAColorSource} + */ + _tryParsingColor(color) { + if (color in ColorNameMap) { + color = ColorNameMap[color]; + } + return color === 'transparent' ? [255, 255, 255, 0] : Color.sourceFromHex(color) || Color.sourceFromRgb(color) || Color.sourceFromHsl(color) || + // color is not recognized + // we default to black as canvas does + // eslint-disable-next-line no-constant-binary-expression + (this.isUnrecognised = true) && [0, 0, 0, 1]; + } + + /** + * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @return {TRGBAColorSource} + */ + getSource() { + return this._source; + } + + /** + * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @param {TRGBAColorSource} source + */ + setSource(source) { + this._source = source; + } + + /** + * Returns color representation in RGB format + * @return {String} ex: rgb(0-255,0-255,0-255) + */ + toRgb() { + const [r, g, b] = this.getSource(); + return "rgb(".concat(r, ",").concat(g, ",").concat(b, ")"); + } + + /** + * Returns color representation in RGBA format + * @return {String} ex: rgba(0-255,0-255,0-255,0-1) + */ + toRgba() { + return "rgba(".concat(this.getSource().join(','), ")"); + } + + /** + * Returns color representation in HSL format + * @return {String} ex: hsl(0-360,0%-100%,0%-100%) + */ + toHsl() { + const [h, s, l] = rgb2Hsl(...this.getSource()); + return "hsl(".concat(h, ",").concat(s, "%,").concat(l, "%)"); + } + + /** + * Returns color representation in HSLA format + * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) + */ + toHsla() { + const [h, s, l, a] = rgb2Hsl(...this.getSource()); + return "hsla(".concat(h, ",").concat(s, "%,").concat(l, "%,").concat(a, ")"); + } + + /** + * Returns color representation in HEX format + * @return {String} ex: FF5555 + */ + toHex() { + const fullHex = this.toHexa(); + return fullHex.slice(0, 6); + } + + /** + * Returns color representation in HEXA format + * @return {String} ex: FF5555CC + */ + toHexa() { + const [r, g, b, a] = this.getSource(); + return "".concat(hexify(r)).concat(hexify(g)).concat(hexify(b)).concat(hexify(Math.round(a * 255))); + } + + /** + * Gets value of alpha channel for this color + * @return {Number} 0-1 + */ + getAlpha() { + return this.getSource()[3]; + } + + /** + * Sets value of alpha channel for this color + * @param {Number} alpha Alpha value 0-1 + * @return {Color} thisArg + */ + setAlpha(alpha) { + this._source[3] = alpha; + return this; + } + + /** + * Transforms color to its grayscale representation + * @return {Color} thisArg + */ + toGrayscale() { + this.setSource(greyAverage(this.getSource())); + return this; + } + + /** + * Transforms color to its black and white representation + * @param {Number} threshold + * @return {Color} thisArg + */ + toBlackWhite(threshold) { + const [average,,, a] = greyAverage(this.getSource()), + bOrW = average < (threshold || 127) ? 0 : 255; + this.setSource([bOrW, bOrW, bOrW, a]); + return this; + } + + /** + * Overlays color with another color + * @param {String|Color} otherColor + * @return {Color} thisArg + */ + overlayWith(otherColor) { + if (!(otherColor instanceof Color)) { + otherColor = new Color(otherColor); + } + const source = this.getSource(), + otherAlpha = 0.5, + otherSource = otherColor.getSource(), + [R, G, B] = source.map((value, index) => Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha)); + this.setSource([R, G, B, source[3]]); + return this; + } + + /** + * Returns new color object, when given a color in RGB format + * @memberOf Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255) + * @return {Color} + */ + static fromRgb(color) { + return Color.fromRgba(color); + } + + /** + * Returns new color object, when given a color in RGBA format + * @static + * @function + * @memberOf Color + * @param {String} color + * @return {Color} + */ + static fromRgba(color) { + return new Color(Color.sourceFromRgb(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format + * @memberOf Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) + * @return {TRGBAColorSource | undefined} source + */ + static sourceFromRgb(color) { + const match = color.match(reRGBa()); + if (match) { + const [r, g, b] = match.slice(1, 4).map(value => { + const parsedValue = parseFloat(value); + return value.endsWith('%') ? Math.round(parsedValue * 2.55) : parsedValue; + }); + return [r, g, b, fromAlphaToFloat(match[4])]; + } + } + + /** + * Returns new color object, when given a color in HSL format + * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%) + * @memberOf Color + * @return {Color} + */ + static fromHsl(color) { + return Color.fromHsla(color); + } + + /** + * Returns new color object, when given a color in HSLA format + * @static + * @function + * @memberOf Color + * @param {String} color + * @return {Color} + */ + static fromHsla(color) { + return new Color(Color.sourceFromHsl(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. + * Adapted from https://github.com/mjijackson + * @memberOf Color + * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) + * @return {TRGBAColorSource | undefined} source + * @see http://http://www.w3.org/TR/css3-color/#hsl-color + */ + static sourceFromHsl(color) { + const match = color.match(reHSLa()); + if (!match) { + return; + } + const match1degrees = Color.parseAngletoDegrees(match[1]); + const h = (match1degrees % 360 + 360) % 360 / 360, + s = parseFloat(match[2]) / 100, + l = parseFloat(match[3]) / 100; + let r, g, b; + if (s === 0) { + r = g = b = l; + } else { + const q = l <= 0.5 ? l * (s + 1) : l + s - l * s, + p = l * 2 - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), fromAlphaToFloat(match[4])]; + } + + /** + * Returns new color object, when given a color in HEX format + * @static + * @memberOf Color + * @param {String} color Color value ex: FF5555 + * @return {Color} + */ + static fromHex(color) { + return new Color(Color.sourceFromHex(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format + * @static + * @memberOf Color + * @param {String} color ex: FF5555 or FF5544CC (RGBa) + * @return {TRGBAColorSource | undefined} source + */ + static sourceFromHex(color) { + if (color.match(reHex())) { + const value = color.slice(color.indexOf('#') + 1), + isShortNotation = value.length <= 4; + let expandedValue; + if (isShortNotation) { + expandedValue = value.split('').map(hex => hex + hex); + } else { + expandedValue = value.match(/.{2}/g); + } + const [r, g, b, a = 255] = expandedValue.map(hexCouple => parseInt(hexCouple, 16)); + return [r, g, b, a / 255]; + } + } + + /** + * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad) + * into degrees without the 'deg' suffix + * @static + * @memberOf Color + * @param {String} value ex: 0deg, 0.5turn, 2rad + * @return {Number} number in degrees or NaN if inputs are invalid + */ + static parseAngletoDegrees(value) { + const lowercase = value.toLowerCase(); + const numeric = parseFloat(lowercase); + if (lowercase.includes('rad')) { + return radiansToDegrees(numeric); + } + if (lowercase.includes('turn')) { + return numeric * 360; + } + + // Value is probably just a number already in degrees eg '50' + return numeric; + } +} + +/** + * A wrapper around Number#toFixed, which contrary to native method returns number, not string. + * @param {number|string} number number to operate on + * @param {number} fractionDigits number of fraction digits to "leave" + * @return {number} + */ +const toFixed = (number, fractionDigits) => parseFloat(Number(number).toFixed(fractionDigits)); + +/** + * Returns array of attributes for given svg that fabric parses + * @param {SVGElementName} type Type of svg element (eg. 'circle') + * @return {Array} string names of supported attributes + */ +const getSvgAttributes = type => { + const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class']; + switch (type) { + case 'linearGradient': + return commonAttributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']); + case 'radialGradient': + return commonAttributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']); + case 'stop': + return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']); + } + return commonAttributes; +}; + +/** + * Converts from attribute value to pixel value if applicable. + * Returns converted pixels or original value not converted. + * @param {string} value number to operate on + * @param {number} fontSize + * @return {number} + */ +const parseUnit = function (value) { + let fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_SVG_FONT_SIZE; + const unit = /\D{0,2}$/.exec(value), + number = parseFloat(value); + const dpi = config.DPI; + switch (unit === null || unit === void 0 ? void 0 : unit[0]) { + case 'mm': + return number * dpi / 25.4; + case 'cm': + return number * dpi / 2.54; + case 'in': + return number * dpi; + case 'pt': + return number * dpi / 72; + // or * 4 / 3 + + case 'pc': + return number * dpi / 72 * 12; + // or * 16 + + case 'em': + return number * fontSize; + default: + return number; + } +}; +// align can be either none or undefined or a combination of mid/max +const parseAlign = align => { + //divide align in alignX and alignY + if (align && align !== NONE) { + return [align.slice(1, 4), align.slice(5, 8)]; + } else if (align === NONE) { + return [align, align]; + } + return ['Mid', 'Mid']; +}; + +/** + * Parse preserveAspectRatio attribute from element + * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio + * @param {string} attribute to be parsed + * @return {Object} an object containing align and meetOrSlice attribute + */ +const parsePreserveAspectRatioAttribute = attribute => { + const [firstPart, secondPart] = attribute.trim().split(' '); + const [alignX, alignY] = parseAlign(firstPart); + return { + meetOrSlice: secondPart || 'meet', + alignX, + alignY + }; +}; + +/** + * given an array of 6 number returns something like `"matrix(...numbers)"` + * @param {TMat2D} transform an array with 6 numbers + * @return {String} transform matrix for svg + */ +const matrixToSVG = transform => 'matrix(' + transform.map(value => toFixed(value, config.NUM_FRACTION_DIGITS)).join(' ') + ')'; + +/** + * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values + * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 + * @param prop + * @param value + * @param {boolean} inlineStyle The default is inline style, the separator used is ":", The other is "=" + * @returns + */ +const colorPropToSVG = function (prop, value) { + let inlineStyle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + let colorValue; + let opacityValue; + if (!value) { + colorValue = 'none'; + } else if (value.toLive) { + colorValue = "url(#SVGID_".concat(value.id, ")"); + } else { + const color = new Color(value), + opacity = color.getAlpha(); + colorValue = color.toRgb(); + if (opacity !== 1) { + opacityValue = opacity.toString(); + } + } + if (inlineStyle) { + return "".concat(prop, ": ").concat(colorValue, "; ").concat(opacityValue ? "".concat(prop, "-opacity: ").concat(opacityValue, "; ") : ''); + } else { + return "".concat(prop, "=\"").concat(colorValue, "\" ").concat(opacityValue ? "".concat(prop, "-opacity=\"").concat(opacityValue, "\" ") : ''); + } +}; +const createSVGRect = function (color, _ref) { + let { + left, + top, + width, + height + } = _ref; + let precision = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : config.NUM_FRACTION_DIGITS; + const svgColor = colorPropToSVG(FILL, color, false); + const [x, y, w, h] = [left, top, width, height].map(value => toFixed(value, precision)); + return ""); +}; + +const isFiller = filler => { + return !!filler && filler.toLive !== undefined; +}; +const isSerializableFiller = filler => { + return !!filler && typeof filler.toObject === 'function'; +}; +const isPattern = filler => { + return !!filler && filler.offsetX !== undefined && 'source' in filler; +}; +const isTextObject = fabricObject => { + return !!fabricObject && typeof fabricObject._renderText === 'function'; +}; +const isPath = fabricObject => { + // we could use instanceof but that would mean pulling in Text code for a simple check + // @todo discuss what to do and how to do + return !!fabricObject && typeof fabricObject._renderPathCommands === 'function'; +}; +const isActiveSelection = fabricObject => !!fabricObject && 'multiSelectionStacking' in fabricObject; + +/** + * Returns element scroll offsets + * @param {HTMLElement} element Element to operate on + * @return {Object} Object with left/top values + */ +function getScrollLeftTop(element) { + const doc = element && getDocumentFromElement(element); + let left = 0, + top = 0; + if (!element || !doc) { + return { + left, + top + }; + } + let elementLoop = element; + const docElement = doc.documentElement, + body = doc.body || { + scrollLeft: 0, + scrollTop: 0 + }; + // While loop checks (and then sets element to) .parentNode OR .host + // to account for ShadowDOM. We still want to traverse up out of ShadowDOM, + // but the .parentNode of a root ShadowDOM node will always be null, instead + // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938 + while (elementLoop && (elementLoop.parentNode || elementLoop.host)) { + elementLoop = elementLoop.parentNode || elementLoop.host; + if (elementLoop === doc) { + left = body.scrollLeft || docElement.scrollLeft || 0; + top = body.scrollTop || docElement.scrollTop || 0; + } else { + left += elementLoop.scrollLeft || 0; + top += elementLoop.scrollTop || 0; + } + if (elementLoop.nodeType === 1 && elementLoop.style.position === 'fixed') { + break; + } + } + return { + left, + top + }; +} +const getDocumentFromElement = el => el.ownerDocument || null; +const getWindowFromElement = el => { + var _el$ownerDocument; + return ((_el$ownerDocument = el.ownerDocument) === null || _el$ownerDocument === void 0 ? void 0 : _el$ownerDocument.defaultView) || null; +}; + +const setCanvasDimensions = function (el, ctx, _ref) { + let { + width, + height + } = _ref; + let retinaScaling = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; + el.width = width; + el.height = height; + if (retinaScaling > 1) { + el.setAttribute('width', (width * retinaScaling).toString()); + el.setAttribute('height', (height * retinaScaling).toString()); + ctx.scale(retinaScaling, retinaScaling); + } +}; +const setCSSDimensions = (el, _ref2) => { + let { + width, + height + } = _ref2; + width && (el.style.width = typeof width === 'number' ? "".concat(width, "px") : width); + height && (el.style.height = typeof height === 'number' ? "".concat(height, "px") : height); +}; + +/** + * Returns offset for a given element + * @param {HTMLElement} element Element to get offset for + * @return {Object} Object with "left" and "top" properties + */ +function getElementOffset(element) { + var _getWindowFromElement; + const doc = element && getDocumentFromElement(element), + offset = { + left: 0, + top: 0 + }; + if (!doc) { + return offset; + } + const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {}; + offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0; + offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0; + offset.left += parseInt(elemStyle.paddingLeft, 10) || 0; + offset.top += parseInt(elemStyle.paddingTop, 10) || 0; + let box = { + left: 0, + top: 0 + }; + const docElem = doc.documentElement; + if (typeof element.getBoundingClientRect !== 'undefined') { + box = element.getBoundingClientRect(); + } + const scrollLeftTop = getScrollLeftTop(element); + return { + left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, + top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top + }; +} + +/** + * Makes element unselectable + * @param {HTMLElement} element Element to make unselectable + * @return {HTMLElement} Element that was passed in + */ +function makeElementUnselectable(element) { + if (typeof element.onselectstart !== 'undefined') { + element.onselectstart = () => false; + } + element.style.userSelect = NONE; + return element; +} + +class StaticCanvasDOMManager { + constructor(arg0) { + /** + * Keeps a copy of the canvas style before setting retina scaling and other potions + * in order to return it to original state on dispose + * @type string + */ + _defineProperty(this, "_originalCanvasStyle", void 0); + _defineProperty(this, "lower", void 0); + const el = this.createLowerCanvas(arg0); + this.lower = { + el, + ctx: el.getContext('2d') + }; + } + createLowerCanvas(arg0) { + // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node + const el = isHTMLCanvas(arg0) ? arg0 : arg0 && getFabricDocument().getElementById(arg0) || createCanvasElement(); + if (el.hasAttribute('data-fabric')) { + throw new FabricError('Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?'); + } + this._originalCanvasStyle = el.style.cssText; + el.setAttribute('data-fabric', 'main'); + el.classList.add('lower-canvas'); + return el; + } + cleanupDOM(_ref) { + let { + width, + height + } = _ref; + const { + el + } = this.lower; + // restore canvas style and attributes + el.classList.remove('lower-canvas'); + el.removeAttribute('data-fabric'); + // restore canvas size to original size in case retina scaling was applied + el.setAttribute('width', "".concat(width)); + el.setAttribute('height', "".concat(height)); + el.style.cssText = this._originalCanvasStyle || ''; + this._originalCanvasStyle = undefined; + } + setDimensions(size, retinaScaling) { + const { + el, + ctx + } = this.lower; + setCanvasDimensions(el, ctx, size, retinaScaling); + } + setCSSDimensions(size) { + setCSSDimensions(this.lower.el, size); + } + + /** + * Calculates canvas element offset relative to the document + */ + calcOffset() { + return getElementOffset(this.lower.el); + } + dispose() { + getEnv().dispose(this.lower.el); + // @ts-expect-error disposing + delete this.lower; + } +} + +const staticCanvasDefaults = { + backgroundVpt: true, + backgroundColor: '', + overlayVpt: true, + overlayColor: '', + includeDefaultValues: true, + svgViewportTransformation: true, + renderOnAddRemove: true, + skipOffscreen: true, + enableRetinaScaling: true, + imageSmoothingEnabled: true, + /** + * @todo move to Canvas + */ + controlsAboveOverlay: false, + /** + * @todo move to Canvas + */ + allowTouchScrolling: false, + viewportTransform: [...iMatrix] +}; + +/** + * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset + * Better try to restrict with types to avoid confusion. + */ + +/** + * Static canvas class + * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} + * @fires before:render + * @fires after:render + * @fires canvas:cleared + * @fires object:added + * @fires object:removed + */ +// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260 +class StaticCanvas extends createCollectionMixin(CommonMethods) { + // background + + // overlay + + // rendering config + + /** + * @todo move to Canvas + */ + + /** + * @todo move to Canvas + */ + + /** + * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries} + */ + + /** + * A reference to the canvas actual HTMLCanvasElement. + * Can be use to read the raw pixels, but never write or manipulate + * @type HTMLCanvasElement + */ + get lowerCanvasEl() { + var _this$elements$lower; + return (_this$elements$lower = this.elements.lower) === null || _this$elements$lower === void 0 ? void 0 : _this$elements$lower.el; + } + get contextContainer() { + var _this$elements$lower2; + return (_this$elements$lower2 = this.elements.lower) === null || _this$elements$lower2 === void 0 ? void 0 : _this$elements$lower2.ctx; + } + + /** + * If true the Canvas is in the process or has been disposed/destroyed. + * No more rendering operation will be executed on this canvas. + * @type boolean + */ + + /** + * Started the process of disposing but not done yet. + * WIll likely complete the render cycle already scheduled but stopping adding more. + * @type boolean + */ + + /** + * When true control drawing is skipped. + * This boolean is used to avoid toDataURL to export controls. + * Usage of this boolean to build up other flows and features is not supported + * @type Boolean + * @default false + */ + + // reference to + + static getDefaults() { + return StaticCanvas.ownDefaults; + } + constructor(el) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, this.constructor.getDefaults()); + this.set(options); + this.initElements(el); + this._setDimensionsImpl({ + width: this.width || this.elements.lower.el.width || 0, + height: this.height || this.elements.lower.el.height || 0 + }); + this.skipControlsDrawing = false; + this.viewportTransform = [...this.viewportTransform]; + this.calcViewportBoundaries(); + } + initElements(el) { + this.elements = new StaticCanvasDOMManager(el); + } + add() { + const size = super.add(...arguments); + arguments.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return size; + } + insertAt(index) { + for (var _len = arguments.length, objects = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + objects[_key - 1] = arguments[_key]; + } + const size = super.insertAt(index, ...objects); + objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return size; + } + remove() { + const removed = super.remove(...arguments); + removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return removed; + } + _onObjectAdded(obj) { + if (obj.canvas && obj.canvas !== this) { + log('warn', 'Canvas is trying to add an object that belongs to a different canvas.\n' + 'Resulting to default behavior: removing object from previous canvas and adding to new canvas'); + obj.canvas.remove(obj); + } + obj._set('canvas', this); + obj.setCoords(); + this.fire('object:added', { + target: obj + }); + obj.fire('added', { + target: this + }); + } + _onObjectRemoved(obj) { + obj._set('canvas', undefined); + this.fire('object:removed', { + target: obj + }); + obj.fire('removed', { + target: this + }); + } + _onStackOrderChanged() { + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * @private + * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html + * @return {Number} retinaScaling if applied, otherwise 1; + */ + getRetinaScaling() { + return this.enableRetinaScaling ? getDevicePixelRatio() : 1; + } + + /** + * Calculates canvas element offset relative to the document + * This method is also attached as "resize" event handler of window + */ + calcOffset() { + return this._offset = this.elements.calcOffset(); + } + + /** + * Returns canvas width (in px) + * @return {Number} + */ + getWidth() { + return this.width; + } + + /** + * Returns canvas height (in px) + * @return {Number} + */ + getHeight() { + return this.height; + } + + /** + * Sets width of this canvas instance + * @param {Number|String} value Value to set width to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @deprecated will be removed in 7.0 + */ + + setWidth(value, options) { + return this.setDimensions({ + width: value + }, options); + } + + /**s + * Sets height of this canvas instance + * @param {Number|String} value Value to set height to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @deprecated will be removed in 7.0 + */ + + setHeight(value, options) { + return this.setDimensions({ + height: value + }, options); + } + + /** + * Internal use only + * @protected + */ + _setDimensionsImpl(dimensions) { + let { + cssOnly = false, + backstoreOnly = false + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (!cssOnly) { + const size = _objectSpread2({ + width: this.width, + height: this.height + }, dimensions); + this.elements.setDimensions(size, this.getRetinaScaling()); + this.hasLostContext = true; + this.width = size.width; + this.height = size.height; + } + if (!backstoreOnly) { + this.elements.setCSSDimensions(dimensions); + } + this.calcOffset(); + } + + /** + * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) + * @param {Object} dimensions Object with width/height properties + * @param {Number|String} [dimensions.width] Width of canvas element + * @param {Number|String} [dimensions.height] Height of canvas element + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + */ + + setDimensions(dimensions, options) { + this._setDimensionsImpl(dimensions, options); + if (!options || !options.cssOnly) { + this.requestRenderAll(); + } + } + + /** + * Returns canvas zoom level + * @return {Number} + */ + getZoom() { + return this.viewportTransform[0]; + } + + /** + * Sets viewport transformation of this canvas instance + * @param {Array} vpt a Canvas 2D API transform matrix + */ + setViewportTransform(vpt) { + this.viewportTransform = vpt; + this.calcViewportBoundaries(); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Sets zoom level of this canvas instance, the zoom centered around point + * meaning that following zoom to point with the same point will have the visual + * effect of the zoom originating from that point. The point won't move. + * It has nothing to do with canvas center or visual center of the viewport. + * @param {Point} point to zoom with respect to + * @param {Number} value to set zoom to, less than 1 zooms out + */ + zoomToPoint(point, value) { + // TODO: just change the scale, preserve other transformations + const before = point, + vpt = [...this.viewportTransform]; + const newPoint = transformPoint(point, invertTransform(vpt)); + vpt[0] = value; + vpt[3] = value; + const after = transformPoint(newPoint, vpt); + vpt[4] += before.x - after.x; + vpt[5] += before.y - after.y; + this.setViewportTransform(vpt); + } + + /** + * Sets zoom level of this canvas instance + * @param {Number} value to set zoom to, less than 1 zooms out + */ + setZoom(value) { + this.zoomToPoint(new Point(0, 0), value); + } + + /** + * Pan viewport so as to place point at top left corner of canvas + * @param {Point} point to move to + */ + absolutePan(point) { + const vpt = [...this.viewportTransform]; + vpt[4] = -point.x; + vpt[5] = -point.y; + return this.setViewportTransform(vpt); + } + + /** + * Pans viewpoint relatively + * @param {Point} point (position vector) to move by + */ + relativePan(point) { + return this.absolutePan(new Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5])); + } + + /** + * Returns <canvas> element corresponding to this instance + * @return {HTMLCanvasElement} + */ + getElement() { + return this.elements.lower.el; + } + + /** + * Clears specified context of canvas element + * @param {CanvasRenderingContext2D} ctx Context to clear + */ + clearContext(ctx) { + ctx.clearRect(0, 0, this.width, this.height); + } + + /** + * Returns context of canvas where objects are drawn + * @return {CanvasRenderingContext2D} + */ + getContext() { + return this.elements.lower.ctx; + } + + /** + * Clears all contexts (background, main, top) of an instance + */ + clear() { + this.remove(...this.getObjects()); + this.backgroundImage = undefined; + this.overlayImage = undefined; + this.backgroundColor = ''; + this.overlayColor = ''; + this.clearContext(this.getContext()); + this.fire('canvas:cleared'); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Renders the canvas + */ + renderAll() { + this.cancelRequestedRender(); + if (this.destroyed) { + return; + } + this.renderCanvas(this.getContext(), this._objects); + } + + /** + * Function created to be instance bound at initialization + * used in requestAnimationFrame rendering + * Let the fabricJS call it. If you call it manually you could have more + * animationFrame stacking on to of each other + * for an imperative rendering, use canvas.renderAll + * @private + */ + renderAndReset() { + this.nextRenderHandle = 0; + this.renderAll(); + } + + /** + * Append a renderAll request to next animation frame. + * unless one is already in progress, in that case nothing is done + * a boolean flag will avoid appending more. + */ + requestRenderAll() { + if (!this.nextRenderHandle && !this.disposed && !this.destroyed) { + this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset()); + } + } + + /** + * Calculate the position of the 4 corner of canvas with current viewportTransform. + * helps to determinate when an object is in the current rendering viewport + */ + calcViewportBoundaries() { + const width = this.width, + height = this.height, + iVpt = invertTransform(this.viewportTransform), + a = transformPoint({ + x: 0, + y: 0 + }, iVpt), + b = transformPoint({ + x: width, + y: height + }, iVpt), + // we don't support vpt flipping + // but the code is robust enough to mostly work with flipping + min = a.min(b), + max = a.max(b); + return this.vptCoords = { + tl: min, + tr: new Point(max.x, min.y), + bl: new Point(min.x, max.y), + br: max + }; + } + cancelRequestedRender() { + if (this.nextRenderHandle) { + cancelAnimFrame(this.nextRenderHandle); + this.nextRenderHandle = 0; + } + } + drawControls(_ctx) { + // Static canvas has no controls + } + + /** + * Renders background, objects, overlay and controls. + * @param {CanvasRenderingContext2D} ctx + * @param {Array} objects to render + */ + renderCanvas(ctx, objects) { + if (this.destroyed) { + return; + } + const v = this.viewportTransform, + path = this.clipPath; + this.calcViewportBoundaries(); + this.clearContext(ctx); + ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; + // @ts-expect-error node-canvas stuff + ctx.patternQuality = 'best'; + this.fire('before:render', { + ctx + }); + this._renderBackground(ctx); + ctx.save(); + //apply viewport transform once for all rendering process + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + this._renderObjects(ctx, objects); + ctx.restore(); + if (!this.controlsAboveOverlay && !this.skipControlsDrawing) { + this.drawControls(ctx); + } + if (path) { + path._set('canvas', this); + // needed to setup a couple of variables + path.shouldCache(); + path._transformDone = true; + path.renderCache({ + forClipping: true + }); + this.drawClipPathOnCanvas(ctx, path); + } + this._renderOverlay(ctx); + if (this.controlsAboveOverlay && !this.skipControlsDrawing) { + this.drawControls(ctx); + } + this.fire('after:render', { + ctx + }); + if (this.__cleanupTask) { + this.__cleanupTask(); + this.__cleanupTask = undefined; + } + } + + /** + * Paint the cached clipPath on the lowerCanvasEl + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawClipPathOnCanvas(ctx, clipPath) { + const v = this.viewportTransform; + ctx.save(); + ctx.transform(...v); + // DEBUG: uncomment this line, comment the following + // ctx.globalAlpha = 0.4; + ctx.globalCompositeOperation = 'destination-in'; + clipPath.transform(ctx); + ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY); + ctx.drawImage(clipPath._cacheCanvas, -clipPath.cacheTranslationX, -clipPath.cacheTranslationY); + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} objects to render + */ + _renderObjects(ctx, objects) { + for (let i = 0, len = objects.length; i < len; ++i) { + objects[i] && objects[i].render(ctx); + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {string} property 'background' or 'overlay' + */ + _renderBackgroundOrOverlay(ctx, property) { + const fill = this["".concat(property, "Color")], + object = this["".concat(property, "Image")], + v = this.viewportTransform, + needsVpt = this["".concat(property, "Vpt")]; + if (!fill && !object) { + return; + } + const isAFiller = isFiller(fill); + if (fill) { + ctx.save(); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(this.width, 0); + ctx.lineTo(this.width, this.height); + ctx.lineTo(0, this.height); + ctx.closePath(); + ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */) : fill; + if (needsVpt) { + ctx.transform(...v); + } + if (isAFiller) { + ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0); + const m = fill.gradientTransform || fill.patternTransform; + m && ctx.transform(...m); + } + ctx.fill(); + ctx.restore(); + } + if (object) { + ctx.save(); + const { + skipOffscreen + } = this; + // if the object doesn't move with the viewport, + // the offscreen concept does not apply; + this.skipOffscreen = needsVpt; + if (needsVpt) { + ctx.transform(...v); + } + object.render(ctx); + this.skipOffscreen = skipOffscreen; + ctx.restore(); + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground(ctx) { + this._renderBackgroundOrOverlay(ctx, 'background'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderOverlay(ctx) { + this._renderBackgroundOrOverlay(ctx, 'overlay'); + } + + /** + * Returns coordinates of a center of canvas. + * Returned value is an object with top and left properties + * @return {Object} object with "top" and "left" number values + * @deprecated migrate to `getCenterPoint` + */ + getCenter() { + return { + top: this.height / 2, + left: this.width / 2 + }; + } + + /** + * Returns coordinates of a center of canvas. + * @return {Point} + */ + getCenterPoint() { + return new Point(this.width / 2, this.height / 2); + } + + /** + * Centers object horizontally in the canvas + */ + centerObjectH(object) { + return this._centerObject(object, new Point(this.getCenterPoint().x, object.getCenterPoint().y)); + } + + /** + * Centers object vertically in the canvas + * @param {FabricObject} object Object to center vertically + */ + centerObjectV(object) { + return this._centerObject(object, new Point(object.getCenterPoint().x, this.getCenterPoint().y)); + } + + /** + * Centers object vertically and horizontally in the canvas + * @param {FabricObject} object Object to center vertically and horizontally + */ + centerObject(object) { + return this._centerObject(object, this.getCenterPoint()); + } + + /** + * Centers object vertically and horizontally in the viewport + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObject(object) { + return this._centerObject(object, this.getVpCenter()); + } + + /** + * Centers object horizontally in the viewport, object.top is unchanged + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObjectH(object) { + return this._centerObject(object, new Point(this.getVpCenter().x, object.getCenterPoint().y)); + } + + /** + * Centers object Vertically in the viewport, object.top is unchanged + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObjectV(object) { + return this._centerObject(object, new Point(object.getCenterPoint().x, this.getVpCenter().y)); + } + + /** + * Calculate the point in canvas that correspond to the center of actual viewport. + * @return {Point} vpCenter, viewport center + */ + getVpCenter() { + return transformPoint(this.getCenterPoint(), invertTransform(this.viewportTransform)); + } + + /** + * @private + * @param {FabricObject} object Object to center + * @param {Point} center Center point + */ + _centerObject(object, center) { + object.setXY(center, CENTER, CENTER); + object.setCoords(); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Returns dataless JSON representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {String} json string + */ + toDatalessJSON(propertiesToInclude) { + return this.toDatalessObject(propertiesToInclude); + } + + /** + * Returns object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject(propertiesToInclude) { + return this._toObjectMethod('toObject', propertiesToInclude); + } + + /** + * Returns Object representation of canvas + * this alias is provided because if you call JSON.stringify on an instance, + * the toJSON object will be invoked if it exists. + * Having a toJSON method means you can do JSON.stringify(myCanvas) + * @return {Object} JSON compatible object + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} + * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} + * @example JSON without additional properties + * var json = canvas.toJSON(); + * @example JSON with additional properties included + * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']); + * @example JSON without default values + * var json = canvas.toJSON(); + */ + toJSON() { + return this.toObject(); + } + + /** + * Returns dataless object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject(propertiesToInclude) { + return this._toObjectMethod('toDatalessObject', propertiesToInclude); + } + + /** + * @private + */ + _toObjectMethod(methodName, propertiesToInclude) { + const clipPath = this.clipPath; + const clipPathData = clipPath && !clipPath.excludeFromExport ? this._toObject(clipPath, methodName, propertiesToInclude) : null; + return _objectSpread2(_objectSpread2(_objectSpread2({ + version: VERSION + }, pick(this, propertiesToInclude)), {}, { + objects: this._objects.filter(object => !object.excludeFromExport).map(instance => this._toObject(instance, methodName, propertiesToInclude)) + }, this.__serializeBgOverlay(methodName, propertiesToInclude)), clipPathData ? { + clipPath: clipPathData + } : null); + } + + /** + * @private + */ + _toObject(instance, methodName, propertiesToInclude) { + let originalValue; + if (!this.includeDefaultValues) { + originalValue = instance.includeDefaultValues; + instance.includeDefaultValues = false; + } + const object = instance[methodName](propertiesToInclude); + if (!this.includeDefaultValues) { + instance.includeDefaultValues = !!originalValue; + } + return object; + } + + /** + * @private + */ + __serializeBgOverlay(methodName, propertiesToInclude) { + const data = {}, + bgImage = this.backgroundImage, + overlayImage = this.overlayImage, + bgColor = this.backgroundColor, + overlayColor = this.overlayColor; + if (isFiller(bgColor)) { + if (!bgColor.excludeFromExport) { + data.background = bgColor.toObject(propertiesToInclude); + } + } else if (bgColor) { + data.background = bgColor; + } + if (isFiller(overlayColor)) { + if (!overlayColor.excludeFromExport) { + data.overlay = overlayColor.toObject(propertiesToInclude); + } + } else if (overlayColor) { + data.overlay = overlayColor; + } + if (bgImage && !bgImage.excludeFromExport) { + data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude); + } + if (overlayImage && !overlayImage.excludeFromExport) { + data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude); + } + return data; + } + + /* _TO_SVG_START_ */ + + /** + * Returns SVG representation of canvas + * @function + * @param {Object} [options] Options object for SVG output + * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included + * @param {Object} [options.viewBox] SVG viewbox object + * @param {Number} [options.viewBox.x] x-coordinate of viewbox + * @param {Number} [options.viewBox.y] y-coordinate of viewbox + * @param {Number} [options.viewBox.width] Width of viewbox + * @param {Number} [options.viewBox.height] Height of viewbox + * @param {String} [options.encoding=UTF-8] Encoding of SVG output + * @param {String} [options.width] desired width of svg with or without units + * @param {String} [options.height] desired height of svg with or without units + * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. + * @return {String} SVG string + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} + * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} + * @example Normal SVG output + * var svg = canvas.toSVG(); + * @example SVG output without preamble (without <?xml ../>) + * var svg = canvas.toSVG({suppressPreamble: true}); + * @example SVG output with viewBox attribute + * var svg = canvas.toSVG({ + * viewBox: { + * x: 100, + * y: 100, + * width: 200, + * height: 300 + * } + * }); + * @example SVG output with different encoding (default: UTF-8) + * var svg = canvas.toSVG({encoding: 'ISO-8859-1'}); + * @example Modify SVG output with reviver function + * var svg = canvas.toSVG(null, function(svg) { + * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', ''); + * }); + */ + toSVG() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let reviver = arguments.length > 1 ? arguments[1] : undefined; + options.reviver = reviver; + const markup = []; + this._setSVGPreamble(markup, options); + this._setSVGHeader(markup, options); + if (this.clipPath) { + markup.push("\n")); + } + this._setSVGBgOverlayColor(markup, 'background'); + this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver); + this._setSVGObjects(markup, reviver); + if (this.clipPath) { + markup.push('\n'); + } + this._setSVGBgOverlayColor(markup, 'overlay'); + this._setSVGBgOverlayImage(markup, 'overlayImage', reviver); + markup.push(''); + return markup.join(''); + } + + /** + * @private + */ + _setSVGPreamble(markup, options) { + if (options.suppressPreamble) { + return; + } + markup.push('\n', '\n'); + } + + /** + * @private + */ + _setSVGHeader(markup, options) { + const width = options.width || "".concat(this.width), + height = options.height || "".concat(this.height), + NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS, + optViewBox = options.viewBox; + let viewBox; + if (optViewBox) { + viewBox = "viewBox=\"".concat(optViewBox.x, " ").concat(optViewBox.y, " ").concat(optViewBox.width, " ").concat(optViewBox.height, "\" "); + } else if (this.svgViewportTransformation) { + const vpt = this.viewportTransform; + viewBox = "viewBox=\"".concat(toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS), " ").concat(toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS), " ").concat(toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS), " ").concat(toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS), "\" "); + } else { + viewBox = "viewBox=\"0 0 ".concat(this.width, " ").concat(this.height, "\" "); + } + markup.push('\n', 'Created with Fabric.js ', VERSION, '\n', '\n', this.createSVGFontFacesMarkup(), this.createSVGRefElementsMarkup(), this.createSVGClipPathMarkup(options), '\n'); + } + createSVGClipPathMarkup(options) { + const clipPath = this.clipPath; + if (clipPath) { + clipPath.clipPathId = "CLIPPATH_".concat(uid()); + return "\n").concat(clipPath.toClipPathSVG(options.reviver), "\n"); + } + return ''; + } + + /** + * Creates markup containing SVG referenced elements like patterns, gradients etc. + * @return {String} + */ + createSVGRefElementsMarkup() { + return ['background', 'overlay'].map(prop => { + const fill = this["".concat(prop, "Color")]; + if (isFiller(fill)) { + const shouldTransform = this["".concat(prop, "Vpt")], + vpt = this.viewportTransform, + object = { + // otherwise circular dependency + isType: () => false, + width: this.width / (shouldTransform ? vpt[0] : 1), + height: this.height / (shouldTransform ? vpt[3] : 1) + }; + return fill.toSVG(object, { + additionalTransform: shouldTransform ? matrixToSVG(vpt) : '' + }); + } + }).join(''); + } + + /** + * Creates markup containing SVG font faces, + * font URLs for font faces must be collected by developers + * and are not extracted from the DOM by fabricjs + * @param {Array} objects Array of fabric objects + * @return {String} + */ + createSVGFontFacesMarkup() { + const objects = [], + fontList = {}, + fontPaths = config.fontPaths; + this._objects.forEach(function add(object) { + objects.push(object); + if (isCollection(object)) { + object._objects.forEach(add); + } + }); + objects.forEach(obj => { + if (!isTextObject(obj)) { + return; + } + const { + styles, + fontFamily + } = obj; + if (fontList[fontFamily] || !fontPaths[fontFamily]) { + return; + } + fontList[fontFamily] = true; + if (!styles) { + return; + } + Object.values(styles).forEach(styleRow => { + Object.values(styleRow).forEach(_ref => { + let { + fontFamily = '' + } = _ref; + if (!fontList[fontFamily] && fontPaths[fontFamily]) { + fontList[fontFamily] = true; + } + }); + }); + }); + const fontListMarkup = Object.keys(fontList).map(fontFamily => "\t\t@font-face {\n\t\t\tfont-family: '".concat(fontFamily, "';\n\t\t\tsrc: url('").concat(fontPaths[fontFamily], "');\n\t\t}\n")).join(''); + if (fontListMarkup) { + return "\t\n"); + } + return ''; + } + + /** + * @private + */ + _setSVGObjects(markup, reviver) { + this.forEachObject(fabricObject => { + if (fabricObject.excludeFromExport) { + return; + } + this._setSVGObject(markup, fabricObject, reviver); + }); + } + + /** + * This is its own function because the Canvas ( non static ) requires extra code here + * @private + */ + _setSVGObject(markup, instance, reviver) { + markup.push(instance.toSVG(reviver)); + } + + /** + * @private + */ + _setSVGBgOverlayImage(markup, property, reviver) { + const bgOrOverlay = this[property]; + if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) { + markup.push(bgOrOverlay.toSVG(reviver)); + } + } + + /** + * @TODO this seems to handle patterns but fail at gradients. + * @private + */ + _setSVGBgOverlayColor(markup, property) { + const filler = this["".concat(property, "Color")]; + if (!filler) { + return; + } + if (isFiller(filler)) { + const repeat = filler.repeat || '', + finalWidth = this.width, + finalHeight = this.height, + shouldInvert = this["".concat(property, "Vpt")], + additionalTransform = shouldInvert ? matrixToSVG(invertTransform(this.viewportTransform)) : ''; + markup.push("\n")); + } else { + markup.push('\n'); + } + } + /* _TO_SVG_END_ */ + + /** + * Populates canvas with data from the specified JSON. + * JSON format must conform to the one of {@link fabric.Canvas#toJSON} + * + * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking + * + * @param {String|Object} json JSON string or object + * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. + * @param {Object} [options] options + * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @return {Promise} instance + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} + * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} + * @example loadFromJSON + * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll()); + * @example loadFromJSON with reviver + * canvas.loadFromJSON(json, function(o, object) { + * // `o` = json object + * // `object` = fabric.Object instance + * // ... do some stuff ... + * }).then((canvas) => { + * ... canvas is restored, add your code. + * }); + * + */ + loadFromJSON(json, reviver) { + let { + signal + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (!json) { + return Promise.reject(new FabricError('`json` is undefined')); + } + + // parse json if it wasn't already + const serialized = typeof json === 'string' ? JSON.parse(json) : json; + const { + objects = [], + backgroundImage, + background, + overlayImage, + overlay, + clipPath + } = serialized; + const renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; + return Promise.all([enlivenObjects(objects, { + reviver, + signal + }), enlivenObjectEnlivables({ + backgroundImage, + backgroundColor: background, + overlayImage, + overlayColor: overlay, + clipPath + }, { + signal + })]).then(_ref2 => { + let [enlived, enlivedMap] = _ref2; + this.clear(); + this.add(...enlived); + this.set(serialized); + this.set(enlivedMap); + this.renderOnAddRemove = renderOnAddRemove; + return this; + }); + } + + /** + * Clones canvas instance + * @param {string[]} [properties] Array of properties to include in the cloned canvas and children + */ + clone(properties) { + const data = this.toObject(properties); + const canvas = this.cloneWithoutData(); + return canvas.loadFromJSON(data); + } + + /** + * Clones canvas instance without cloning existing data. + * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size. + */ + cloneWithoutData() { + const el = createCanvasElement(); + el.width = this.width; + el.height = this.height; + return new this.constructor(el); + } + + /** + * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately + * @param {Object} [options] Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0 + * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects. + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + * @see {@link https://jsfiddle.net/xsjua1rd/ demo} + * @example Generate jpeg dataURL with lower quality + * var dataURL = canvas.toDataURL({ + * format: 'jpeg', + * quality: 0.8 + * }); + * @example Generate cropped png dataURL (clipping of canvas) + * var dataURL = canvas.toDataURL({ + * format: 'png', + * left: 100, + * top: 100, + * width: 200, + * height: 200 + * }); + * @example Generate double scaled png dataURL + * var dataURL = canvas.toDataURL({ + * format: 'png', + * multiplier: 2 + * }); + * @example Generate dataURL with objects that overlap a specified object + * var myObject; + * var dataURL = canvas.toDataURL({ + * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject) + * }); + */ + toDataURL() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const { + format = 'png', + quality = 1, + multiplier = 1, + enableRetinaScaling = false + } = options; + const finalMultiplier = multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1); + return toDataURL(this.toCanvasElement(finalMultiplier, options), format, quality); + } + + /** + * Create a new HTMLCanvas element painted with the current canvas content. + * No need to resize the actual one or repaint it. + * Will transfer object ownership to a new canvas, paint it, and set everything back. + * This is an intermediary step used to get to a dataUrl but also it is useful to + * create quick image copies of a canvas without passing for the dataUrl string + * @param {Number} [multiplier] a zoom factor. + * @param {Object} [options] Cropping informations + * @param {Number} [options.left] Cropping left offset. + * @param {Number} [options.top] Cropping top offset. + * @param {Number} [options.width] Cropping width. + * @param {Number} [options.height] Cropping height. + * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects. + */ + toCanvasElement() { + let multiplier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + let { + width, + height, + left, + top, + filter + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const scaledWidth = (width || this.width) * multiplier, + scaledHeight = (height || this.height) * multiplier, + zoom = this.getZoom(), + originalWidth = this.width, + originalHeight = this.height, + originalSkipControlsDrawing = this.skipControlsDrawing, + newZoom = zoom * multiplier, + vp = this.viewportTransform, + translateX = (vp[4] - (left || 0)) * multiplier, + translateY = (vp[5] - (top || 0)) * multiplier, + newVp = [newZoom, 0, 0, newZoom, translateX, translateY], + originalRetina = this.enableRetinaScaling, + canvasEl = createCanvasElement(), + objectsToRender = filter ? this._objects.filter(obj => filter(obj)) : this._objects; + canvasEl.width = scaledWidth; + canvasEl.height = scaledHeight; + this.enableRetinaScaling = false; + this.viewportTransform = newVp; + this.width = scaledWidth; + this.height = scaledHeight; + this.skipControlsDrawing = true; + this.calcViewportBoundaries(); + this.renderCanvas(canvasEl.getContext('2d'), objectsToRender); + this.viewportTransform = vp; + this.width = originalWidth; + this.height = originalHeight; + this.calcViewportBoundaries(); + this.enableRetinaScaling = originalRetina; + this.skipControlsDrawing = originalSkipControlsDrawing; + return canvasEl; + } + + /** + * Waits until rendering has settled to destroy the canvas + * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed + * @throws if aborted by a consequent call + */ + dispose() { + !this.disposed && this.elements.cleanupDOM({ + width: this.width, + height: this.height + }); + runningAnimations.cancelByCanvas(this); + this.disposed = true; + return new Promise((resolve, reject) => { + const task = () => { + this.destroy(); + resolve(true); + }; + task.kill = reject; + if (this.__cleanupTask) { + this.__cleanupTask.kill('aborted'); + } + if (this.destroyed) { + resolve(false); + } else if (this.nextRenderHandle) { + this.__cleanupTask = task; + } else { + task(); + } + }); + } + + /** + * Clears the canvas element, disposes objects and frees resources. + * + * Invoked as part of the **async** operation of {@link dispose}. + * + * **CAUTION**: + * + * This method is **UNSAFE**. + * You may encounter a race condition using it if there's a requested render. + * Call this method only if you are sure rendering has settled. + * Consider using {@link dispose} as it is **SAFE** + * + * @private + */ + destroy() { + this.destroyed = true; + this.cancelRequestedRender(); + this.forEachObject(object => object.dispose()); + this._objects = []; + if (this.backgroundImage) { + this.backgroundImage.dispose(); + } + this.backgroundImage = undefined; + if (this.overlayImage) { + this.overlayImage.dispose(); + } + this.overlayImage = undefined; + this.elements.dispose(); + } + + /** + * Returns a string representation of an instance + * @return {String} string representation of an instance + */ + toString() { + return "#"); + } +} +_defineProperty(StaticCanvas, "ownDefaults", staticCanvasDefaults); + +const touchEvents = ['touchstart', 'touchmove', 'touchend']; +function getTouchInfo(event) { + const touchProp = event.changedTouches; + if (touchProp && touchProp[0]) { + return touchProp[0]; + } + return event; +} +const getPointer = event => { + const element = event.target, + scroll = getScrollLeftTop(element), + _evt = getTouchInfo(event); + return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top); +}; +const isTouchEvent = event => touchEvents.includes(event.type) || event.pointerType === 'touch'; +const stopEvent = e => { + e.preventDefault(); + e.stopPropagation(); +}; + +/** + * Calculates bounding box (left, top, width, height) from given `points` + * @param {XY[]} points + * @return {Object} Object with left, top, width, height properties + */ +const makeBoundingBoxFromPoints = points => { + let left = 0, + top = 0, + width = 0, + height = 0; + for (let i = 0, len = points.length; i < len; i++) { + const { + x, + y + } = points[i]; + if (x > width || !i) width = x; + if (x < left || !i) left = x; + if (y > height || !i) height = y; + if (y < top || !i) top = y; + } + return { + left, + top, + width: width - left, + height: height - top + }; +}; + +const _excluded$i = ["translateX", "translateY", "scaleX", "scaleY"]; + +/** + * given an object and a transform, apply the inverse transform to the object, + * this is equivalent to remove from that object that transformation, so that + * added in a space with the removed transform, the object will be the same as before. + * Removing from an object a transform that scale by 2 is like scaling it by 1/2. + * Removing from an object a transform that rotate by 30deg is like rotating by 30deg + * in the opposite direction. + * This util is used to add objects inside transformed groups or nested groups. + * @param {FabricObject} object the object you want to transform + * @param {TMat2D} transform the destination transform + */ +const removeTransformFromObject = (object, transform) => { + const inverted = invertTransform(transform), + finalTransform = multiplyTransformMatrices(inverted, object.calcOwnMatrix()); + applyTransformToObject(object, finalTransform); +}; + +/** + * given an object and a transform, apply the transform to the object. + * this is equivalent to change the space where the object is drawn. + * Adding to an object a transform that scale by 2 is like scaling it by 2. + * This is used when removing an object from an active selection for example. + * @param {FabricObject} object the object you want to transform + * @param {Array} transform the destination transform + */ +const addTransformToObject = (object, transform) => applyTransformToObject(object, multiplyTransformMatrices(transform, object.calcOwnMatrix())); + +/** + * discard an object transform state and apply the one from the matrix. + * @param {FabricObject} object the object you want to transform + * @param {Array} transform the destination transform + */ +const applyTransformToObject = (object, transform) => { + const _qrDecompose = qrDecompose(transform), + { + translateX, + translateY, + scaleX, + scaleY + } = _qrDecompose, + otherOptions = _objectWithoutProperties(_qrDecompose, _excluded$i), + center = new Point(translateX, translateY); + object.flipX = false; + object.flipY = false; + Object.assign(object, otherOptions); + object.set({ + scaleX, + scaleY + }); + object.setPositionByOrigin(center, CENTER, CENTER); +}; +/** + * reset an object transform state to neutral. Top and left are not accounted for + * @param {FabricObject} target object to transform + */ +const resetObjectTransform = target => { + target.scaleX = 1; + target.scaleY = 1; + target.skewX = 0; + target.skewY = 0; + target.flipX = false; + target.flipY = false; + target.rotate(0); +}; + +/** + * Extract Object transform values + * @param {FabricObject} target object to read from + * @return {Object} Components of transform + */ +const saveObjectTransform = target => ({ + scaleX: target.scaleX, + scaleY: target.scaleY, + skewX: target.skewX, + skewY: target.skewY, + angle: target.angle, + left: target.left, + flipX: target.flipX, + flipY: target.flipY, + top: target.top +}); + +/** + * given a width and height, return the size of the bounding box + * that can contains the box with width/height with applied transform. + * Use to calculate the boxes around objects for controls. + * @param {Number} width + * @param {Number} height + * @param {TMat2D} t + * @returns {Point} size + */ +const sizeAfterTransform = (width, height, t) => { + const dimX = width / 2, + dimY = height / 2, + points = [new Point(-dimX, -dimY), new Point(dimX, -dimY), new Point(-dimX, dimY), new Point(dimX, dimY)].map(p => p.transform(t)), + bbox = makeBoundingBoxFromPoints(points); + return new Point(bbox.width, bbox.height); +}; + +/** + * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\ + * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`) + * @param [from] + * @param [to] + * @returns + */ +const calcPlaneChangeMatrix = function () { + let from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : iMatrix; + let to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + return multiplyTransformMatrices(invertTransform(to), from); +}; + +/** + * Sends a point from the source coordinate plane to the destination coordinate plane.\ + * From the canvas/viewer's perspective the point remains unchanged. + * + * @example Send point from canvas plane to group plane + * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 }); + * var group = new Group([obj], { strokeWidth: 0 }); + * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix()); + * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix()); + * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group + * + * @param {Point} point + * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane. + * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane. + * @returns {Point} transformed point + */ +const sendPointToPlane = function (point) { + let from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + let to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : iMatrix; + return point.transform(calcPlaneChangeMatrix(from, to)); +}; + +/** + * See {@link sendPointToPlane} + */ +const sendVectorToPlane = function (point) { + let from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + let to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : iMatrix; + return point.transform(calcPlaneChangeMatrix(from, to), true); +}; + +/** + * + * A util that abstracts applying transform to objects.\ + * Sends `object` to the destination coordinate plane by applying the relevant transformations.\ + * Changes the space/plane where `object` is drawn.\ + * From the canvas/viewer's perspective `object` remains unchanged. + * + * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer + * let obj, obj2; + * let clipPath = new Circle({ radius: 50 }); + * obj.clipPath = clipPath; + * // render + * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix()); + * obj.clipPath = undefined; + * obj2.clipPath = clipPath; + * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer + * + * @example Clip an object's clip path with an existing object + * let obj, existingObj; + * let clipPath = new Circle({ radius: 50 }); + * obj.clipPath = clipPath; + * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix()); + * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo); + * clipPath.clipPath = existingObj; + * + * @param {FabricObject} object + * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas. + * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane. + * @returns {Matrix} the transform matrix that was applied to `object` + */ +const sendObjectToPlane = (object, from, to) => { + const t = calcPlaneChangeMatrix(from, to); + applyTransformToObject(object, multiplyTransformMatrices(t, object.calcOwnMatrix())); + return t; +}; + +const fireEvent = (eventName, options) => { + var _target$canvas; + const { + transform: { + target + } + } = options; + (_target$canvas = target.canvas) === null || _target$canvas === void 0 || _target$canvas.fire("object:".concat(eventName), _objectSpread2(_objectSpread2({}, options), {}, { + target + })); + target.fire(eventName, options); +}; + +const originOffset = { + left: -0.5, + top: -0.5, + center: 0, + bottom: 0.5, + right: 0.5 +}; +/** + * Resolves origin value relative to center + * @private + * @param {TOriginX | TOriginY} originValue originX / originY + * @returns number + */ + +const resolveOrigin = originValue => typeof originValue === 'string' ? originOffset[originValue] : originValue - 0.5; + +const NOT_ALLOWED_CURSOR = 'not-allowed'; + +/** + * @param {Boolean} alreadySelected true if target is already selected + * @param {String} corner a string representing the corner ml, mr, tl ... + * @param {Event} e Event object + * @param {FabricObject} [target] inserted back to help overriding. Unused + */ +const getActionFromCorner = (alreadySelected, corner, e, target) => { + if (!corner || !alreadySelected) { + return 'drag'; + } + const control = target.controls[corner]; + return control.getActionName(e, control, target); +}; + +/** + * Checks if transform is centered + * @param {Object} transform transform data + * @return {Boolean} true if transform is centered + */ +function isTransformCentered(transform) { + return resolveOrigin(transform.originX) === resolveOrigin(CENTER) && resolveOrigin(transform.originY) === resolveOrigin(CENTER); +} +function invertOrigin(origin) { + return -resolveOrigin(origin) + 0.5; +} +const isLocked = (target, lockingKey) => target[lockingKey]; +const commonEventInfo = (eventData, transform, x, y) => { + return { + e: eventData, + transform, + pointer: new Point(x, y) + }; +}; + +/** + * Combine control position and object angle to find the control direction compared + * to the object center. + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + * @param {Control} control the control class + * @return {Number} 0 - 7 a quadrant number + */ +function findCornerQuadrant(fabricObject, control) { + // angle is relative to canvas plane + const angle = fabricObject.getTotalAngle(), + cornerAngle = angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360; + return Math.round(cornerAngle % 360 / 45); +} + +/** + * @returns the normalized point (rotated relative to center) in local coordinates + */ +function normalizePoint(target, point, originX, originY) { + const center = target.getRelativeCenterPoint(), + p = typeof originX !== 'undefined' && typeof originY !== 'undefined' ? target.translateToGivenOrigin(center, CENTER, CENTER, originX, originY) : new Point(target.left, target.top), + p2 = target.angle ? point.rotate(-degreesToRadians(target.angle), center) : point; + return p2.subtract(p); +} + +/** + * Transforms a point to the offset from the given origin + * @param {Object} transform + * @param {String} originX + * @param {String} originY + * @param {number} x + * @param {number} y + * @return {Fabric.Point} the normalized point + */ +function getLocalPoint(_ref, originX, originY, x, y) { + var _target$canvas; + let { + target, + corner + } = _ref; + const control = target.controls[corner], + zoom = ((_target$canvas = target.canvas) === null || _target$canvas === void 0 ? void 0 : _target$canvas.getZoom()) || 1, + padding = target.padding / zoom, + localPoint = normalizePoint(target, new Point(x, y), originX, originY); + if (localPoint.x >= padding) { + localPoint.x -= padding; + } + if (localPoint.x <= -padding) { + localPoint.x += padding; + } + if (localPoint.y >= padding) { + localPoint.y -= padding; + } + if (localPoint.y <= padding) { + localPoint.y += padding; + } + localPoint.x -= control.offsetX; + localPoint.y -= control.offsetY; + return localPoint; +} + +/** + * Action handler + * @private + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if the translation occurred + */ +const dragHandler = (eventData, transform, x, y) => { + const { + target, + offsetX, + offsetY + } = transform, + newLeft = x - offsetX, + newTop = y - offsetY, + moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft, + moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop; + moveX && target.set(LEFT, newLeft); + moveY && target.set(TOP, newTop); + if (moveX || moveY) { + fireEvent(MOVING, commonEventInfo(eventData, transform, x, y)); + } + return moveX || moveY; +}; + +class FabricObjectSVGExportMixin { + /** + * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed. + * This reference is a UID in the fabric namespace and is temporary stored here. + * @type {String} + */ + + /** + * Returns styles-string for svg-export + * @param {Boolean} skipShadow a boolean to skip shadow filter output + * @return {String} + */ + getSvgStyles(skipShadow) { + const fillRule = this.fillRule ? this.fillRule : 'nonzero', + strokeWidth = this.strokeWidth ? this.strokeWidth : '0', + strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : NONE, + strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', + strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', + strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', + strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', + opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', + visibility = this.visible ? '' : ' visibility: hidden;', + filter = skipShadow ? '' : this.getSvgFilter(), + fill = colorPropToSVG(FILL, this.fill), + stroke = colorPropToSVG(STROKE, this.stroke); + return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].join(''); + } + + /** + * Returns filter for svg shadow + * @return {String} + */ + getSvgFilter() { + return this.shadow ? "filter: url(#SVGID_".concat(this.shadow.id, ");") : ''; + } + + /** + * Returns id attribute for svg output + * @return {String} + */ + getSvgCommons() { + return [this.id ? "id=\"".concat(this.id, "\" ") : '', this.clipPath ? "clip-path=\"url(#".concat(this.clipPath.clipPathId, ")\" ") : ''].join(''); + } + + /** + * Returns transform-string for svg-export + * @param {Boolean} use the full transform or the single object one. + * @return {String} + */ + getSvgTransform(full) { + let additionalTransform = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), + svgTransform = "transform=\"".concat(matrixToSVG(transform)); + return "".concat(svgTransform).concat(additionalTransform, "\" "); + } + + /** + * Returns svg representation of an instance + * This function is implemented in each subclass + * This is just because typescript otherwise cryies all the time + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG(_reviver) { + return ['']; + } + + /** + * Returns svg representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG(reviver) { + return this._createBaseSVGMarkup(this._toSVG(reviver), { + reviver + }); + } + + /** + * Returns svg clipPath representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toClipPathSVG(reviver) { + return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { + reviver + }); + } + + /** + * @private + */ + _createBaseClipPathSVGMarkup(objectMarkup) { + let { + reviver, + additionalTransform = '' + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const commonPieces = [this.getSvgTransform(true, additionalTransform), this.getSvgCommons()].join(''), + // insert commons in the markup, style and svgCommons + index = objectMarkup.indexOf('COMMON_PARTS'); + objectMarkup[index] = commonPieces; + return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); + } + + /** + * @private + */ + _createBaseSVGMarkup(objectMarkup) { + let { + noStyle, + reviver, + withShadow, + additionalTransform + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const styleInfo = noStyle ? '' : "style=\"".concat(this.getSvgStyles(), "\" "), + shadowInfo = withShadow ? "style=\"".concat(this.getSvgFilter(), "\" ") : '', + clipPath = this.clipPath, + vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', + absoluteClipPath = clipPath && clipPath.absolutePositioned, + stroke = this.stroke, + fill = this.fill, + shadow = this.shadow, + markup = [], + // insert commons in the markup, style and svgCommons + index = objectMarkup.indexOf('COMMON_PARTS'); + let clipPathMarkup; + if (clipPath) { + clipPath.clipPathId = "CLIPPATH_".concat(uid()); + clipPathMarkup = "\n").concat(clipPath.toClipPathSVG(reviver), "\n"); + } + if (absoluteClipPath) { + markup.push('\n'); + } + markup.push('\n'); + const commonPieces = [styleInfo, vectorEffect, noStyle ? '' : this.addPaintOrder(), ' ', additionalTransform ? "transform=\"".concat(additionalTransform, "\" ") : ''].join(''); + objectMarkup[index] = commonPieces; + if (isFiller(fill)) { + markup.push(fill.toSVG(this)); + } + if (isFiller(stroke)) { + markup.push(stroke.toSVG(this)); + } + if (shadow) { + markup.push(shadow.toSVG(this)); + } + if (clipPath) { + markup.push(clipPathMarkup); + } + markup.push(objectMarkup.join('')); + markup.push('\n'); + absoluteClipPath && markup.push('\n'); + return reviver ? reviver(markup.join('')) : markup.join(''); + } + addPaintOrder() { + return this.paintFirst !== FILL ? " paint-order=\"".concat(this.paintFirst, "\" ") : ''; + } +} + +function getSvgRegex(arr) { + return new RegExp('^(' + arr.join('|') + ')\\b', 'i'); +} + +var _templateObject$1; +const reNum = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"]))); +const svgNS = 'http://www.w3.org/2000/svg'; +const reFontDeclaration = new RegExp('(normal|italic)?\\s*(normal|small-caps)?\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + reNum + '))?\\s+(.*)'); +const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'], + svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'], + svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'], + svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'], + attributesMap = { + cx: LEFT, + x: LEFT, + r: 'radius', + cy: TOP, + y: TOP, + display: 'visible', + visibility: 'visible', + transform: 'transformMatrix', + 'fill-opacity': 'fillOpacity', + 'fill-rule': 'fillRule', + 'font-family': 'fontFamily', + 'font-size': 'fontSize', + 'font-style': 'fontStyle', + 'font-weight': 'fontWeight', + 'letter-spacing': 'charSpacing', + 'paint-order': 'paintFirst', + 'stroke-dasharray': 'strokeDashArray', + 'stroke-dashoffset': 'strokeDashOffset', + 'stroke-linecap': 'strokeLineCap', + 'stroke-linejoin': 'strokeLineJoin', + 'stroke-miterlimit': 'strokeMiterLimit', + 'stroke-opacity': 'strokeOpacity', + 'stroke-width': 'strokeWidth', + 'text-decoration': 'textDecoration', + 'text-anchor': 'textAnchor', + opacity: 'opacity', + 'clip-path': 'clipPath', + 'clip-rule': 'clipRule', + 'vector-effect': 'strokeUniform', + 'image-rendering': 'imageSmoothing' + }, + fSize = 'font-size', + cPath = 'clip-path'; +const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames); +const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements); +const svgValidParentsRegEx = getSvgRegex(svgValidParents); + +// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute +// matches, e.g.: +14.56e-12, etc. +const reViewBoxAttrValue = new RegExp('^' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*' + '$'); + +const unitVectorX = new Point(1, 0); +const zero = new Point(); + +/** + * Rotates `vector` with `radians` + * @param {Point} vector The vector to rotate (x and y) + * @param {Number} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ +const rotateVector = (vector, radians) => vector.rotate(radians); + +/** + * Creates a vector from points represented as a point + * + * @param {Point} from + * @param {Point} to + * @returns {Point} vector + */ +const createVector = (from, to) => new Point(to).subtract(from); + +/** + * return the magnitude of a vector + * @return {number} + */ +const magnitude = point => point.distanceFrom(zero); + +/** + * Calculates the angle between 2 vectors + * @param {Point} a + * @param {Point} b + * @returns the angle in radians from `a` to `b` + */ +const calcAngleBetweenVectors = (a, b) => Math.atan2(crossProduct(a, b), dotProduct(a, b)); + +/** + * Calculates the angle between the x axis and the vector + * @param {Point} v + * @returns the angle in radians of `v` + */ +const calcVectorRotation = v => calcAngleBetweenVectors(unitVectorX, v); + +/** + * @param {Point} v + * @returns {Point} vector representing the unit vector pointing to the direction of `v` + */ +const getUnitVector = v => v.eq(zero) ? v : v.scalarDivide(magnitude(v)); + +/** + * @param {Point} v + * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true` + * @returns {Point} the unit orthogonal vector + */ +const getOrthonormalVector = function (v) { + let counterClockwise = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1)); +}; + +/** + * Cross product of two vectors in 2D + * @param {Point} a + * @param {Point} b + * @returns {number} the magnitude of Z vector + */ +const crossProduct = (a, b) => a.x * b.y - a.y * b.x; + +/** + * Dot product of two vectors in 2D + * @param {Point} a + * @param {Point} b + * @returns {number} + */ +const dotProduct = (a, b) => a.x * b.x + a.y * b.y; + +/** + * Checks if the vector is between two others. It is considered + * to be inside when the vector to be tested is between the + * initial vector and the final vector (included) in a counterclockwise direction. + * @param {Point} t vector to be tested + * @param {Point} a initial vector + * @param {Point} b final vector + * @returns {boolean} true if the vector is among the others + */ +const isBetweenVectors = (t, a, b) => { + if (t.eq(a) || t.eq(b)) return true; + const AxB = crossProduct(a, b), + AxT = crossProduct(a, t), + BxT = crossProduct(b, t); + return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0); +}; + +/** + * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px") + * - (?:\s|^): This part captures either a whitespace character (\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group. + * - (-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down: + * - (-?\d+): Captures an optional minus sign followed by one or more digits (integer part of the number). + * - (?:\.\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number). + * - (?:px)?: Optionally captures the "px" unit. + * - (?:\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?. + * - (-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?: Similar to the previous step, this captures the vertical offset. + +(\d+(?:\.\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign. + +(?:\s+(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and "px" unit. + +(?:$|\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character. + */ +// eslint-disable-next-line max-len + +const shadowOffsetRegex = '(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?'; +const reOffsetsAndBlur = new RegExp('(?:\\s|^)' + shadowOffsetRegex + shadowOffsetRegex + '(' + reNum + '?(?:px)?)?(?:\\s?|$)(?:$|\\s)'); +const shadowDefaultValues = { + color: 'rgb(0,0,0)', + blur: 0, + offsetX: 0, + offsetY: 0, + affectStroke: false, + includeDefaultValues: true, + nonScaling: false +}; +class Shadow { + /** + * @see {@link http://fabricjs.com/shadows|Shadow demo} + * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px") + */ + + constructor(arg0) { + const options = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0; + Object.assign(this, Shadow.ownDefaults, options); + this.id = uid(); + } + + /** + * @param {String} value Shadow value to parse + * @return {Object} Shadow object with color, offsetX, offsetY and blur + */ + static parseShadow(value) { + const shadowStr = value.trim(), + [, offsetX = 0, offsetY = 0, blur = 0] = (reOffsetsAndBlur.exec(shadowStr) || []).map(value => parseFloat(value) || 0), + color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim(); + return { + color, + offsetX, + offsetY, + blur + }; + } + + /** + * Returns a string representation of an instance + * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow + * @return {String} Returns CSS3 text-shadow declaration + */ + toString() { + return [this.offsetX, this.offsetY, this.blur, this.color].join('px '); + } + + /** + * Returns SVG representation of a shadow + * @param {FabricObject} object + * @return {String} SVG representation of a shadow + */ + toSVG(object) { + const offset = rotateVector(new Point(this.offsetX, this.offsetY), degreesToRadians(-object.angle)), + BLUR_BOX = 20, + color = new Color(this.color); + let fBoxX = 40, + fBoxY = 40; + if (object.width && object.height) { + //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion + // we add some extra space to filter box to contain the blur ( 20 ) + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, config.NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, config.NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; + } + if (object.flipX) { + offset.x *= -1; + } + if (object.flipY) { + offset.y *= -1; + } + return "\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n"); + } + + /** + * Returns object representation of a shadow + * @return {Object} Object representation of a shadow instance + */ + toObject() { + const data = { + color: this.color, + blur: this.blur, + offsetX: this.offsetX, + offsetY: this.offsetY, + affectStroke: this.affectStroke, + nonScaling: this.nonScaling, + type: this.constructor.type + }; + const defaults = Shadow.ownDefaults; + return !this.includeDefaultValues ? pickBy(data, (value, key) => value !== defaults[key]) : data; + } + static async fromObject(options) { + return new this(options); + } +} +/** + * Shadow color + * @type String + * @default + */ +/** + * Shadow blur + * @type Number + */ +/** + * Shadow horizontal offset + * @type Number + * @default + */ +/** + * Shadow vertical offset + * @type Number + * @default + */ +/** + * Whether the shadow should affect stroke operations + * @type Boolean + * @default + */ +/** + * Indicates whether toObject should include default values + * @type Boolean + * @default + */ +/** + * When `false`, the shadow will scale with the object. + * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale. + * default to false + * @type Boolean + * @default + */ +_defineProperty(Shadow, "ownDefaults", shadowDefaultValues); +_defineProperty(Shadow, "type", 'shadow'); +classRegistry.setClass(Shadow, 'shadow'); + +const capValue = (min, value, max) => Math.max(min, Math.min(value, max)); + +const stateProperties = [TOP, LEFT, SCALE_X, SCALE_Y, 'flipX', 'flipY', 'originX', 'originY', 'angle', 'opacity', 'globalCompositeOperation', 'shadow', 'visible', SKEW_X, SKEW_Y]; +const cacheProperties = [FILL, STROKE, 'strokeWidth', 'strokeDashArray', 'width', 'height', 'paintFirst', 'strokeUniform', 'strokeLineCap', 'strokeDashOffset', 'strokeLineJoin', 'strokeMiterLimit', 'backgroundColor', 'clipPath']; +const fabricObjectDefaultValues = { + // see composeMatrix() to see order of transforms. First defaults listed based on this + top: 0, + left: 0, + width: 0, + height: 0, + angle: 0, + flipX: false, + flipY: false, + scaleX: 1, + scaleY: 1, + minScaleLimit: 0, + skewX: 0, + skewY: 0, + originX: LEFT, + originY: TOP, + strokeWidth: 1, + strokeUniform: false, + padding: 0, + opacity: 1, + paintFirst: FILL, + fill: 'rgb(0,0,0)', + fillRule: 'nonzero', + stroke: null, + strokeDashArray: null, + strokeDashOffset: 0, + strokeLineCap: 'butt', + strokeLineJoin: 'miter', + strokeMiterLimit: 4, + globalCompositeOperation: 'source-over', + backgroundColor: '', + shadow: null, + visible: true, + includeDefaultValues: true, + excludeFromExport: false, + objectCaching: true, + clipPath: undefined, + inverted: false, + absolutePositioned: false, + centeredRotation: true, + centeredScaling: false, + dirty: true +}; +const interactiveObjectDefaultValues = { + noScaleCache: true, + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, + lockSkewingX: false, + lockSkewingY: false, + lockScalingFlip: false, + cornerSize: 13, + touchCornerSize: 24, + transparentCorners: true, + cornerColor: 'rgb(178,204,255)', + cornerStrokeColor: '', + cornerStyle: 'rect', + cornerDashArray: null, + hasControls: true, + borderColor: 'rgb(178,204,255)', + borderDashArray: null, + borderOpacityWhenMoving: 0.4, + borderScaleFactor: 1, + hasBorders: true, + selectionBackgroundColor: '', + selectable: true, + evented: true, + perPixelTargetFind: false, + activeOn: 'down', + hoverCursor: null, + moveCursor: null +}; + +/** + * Easing functions + * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner} + */ + +const normalize = (a, c, p, s) => { + if (a < Math.abs(c)) { + a = c; + s = p / 4; + } else { + //handle the 0/0 case: + if (c === 0 && a === 0) { + s = p / twoMathPi * Math.asin(1); + } else { + s = p / twoMathPi * Math.asin(c / a); + } + } + return { + a, + c, + p, + s + }; +}; +const elastic = (a, s, p, t, d) => a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * twoMathPi / p); + +/** + * Default sinusoidal easing + */ +const defaultEasing = (t, b, c, d) => -c * Math.cos(t / d * halfPI) + c + b; + +/** + * Cubic easing in + */ +const easeInCubic = (t, b, c, d) => c * (t / d) ** 3 + b; + +/** + * Cubic easing out + */ +const easeOutCubic = (t, b, c, d) => c * ((t / d - 1) ** 3 + 1) + b; + +/** + * Cubic easing in and out + */ +const easeInOutCubic = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 3 + b; + } + return c / 2 * ((t - 2) ** 3 + 2) + b; +}; + +/** + * Quartic easing in + */ +const easeInQuart = (t, b, c, d) => c * (t /= d) * t ** 3 + b; + +/** + * Quartic easing out + */ +const easeOutQuart = (t, b, c, d) => -c * ((t = t / d - 1) * t ** 3 - 1) + b; + +/** + * Quartic easing in and out + */ +const easeInOutQuart = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 4 + b; + } + return -c / 2 * ((t -= 2) * t ** 3 - 2) + b; +}; + +/** + * Quintic easing in + */ +const easeInQuint = (t, b, c, d) => c * (t / d) ** 5 + b; + +/** + * Quintic easing out + */ +const easeOutQuint = (t, b, c, d) => c * ((t / d - 1) ** 5 + 1) + b; + +/** + * Quintic easing in and out + */ +const easeInOutQuint = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 5 + b; + } + return c / 2 * ((t - 2) ** 5 + 2) + b; +}; + +/** + * Sinusoidal easing in + */ +const easeInSine = (t, b, c, d) => -c * Math.cos(t / d * halfPI) + c + b; + +/** + * Sinusoidal easing out + */ +const easeOutSine = (t, b, c, d) => c * Math.sin(t / d * halfPI) + b; + +/** + * Sinusoidal easing in and out + */ +const easeInOutSine = (t, b, c, d) => -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; + +/** + * Exponential easing in + */ +const easeInExpo = (t, b, c, d) => t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b; + +/** + * Exponential easing out + */ +const easeOutExpo = (t, b, c, d) => t === d ? b + c : c * -(2 ** (-10 * t / d) + 1) + b; + +/** + * Exponential easing in and out + */ +const easeInOutExpo = (t, b, c, d) => { + if (t === 0) { + return b; + } + if (t === d) { + return b + c; + } + t /= d / 2; + if (t < 1) { + return c / 2 * 2 ** (10 * (t - 1)) + b; + } + return c / 2 * -(2 ** (-10 * --t) + 2) + b; +}; + +/** + * Circular easing in + */ +const easeInCirc = (t, b, c, d) => -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; + +/** + * Circular easing out + */ +const easeOutCirc = (t, b, c, d) => c * Math.sqrt(1 - (t = t / d - 1) * t) + b; + +/** + * Circular easing in and out + */ +const easeInOutCirc = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return -c / 2 * (Math.sqrt(1 - t ** 2) - 1) + b; + } + return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; +}; + +/** + * Elastic easing in + */ +const easeInElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + const { + a: normA, + s: normS, + p: normP + } = normalize(a, c, p, s); + return -elastic(normA, normS, normP, t, d) + b; +}; + +/** + * Elastic easing out + */ +const easeOutElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + const { + a: normA, + s: normS, + p: normP, + c: normC + } = normalize(a, c, p, s); + return normA * 2 ** (-10 * t) * Math.sin((t * d - normS) * twoMathPi / normP) + normC + b; +}; + +/** + * Elastic easing in and out + */ +const easeInOutElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d / 2; + if (t === 2) { + return b + c; + } + if (!p) { + p = d * (0.3 * 1.5); + } + const { + a: normA, + s: normS, + p: normP, + c: normC + } = normalize(a, c, p, s); + if (t < 1) { + return -0.5 * elastic(normA, normS, normP, t, d) + b; + } + return normA * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - normS) * twoMathPi / normP) * 0.5 + normC + b; +}; + +/** + * Backwards easing in + */ +const easeInBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + return c * (t /= d) * t * ((s + 1) * t - s) + b; +}; + +/** + * Backwards easing out + */ +const easeOutBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; +}; + +/** + * Backwards easing in and out + */ +const easeInOutBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + t /= d / 2; + if (t < 1) { + return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; + } + return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; +}; + +/** + * Bouncing easing out + */ +const easeOutBounce = (t, b, c, d) => { + if ((t /= d) < 1 / 2.75) { + return c * (7.5625 * t * t) + b; + } else if (t < 2 / 2.75) { + return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b; + } else if (t < 2.5 / 2.75) { + return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b; + } else { + return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b; + } +}; + +/** + * Bouncing easing in + */ +const easeInBounce = (t, b, c, d) => c - easeOutBounce(d - t, 0, c, d) + b; + +/** + * Bouncing easing in and out + */ +const easeInOutBounce = (t, b, c, d) => t < d / 2 ? easeInBounce(t * 2, 0, c, d) * 0.5 + b : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; + +/** + * Quadratic easing in + */ +const easeInQuad = (t, b, c, d) => c * (t /= d) * t + b; + +/** + * Quadratic easing out + */ +const easeOutQuad = (t, b, c, d) => -c * (t /= d) * (t - 2) + b; + +/** + * Quadratic easing in and out + */ +const easeInOutQuad = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 2 + b; + } + return -c / 2 * (--t * (t - 2) - 1) + b; +}; + +var easing = /*#__PURE__*/Object.freeze({ + __proto__: null, + defaultEasing: defaultEasing, + easeInBack: easeInBack, + easeInBounce: easeInBounce, + easeInCirc: easeInCirc, + easeInCubic: easeInCubic, + easeInElastic: easeInElastic, + easeInExpo: easeInExpo, + easeInOutBack: easeInOutBack, + easeInOutBounce: easeInOutBounce, + easeInOutCirc: easeInOutCirc, + easeInOutCubic: easeInOutCubic, + easeInOutElastic: easeInOutElastic, + easeInOutExpo: easeInOutExpo, + easeInOutQuad: easeInOutQuad, + easeInOutQuart: easeInOutQuart, + easeInOutQuint: easeInOutQuint, + easeInOutSine: easeInOutSine, + easeInQuad: easeInQuad, + easeInQuart: easeInQuart, + easeInQuint: easeInQuint, + easeInSine: easeInSine, + easeOutBack: easeOutBack, + easeOutBounce: easeOutBounce, + easeOutCirc: easeOutCirc, + easeOutCubic: easeOutCubic, + easeOutElastic: easeOutElastic, + easeOutExpo: easeOutExpo, + easeOutQuad: easeOutQuad, + easeOutQuart: easeOutQuart, + easeOutQuint: easeOutQuint, + easeOutSine: easeOutSine +}); + +const defaultAbort = () => false; +class AnimationBase { + /** + * Current value + */ + + /** + * Animation start time ms + */ + + constructor(_ref) { + let { + startValue, + byValue, + duration = 500, + delay = 0, + easing = defaultEasing, + onStart = noop, + onChange = noop, + onComplete = noop, + abort = defaultAbort, + target + } = _ref; + /** + * Used to register the animation to a target object + * so that it can be cancelled within the object context + */ + _defineProperty(this, "_state", 'pending'); + /** + * Time %, or the ratio of `timeElapsed / duration` + * @see tick + */ + _defineProperty(this, "durationProgress", 0); + /** + * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)` + */ + _defineProperty(this, "valueProgress", 0); + this.tick = this.tick.bind(this); + this.duration = duration; + this.delay = delay; + this.easing = easing; + this._onStart = onStart; + this._onChange = onChange; + this._onComplete = onComplete; + this._abort = abort; + this.target = target; + this.startValue = startValue; + this.byValue = byValue; + this.value = this.startValue; + this.endValue = Object.freeze(this.calculate(this.duration).value); + } + get state() { + return this._state; + } + isDone() { + return this._state === 'aborted' || this._state === 'completed'; + } + + /** + * Calculate the current value based on the easing parameters + * @param timeElapsed in ms + * @protected + */ + + start() { + const firstTick = timestamp => { + if (this._state !== 'pending') return; + this.startTime = timestamp || +new Date(); + this._state = 'running'; + this._onStart(); + this.tick(this.startTime); + }; + this.register(); + + // setTimeout(cb, 0) will run cb on the next frame, causing a delay + // we don't want that + if (this.delay > 0) { + setTimeout(() => requestAnimFrame(firstTick), this.delay); + } else { + requestAnimFrame(firstTick); + } + } + tick(t) { + const durationMs = (t || +new Date()) - this.startTime; + const boundDurationMs = Math.min(durationMs, this.duration); + this.durationProgress = boundDurationMs / this.duration; + const { + value, + valueProgress + } = this.calculate(boundDurationMs); + this.value = Object.freeze(value); + this.valueProgress = valueProgress; + if (this._state === 'aborted') { + return; + } else if (this._abort(this.value, this.valueProgress, this.durationProgress)) { + this._state = 'aborted'; + this.unregister(); + } else if (durationMs >= this.duration) { + this.durationProgress = this.valueProgress = 1; + this._onChange(this.endValue, this.valueProgress, this.durationProgress); + this._state = 'completed'; + this._onComplete(this.endValue, this.valueProgress, this.durationProgress); + this.unregister(); + } else { + this._onChange(this.value, this.valueProgress, this.durationProgress); + requestAnimFrame(this.tick); + } + } + register() { + runningAnimations.push(this); + } + unregister() { + runningAnimations.remove(this); + } + abort() { + this._state = 'aborted'; + this.unregister(); + } +} + +const _excluded$h = ["startValue", "endValue"]; +class ValueAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue = 0, + endValue = 100 + } = _ref, + otherOptions = _objectWithoutProperties(_ref, _excluded$h); + super(_objectSpread2(_objectSpread2({}, otherOptions), {}, { + startValue, + byValue: endValue - startValue + })); + } + calculate(timeElapsed) { + const value = this.easing(timeElapsed, this.startValue, this.byValue, this.duration); + return { + value, + valueProgress: Math.abs((value - this.startValue) / this.byValue) + }; + } +} + +const _excluded$g = ["startValue", "endValue"]; +class ArrayAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue = [0], + endValue = [100] + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$g); + super(_objectSpread2(_objectSpread2({}, options), {}, { + startValue, + byValue: endValue.map((value, i) => value - startValue[i]) + })); + } + calculate(timeElapsed) { + const values = this.startValue.map((value, i) => this.easing(timeElapsed, value, this.byValue[i], this.duration, i)); + return { + value: values, + valueProgress: Math.abs((values[0] - this.startValue[0]) / this.byValue[0]) + }; + } +} + +const _excluded$f = ["startValue", "endValue", "easing", "onChange", "onComplete", "abort"]; +const defaultColorEasing = (timeElapsed, startValue, byValue, duration) => { + const durationProgress = 1 - Math.cos(timeElapsed / duration * halfPI); + return startValue + byValue * durationProgress; +}; +const wrapColorCallback = callback => callback && ((rgba, valueProgress, durationProgress) => callback(new Color(rgba).toRgba(), valueProgress, durationProgress)); +class ColorAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue, + endValue, + easing = defaultColorEasing, + onChange, + onComplete, + abort + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$f); + const startColor = new Color(startValue).getSource(); + const endColor = new Color(endValue).getSource(); + super(_objectSpread2(_objectSpread2({}, options), {}, { + startValue: startColor, + byValue: endColor.map((value, i) => value - startColor[i]), + easing, + onChange: wrapColorCallback(onChange), + onComplete: wrapColorCallback(onComplete), + abort: wrapColorCallback(abort) + })); + } + calculate(timeElapsed) { + const [r, g, b, a] = this.startValue.map((value, i) => this.easing(timeElapsed, value, this.byValue[i], this.duration, i)); + const value = [...[r, g, b].map(Math.round), capValue(0, a, 1)]; + return { + value, + valueProgress: + // to correctly calculate the change ratio we must find a changed value + value.map((p, i) => this.byValue[i] !== 0 ? Math.abs((p - this.startValue[i]) / this.byValue[i]) : 0).find(p => p !== 0) || 0 + }; + } +} + +const isArrayAnimation = options => { + return Array.isArray(options.startValue) || Array.isArray(options.endValue); +}; + +/** + * Changes value(s) from startValue to endValue within a certain period of time, + * invoking callbacks as the value(s) change. + * + * @example + * animate({ + * startValue: 1, + * endValue: 0, + * onChange: (v) => { + * obj.set('opacity', v); + * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll` + * canvas.renderAll(); + * } + * }); + * + * @example Using lists: + * animate({ + * startValue: [1, 2, 3], + * endValue: [2, 4, 6], + * onChange: ([x, y, zoom]) => { + * canvas.zoomToPoint(new Point(x, y), zoom); + * canvas.renderAll(); + * } + * }); + * + */ + +function animate(options) { + const animation = isArrayAnimation(options) ? new ArrayAnimation(options) : new ValueAnimation(options); + animation.start(); + return animation; +} +function animateColor(options) { + const animation = new ColorAnimation(options); + animation.start(); + return animation; +} + +/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ + +class Intersection { + constructor(status) { + this.status = status; + this.points = []; + } + + /** + * Used to verify if a point is alredy in the collection + * @param {Point} point + * @returns {boolean} + */ + includes(point) { + return this.points.some(p => p.eq(point)); + } + + /** + * Appends points of intersection + * @param {...Point[]} points + * @return {Intersection} thisArg + * @chainable + */ + append() { + for (var _len = arguments.length, points = new Array(_len), _key = 0; _key < _len; _key++) { + points[_key] = arguments[_key]; + } + this.points = this.points.concat(points.filter(point => { + return !this.includes(point); + })); + return this; + } + + /** + * check if point T is on the segment or line defined between A and B + * + * @param {Point} T the point we are checking for + * @param {Point} A one extremity of the segment + * @param {Point} B the other extremity of the segment + * @param [infinite] if true checks if `T` is on the line defined by `A` and `B` + * @returns true if `T` is contained + */ + static isPointContained(T, A, B) { + let infinite = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + if (A.eq(B)) { + // Edge case: the segment is a point, we check for coincidence, + // infinite param has no meaning because there are infinite lines to consider + return T.eq(A); + } else if (A.x === B.x) { + // Edge case: horizontal line. + // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y + return T.x === A.x && (infinite || T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)); + } else if (A.y === B.y) { + // Edge case: vertical line. + // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x + return T.y === A.y && (infinite || T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)); + } else { + // Generic case: sloped line. + // we check that AT has the same slope as AB + // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size + // for the infinite case we check the absolute value of the slope, since direction is meaningless + const AB = createVector(A, B); + const AT = createVector(A, T); + const s = AT.divide(AB); + return infinite ? Math.abs(s.x) === Math.abs(s.y) : s.x === s.y && s.x >= 0 && s.x <= 1; + } + } + + /** + * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points} + * @see https://en.wikipedia.org/wiki/Point_in_polygon + * @param point + * @param points polygon points + * @returns + */ + static isPointInPolygon(point, points) { + const other = new Point(point).setX(Math.min(point.x - 1, ...points.map(p => p.x))); + let hits = 0; + for (let index = 0; index < points.length; index++) { + const inter = this.intersectSegmentSegment( + // polygon side + points[index], points[(index + 1) % points.length], + // ray + point, other); + if (inter.includes(point)) { + // point is on the polygon side + return true; + } + hits += Number(inter.status === 'Intersection'); + } + return hits % 2 === 1; + } + + /** + * Checks if a line intersects another + * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection} + * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule} + * @static + * @param {Point} a1 + * @param {Point} a2 + * @param {Point} b1 + * @param {Point} b2 + * @param {boolean} [aInfinite=true] check segment intersection by passing `false` + * @param {boolean} [bInfinite=true] check segment intersection by passing `false` + * @return {Intersection} + */ + static intersectLineLine(a1, a2, b1, b2) { + let aInfinite = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + let bInfinite = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + const a2xa1x = a2.x - a1.x, + a2ya1y = a2.y - a1.y, + b2xb1x = b2.x - b1.x, + b2yb1y = b2.y - b1.y, + a1xb1x = a1.x - b1.x, + a1yb1y = a1.y - b1.y, + uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x, + ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x, + uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y; + if (uB !== 0) { + const ua = uaT / uB, + ub = ubT / uB; + if ((aInfinite || 0 <= ua && ua <= 1) && (bInfinite || 0 <= ub && ub <= 1)) { + return new Intersection('Intersection').append(new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y)); + } else { + return new Intersection(); + } + } else { + if (uaT === 0 || ubT === 0) { + const segmentsCoincide = aInfinite || bInfinite || Intersection.isPointContained(a1, b1, b2) || Intersection.isPointContained(a2, b1, b2) || Intersection.isPointContained(b1, a1, a2) || Intersection.isPointContained(b2, a1, a2); + return new Intersection(segmentsCoincide ? 'Coincident' : undefined); + } else { + return new Intersection('Parallel'); + } + } + } + + /** + * Checks if a segment intersects a line + * @see {@link intersectLineLine} for line intersection + * @static + * @param {Point} s1 boundary point of segment + * @param {Point} s2 other boundary point of segment + * @param {Point} l1 point on line + * @param {Point} l2 other point on line + * @return {Intersection} + */ + static intersectSegmentLine(s1, s2, l1, l2) { + return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); + } + + /** + * Checks if a segment intersects another + * @see {@link intersectLineLine} for line intersection + * @static + * @param {Point} a1 boundary point of segment + * @param {Point} a2 other boundary point of segment + * @param {Point} b1 boundary point of segment + * @param {Point} b2 other boundary point of segment + * @return {Intersection} + */ + static intersectSegmentSegment(a1, a2, b1, b2) { + return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); + } + + /** + * Checks if line intersects polygon + * + * @todo account for stroke + * + * @static + * @see {@link intersectSegmentPolygon} for segment intersection + * @param {Point} a1 point on line + * @param {Point} a2 other point on line + * @param {Point[]} points polygon points + * @param {boolean} [infinite=true] check segment intersection by passing `false` + * @return {Intersection} + */ + static intersectLinePolygon(a1, a2, points) { + let infinite = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + const result = new Intersection(); + const length = points.length; + for (let i = 0, b1, b2, inter; i < length; i++) { + b1 = points[i]; + b2 = points[(i + 1) % length]; + inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false); + if (inter.status === 'Coincident') { + return inter; + } + result.append(...inter.points); + } + if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + } + + /** + * Checks if segment intersects polygon + * @static + * @see {@link intersectLinePolygon} for line intersection + * @param {Point} a1 boundary point of segment + * @param {Point} a2 other boundary point of segment + * @param {Point[]} points polygon points + * @return {Intersection} + */ + static intersectSegmentPolygon(a1, a2, points) { + return Intersection.intersectLinePolygon(a1, a2, points, false); + } + + /** + * Checks if polygon intersects another polygon + * + * @todo account for stroke + * + * @static + * @param {Point[]} points1 + * @param {Point[]} points2 + * @return {Intersection} + */ + static intersectPolygonPolygon(points1, points2) { + const result = new Intersection(), + length = points1.length; + const coincidences = []; + for (let i = 0; i < length; i++) { + const a1 = points1[i], + a2 = points1[(i + 1) % length], + inter = Intersection.intersectSegmentPolygon(a1, a2, points2); + if (inter.status === 'Coincident') { + coincidences.push(inter); + result.append(a1, a2); + } else { + result.append(...inter.points); + } + } + if (coincidences.length > 0 && coincidences.length === points1.length) { + return new Intersection('Coincident'); + } else if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + } + + /** + * Checks if polygon intersects rectangle + * @static + * @see {@link intersectPolygonPolygon} for polygon intersection + * @param {Point[]} points polygon points + * @param {Point} r1 top left point of rect + * @param {Point} r2 bottom right point of rect + * @return {Intersection} + */ + static intersectPolygonRectangle(points, r1, r2) { + const min = r1.min(r2), + max = r1.max(r2), + topRight = new Point(max.x, min.y), + bottomLeft = new Point(min.x, max.y); + return Intersection.intersectPolygonPolygon(points, [min, topRight, max, bottomLeft]); + } +} + +class ObjectGeometry extends CommonMethods { + // #region Geometry + + /** + * Describe object's corner position in scene coordinates. + * The coordinates are derived from the following: + * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth. + * The coordinates do not depend on viewport changes. + * The coordinates get updated with {@link setCoords}. + * You can calculate them without updating with {@link calcACoords()} + */ + + /** + * storage cache for object transform matrix + */ + + /** + * storage cache for object full transform matrix + */ + + /** + * A Reference of the Canvas where the object is actually added + * @type StaticCanvas | Canvas; + * @default undefined + * @private + */ + + /** + * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane + */ + getX() { + return this.getXY().x; + } + + /** + * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane + */ + setX(value) { + this.setXY(this.getXY().setX(value)); + } + + /** + * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane + */ + getY() { + return this.getXY().y; + } + + /** + * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane + */ + setY(value) { + this.setXY(this.getXY().setY(value)); + } + + /** + * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link getX} + */ + getRelativeX() { + return this.left; + } + + /** + * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\ + * if parent is canvas then this method is identical to {@link setX} + */ + setRelativeX(value) { + this.left = value; + } + + /** + * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link getY} + */ + getRelativeY() { + return this.top; + } + + /** + * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link setY} + */ + setRelativeY(value) { + this.top = value; + } + + /** + * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane + */ + getXY() { + const relativePosition = this.getRelativeXY(); + return this.group ? transformPoint(relativePosition, this.group.calcTransformMatrix()) : relativePosition; + } + + /** + * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate. + * You can specify {@link originX} and {@link originY} values, + * that otherwise are the object's current values. + * @example Set object's bottom left corner to point (5,5) on canvas + * object.setXY(new Point(5, 5), 'left', 'bottom'). + * @param {Point} point position in scene coordinate plane + * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom' + */ + setXY(point, originX, originY) { + if (this.group) { + point = transformPoint(point, invertTransform(this.group.calcTransformMatrix())); + } + this.setRelativeXY(point, originX, originY); + } + + /** + * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane + */ + getRelativeXY() { + return new Point(this.left, this.top); + } + + /** + * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas) + * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane + * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom' + */ + setRelativeXY(point) { + let originX = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.originX; + let originY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.originY; + this.setPositionByOrigin(point, originX, originY); + } + + /** + * @deprecated intermidiate method to be removed, do not use + */ + isStrokeAccountedForInDimensions() { + return false; + } + + /** + * @return {Point[]} [tl, tr, br, bl] in the scene plane + */ + getCoords() { + const { + tl, + tr, + br, + bl + } = this.aCoords || (this.aCoords = this.calcACoords()); + const coords = [tl, tr, br, bl]; + if (this.group) { + const t = this.group.calcTransformMatrix(); + return coords.map(p => transformPoint(p, t)); + } + return coords; + } + + /** + * Checks if object intersects with the scene rect formed by {@link tl} and {@link br} + */ + intersectsWithRect(tl, br) { + const intersection = Intersection.intersectPolygonRectangle(this.getCoords(), tl, br); + return intersection.status === 'Intersection'; + } + + /** + * Checks if object intersects with another object + * @param {Object} other Object to test + * @return {Boolean} true if object intersects with another object + */ + intersectsWithObject(other) { + const intersection = Intersection.intersectPolygonPolygon(this.getCoords(), other.getCoords()); + return intersection.status === 'Intersection' || intersection.status === 'Coincident' || other.isContainedWithinObject(this) || this.isContainedWithinObject(other); + } + + /** + * Checks if object is fully contained within area of another object + * @param {Object} other Object to test + * @return {Boolean} true if object is fully contained within area of another object + */ + isContainedWithinObject(other) { + const points = this.getCoords(); + return points.every(point => other.containsPoint(point)); + } + + /** + * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br} + */ + isContainedWithinRect(tl, br) { + const { + left, + top, + width, + height + } = this.getBoundingRect(); + return left >= tl.x && left + width <= br.x && top >= tl.y && top + height <= br.y; + } + isOverlapping(other) { + return this.intersectsWithObject(other) || this.isContainedWithinObject(other) || other.isContainedWithinObject(this); + } + + /** + * Checks if point is inside the object + * @param {Point} point Point to check against + * @return {Boolean} true if point is inside the object + */ + containsPoint(point) { + return Intersection.isPointInPolygon(point, this.getCoords()); + } + + /** + * Checks if object is contained within the canvas with current viewportTransform + * the check is done stopping at first point that appears on screen + * @return {Boolean} true if object is fully or partially contained within canvas + */ + isOnScreen() { + if (!this.canvas) { + return false; + } + const { + tl, + br + } = this.canvas.vptCoords; + const points = this.getCoords(); + // if some point is on screen, the object is on screen. + if (points.some(point => point.x <= br.x && point.x >= tl.x && point.y <= br.y && point.y >= tl.y)) { + return true; + } + // no points on screen, check intersection with absolute coordinates + if (this.intersectsWithRect(tl, br)) { + return true; + } + // check if the object is so big that it contains the entire viewport + return this.containsPoint(tl.midPointFrom(br)); + } + + /** + * Checks if object is partially contained within the canvas with current viewportTransform + * @return {Boolean} true if object is partially contained within canvas + */ + isPartiallyOnScreen() { + if (!this.canvas) { + return false; + } + const { + tl, + br + } = this.canvas.vptCoords; + if (this.intersectsWithRect(tl, br)) { + return true; + } + const allPointsAreOutside = this.getCoords().every(point => (point.x >= br.x || point.x <= tl.x) && (point.y >= br.y || point.y <= tl.y)); + // check if the object is so big that it contains the entire viewport + return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br)); + } + + /** + * Returns coordinates of object's bounding rectangle (left, top, width, height) + * the box is intended as aligned to axis of canvas. + * @return {Object} Object with left, top, width, height properties + */ + getBoundingRect() { + return makeBoundingBoxFromPoints(this.getCoords()); + } + + /** + * Returns width of an object's bounding box counting transformations + * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane? + * @return {Number} width value + */ + getScaledWidth() { + return this._getTransformedDimensions().x; + } + + /** + * Returns height of an object bounding box counting transformations + * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane? + * @return {Number} height value + */ + getScaledHeight() { + return this._getTransformedDimensions().y; + } + + /** + * Scales an object (equally by x and y) + * @param {Number} value Scale factor + * @return {void} + */ + scale(value) { + this._set(SCALE_X, value); + this._set(SCALE_Y, value); + this.setCoords(); + } + + /** + * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New width value + * @return {void} + */ + scaleToWidth(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + const boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); + return this.scale(value / this.width / boundingRectFactor); + } + + /** + * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New height value + * @return {void} + */ + scaleToHeight(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + const boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); + return this.scale(value / this.height / boundingRectFactor); + } + getCanvasRetinaScaling() { + var _this$canvas; + return ((_this$canvas = this.canvas) === null || _this$canvas === void 0 ? void 0 : _this$canvas.getRetinaScaling()) || 1; + } + + /** + * Returns the object angle relative to canvas counting also the group property + * @returns {TDegree} + */ + getTotalAngle() { + return this.group ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix())) : this.angle; + } + + /** + * Retrieves viewportTransform from Object's canvas if available + * @return {TMat2D} + */ + getViewportTransform() { + var _this$canvas2; + return ((_this$canvas2 = this.canvas) === null || _this$canvas2 === void 0 ? void 0 : _this$canvas2.viewportTransform) || iMatrix.concat(); + } + + /** + * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates. + * those never change with zoom or viewport changes. + * @return {TCornerPoint} + */ + calcACoords() { + const rotateMatrix = createRotateMatrix({ + angle: this.angle + }), + { + x, + y + } = this.getRelativeCenterPoint(), + tMatrix = createTranslateMatrix(x, y), + finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix), + dim = this._getTransformedDimensions(), + w = dim.x / 2, + h = dim.y / 2; + return { + // corners + tl: transformPoint({ + x: -w, + y: -h + }, finalMatrix), + tr: transformPoint({ + x: w, + y: -h + }, finalMatrix), + bl: transformPoint({ + x: -w, + y: h + }, finalMatrix), + br: transformPoint({ + x: w, + y: h + }, finalMatrix) + }; + } + + /** + * Sets corner and controls position coordinates based on current angle, width and height, left and top. + * aCoords are used to quickly find an object on the canvas. + * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas} + */ + setCoords() { + this.aCoords = this.calcACoords(); + } + transformMatrixKey() { + let skipGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + let prefix = []; + if (!skipGroup && this.group) { + prefix = this.group.transformMatrixKey(skipGroup); + } + prefix.push(this.top, this.left, this.width, this.height, this.scaleX, this.scaleY, this.angle, this.strokeWidth, this.skewX, this.skewY, +this.flipX, +this.flipY, resolveOrigin(this.originX), resolveOrigin(this.originY)); + return prefix; + } + + /** + * calculate transform matrix that represents the current transformations from the + * object's properties. + * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations + * There are some situation in which this is useful to avoid the fake rotation. + * @return {TMat2D} transform matrix for the object + */ + calcTransformMatrix() { + let skipGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + let matrix = this.calcOwnMatrix(); + if (skipGroup || !this.group) { + return matrix; + } + const key = this.transformMatrixKey(skipGroup), + cache = this.matrixCache; + if (cache && cache.key.every((x, i) => x === key[i])) { + return cache.value; + } + if (this.group) { + matrix = multiplyTransformMatrices(this.group.calcTransformMatrix(false), matrix); + } + this.matrixCache = { + key, + value: matrix + }; + return matrix; + } + + /** + * calculate transform matrix that represents the current transformations from the + * object's properties, this matrix does not include the group transformation + * @return {TMat2D} transform matrix for the object + */ + calcOwnMatrix() { + const key = this.transformMatrixKey(true), + cache = this.ownMatrixCache; + if (cache && cache.key === key) { + return cache.value; + } + const center = this.getRelativeCenterPoint(), + options = { + angle: this.angle, + translateX: center.x, + translateY: center.y, + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + flipX: this.flipX, + flipY: this.flipY + }, + value = composeMatrix(options); + this.ownMatrixCache = { + key, + value + }; + return value; + } + + /** + * Calculate object dimensions from its properties + * @private + * @returns {Point} dimensions + */ + _getNonTransformedDimensions() { + return new Point(this.width, this.height).scalarAdd(this.strokeWidth); + } + + /** + * Calculate object dimensions for controls box, including padding and canvas zoom. + * and active selection + * @private + * @param {object} [options] transform options + * @returns {Point} dimensions + */ + _calculateCurrentDimensions(options) { + return this._getTransformedDimensions(options).transform(this.getViewportTransform(), true).scalarAdd(2 * this.padding); + } + + // #region Origin + + /** + * @deprecated please use 'center' as value in new projects + * */ + + /** + * @deprecated please use 'center' as value in new projects + * */ + + /** + * Object containing this object. + * can influence its size and position + */ + + /** + * Calculate object bounding box dimensions from its properties scale, skew. + * This bounding box is aligned with object angle and not with canvas axis or screen. + * @param {Object} [options] + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @private + * @returns {Point} dimensions + */ + _getTransformedDimensions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const dimOptions = _objectSpread2({ + // if scaleX or scaleY are negative numbers, + // this will return dimensions that are negative. + // and this will break assumptions around the codebase + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + width: this.width, + height: this.height, + strokeWidth: this.strokeWidth + }, options); + // stroke is applied before/after transformations are applied according to `strokeUniform` + const strokeWidth = dimOptions.strokeWidth; + let preScalingStrokeValue = strokeWidth, + postScalingStrokeValue = 0; + if (this.strokeUniform) { + preScalingStrokeValue = 0; + postScalingStrokeValue = strokeWidth; + } + const dimX = dimOptions.width + preScalingStrokeValue, + dimY = dimOptions.height + preScalingStrokeValue, + noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0; + let finalDimensions; + if (noSkew) { + finalDimensions = new Point(dimX * dimOptions.scaleX, dimY * dimOptions.scaleY); + } else { + finalDimensions = sizeAfterTransform(dimX, dimY, calcDimensionsMatrix(dimOptions)); + } + return finalDimensions.scalarAdd(postScalingStrokeValue); + } + + /** + * Translates the coordinates from a set of origin to another (based on the object's dimensions) + * @param {Point} point The point which corresponds to the originX and originY params + * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom' + * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToGivenOrigin(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { + let x = point.x, + y = point.y; + const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX), + offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY); + if (offsetX || offsetY) { + const dim = this._getTransformedDimensions(); + x += offsetX * dim.x; + y += offsetY * dim.y; + } + return new Point(x, y); + } + + /** + * Translates the coordinates from origin to center coordinates (based on the object's dimensions) + * @param {Point} point The point which corresponds to the originX and originY params + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToCenterPoint(point, originX, originY) { + if (originX === CENTER && originY === CENTER) { + return point; + } + const p = this.translateToGivenOrigin(point, originX, originY, CENTER, CENTER); + if (this.angle) { + return p.rotate(degreesToRadians(this.angle), point); + } + return p; + } + + /** + * Translates the coordinates from center to origin coordinates (based on the object's dimensions) + * @param {Point} center The point which corresponds to center of the object + * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToOriginPoint(center, originX, originY) { + const p = this.translateToGivenOrigin(center, CENTER, CENTER, originX, originY); + if (this.angle) { + return p.rotate(degreesToRadians(this.angle), center); + } + return p; + } + + /** + * Returns the center coordinates of the object relative to canvas + * @return {Point} + */ + getCenterPoint() { + const relCenter = this.getRelativeCenterPoint(); + return this.group ? transformPoint(relCenter, this.group.calcTransformMatrix()) : relCenter; + } + + /** + * Returns the center coordinates of the object relative to it's parent + * @return {Point} + */ + getRelativeCenterPoint() { + return this.translateToCenterPoint(new Point(this.left, this.top), this.originX, this.originY); + } + + /** + * Returns the position of the object as if it has a different origin. + * Take an object that has left, top set to 100, 100 with origin 'left', 'top'. + * Return the values of left top ( wrapped in a point ) that you would need to keep + * the same position if origin where different. + * Alternatively you can use this to also find which point in the parent plane is a specific origin + * ( where is the bottom right corner of my object? ) + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + getPointByOrigin(originX, originY) { + return this.translateToOriginPoint(this.getRelativeCenterPoint(), originX, originY); + } + + /** + * Sets the position of the object taking into consideration the object's origin + * @param {Point} pos The new position of the object + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {void} + */ + setPositionByOrigin(pos, originX, originY) { + const center = this.translateToCenterPoint(pos, originX, originY), + position = this.translateToOriginPoint(center, this.originX, this.originY); + this.set({ + left: position.x, + top: position.y + }); + } + + /** + * @private + */ + _getLeftTopCoords() { + return this.translateToOriginPoint(this.getRelativeCenterPoint(), LEFT, TOP); + } +} + +const _excluded$e = ["type"], + _excluded2$4 = ["extraParam"]; +/** + * Root object class from which all 2d shape classes inherit from + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} + * + * @fires added + * @fires removed + * + * @fires selected + * @fires deselected + * + * @fires rotating + * @fires scaling + * @fires moving + * @fires skewing + * @fires modified + * + * @fires mousedown + * @fires mouseup + * @fires mouseover + * @fires mouseout + * @fires mousewheel + * @fires mousedblclick + * + * @fires dragover + * @fires dragenter + * @fires dragleave + * @fires drop + */ +let FabricObject$1 = class FabricObject extends ObjectGeometry { + static getDefaults() { + return FabricObject.ownDefaults; + } + + /** + * The class type. + * This is used for serialization and deserialization purposes and internally it can be used + * to identify classes. + * When we transform a class in a plain JS object we need a way to recognize which class it was, + * and the type is the way we do that. It has no other purposes and you should not give one. + * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type). + * To idenfity a class use instanceof class ( instanceof Rect ). + * We do not do that in fabricJS code because we want to try to have code splitting possible. + */ + + /** + * Legacy identifier of the class. Prefer using utils like isType or instanceOf + * Will be removed in fabric 7 or 8. + * The setter exists to avoid type errors in old code and possibly current deserialization code. + * @TODO add sustainable warning message + * @type string + * @deprecated + */ + get type() { + const name = this.constructor.type; + if (name === 'FabricObject') { + return 'object'; + } + return name.toLowerCase(); + } + set type(value) { + log('warn', 'Setting type has no effect', value); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + /** + * Quick access for the _cacheCanvas rendering context + * This is part of the objectCaching feature + * since 1.7.0 + * @type boolean + * @default undefined + * @private + */ + _defineProperty(this, "_cacheContext", null); + Object.assign(this, FabricObject.ownDefaults); + this.setOptions(options); + } + + /** + * Create a the canvas used to keep the cached copy of the object + * @private + */ + _createCacheCanvas() { + this._cacheCanvas = createCanvasElement(); + this._cacheContext = this._cacheCanvas.getContext('2d'); + this._updateCacheCanvas(); + // if canvas gets created, is empty, so dirty. + this.dirty = true; + } + + /** + * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal + * and each side do not cross fabric.cacheSideLimit + * those numbers are configurable so that you can get as much detail as you want + * making bargain with performances. + * @param {Object} dims + * @param {Object} dims.width width of canvas + * @param {Object} dims.height height of canvas + * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _limitCacheSize(dims) { + const width = dims.width, + height = dims.height, + max = config.maxCacheSideLimit, + min = config.minCacheSideLimit; + if (width <= max && height <= max && width * height <= config.perfLimitSizeTotal) { + if (width < min) { + dims.width = min; + } + if (height < min) { + dims.height = min; + } + return dims; + } + const ar = width / height, + [limX, limY] = cache.limitDimsByArea(ar), + x = capValue(min, limX, max), + y = capValue(min, limY, max); + if (width > x) { + dims.zoomX /= width / x; + dims.width = x; + dims.capped = true; + } + if (height > y) { + dims.zoomY /= height / y; + dims.height = y; + dims.capped = true; + } + return dims; + } + + /** + * Return the dimension and the zoom level needed to create a cache canvas + * big enough to host the object to be cached. + * @private + * @return {Object}.x width of object to be cached + * @return {Object}.y height of object to be cached + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _getCacheCanvasDimensions() { + const objectScale = this.getTotalObjectScaling(), + // calculate dimensions without skewing + dim = this._getTransformedDimensions({ + skewX: 0, + skewY: 0 + }), + neededX = dim.x * objectScale.x / this.scaleX, + neededY = dim.y * objectScale.y / this.scaleY; + return { + // for sure this ALIASING_LIMIT is slightly creating problem + // in situation in which the cache canvas gets an upper limit + // also objectScale contains already scaleX and scaleY + width: neededX + ALIASING_LIMIT, + height: neededY + ALIASING_LIMIT, + zoomX: objectScale.x, + zoomY: objectScale.y, + x: neededX, + y: neededY + }; + } + + /** + * Update width and height of the canvas for cache + * returns true or false if canvas needed resize. + * @private + * @return {Boolean} true if the canvas has been resized + */ + _updateCacheCanvas() { + const canvas = this._cacheCanvas, + context = this._cacheContext, + dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + minCacheSize = config.minCacheSideLimit, + width = dims.width, + height = dims.height, + zoomX = dims.zoomX, + zoomY = dims.zoomY, + dimensionsChanged = width !== canvas.width || height !== canvas.height, + zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY; + if (!canvas || !context) { + return false; + } + let drawingWidth, + drawingHeight, + shouldRedraw = dimensionsChanged || zoomChanged, + additionalWidth = 0, + additionalHeight = 0, + shouldResizeCanvas = false; + if (dimensionsChanged) { + const canvasWidth = this._cacheCanvas.width, + canvasHeight = this._cacheCanvas.height, + sizeGrowing = width > canvasWidth || height > canvasHeight, + sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize; + shouldResizeCanvas = sizeGrowing || sizeShrinking; + if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { + additionalWidth = width * 0.1; + additionalHeight = height * 0.1; + } + } + if (isTextObject(this) && this.path) { + shouldRedraw = true; + shouldResizeCanvas = true; + // IMHO in those lines we are using zoomX and zoomY not the this version. + additionalWidth += this.getHeightOfLine(0) * this.zoomX; + additionalHeight += this.getHeightOfLine(0) * this.zoomY; + } + if (shouldRedraw) { + if (shouldResizeCanvas) { + canvas.width = Math.ceil(width + additionalWidth); + canvas.height = Math.ceil(height + additionalHeight); + } else { + context.setTransform(1, 0, 0, 1, 0, 0); + context.clearRect(0, 0, canvas.width, canvas.height); + } + drawingWidth = dims.x / 2; + drawingHeight = dims.y / 2; + this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; + this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; + context.translate(this.cacheTranslationX, this.cacheTranslationY); + context.scale(zoomX, zoomY); + this.zoomX = zoomX; + this.zoomY = zoomY; + return true; + } + return false; + } + + /** + * Sets object's properties from options, for class constructor only. + * Needs to be overridden for different defaults. + * @protected + * @param {Object} [options] Options object + */ + setOptions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this._setOptions(options); + } + + /** + * Transforms context when rendering an object + * @param {CanvasRenderingContext2D} ctx Context + */ + transform(ctx) { + const needFullTransform = this.group && !this.group._transformDone || this.group && this.canvas && ctx === this.canvas.contextTop; + const m = this.calcTransformMatrix(!needFullTransform); + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + + /** + * Return the object scale factor counting also the group scaling + * @return {Point} + */ + getObjectScaling() { + // if the object is a top level one, on the canvas, we go for simple aritmetic + // otherwise the complex method with angles will return approximations and decimals + // and will likely kill the cache when not needed + // https://github.com/fabricjs/fabric.js/issues/7157 + if (!this.group) { + return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY)); + } + // if we are inside a group total zoom calculation is complex, we defer to generic matrices + const options = qrDecompose(this.calcTransformMatrix()); + return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY)); + } + + /** + * Return the object scale factor counting also the group scaling, zoom and retina + * @return {Object} object with scaleX and scaleY properties + */ + getTotalObjectScaling() { + const scale = this.getObjectScaling(); + if (this.canvas) { + const zoom = this.canvas.getZoom(); + const retina = this.getCanvasRetinaScaling(); + return scale.scalarMultiply(zoom * retina); + } + return scale; + } + + /** + * Return the object opacity counting also the group property + * @return {Number} + */ + getObjectOpacity() { + let opacity = this.opacity; + if (this.group) { + opacity *= this.group.getObjectOpacity(); + } + return opacity; + } + + /** + * Makes sure the scale is valid and modifies it if necessary + * @todo: this is a control action issue, not a geometry one + * @private + * @param {Number} value, unconstrained + * @return {Number} constrained value; + */ + _constrainScale(value) { + if (Math.abs(value) < this.minScaleLimit) { + if (value < 0) { + return -this.minScaleLimit; + } else { + return this.minScaleLimit; + } + } else if (value === 0) { + return 0.0001; + } + return value; + } + + /** + * Handles setting values on the instance and handling internal side effects + * @protected + * @param {String} key + * @param {*} value + */ + _set(key, value) { + if (key === SCALE_X || key === SCALE_Y) { + value = this._constrainScale(value); + } + if (key === SCALE_X && value < 0) { + this.flipX = !this.flipX; + value *= -1; + } else if (key === 'scaleY' && value < 0) { + this.flipY = !this.flipY; + value *= -1; + // i don't like this automatic initialization here + } else if (key === 'shadow' && value && !(value instanceof Shadow)) { + value = new Shadow(value); + } + const isChanged = this[key] !== value; + this[key] = value; + + // invalidate caches + if (isChanged && this.constructor.cacheProperties.includes(key)) { + this.dirty = true; + } + // a dirty child makes the parent dirty. + // but a non dirty child does not make the parent not dirty. + // the parent could be dirty for some other reason. + this.parent && (this.dirty || isChanged && this.constructor.stateProperties.includes(key)) && this.parent._set('dirty', true); + return this; + } + + /* + * @private + * return if the object would be visible in rendering + * @memberOf FabricObject.prototype + * @return {Boolean} + */ + isNotVisible() { + return this.opacity === 0 || !this.width && !this.height && this.strokeWidth === 0 || !this.visible; + } + + /** + * Renders an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + // do not render if width/height are zeros or object is not visible + if (this.isNotVisible()) { + return; + } + if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { + return; + } + ctx.save(); + this._setupCompositeOperation(ctx); + this.drawSelectionBackground(ctx); + this.transform(ctx); + this._setOpacity(ctx); + this._setShadow(ctx); + if (this.shouldCache()) { + this.renderCache(); + this.drawCacheOnCanvas(ctx); + } else { + this._removeCacheCanvas(); + this.drawObject(ctx); + this.dirty = false; + } + ctx.restore(); + } + drawSelectionBackground(_ctx) { + /* no op */ + } + renderCache(options) { + options = options || {}; + if (!this._cacheCanvas || !this._cacheContext) { + this._createCacheCanvas(); + } + if (this.isCacheDirty() && this._cacheContext) { + this.drawObject(this._cacheContext, options.forClipping); + this.dirty = false; + } + } + + /** + * Remove cacheCanvas and its dimensions from the objects + */ + _removeCacheCanvas() { + this._cacheCanvas = undefined; + this._cacheContext = null; + } + + /** + * return true if the object will draw a stroke + * Does not consider text styles. This is just a shortcut used at rendering time + * We want it to be an approximation and be fast. + * wrote to avoid extra caching, it has to return true when stroke happens, + * can guess when it will not happen at 100% chance, does not matter if it misses + * some use case where the stroke is invisible. + * @since 3.0.0 + * @returns Boolean + */ + hasStroke() { + return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0; + } + + /** + * return true if the object will draw a fill + * Does not consider text styles. This is just a shortcut used at rendering time + * We want it to be an approximation and be fast. + * wrote to avoid extra caching, it has to return true when fill happens, + * can guess when it will not happen at 100% chance, does not matter if it misses + * some use case where the fill is invisible. + * @since 3.0.0 + * @returns Boolean + */ + hasFill() { + return this.fill && this.fill !== 'transparent'; + } + + /** + * When set to `true`, force the object to have its own cache, even if it is inside a group + * it may be needed when your object behave in a particular way on the cache and always needs + * its own isolated canvas to render correctly. + * Created to be overridden + * since 1.7.12 + * @returns Boolean + */ + needsItsOwnCache() { + if (this.paintFirst === STROKE && this.hasFill() && this.hasStroke() && !!this.shadow) { + return true; + } + if (this.clipPath) { + return true; + } + return false; + } + + /** + * Decide if the object should cache or not. Create its own cache level + * objectCaching is a global flag, wins over everything + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * Read as: cache if is needed, or if the feature is enabled but we are not already caching. + * @return {Boolean} + */ + shouldCache() { + this.ownCaching = this.needsItsOwnCache() || this.objectCaching && (!this.parent || !this.parent.isOnACache()); + return this.ownCaching; + } + + /** + * Check if this object will cast a shadow with an offset. + * used by Group.shouldCache to know if child has a shadow recursively + * @return {Boolean} + * @deprecated + */ + willDrawShadow() { + return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); + } + + /** + * Execute the drawing operation for an object clipPath + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {FabricObject} clipPath + */ + drawClipPathOnCache(ctx, clipPath) { + ctx.save(); + // DEBUG: uncomment this line, comment the following + // ctx.globalAlpha = 0.4 + if (clipPath.inverted) { + ctx.globalCompositeOperation = 'destination-out'; + } else { + ctx.globalCompositeOperation = 'destination-in'; + } + //ctx.scale(1 / 2, 1 / 2); + if (clipPath.absolutePositioned) { + const m = invertTransform(this.calcTransformMatrix()); + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + clipPath.transform(ctx); + ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY); + ctx.drawImage(clipPath._cacheCanvas, -clipPath.cacheTranslationX, -clipPath.cacheTranslationY); + ctx.restore(); + } + + /** + * Execute the drawing operation for an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {boolean} forClipping apply clipping styles + */ + drawObject(ctx, forClipping) { + const originalFill = this.fill, + originalStroke = this.stroke; + if (forClipping) { + this.fill = 'black'; + this.stroke = ''; + this._setClippingProperties(ctx); + } else { + this._renderBackground(ctx); + } + this._render(ctx); + this._drawClipPath(ctx, this.clipPath); + this.fill = originalFill; + this.stroke = originalStroke; + } + + /** + * Prepare clipPath state and cache and draw it on instance's cache + * @param {CanvasRenderingContext2D} ctx + * @param {FabricObject} clipPath + */ + _drawClipPath(ctx, clipPath) { + if (!clipPath) { + return; + } + // needed to setup a couple of variables + // path canvas gets overridden with this one. + // TODO find a better solution? + clipPath._set('canvas', this.canvas); + clipPath.shouldCache(); + clipPath._transformDone = true; + clipPath.renderCache({ + forClipping: true + }); + this.drawClipPathOnCache(ctx, clipPath); + } + + /** + * Paint the cached copy of the object on the target context. + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawCacheOnCanvas(ctx) { + ctx.scale(1 / this.zoomX, 1 / this.zoomY); + ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); + } + + /** + * Check if cache is dirty + * @param {Boolean} skipCanvas skip canvas checks because this object is painted + * on parent canvas. + */ + isCacheDirty() { + let skipCanvas = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (this.isNotVisible()) { + return false; + } + const canvas = this._cacheCanvas; + const ctx = this._cacheContext; + if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) { + // in this case the context is already cleared. + return true; + } else { + if (this.dirty || this.clipPath && this.clipPath.absolutePositioned) { + if (canvas && ctx && !skipCanvas) { + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + } + return true; + } + } + return false; + } + + /** + * Draws a background for the object big as its untransformed dimensions + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground(ctx) { + if (!this.backgroundColor) { + return; + } + const dim = this._getNonTransformedDimensions(); + ctx.fillStyle = this.backgroundColor; + ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); + // if there is background color no other shadows + // should be casted + this._removeShadow(ctx); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setOpacity(ctx) { + if (this.group && !this.group._transformDone) { + ctx.globalAlpha = this.getObjectOpacity(); + } else { + ctx.globalAlpha *= this.opacity; + } + } + _setStrokeStyles(ctx, decl) { + const stroke = decl.stroke; + if (stroke) { + ctx.lineWidth = decl.strokeWidth; + ctx.lineCap = decl.strokeLineCap; + ctx.lineDashOffset = decl.strokeDashOffset; + ctx.lineJoin = decl.strokeLineJoin; + ctx.miterLimit = decl.strokeMiterLimit; + if (isFiller(stroke)) { + if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) { + // need to transform gradient in a pattern. + // this is a slow process. If you are hitting this codepath, and the object + // is not using caching, you should consider switching it on. + // we need a canvas as big as the current object caching canvas. + this._applyPatternForTransformedGradient(ctx, stroke); + } else { + // is a simple gradient or pattern + ctx.strokeStyle = stroke.toLive(ctx); + this._applyPatternGradientTransform(ctx, stroke); + } + } else { + // is a color + ctx.strokeStyle = decl.stroke; + } + } + } + _setFillStyles(ctx, _ref) { + let { + fill + } = _ref; + if (fill) { + if (isFiller(fill)) { + ctx.fillStyle = fill.toLive(ctx); + this._applyPatternGradientTransform(ctx, fill); + } else { + ctx.fillStyle = fill; + } + } + } + _setClippingProperties(ctx) { + ctx.globalAlpha = 1; + ctx.strokeStyle = 'transparent'; + ctx.fillStyle = '#000000'; + } + + /** + * @private + * Sets line dash + * @param {CanvasRenderingContext2D} ctx Context to set the dash line on + * @param {Array} dashArray array representing dashes + */ + _setLineDash(ctx, dashArray) { + if (!dashArray || dashArray.length === 0) { + return; + } + // Spec requires the concatenation of two copies of the dash array when the number of elements is odd + if (1 & dashArray.length) { + dashArray.push(...dashArray); + } + ctx.setLineDash(dashArray); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setShadow(ctx) { + if (!this.shadow) { + return; + } + const shadow = this.shadow, + canvas = this.canvas, + retinaScaling = this.getCanvasRetinaScaling(), + [sx,,, sy] = (canvas === null || canvas === void 0 ? void 0 : canvas.viewportTransform) || iMatrix, + multX = sx * retinaScaling, + multY = sy * retinaScaling, + scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling(); + ctx.shadowColor = shadow.color; + ctx.shadowBlur = shadow.blur * config.browserShadowBlurConstant * (multX + multY) * (scaling.x + scaling.y) / 4; + ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x; + ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _removeShadow(ctx) { + if (!this.shadow) { + return; + } + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {TFiller} filler {@link Pattern} or {@link Gradient} + */ + _applyPatternGradientTransform(ctx, filler) { + if (!isFiller(filler)) { + return { + offsetX: 0, + offsetY: 0 + }; + } + const t = filler.gradientTransform || filler.patternTransform; + const offsetX = -this.width / 2 + filler.offsetX || 0, + offsetY = -this.height / 2 + filler.offsetY || 0; + if (filler.gradientUnits === 'percentage') { + ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY); + } else { + ctx.transform(1, 0, 0, 1, offsetX, offsetY); + } + if (t) { + ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); + } + return { + offsetX: offsetX, + offsetY: offsetY + }; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderPaintInOrder(ctx) { + if (this.paintFirst === STROKE) { + this._renderStroke(ctx); + this._renderFill(ctx); + } else { + this._renderFill(ctx); + this._renderStroke(ctx); + } + } + + /** + * @private + * function that actually render something on the context. + * empty here to allow Obects to work on tests to benchmark fabric functionalites + * not related to rendering + * @param {CanvasRenderingContext2D} _ctx Context to render on + */ + _render(_ctx) { + // placeholder to be overridden + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderFill(ctx) { + if (!this.fill) { + return; + } + ctx.save(); + this._setFillStyles(ctx, this); + if (this.fillRule === 'evenodd') { + ctx.fill('evenodd'); + } else { + ctx.fill(); + } + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderStroke(ctx) { + if (!this.stroke || this.strokeWidth === 0) { + return; + } + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + ctx.save(); + if (this.strokeUniform) { + const scaling = this.getObjectScaling(); + ctx.scale(1 / scaling.x, 1 / scaling.y); + } + this._setLineDash(ctx, this.strokeDashArray); + this._setStrokeStyles(ctx, this); + ctx.stroke(); + ctx.restore(); + } + + /** + * This function try to patch the missing gradientTransform on canvas gradients. + * transforming a context to transform the gradient, is going to transform the stroke too. + * we want to transform the gradient but not the stroke operation, so we create + * a transformed gradient on a pattern and then we use the pattern instead of the gradient. + * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size + * is limited. + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Gradient} filler + */ + _applyPatternForTransformedGradient(ctx, filler) { + var _pCtx$createPattern; + const dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + pCanvas = createCanvasElement(), + retinaScaling = this.getCanvasRetinaScaling(), + width = dims.x / this.scaleX / retinaScaling, + height = dims.y / this.scaleY / retinaScaling; + // in case width and height are less than 1px, we have to round up. + // since the pattern is no-repeat, this is fine + pCanvas.width = Math.ceil(width); + pCanvas.height = Math.ceil(height); + const pCtx = pCanvas.getContext('2d'); + if (!pCtx) { + return; + } + pCtx.beginPath(); + pCtx.moveTo(0, 0); + pCtx.lineTo(width, 0); + pCtx.lineTo(width, height); + pCtx.lineTo(0, height); + pCtx.closePath(); + pCtx.translate(width / 2, height / 2); + pCtx.scale(dims.zoomX / this.scaleX / retinaScaling, dims.zoomY / this.scaleY / retinaScaling); + this._applyPatternGradientTransform(pCtx, filler); + pCtx.fillStyle = filler.toLive(ctx); + pCtx.fill(); + ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2); + ctx.scale(retinaScaling * this.scaleX / dims.zoomX, retinaScaling * this.scaleY / dims.zoomY); + ctx.strokeStyle = (_pCtx$createPattern = pCtx.createPattern(pCanvas, 'no-repeat')) !== null && _pCtx$createPattern !== void 0 ? _pCtx$createPattern : ''; + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + return new Point(this.left + this.width / 2, this.top + this.height / 2); + } + + /** + * Clones an instance. + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @returns {Promise} + */ + clone(propertiesToInclude) { + const objectForm = this.toObject(propertiesToInclude); + return this.constructor.fromObject(objectForm); + } + + /** + * Creates an instance of Image out of an object + * makes use of toCanvasElement. + * Once this method was based on toDataUrl and loadImage, so it also had a quality + * and format option. toCanvasElement is faster and produce no loss of quality. + * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it. + * toCanvasElement and then toBlob from the obtained canvas is also a good option. + * @todo fix the export type, it could not be Image but the type that getClass return for 'image'. + * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @return {FabricImage} Object cloned as image. + */ + cloneAsImage(options) { + const canvasEl = this.toCanvasElement(options); + // TODO: how to import Image w/o an import cycle? + const ImageClass = classRegistry.getClass('image'); + return new ImageClass(canvasEl); + } + + /** + * Converts an object into a HTMLCanvas element + * @param {ObjectToCanvasElementOptions} options Options object + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform + * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas + * @return {HTMLCanvasElement} Returns DOM element with the FabricObject + */ + toCanvasElement() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const origParams = saveObjectTransform(this), + originalGroup = this.group, + originalShadow = this.shadow, + abs = Math.abs, + retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1, + multiplier = (options.multiplier || 1) * retinaScaling, + canvasProvider = options.canvasProvider || (el => new StaticCanvas(el, { + enableRetinaScaling: false, + renderOnAddRemove: false, + skipOffscreen: false + })); + delete this.group; + if (options.withoutTransform) { + resetObjectTransform(this); + } + if (options.withoutShadow) { + this.shadow = null; + } + if (options.viewportTransform) { + sendObjectToPlane(this, this.getViewportTransform()); + } + this.setCoords(); + const el = createCanvasElement(), + boundingRect = this.getBoundingRect(), + shadow = this.shadow, + shadowOffset = new Point(); + if (shadow) { + const shadowBlur = shadow.blur; + const scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling(); + // consider non scaling shadow. + shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x); + shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y); + } + const width = boundingRect.width + shadowOffset.x, + height = boundingRect.height + shadowOffset.y; + // if the current width/height is not an integer + // we need to make it so. + el.width = Math.ceil(width); + el.height = Math.ceil(height); + const canvas = canvasProvider(el); + if (options.format === 'jpeg') { + canvas.backgroundColor = '#fff'; + } + this.setPositionByOrigin(new Point(canvas.width / 2, canvas.height / 2), CENTER, CENTER); + const originalCanvas = this.canvas; + // static canvas and canvas have both an array of InteractiveObjects + // @ts-expect-error this needs to be fixed somehow, or ignored globally + canvas._objects = [this]; + this.set('canvas', canvas); + this.setCoords(); + const canvasEl = canvas.toCanvasElement(multiplier || 1, options); + this.set('canvas', originalCanvas); + this.shadow = originalShadow; + if (originalGroup) { + this.group = originalGroup; + } + this.set(origParams); + this.setCoords(); + // canvas.dispose will call image.dispose that will nullify the elements + // since this canvas is a simple element for the process, we remove references + // to objects in this way in order to avoid object trashing. + canvas._objects = []; + // since render has settled it is safe to destroy canvas + canvas.destroy(); + return canvasEl; + } + + /** + * Converts an object into a data-url-like string + * @param {Object} options Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + */ + toDataURL() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1); + } + + /** + * Returns true if any of the specified types is identical to the type of an instance + * @param {String} type Type to check against + * @return {Boolean} + */ + isType() { + for (var _len = arguments.length, types = new Array(_len), _key = 0; _key < _len; _key++) { + types[_key] = arguments[_key]; + } + return types.includes(this.constructor.type) || types.includes(this.type); + } + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance (is 1 unless subclassed) + */ + complexity() { + return 1; + } + + /** + * Returns a JSON representation of an instance + * @return {Object} JSON + */ + toJSON() { + // delegate, not alias + return this.toObject(); + } + + /** + * Sets "angle" of an instance with centered rotation + * @param {TDegree} angle Angle value (in degrees) + */ + rotate(angle) { + const { + centeredRotation, + originX, + originY + } = this; + if (centeredRotation) { + const { + x, + y + } = this.getRelativeCenterPoint(); + this.originX = CENTER; + this.originY = CENTER; + this.left = x; + this.top = y; + } + this.set('angle', angle); + if (centeredRotation) { + const { + x, + y + } = this.translateToOriginPoint(this.getRelativeCenterPoint(), originX, originY); + this.left = x; + this.top = y; + this.originX = originX; + this.originY = originY; + } + } + + /** + * This callback function is called by the parent group of an object every + * time a non-delegated property changes on the group. It is passed the key + * and value as parameters. Not adding in this function's signature to avoid + * Travis build error about unused variables. + */ + setOnGroup() { + // implemented by sub-classes, as needed. + } + + /** + * Sets canvas globalCompositeOperation for specific object + * custom composition operation for the particular object can be specified using globalCompositeOperation property + * @param {CanvasRenderingContext2D} ctx Rendering canvas context + */ + _setupCompositeOperation(ctx) { + if (this.globalCompositeOperation) { + ctx.globalCompositeOperation = this.globalCompositeOperation; + } + } + + /** + * cancel instance's running animations + * override if necessary to dispose artifacts such as `clipPath` + */ + dispose() { + runningAnimations.cancelByTarget(this); + this.off(); + this._set('canvas', undefined); + // clear caches + this._cacheCanvas && getEnv().dispose(this._cacheCanvas); + this._cacheCanvas = undefined; + this._cacheContext = null; + } + + // #region Animation methods + /** + * List of properties to consider for animating colors. + * @type String[] + */ + + /** + * Animates object's properties + * @param {Record} animatable map of keys and end values + * @param {Partial>} options + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} + * @return {Record>} map of animation contexts + * + * As object — multiple properties + * + * object.animate({ left: ..., top: ... }); + * object.animate({ left: ..., top: ... }, { duration: ... }); + */ + animate(animatable, options) { + return Object.entries(animatable).reduce((acc, _ref2) => { + let [key, endValue] = _ref2; + acc[key] = this._animate(key, endValue, options); + return acc; + }, {}); + } + + /** + * @private + * @param {String} key Property to animate + * @param {String} to Value to animate to + * @param {Object} [options] Options object + */ + _animate(key, endValue) { + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const path = key.split('.'); + const propIsColor = this.constructor.colorProperties.includes(path[path.length - 1]); + const { + abort, + startValue, + onChange, + onComplete + } = options; + const animationOptions = _objectSpread2(_objectSpread2({}, options), {}, { + target: this, + // path.reduce... is the current value in case start value isn't provided + startValue: startValue !== null && startValue !== void 0 ? startValue : path.reduce((deep, key) => deep[key], this), + endValue, + abort: abort === null || abort === void 0 ? void 0 : abort.bind(this), + onChange: (value, valueProgress, durationProgress) => { + path.reduce((deep, key, index) => { + if (index === path.length - 1) { + deep[key] = value; + } + return deep[key]; + }, this); + onChange && + // @ts-expect-error generic callback arg0 is wrong + onChange(value, valueProgress, durationProgress); + }, + onComplete: (value, valueProgress, durationProgress) => { + this.setCoords(); + onComplete && + // @ts-expect-error generic callback arg0 is wrong + onComplete(value, valueProgress, durationProgress); + } + }); + return propIsColor ? animateColor(animationOptions) : animate(animationOptions); + } + + // #region Object stacking methods + + /** + * A reference to the parent of the object + * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref + */ + + /** + * Checks if object is descendant of target + * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons + * @param {TAncestor} target + * @returns {boolean} + */ + isDescendantOf(target) { + const { + parent, + group + } = this; + return parent === target || group === target || + // walk up + !!parent && parent.isDescendantOf(target) || !!group && group !== parent && group.isDescendantOf(target); + } + + /** + * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top + */ + getAncestors() { + const ancestors = []; + // eslint-disable-next-line @typescript-eslint/no-this-alias + let parent = this; + do { + parent = parent.parent; + parent && ancestors.push(parent); + } while (parent); + return ancestors; + } + + /** + * Compare ancestors + * + * @param {StackedObject} other + * @returns {AncestryComparison} an object that represent the ancestry situation. + */ + findCommonAncestors(other) { + if (this === other) { + return { + fork: [], + otherFork: [], + common: [this, ...this.getAncestors()] + }; + } + const ancestors = this.getAncestors(); + const otherAncestors = other.getAncestors(); + // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case + if (ancestors.length === 0 && otherAncestors.length > 0 && this === otherAncestors[otherAncestors.length - 1]) { + return { + fork: [], + otherFork: [other, ...otherAncestors.slice(0, otherAncestors.length - 1)], + common: [this] + }; + } + // compare ancestors + for (let i = 0, ancestor; i < ancestors.length; i++) { + ancestor = ancestors[i]; + if (ancestor === other) { + return { + fork: [this, ...ancestors.slice(0, i)], + otherFork: [], + common: ancestors.slice(i) + }; + } + for (let j = 0; j < otherAncestors.length; j++) { + if (this === otherAncestors[j]) { + return { + fork: [], + otherFork: [other, ...otherAncestors.slice(0, j)], + common: [this, ...ancestors] + }; + } + if (ancestor === otherAncestors[j]) { + return { + fork: [this, ...ancestors.slice(0, i)], + otherFork: [other, ...otherAncestors.slice(0, j)], + common: ancestors.slice(i) + }; + } + } + } + // nothing shared + return { + fork: [this, ...ancestors], + otherFork: [other, ...otherAncestors], + common: [] + }; + } + + /** + * + * @param {StackedObject} other + * @returns {boolean} + */ + hasCommonAncestors(other) { + const commonAncestors = this.findCommonAncestors(other); + return commonAncestors && !!commonAncestors.common.length; + } + + /** + * + * @param {FabricObject} other object to compare against + * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined` + */ + isInFrontOf(other) { + if (this === other) { + return undefined; + } + const ancestorData = this.findCommonAncestors(other); + if (ancestorData.fork.includes(other)) { + return true; + } + if (ancestorData.otherFork.includes(this)) { + return false; + } + // if there isn't a common ancestor, we take the canvas. + // if there is no canvas, there is nothing to compare + const firstCommonAncestor = ancestorData.common[0] || this.canvas; + if (!firstCommonAncestor) { + return undefined; + } + const headOfFork = ancestorData.fork.pop(), + headOfOtherFork = ancestorData.otherFork.pop(), + thisIndex = firstCommonAncestor._objects.indexOf(headOfFork), + otherIndex = firstCommonAncestor._objects.indexOf(headOfOtherFork); + return thisIndex > -1 && thisIndex > otherIndex; + } + + // #region Serialization + /** + * Define a list of custom properties that will be serialized when + * instance.toObject() gets called + */ + + /** + * Returns an object representation of an instance + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const propertiesToSerialize = propertiesToInclude.concat(FabricObject.customProperties, this.constructor.customProperties || []); + let clipPathData; + const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS; + const { + clipPath, + fill, + stroke, + shadow, + strokeDashArray, + left, + top, + originX, + originY, + width, + height, + strokeWidth, + strokeLineCap, + strokeDashOffset, + strokeLineJoin, + strokeUniform, + strokeMiterLimit, + scaleX, + scaleY, + angle, + flipX, + flipY, + opacity, + visible, + backgroundColor, + fillRule, + paintFirst, + globalCompositeOperation, + skewX, + skewY + } = this; + if (clipPath && !clipPath.excludeFromExport) { + clipPathData = clipPath.toObject(propertiesToSerialize.concat('inverted', 'absolutePositioned')); + } + const toFixedBound = val => toFixed(val, NUM_FRACTION_DIGITS); + const object = _objectSpread2(_objectSpread2({}, pick(this, propertiesToSerialize)), {}, { + type: this.constructor.type, + version: VERSION, + originX, + originY, + left: toFixedBound(left), + top: toFixedBound(top), + width: toFixedBound(width), + height: toFixedBound(height), + fill: isSerializableFiller(fill) ? fill.toObject() : fill, + stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke, + strokeWidth: toFixedBound(strokeWidth), + strokeDashArray: strokeDashArray ? strokeDashArray.concat() : strokeDashArray, + strokeLineCap, + strokeDashOffset, + strokeLineJoin, + strokeUniform, + strokeMiterLimit: toFixedBound(strokeMiterLimit), + scaleX: toFixedBound(scaleX), + scaleY: toFixedBound(scaleY), + angle: toFixedBound(angle), + flipX, + flipY, + opacity: toFixedBound(opacity), + shadow: shadow ? shadow.toObject() : shadow, + visible, + backgroundColor, + fillRule, + paintFirst, + globalCompositeOperation, + skewX: toFixedBound(skewX), + skewY: toFixedBound(skewY) + }, clipPathData ? { + clipPath: clipPathData + } : null); + return !this.includeDefaultValues ? this._removeDefaultValues(object) : object; + } + + /** + * Returns (dataless) object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toDatalessObject(propertiesToInclude) { + // will be overwritten by subclasses + return this.toObject(propertiesToInclude); + } + + /** + * @private + * @param {Object} object + */ + _removeDefaultValues(object) { + // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance + // ownDefault vs prototype is swappable only if you change all the fabric objects consistently. + const defaults = this.constructor.getDefaults(); + const hasStaticDefaultValues = Object.keys(defaults).length > 0; + const baseValues = hasStaticDefaultValues ? defaults : Object.getPrototypeOf(this); + return pickBy(object, (value, key) => { + if (key === LEFT || key === TOP || key === 'type') { + return true; + } + const baseValue = baseValues[key]; + return value !== baseValue && + // basically a check for [] === [] + !(Array.isArray(value) && Array.isArray(baseValue) && value.length === 0 && baseValue.length === 0); + }); + } + + /** + * Returns a string representation of an instance + * @return {String} + */ + toString() { + return "#<".concat(this.constructor.type, ">"); + } + + /** + * + * @param {Function} klass + * @param {object} object + * @param {object} [options] + * @param {string} [options.extraParam] property to pass as first argument to the constructor + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static _fromObject(_ref3) { + let serializedObjectOptions = _objectWithoutProperties(_ref3, _excluded$e); + let _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + { + extraParam + } = _ref4, + options = _objectWithoutProperties(_ref4, _excluded2$4); + return enlivenObjectEnlivables(serializedObjectOptions, options).then(enlivedObjectOptions => { + // from the resulting enlived options, extract options.extraParam to arg0 + // to avoid accidental overrides later + if (extraParam) { + delete enlivedObjectOptions[extraParam]; + return new this(serializedObjectOptions[extraParam], + // @ts-expect-error different signature + enlivedObjectOptions); + } else { + return new this(enlivedObjectOptions); + } + }); + } + + /** + * + * @param {object} object + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(object, options) { + return this._fromObject(object, options); + } +}; +/** + * This list of properties is used to check if the state of an object is changed. + * This state change now is only used for children of groups to understand if a group + * needs its cache regenerated during a .set call + * @type Array + */ +_defineProperty(FabricObject$1, "stateProperties", stateProperties); +/** + * List of properties to consider when checking if cache needs refresh + * Those properties are checked by + * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty + * and refreshed at the next render + * @type Array + */ +_defineProperty(FabricObject$1, "cacheProperties", cacheProperties); +_defineProperty(FabricObject$1, "ownDefaults", fabricObjectDefaultValues); +_defineProperty(FabricObject$1, "type", 'FabricObject'); +_defineProperty(FabricObject$1, "colorProperties", [FILL, STROKE, 'backgroundColor']); +_defineProperty(FabricObject$1, "customProperties", []); +classRegistry.setClass(FabricObject$1); +classRegistry.setClass(FabricObject$1, 'object'); + +/** + * Wrap an action handler with firing an event if the action is performed + * @param {TModificationEvents} eventName the event we want to fire + * @param {TransformActionHandler} actionHandler the function to wrap + * @param {object} extraEventInfo extra information to pas to the event handler + * @return {TransformActionHandler} a function with an action handler signature + */ +const wrapWithFireEvent = (eventName, actionHandler, extraEventInfo) => { + return (eventData, transform, x, y) => { + const actionPerformed = actionHandler(eventData, transform, x, y); + if (actionPerformed) { + fireEvent(eventName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), extraEventInfo)); + } + return actionPerformed; + }; +}; + +/** + * Wrap an action handler with saving/restoring object position on the transform. + * this is the code that permits to objects to keep their position while transforming. + * @param {Function} actionHandler the function to wrap + * @return {Function} a function with an action handler signature + */ +function wrapWithFixedAnchor(actionHandler) { + return (eventData, transform, x, y) => { + const { + target, + originX, + originY + } = transform, + centerPoint = target.getRelativeCenterPoint(), + constraint = target.translateToOriginPoint(centerPoint, originX, originY), + actionPerformed = actionHandler(eventData, transform, x, y); + // flipping requires to change the transform origin, so we read from the mutated transform + // instead of leveraging the one destructured before + target.setPositionByOrigin(constraint, transform.originX, transform.originY); + return actionPerformed; + }; +} + +/** + * Action handler to change object's width + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const changeObjectWidth = (eventData, transform, x, y) => { + const localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); + // make sure the control changes width ONLY from it's side of target + if (resolveOrigin(transform.originX) === resolveOrigin(CENTER) || resolveOrigin(transform.originX) === resolveOrigin(RIGHT) && localPoint.x < 0 || resolveOrigin(transform.originX) === resolveOrigin(LEFT) && localPoint.x > 0) { + const { + target + } = transform, + strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1), + multiplier = isTransformCentered(transform) ? 2 : 1, + oldWidth = target.width, + newWidth = Math.ceil(Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding); + target.set('width', Math.max(newWidth, 0)); + // check against actual target width in case `newWidth` was rejected + return oldWidth !== target.width; + } + return false; +}; +const changeWidth = wrapWithFireEvent(RESIZING, wrapWithFixedAnchor(changeObjectWidth)); + +/** + * Render a round control, as per fabric features. + * This function is written to respect object properties like transparentCorners, cornerSize + * cornerColor, cornerStrokeColor + * plus the addition of offsetY and offsetX. + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Number} left x coordinate where the control center should be + * @param {Number} top y coordinate where the control center should be + * @param {Object} styleOverride override for FabricObject controls style + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + */ +function renderCircleControl(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + const xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, + ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, + transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners, + methodName = transparentCorners ? STROKE : FILL, + stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor); + let myLeft = left, + myTop = top, + size; + ctx.save(); + ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || ''; + ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || ''; + // TODO: use proper ellipse code. + if (xSize > ySize) { + size = xSize; + ctx.scale(1.0, ySize / xSize); + myTop = top * xSize / ySize; + } else if (ySize > xSize) { + size = ySize; + ctx.scale(xSize / ySize, 1.0); + myLeft = left * ySize / xSize; + } else { + size = xSize; + } + // this is still wrong + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false); + ctx[methodName](); + if (stroke) { + ctx.stroke(); + } + ctx.restore(); +} + +/** + * Render a square control, as per fabric features. + * This function is written to respect object properties like transparentCorners, cornerSize + * cornerColor, cornerStrokeColor + * plus the addition of offsetY and offsetX. + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Number} left x coordinate where the control center should be + * @param {Number} top y coordinate where the control center should be + * @param {Object} styleOverride override for FabricObject controls style + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + */ +function renderSquareControl(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + const xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, + ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, + transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners, + methodName = transparentCorners ? STROKE : FILL, + stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor), + xSizeBy2 = xSize / 2, + ySizeBy2 = ySize / 2; + ctx.save(); + ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || ''; + ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || ''; + // this is still wrong + ctx.lineWidth = 1; + ctx.translate(left, top); + // angle is relative to canvas plane + const angle = fabricObject.getTotalAngle(); + ctx.rotate(degreesToRadians(angle)); + // this does not work, and fixed with ( && ) does not make sense. + // to have real transparent corners we need the controls on upperCanvas + // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize); + ctx["".concat(methodName, "Rect")](-xSizeBy2, -ySizeBy2, xSize, ySize); + if (stroke) { + ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize); + } + ctx.restore(); +} + +class Control { + constructor(options) { + /** + * keep track of control visibility. + * mainly for backward compatibility. + * if you do not want to see a control, you can remove it + * from the control set. + * @type {Boolean} + * @default true + */ + _defineProperty(this, "visible", true); + /** + * Name of the action that the control will likely execute. + * This is optional. FabricJS uses to identify what the user is doing for some + * extra optimizations. If you are writing a custom control and you want to know + * somewhere else in the code what is going on, you can use this string here. + * you can also provide a custom getActionName if your control run multiple actions + * depending on some external state. + * default to scale since is the most common, used on 4 corners by default + * @type {String} + * @default 'scale' + */ + _defineProperty(this, "actionName", SCALE); + /** + * Drawing angle of the control. + * NOT used for now, but name marked as needed for internal logic + * example: to reuse the same drawing function for different rotated controls + * @type {Number} + * @default 0 + */ + _defineProperty(this, "angle", 0); + /** + * Relative position of the control. X + * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "x", 0); + /** + * Relative position of the control. Y + * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "y", 0); + /** + * Horizontal offset of the control from the defined position. In pixels + * Positive offset moves the control to the right, negative to the left. + * It used when you want to have position of control that does not scale with + * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on + * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will + * stay 30 pixels no matter how the object is big. Another example is having 2 + * controls in the corner, that stay in the same position when the object scale. + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "offsetX", 0); + /** + * Vertical offset of the control from the defined position. In pixels + * Positive offset moves the control to the bottom, negative to the top. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "offsetY", 0); + /** + * Sets the length of the control. If null, defaults to object's cornerSize. + * Expects both sizeX and sizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "sizeX", 0); + /** + * Sets the height of the control. If null, defaults to object's cornerSize. + * Expects both sizeX and sizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "sizeY", 0); + /** + * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize. + * Expects both touchSizeX and touchSizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "touchSizeX", 0); + /** + * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize. + * Expects both touchSizeX and touchSizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "touchSizeY", 0); + /** + * Css cursor style to display when the control is hovered. + * if the method `cursorStyleHandler` is provided, this property is ignored. + * @type {String} + * @default 'crosshair' + */ + _defineProperty(this, "cursorStyle", 'crosshair'); + /** + * If controls has an offsetY or offsetX, draw a line that connects + * the control to the bounding box + * @type {Boolean} + * @default false + */ + _defineProperty(this, "withConnection", false); + Object.assign(this, options); + } + + /** + * The control actionHandler, provide one to handle action ( control being moved ) + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + /** + * The control handler for mouse down, provide one to handle mouse down on control + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + /** + * The control mouseUpHandler, provide one to handle an effect on mouse up. + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + shouldActivate(controlKey, fabricObject, pointer, _ref) { + var _fabricObject$canvas; + let { + tl, + tr, + br, + bl + } = _ref; + // TODO: locking logic can be handled here instead of in the control handler logic + return ((_fabricObject$canvas = fabricObject.canvas) === null || _fabricObject$canvas === void 0 ? void 0 : _fabricObject$canvas.getActiveObject()) === fabricObject && fabricObject.isControlVisible(controlKey) && Intersection.isPointInPolygon(pointer, [tl, tr, br, bl]); + } + + /** + * Returns control actionHandler + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getActionHandler(eventData, fabricObject, control) { + return this.actionHandler; + } + + /** + * Returns control mouseDown handler + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getMouseDownHandler(eventData, fabricObject, control) { + return this.mouseDownHandler; + } + + /** + * Returns control mouseUp handler. + * During actions the fabricObject or the control can be of different obj + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getMouseUpHandler(eventData, fabricObject, control) { + return this.mouseUpHandler; + } + + /** + * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate + * function you can pass one in the constructor + * the cursorStyle property + * @param {Event} eventData the native mouse event + * @param {Control} control the current control ( likely this) + * @param {FabricObject} object on which the control is displayed + * @return {String} + */ + cursorStyleHandler(eventData, control, fabricObject) { + return control.cursorStyle; + } + + /** + * Returns the action name. The basic implementation just return the actionName property. + * @param {Event} eventData the native mouse event + * @param {Control} control the current control ( likely this) + * @param {FabricObject} object on which the control is displayed + * @return {String} + */ + getActionName(eventData, control, fabricObject) { + return control.actionName; + } + + /** + * Returns controls visibility + * @param {FabricObject} object on which the control is displayed + * @param {String} controlKey key where the control is memorized on the + * @return {Boolean} + */ + getVisibility(fabricObject, controlKey) { + var _fabricObject$_contro, _fabricObject$_contro2; + return (_fabricObject$_contro = (_fabricObject$_contro2 = fabricObject._controlsVisibility) === null || _fabricObject$_contro2 === void 0 ? void 0 : _fabricObject$_contro2[controlKey]) !== null && _fabricObject$_contro !== void 0 ? _fabricObject$_contro : this.visible; + } + + /** + * Sets controls visibility + * @param {Boolean} visibility for the object + * @return {Void} + */ + setVisibility(visibility, name, fabricObject) { + this.visible = visibility; + } + positionHandler(dim, finalMatrix, fabricObject, currentControl) { + return new Point(this.x * dim.x + this.offsetX, this.y * dim.y + this.offsetY).transform(finalMatrix); + } + + /** + * Returns the coords for this control based on object values. + * @param {Number} objectAngle angle from the fabric object holding the control + * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if + * isTouch is true) + * @param {Number} centerX x coordinate where the control center should be + * @param {Number} centerY y coordinate where the control center should be + * @param {boolean} isTouch true if touch corner, false if normal corner + */ + calcCornerCoords(angle, objectCornerSize, centerX, centerY, isTouch, fabricObject) { + const t = multiplyTransformMatrixArray([createTranslateMatrix(centerX, centerY), createRotateMatrix({ + angle + }), createScaleMatrix((isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize, (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize)]); + return { + tl: new Point(-0.5, -0.5).transform(t), + tr: new Point(0.5, -0.5).transform(t), + br: new Point(0.5, 0.5).transform(t), + bl: new Point(-0.5, 0.5).transform(t) + }; + } + + /** + * Render function for the control. + * When this function runs the context is unscaled. unrotate. Just retina scaled. + * all the functions will have to translate to the point left,top before starting Drawing + * if they want to draw a control where the position is detected. + * left and top are the result of the positionHandler function + * @param {RenderingContext2D} ctx the context where the control will be drawn + * @param {Number} left position of the canvas where we are about to render the control. + * @param {Number} top position of the canvas where we are about to render the control. + * @param {Object} styleOverride + * @param {FabricObject} fabricObject the object where the control is about to be rendered + */ + render(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + switch (styleOverride.cornerStyle || fabricObject.cornerStyle) { + case 'circle': + renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject); + break; + default: + renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject); + } + } +} + +/** + * Find the correct style for the control that is used for rotation. + * this function is very simple and it just take care of not-allowed or standard cursor + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const rotationStyleHandler = (eventData, control, fabricObject) => { + if (fabricObject.lockRotation) { + return NOT_ALLOWED_CURSOR; + } + return control.cursorStyle; +}; + +/** + * Action handler for rotation and snapping, without anchor point. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + * @private + */ +const rotateObjectWithSnapping = (eventData, _ref, x, y) => { + let { + target, + ex, + ey, + theta, + originX, + originY + } = _ref; + const pivotPoint = target.translateToOriginPoint(target.getRelativeCenterPoint(), originX, originY); + if (isLocked(target, 'lockRotation')) { + return false; + } + const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x), + curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x); + let angle = radiansToDegrees(curAngle - lastAngle + theta); + if (target.snapAngle && target.snapAngle > 0) { + const snapAngle = target.snapAngle, + snapThreshold = target.snapThreshold || snapAngle, + rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, + leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle; + if (Math.abs(angle - leftAngleLocked) < snapThreshold) { + angle = leftAngleLocked; + } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) { + angle = rightAngleLocked; + } + } + + // normalize angle to positive value + if (angle < 0) { + angle = 360 + angle; + } + angle %= 360; + const hasRotated = target.angle !== angle; + // TODO: why aren't we using set? + target.angle = angle; + return hasRotated; +}; +const rotationWithSnapping = wrapWithFireEvent(ROTATING, wrapWithFixedAnchor(rotateObjectWithSnapping)); + +/** + * Inspect event and fabricObject properties to understand if the scaling action + * @param {Event} eventData from the user action + * @param {FabricObject} fabricObject the fabric object about to scale + * @return {Boolean} true if scale is proportional + */ +function scaleIsProportional(eventData, fabricObject) { + const canvas = fabricObject.canvas, + uniformIsToggled = eventData[canvas.uniScaleKey]; + return canvas.uniformScaling && !uniformIsToggled || !canvas.uniformScaling && uniformIsToggled; +} + +/** + * Inspect fabricObject to understand if the current scaling action is allowed + * @param {FabricObject} fabricObject the fabric object about to scale + * @param {String} by 'x' or 'y' or '' + * @param {Boolean} scaleProportionally true if we are trying to scale proportionally + * @return {Boolean} true if scaling is not allowed at current conditions + */ +function scalingIsForbidden(fabricObject, by, scaleProportionally) { + const lockX = isLocked(fabricObject, 'lockScalingX'), + lockY = isLocked(fabricObject, 'lockScalingY'); + if (lockX && lockY) { + return true; + } + if (!by && (lockX || lockY) && scaleProportionally) { + return true; + } + if (lockX && by === 'x') { + return true; + } + if (lockY && by === 'y') { + return true; + } + // code crashes because of a division by 0 if a 0 sized object is scaled + // forbid to prevent scaling to happen. ISSUE-9475 + const { + width, + height, + strokeWidth + } = fabricObject; + if (width === 0 && strokeWidth === 0 && by !== 'y') { + return true; + } + if (height === 0 && strokeWidth === 0 && by !== 'x') { + return true; + } + return false; +} +const scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; + +/** + * return the correct cursor style for the scale action + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const scaleCursorStyleHandler = (eventData, control, fabricObject) => { + const scaleProportionally = scaleIsProportional(eventData, fabricObject), + by = control.x !== 0 && control.y === 0 ? 'x' : control.x === 0 && control.y !== 0 ? 'y' : ''; + if (scalingIsForbidden(fabricObject, by, scaleProportionally)) { + return NOT_ALLOWED_CURSOR; + } + const n = findCornerQuadrant(fabricObject, control); + return "".concat(scaleMap[n], "-resize"); +}; + +/** + * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @param {Object} options additional information for scaling + * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling + * @return {Boolean} true if some change happened + * @private + */ +function scaleObject(eventData, transform, x, y) { + let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + const target = transform.target, + by = options.by, + scaleProportionally = scaleIsProportional(eventData, target), + forbidScaling = scalingIsForbidden(target, by, scaleProportionally); + let newPoint, scaleX, scaleY, dim, signX, signY; + if (forbidScaling) { + return false; + } + if (transform.gestureScale) { + scaleX = transform.scaleX * transform.gestureScale; + scaleY = transform.scaleY * transform.gestureScale; + } else { + newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); + // use of sign: We use sign to detect change of direction of an action. sign usually change when + // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling + // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily + // cross many time the origin point and flip the object. so we need a way to filter out the noise. + // This ternary here should be ok to filter out X scaling when we want Y only and vice versa. + signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1; + signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1; + if (!transform.signX) { + transform.signX = signX; + } + if (!transform.signY) { + transform.signY = signY; + } + if (isLocked(target, 'lockScalingFlip') && (transform.signX !== signX || transform.signY !== signY)) { + return false; + } + dim = target._getTransformedDimensions(); + // missing detection of flip and logic to switch the origin + if (scaleProportionally && !by) { + // uniform scaling + const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y), + { + original + } = transform, + originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) + Math.abs(dim.y * original.scaleY / target.scaleY), + scale = distance / originalDistance; + scaleX = original.scaleX * scale; + scaleY = original.scaleY * scale; + } else { + scaleX = Math.abs(newPoint.x * target.scaleX / dim.x); + scaleY = Math.abs(newPoint.y * target.scaleY / dim.y); + } + // if we are scaling by center, we need to double the scale + if (isTransformCentered(transform)) { + scaleX *= 2; + scaleY *= 2; + } + if (transform.signX !== signX && by !== 'y') { + transform.originX = invertOrigin(transform.originX); + scaleX *= -1; + transform.signX = signX; + } + if (transform.signY !== signY && by !== 'x') { + transform.originY = invertOrigin(transform.originY); + scaleY *= -1; + transform.signY = signY; + } + } + // minScale is taken care of in the setter. + const oldScaleX = target.scaleX, + oldScaleY = target.scaleY; + if (!by) { + !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX); + !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY); + } else { + // forbidden cases already handled on top here. + by === 'x' && target.set(SCALE_X, scaleX); + by === 'y' && target.set(SCALE_Y, scaleY); + } + return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY; +} + +/** + * Generic scaling logic, to scale from corners either equally or freely. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectFromCorner = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y); +}; + +/** + * Scaling logic for the X axis. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectX = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y, { + by: 'x' + }); +}; + +/** + * Scaling logic for the Y axis. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectY = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y, { + by: 'y' + }); +}; +const scalingEqually = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectFromCorner)); +const scalingX = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectX)); +const scalingY = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectY)); + +const _excluded$d = ["target", "ex", "ey", "skewingSide"]; +const AXIS_KEYS = { + x: { + counterAxis: 'y', + scale: SCALE_X, + skew: SKEW_X, + lockSkewing: 'lockSkewingX', + origin: 'originX', + flip: 'flipX' + }, + y: { + counterAxis: 'x', + scale: SCALE_Y, + skew: SKEW_Y, + lockSkewing: 'lockSkewingY', + origin: 'originY', + flip: 'flipY' + } +}; +const skewMap = ['ns', 'nesw', 'ew', 'nwse']; + +/** + * return the correct cursor style for the skew action + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const skewCursorStyleHandler = (eventData, control, fabricObject) => { + if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) { + return NOT_ALLOWED_CURSOR; + } + if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) { + return NOT_ALLOWED_CURSOR; + } + const n = findCornerQuadrant(fabricObject, control) % 4; + return "".concat(skewMap[n], "-resize"); +}; + +/** + * Since skewing is applied before scaling, calculations are done in a scaleless plane + * @see https://github.com/fabricjs/fabric.js/pull/8380 + */ +function skewObject(axis, _ref, pointer) { + let { + target, + ex, + ey, + skewingSide + } = _ref, + transform = _objectWithoutProperties(_ref, _excluded$d); + const { + skew: skewKey + } = AXIS_KEYS[axis], + offset = pointer.subtract(new Point(ex, ey)).divide(new Point(target.scaleX, target.scaleY))[axis], + skewingBefore = target[skewKey], + skewingStart = transform[skewKey], + shearingStart = Math.tan(degreesToRadians(skewingStart)), + // let a, b be the size of target + // let a' be the value of a after applying skewing + // then: + // a' = a + b * skewA => skewA = (a' - a) / b + // the value b is tricky since skewY is applied before skewX + b = axis === 'y' ? target._getTransformedDimensions({ + scaleX: 1, + scaleY: 1, + // since skewY is applied before skewX, b (=width) is not affected by skewX + skewX: 0 + }).x : target._getTransformedDimensions({ + scaleX: 1, + scaleY: 1 + }).y; + const shearing = 2 * offset * skewingSide / + // we max out fractions to safeguard from asymptotic behavior + Math.max(b, 1) + + // add starting state + shearingStart; + const skewing = radiansToDegrees(Math.atan(shearing)); + target.set(skewKey, skewing); + const changed = skewingBefore !== target[skewKey]; + if (changed && axis === 'y') { + // we don't want skewing to affect scaleX + // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer + const { + skewX, + scaleX + } = target, + dimBefore = target._getTransformedDimensions({ + skewY: skewingBefore + }), + dimAfter = target._getTransformedDimensions(), + compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1; + compensationFactor !== 1 && target.set(SCALE_X, compensationFactor * scaleX); + } + return changed; +} + +/** + * Wrapped Action handler for skewing on a given axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +function skewHandler(axis, eventData, transform, x, y) { + const { + target + } = transform, + { + counterAxis, + origin: originKey, + lockSkewing: lockSkewingKey, + skew: skewKey, + flip: flipKey + } = AXIS_KEYS[axis]; + if (isLocked(target, lockSkewingKey)) { + return false; + } + const { + origin: counterOriginKey, + flip: counterFlipKey + } = AXIS_KEYS[counterAxis], + counterOriginFactor = resolveOrigin(transform[counterOriginKey]) * (target[counterFlipKey] ? -1 : 1), + // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively. + // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively. + // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer, + // so we factor skewing direction by this value. + skewingSide = -Math.sign(counterOriginFactor) * (target[flipKey] ? -1 : 1), + skewingDirection = (target[skewKey] === 0 && + // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing + getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0 || + // in case target has skewing we use that as the direction + target[skewKey] > 0 ? 1 : -1) * skewingSide, + // anchor to the opposite side of the skewing direction + // normalize value from [-1, 1] to origin value [0, 1] + origin = -skewingDirection * 0.5 + 0.5; + const finalHandler = wrapWithFireEvent(SKEWING, wrapWithFixedAnchor((eventData, transform, x, y) => skewObject(axis, transform, new Point(x, y)))); + return finalHandler(eventData, _objectSpread2(_objectSpread2({}, transform), {}, { + [originKey]: origin, + skewingSide + }), x, y); +} + +/** + * Wrapped Action handler for skewing on the X axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const skewHandlerX = (eventData, transform, x, y) => { + return skewHandler('x', eventData, transform, x, y); +}; + +/** + * Wrapped Action handler for skewing on the Y axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const skewHandlerY = (eventData, transform, x, y) => { + return skewHandler('y', eventData, transform, x, y); +}; + +function isAltAction(eventData, target) { + return eventData[target.canvas.altActionKey]; +} + +/** + * Inspect event, control and fabricObject to return the correct action name + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} an action name + */ +const scaleOrSkewActionName = (eventData, control, fabricObject) => { + const isAlternative = isAltAction(eventData, fabricObject); + if (control.x === 0) { + // then is scaleY or skewX + return isAlternative ? SKEW_X : SCALE_Y; + } + if (control.y === 0) { + // then is scaleY or skewX + return isAlternative ? SKEW_Y : SCALE_X; + } + return ''; +}; + +/** + * Combine skew and scale style handlers to cover fabric standard use case + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const scaleSkewCursorStyleHandler = (eventData, control, fabricObject) => { + return isAltAction(eventData, fabricObject) ? skewCursorStyleHandler(eventData, control, fabricObject) : scaleCursorStyleHandler(eventData, control, fabricObject); +}; +/** + * Composed action handler to either scale X or skew Y + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scalingXOrSkewingY = (eventData, transform, x, y) => { + return isAltAction(eventData, transform.target) ? skewHandlerY(eventData, transform, x, y) : scalingX(eventData, transform, x, y); +}; + +/** + * Composed action handler to either scale Y or skew X + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scalingYOrSkewingX = (eventData, transform, x, y) => { + return isAltAction(eventData, transform.target) ? skewHandlerX(eventData, transform, x, y) : scalingY(eventData, transform, x, y); +}; + +// use this function if you want to generate new controls for every instance +const createObjectDefaultControls = () => ({ + ml: new Control({ + x: -0.5, + y: 0, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingXOrSkewingY, + getActionName: scaleOrSkewActionName + }), + mr: new Control({ + x: 0.5, + y: 0, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingXOrSkewingY, + getActionName: scaleOrSkewActionName + }), + mb: new Control({ + x: 0, + y: 0.5, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingYOrSkewingX, + getActionName: scaleOrSkewActionName + }), + mt: new Control({ + x: 0, + y: -0.5, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingYOrSkewingX, + getActionName: scaleOrSkewActionName + }), + tl: new Control({ + x: -0.5, + y: -0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + tr: new Control({ + x: 0.5, + y: -0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + bl: new Control({ + x: -0.5, + y: 0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + br: new Control({ + x: 0.5, + y: 0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + mtr: new Control({ + x: 0, + y: -0.5, + actionHandler: rotationWithSnapping, + cursorStyleHandler: rotationStyleHandler, + offsetY: -40, + withConnection: true, + actionName: ROTATE + }) +}); +const createResizeControls = () => ({ + mr: new Control({ + x: 0.5, + y: 0, + actionHandler: changeWidth, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionName: RESIZING + }), + ml: new Control({ + x: -0.5, + y: 0, + actionHandler: changeWidth, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionName: RESIZING + }) +}); +const createTextboxDefaultControls = () => _objectSpread2(_objectSpread2({}, createObjectDefaultControls()), createResizeControls()); + +class InteractiveFabricObject extends FabricObject$1 { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), InteractiveFabricObject.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, this.constructor.createControls(), InteractiveFabricObject.ownDefaults); + this.setOptions(options); + } + + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults + * @param {Object} [options] Options object + */ + static createControls() { + return { + controls: createObjectDefaultControls() + }; + } + + /** + * Update width and height of the canvas for cache + * returns true or false if canvas needed resize. + * @private + * @return {Boolean} true if the canvas has been resized + */ + _updateCacheCanvas() { + const targetCanvas = this.canvas; + if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) { + const transform = targetCanvas._currentTransform, + target = transform.target, + action = transform.action; + if (this === target && action && action.startsWith(SCALE)) { + return false; + } + } + return super._updateCacheCanvas(); + } + getActiveControl() { + const key = this.__corner; + return key ? { + key, + control: this.controls[key], + coord: this.oCoords[key] + } : undefined; + } + + /** + * Determines which corner is under the mouse cursor, represented by `pointer`. + * This function is return a corner only if the object is the active one. + * This is done to avoid selecting corner of non active object and activating transformations + * rather than drag action. The default behavior of fabricJS is that if you want to transform + * an object, first you select it to show the control set + * @private + * @param {Object} pointer The pointer indicating the mouse position + * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action + * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found. + */ + findControl(pointer) { + let forTouch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.hasControls || !this.canvas) { + return undefined; + } + this.__corner = undefined; + const cornerEntries = Object.entries(this.oCoords); + for (let i = cornerEntries.length - 1; i >= 0; i--) { + const [key, corner] = cornerEntries[i]; + const control = this.controls[key]; + if (control.shouldActivate(key, this, pointer, forTouch ? corner.touchCorner : corner.corner)) { + // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2); + this.__corner = key; + return { + key, + control, + coord: this.oCoords[key] + }; + } + } + return undefined; + } + + /** + * Calculates the coordinates of the center of each control plus the corners of the control itself + * This basically just delegates to each control positionHandler + * WARNING: changing what is passed to positionHandler is a breaking change, since position handler + * is a public api and should be done just if extremely necessary + * @return {Record} + */ + calcOCoords() { + const vpt = this.getViewportTransform(), + center = this.getCenterPoint(), + tMatrix = createTranslateMatrix(center.x, center.y), + rMatrix = createRotateMatrix({ + angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0) + }), + positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix), + startMatrix = multiplyTransformMatrices(vpt, positionMatrix), + finalMatrix = multiplyTransformMatrices(startMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]), + transformOptions = this.group ? qrDecompose(this.calcTransformMatrix()) : undefined; + // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it + if (transformOptions) { + transformOptions.scaleX = Math.abs(transformOptions.scaleX); + transformOptions.scaleY = Math.abs(transformOptions.scaleY); + } + const dim = this._calculateCurrentDimensions(transformOptions), + coords = {}; + this.forEachControl((control, key) => { + const position = control.positionHandler(dim, finalMatrix, this, control); + // coords[key] are sometimes used as points. Those are points to which we add + // the property corner and touchCorner from `_calcCornerCoords`. + // don't remove this assign for an object spread. + coords[key] = Object.assign(position, this._calcCornerCoords(control, position)); + }); + + // debug code + /* + const canvas = this.canvas; + setTimeout(function () { + if (!canvas) return; + canvas.contextTop.clearRect(0, 0, 700, 700); + canvas.contextTop.fillStyle = 'green'; + Object.keys(coords).forEach(function(key) { + const control = coords[key]; + canvas.contextTop.fillRect(control.x, control.y, 3, 3); + }); + } 50); + */ + return coords; + } + + /** + * Sets the coordinates that determine the interaction area of each control + * note: if we would switch to ROUND corner area, all of this would disappear. + * everything would resolve to a single point and a pythagorean theorem for the distance + * @todo evaluate simplification of code switching to circle interaction area at runtime + * @private + */ + _calcCornerCoords(control, position) { + const angle = this.getTotalAngle(); + const corner = control.calcCornerCoords(angle, this.cornerSize, position.x, position.y, false, this); + const touchCorner = control.calcCornerCoords(angle, this.touchCornerSize, position.x, position.y, true, this); + return { + corner, + touchCorner + }; + } + + /** + * @override set controls' coordinates as well + * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas} + * @return {void} + */ + setCoords() { + super.setCoords(); + this.canvas && (this.oCoords = this.calcOCoords()); + } + + /** + * Calls a function for each control. The function gets called, + * with the control, the control's key and the object that is calling the iterator + * @param {Function} fn function to iterate over the controls over + */ + forEachControl(fn) { + for (const i in this.controls) { + fn(this.controls[i], i, this); + } + } + + /** + * Draws a colored layer behind the object, inside its selection borders. + * Requires public options: padding, selectionBackgroundColor + * this function is called when the context is transformed + * has checks to be skipped when the object is on a staticCanvas + * @todo evaluate if make this disappear in favor of a pre-render hook for objects + * this was added by Andrea Bogazzi to make possible some feature for work reasons + * it seemed a good option, now is an edge case + * @param {CanvasRenderingContext2D} ctx Context to draw on + */ + drawSelectionBackground(ctx) { + if (!this.selectionBackgroundColor || this.canvas && this.canvas._activeObject !== this) { + return; + } + ctx.save(); + const center = this.getRelativeCenterPoint(), + wh = this._calculateCurrentDimensions(), + vpt = this.getViewportTransform(); + ctx.translate(center.x, center.y); + ctx.scale(1 / vpt[0], 1 / vpt[3]); + ctx.rotate(degreesToRadians(this.angle)); + ctx.fillStyle = this.selectionBackgroundColor; + ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); + ctx.restore(); + } + + /** + * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style. + * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center + * @param {Point} size the control box size used + */ + strokeBorders(ctx, size) { + ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {Point} size + * @param {TStyleOverride} styleOverride object to override the object style + */ + _drawBorders(ctx, size) { + let styleOverride = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const options = _objectSpread2({ + hasControls: this.hasControls, + borderColor: this.borderColor, + borderDashArray: this.borderDashArray + }, styleOverride); + ctx.save(); + ctx.strokeStyle = options.borderColor; + this._setLineDash(ctx, options.borderDashArray); + this.strokeBorders(ctx, size); + options.hasControls && this.drawControlsConnectingLines(ctx, size); + ctx.restore(); + } + + /** + * Renders controls and borders for the object + * the context here is not transformed + * @todo move to interactivity + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {TStyleOverride} [styleOverride] properties to override the object style + */ + _renderControls(ctx) { + let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + hasBorders, + hasControls + } = this; + const styleOptions = _objectSpread2({ + hasBorders, + hasControls + }, styleOverride); + const vpt = this.getViewportTransform(), + shouldDrawBorders = styleOptions.hasBorders, + shouldDrawControls = styleOptions.hasControls; + const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix()); + const options = qrDecompose(matrix); + ctx.save(); + ctx.translate(options.translateX, options.translateY); + ctx.lineWidth = 1 * this.borderScaleFactor; + // since interactive groups have been introduced, an object could be inside a group and needing controls + // the following equality check `this.group === this.parent` covers: + // object without a group ( undefined === undefined ) + // object inside a group + // excludes object inside a group but multi selected since group and parent will differ in value + if (this.group === this.parent) { + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + } + if (this.flipX) { + options.angle -= 180; + } + ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle)); + shouldDrawBorders && this.drawBorders(ctx, options, styleOverride); + shouldDrawControls && this.drawControls(ctx, styleOverride); + ctx.restore(); + } + + /** + * Draws borders of an object's bounding box. + * Requires public properties: width, height + * Requires public options: padding, borderColor + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {object} options object representing current object parameters + * @param {TStyleOverride} [styleOverride] object to override the object style + */ + drawBorders(ctx, options, styleOverride) { + let size; + if (styleOverride && styleOverride.forActiveSelection || this.group) { + const bbox = sizeAfterTransform(this.width, this.height, calcDimensionsMatrix(options)), + stroke = !this.isStrokeAccountedForInDimensions() ? (this.strokeUniform ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1) : + // this is extremely confusing. options comes from the upper function + // and is the qrDecompose of a matrix that takes in account zoom too + new Point(options.scaleX, options.scaleY)).scalarMultiply(this.strokeWidth) : ZERO; + size = bbox.add(stroke).scalarAdd(this.borderScaleFactor).scalarAdd(this.padding * 2); + } else { + size = this._calculateCurrentDimensions().scalarAdd(this.borderScaleFactor); + } + this._drawBorders(ctx, size, styleOverride); + } + + /** + * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set. + * Requires public properties: width, height + * Requires public options: padding, borderColor + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {Point} size object size x = width, y = height + */ + drawControlsConnectingLines(ctx, size) { + let shouldStroke = false; + ctx.beginPath(); + this.forEachControl((control, key) => { + // in this moment, the ctx is centered on the object. + // width and height of the above function are the size of the bbox. + if (control.withConnection && control.getVisibility(this, key)) { + // reset movement for each control + shouldStroke = true; + ctx.moveTo(control.x * size.x, control.y * size.y); + ctx.lineTo(control.x * size.x + control.offsetX, control.y * size.y + control.offsetY); + } + }); + shouldStroke && ctx.stroke(); + } + + /** + * Draws corners of an object's bounding box. + * Requires public properties: width, height + * Requires public options: cornerSize, padding + * Be aware that since fabric 6.0 this function does not call setCoords anymore. + * setCoords needs to be called manually if the object of which we are rendering controls + * is outside the standard selection and transform process. + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {ControlRenderingStyleOverride} styleOverride object to override the object style + */ + drawControls(ctx) { + let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + ctx.save(); + const retinaScaling = this.getCanvasRetinaScaling(); + const { + cornerStrokeColor, + cornerDashArray, + cornerColor + } = this; + const options = _objectSpread2({ + cornerStrokeColor, + cornerDashArray, + cornerColor + }, styleOverride); + ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0); + ctx.strokeStyle = ctx.fillStyle = options.cornerColor; + if (!this.transparentCorners) { + ctx.strokeStyle = options.cornerStrokeColor; + } + this._setLineDash(ctx, options.cornerDashArray); + this.forEachControl((control, key) => { + if (control.getVisibility(this, key)) { + const p = this.oCoords[key]; + control.render(ctx, p.x, p.y, options, this); + } + }); + ctx.restore(); + } + + /** + * Returns true if the specified control is visible, false otherwise. + * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr', + * but since the control api allow for any control name, can be any string. + * @returns {boolean} true if the specified control is visible, false otherwise + */ + isControlVisible(controlKey) { + return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey); + } + + /** + * Sets the visibility of the specified control. + * please do not use. + * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. + * but since the control api allow for any control name, can be any string. + * @param {Boolean} visible true to set the specified control visible, false otherwise + * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details + */ + setControlVisible(controlKey, visible) { + if (!this._controlsVisibility) { + this._controlsVisibility = {}; + } + this._controlsVisibility[controlKey] = visible; + } + + /** + * Sets the visibility state of object controls, this is just a bulk option for setControlVisible; + * @param {Record} [options] with an optional key per control + * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it + */ + setControlsVisibility() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + Object.entries(options).forEach(_ref => { + let [controlKey, visibility] = _ref; + return this.setControlVisible(controlKey, visibility); + }); + } + + /** + * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box + * that is in the canvas.contextContainer. + * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object. + * Example: blinking cursor text selection, drag effects. + * @todo discuss swapping restoreManually with a renderCallback, but think of async issues + * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else. + * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed + * with the object transformMatrix, or restored to neutral transform + */ + clearContextTop(restoreManually) { + if (!this.canvas) { + return; + } + const ctx = this.canvas.contextTop; + if (!ctx) { + return; + } + const v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + this.transform(ctx); + // we add 4 pixel, to be sure to do not leave any pixel out + const width = this.width + 4, + height = this.height + 4; + ctx.clearRect(-width / 2, -height / 2, width, height); + restoreManually || ctx.restore(); + return ctx; + } + + /** + * This callback function is called every time _discardActiveObject or _setActiveObject + * try to to deselect this object. If the function returns true, the process is cancelled + * @param {Object} [_options] options sent from the upper functions + * @param {TPointerEvent} [options.e] event if the process is generated by an event + * @param {FabricObject} [options.object] next object we are setting as active, and reason why + * this is being deselected + */ + onDeselect(_options) { + // implemented by sub-classes, as needed. + return false; + } + + /** + * This callback function is called every time _discardActiveObject or _setActiveObject + * try to to select this object. If the function returns true, the process is cancelled + * @param {Object} [_options] options sent from the upper functions + * @param {Event} [_options.e] event if the process is generated by an event + */ + onSelect(_options) { + // implemented by sub-classes, as needed. + return false; + } + + /** + * Override to customize Drag behavior + * Fired from {@link Canvas#_onMouseMove} + * @returns true in order for the window to start a drag session + */ + shouldStartDragging(_e) { + return false; + } + + /** + * Override to customize Drag behavior\ + * Fired once a drag session has started + * @returns true to handle the drag event + */ + onDragStart(_e) { + return false; + } + + /** + * Override to customize drag and drop behavior + * @public + * @param {DragEvent} _e + * @returns {boolean} true if the object currently dragged can be dropped on the target + */ + canDrop(_e) { + return false; + } + + /** + * Override to customize drag and drop behavior + * render a specific effect when an object is the source of a drag event + * example: render the selection status for the part of text that is being dragged from a text object + * @public + * @param {DragEvent} _e + */ + renderDragSourceEffect(_e) { + // for subclasses + } + + /** + * Override to customize drag and drop behavior + * render a specific effect when an object is the target of a drag event + * used to show that the underly object can receive a drop, or to show how the + * object will change when dropping. example: show the cursor where the text is about to be dropped + * @public + * @param {DragEvent} _e + */ + renderDropTargetEffect(_e) { + // for subclasses + } +} +/** + * The object's controls' position in viewport coordinates + * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}. + * `corner/touchCorner` describe the 4 points forming the interactive area of the corner. + * Used to draw and locate controls. + */ +/** + * keeps the value of the last hovered corner during mouse move. + * 0 is no corner, or 'mt', 'ml', 'mtr' etc.. + * It should be private, but there is no harm in using it as + * a read-only property. + * this isn't cleaned automatically. Non selected objects may have wrong values + * @type [string] + */ +/** + * a map of control visibility for this object. + * this was left when controls were introduced to not break the api too much + * this takes priority over the generic control visibility + */ +/** + * holds the controls for the object. + * controls are added by default_controls.js + */ +/** + * internal boolean to signal the code that the object is + * part of the move action. + */ +/** + * A boolean used from the gesture module to keep tracking of a scaling + * action when there is no scaling transform in place. + * This is an edge case and is used twice in all codebase. + * Probably added to keep track of some performance issues + * @TODO use git blame to investigate why it was added + * DON'T USE IT. WE WILL TRY TO REMOVE IT + */ +_defineProperty(InteractiveFabricObject, "ownDefaults", interactiveObjectDefaultValues); + +/*** + * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern + */ +function applyMixins(derivedCtor, constructors) { + constructors.forEach(baseCtor => { + Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { + name !== 'constructor' && Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)); + }); + }); + return derivedCtor; +} + +// TODO somehow we have to make a tree-shakeable import + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type + +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging +class FabricObject extends InteractiveFabricObject {} +applyMixins(FabricObject, [FabricObjectSVGExportMixin]); +classRegistry.setClass(FabricObject); +classRegistry.setClass(FabricObject, 'object'); + +/** + * Returns true if context has transparent pixel + * at specified location (taking tolerance into account) + * @param {CanvasRenderingContext2D} ctx context + * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer + * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer + * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer + * @return {boolean} true if transparent + */ +const isTransparent = (ctx, x, y, tolerance) => { + tolerance = Math.round(tolerance); + const size = tolerance * 2 + 1; + const { + data + } = ctx.getImageData(x - tolerance, y - tolerance, size, size); + + // Split image data - for tolerance > 1, pixelDataSize = 4; + for (let i = 3; i < data.length; i += 4) { + const alphaChannel = data[i]; + if (alphaChannel > 0) { + return false; + } + } + return true; +}; + +/** + * Rotates `point` around `origin` with `radians` + * @deprecated use the Point.rotate + * @param {Point} origin The origin of the rotation + * @param {Point} origin The origin of the rotation + * @param {TRadian} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ +const rotatePoint = (point, origin, radians) => point.rotate(radians, origin); + +const findIndexRight = (array, predicate) => { + for (let index = array.length - 1; index >= 0; index--) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +}; + +/** + * @see https://github.com/fabricjs/fabric.js/pull/8344 + * @todo consider removing skewing from points before calculating stroke projection, + * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537 + */ +class StrokeProjectionsBase { + constructor(options) { + this.options = options; + this.strokeProjectionMagnitude = this.options.strokeWidth / 2; + this.scale = new Point(this.options.scaleX, this.options.scaleY); + this.strokeUniformScalar = this.options.strokeUniform ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY) : new Point(1, 1); + } + + /** + * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account. + */ + createSideVector(from, to) { + const v = createVector(from, to); + return this.options.strokeUniform ? v.multiply(this.scale) : v; + } + projectOrthogonally(from, to, magnitude) { + return this.applySkew(from.add(this.calcOrthogonalProjection(from, to, magnitude))); + } + isSkewed() { + return this.options.skewX !== 0 || this.options.skewY !== 0; + } + applySkew(point) { + const p = new Point(point); + // skewY must be applied before skewX as this distortion affects skewX calculation + p.y += p.x * Math.tan(degreesToRadians(this.options.skewY)); + p.x += p.y * Math.tan(degreesToRadians(this.options.skewX)); + return p; + } + scaleUnitVector(unitVector, scalar) { + return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar); + } +} + +const zeroVector = new Point(); + +/** + * class in charge of finding projections for each type of line join + * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)} + * + * - MDN: + * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin + * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin + * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty + * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html + * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js + * + */ +class StrokeLineJoinProjections extends StrokeProjectionsBase { + static getOrthogonalRotationFactor(vector1, vector2) { + const angle = vector2 ? calcAngleBetweenVectors(vector1, vector2) : calcVectorRotation(vector1); + return Math.abs(angle) < halfPI ? -1 : 1; + } + constructor(A, B, C, options) { + super(options); + /** + * The point being projected (the angle ∠BAC) + */ + /** + * The point before A + */ + /** + * The point after A + */ + /** + * The AB vector + */ + _defineProperty(this, "AB", void 0); + /** + * The AC vector + */ + _defineProperty(this, "AC", void 0); + /** + * The angle of A (∠BAC) + */ + _defineProperty(this, "alpha", void 0); + /** + * The bisector of A (∠BAC) + */ + _defineProperty(this, "bisector", void 0); + this.A = new Point(A); + this.B = new Point(B); + this.C = new Point(C); + this.AB = this.createSideVector(this.A, this.B); + this.AC = this.createSideVector(this.A, this.C); + this.alpha = calcAngleBetweenVectors(this.AB, this.AC); + this.bisector = getUnitVector( + // if AC is also the zero vector nothing will be projected + // in that case the next point will handle the projection + rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2)); + } + calcOrthogonalProjection(from, to) { + let magnitude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.strokeProjectionMagnitude; + const vector = this.createSideVector(from, to); + const orthogonalProjection = getOrthonormalVector(vector); + const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(orthogonalProjection, this.bisector); + return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide); + } + + /** + * BEVEL + * Calculation: the projection points are formed by the vector orthogonal to the vertex. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel + */ + projectBevel() { + const projections = []; + // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C` + (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(to => { + projections.push(this.projectOrthogonally(this.A, to)); + projections.push(this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude)); + }); + return projections; + } + + /** + * MITER + * Calculation: the corner is formed by extending the outer edges of the stroke + * at the tangents of the path segments until they intersect. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter + */ + projectMiter() { + const projections = [], + alpha = Math.abs(this.alpha), + hypotUnitScalar = 1 / Math.sin(alpha / 2), + miterVector = this.scaleUnitVector(this.bisector, -this.strokeProjectionMagnitude * hypotUnitScalar); + + // When two line segments meet at a sharp angle, it is possible for the join to extend, + // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes + // a limit on the extent of the line join. + // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit + // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit + const strokeMiterLimit = this.options.strokeUniform ? magnitude(this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit)) : this.options.strokeMiterLimit; + if (magnitude(miterVector) / this.strokeProjectionMagnitude <= strokeMiterLimit) { + projections.push(this.applySkew(this.A.add(miterVector))); + } + /* when the miter-limit is reached, the stroke line join becomes of type bevel. + We always need two orthogonal projections which are basically bevel-type projections, + so regardless of whether the miter-limit was reached or not, we include these projections. + */ + projections.push(...this.projectBevel()); + return projections; + } + + /** + * ROUND (without skew) + * Calculation: the projections are the two vectors parallel to X and Y axes + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew + */ + projectRoundNoSkew(startCircle, endCircle) { + const projections = [], + // correctSide is used to only consider projecting for the outer side + correctSide = new Point(StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector), StrokeLineJoinProjections.getOrthogonalRotationFactor(new Point(this.bisector.y, this.bisector.x))), + radiusOnAxisX = new Point(1, 0).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(correctSide), + radiusOnAxisY = new Point(0, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(correctSide); + [radiusOnAxisX, radiusOnAxisY].forEach(vector => { + if (isBetweenVectors(vector, startCircle, endCircle)) { + projections.push(this.A.add(vector)); + } + }); + return projections; + } + + /** + * ROUND (with skew) + * Calculation: the projections are the points furthest from the vertex in + * the direction of the X and Y axes after distortion. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew + */ + projectRoundWithSkew(startCircle, endCircle) { + const projections = []; + const { + skewX, + skewY, + scaleX, + scaleY, + strokeUniform + } = this.options, + shearing = new Point(Math.tan(degreesToRadians(skewX)), Math.tan(degreesToRadians(skewY))); + // The points furthest from the vertex in the direction of the X and Y axes after distortion + const circleRadius = this.strokeProjectionMagnitude, + newY = strokeUniform ? circleRadius / scaleY / Math.sqrt(1 / scaleY ** 2 + 1 / scaleX ** 2 * shearing.y ** 2) : circleRadius / Math.sqrt(1 + shearing.y ** 2), + furthestY = new Point( + // Safe guard due to floating point precision. In some situations the square root + // was returning NaN because of a negative number close to zero. + Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)), newY), + newX = strokeUniform ? circleRadius / Math.sqrt(1 + shearing.x ** 2 * (1 / scaleY) ** 2 / (1 / scaleX + 1 / scaleX * shearing.x * shearing.y) ** 2) : circleRadius / Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2), + furthestX = new Point(newX, Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0))); + [furthestX, furthestX.scalarMultiply(-1), furthestY, furthestY.scalarMultiply(-1)] + // We need to skew the vector here as this information is used to check if + // it is between the start and end of the circle segment + .map(vector => this.applySkew(strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector)).forEach(vector => { + if (isBetweenVectors(vector, startCircle, endCircle)) { + projections.push(this.applySkew(this.A).add(vector)); + } + }); + return projections; + } + projectRound() { + const projections = []; + /* Include the start and end points of the circle segment, so that only + the projections contained within it are included */ + // add the orthogonal projections (start and end points of circle segment) + projections.push(...this.projectBevel()); + // let's determines which one of the orthogonal projection is the beginning and end of the circle segment. + // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different. + const isStraightLine = this.alpha % twoMathPi === 0, + // change the origin of the projections to point A + // so that the cross product calculation is correct + newOrigin = this.applySkew(this.A), + proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin), + proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin), + // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector. + comparisonVector = isStraightLine ? this.applySkew(this.AB.scalarMultiply(-1)) : this.applySkew(this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1)), + // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0) + isProj0Start = crossProduct(proj0, comparisonVector) > 0, + startCircle = isProj0Start ? proj0 : proj1, + endCircle = isProj0Start ? proj1 : proj0; + if (!this.isSkewed()) { + projections.push(...this.projectRoundNoSkew(startCircle, endCircle)); + } else { + projections.push(...this.projectRoundWithSkew(startCircle, endCircle)); + } + return projections; + } + + /** + * Project stroke width on points returning projections for each point as follows: + * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel) + * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke. + * - `round`: same as `bevel` when it has no skew, with skew are 4 points. + */ + projectPoints() { + switch (this.options.strokeLineJoin) { + case 'miter': + return this.projectMiter(); + case 'round': + return this.projectRound(); + default: + return this.projectBevel(); + } + } + project() { + return this.projectPoints().map(point => ({ + originPoint: this.A, + projectedPoint: point, + angle: this.alpha, + bisector: this.bisector + })); + } +} + +/** + * class in charge of finding projections for each type of line cap for start/end of an open path + * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)} + * + * Reference: + * - MDN: + * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap + * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap + * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev + * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html + * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js + */ +class StrokeLineCapProjections extends StrokeProjectionsBase { + /** + * edge point + */ + + /** + * point next to edge point + */ + + constructor(A, T, options) { + super(options); + this.A = new Point(A); + this.T = new Point(T); + } + calcOrthogonalProjection(from, to) { + let magnitude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.strokeProjectionMagnitude; + const vector = this.createSideVector(from, to); + return this.scaleUnitVector(getOrthonormalVector(vector), magnitude); + } + + /** + * OPEN PATH START/END - Line cap: Butt + * Calculation: to find the projections, just find the points orthogonal to the stroke + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt + */ + projectButt() { + return [this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude), this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude)]; + } + + /** + * OPEN PATH START/END - Line cap: Round + * Calculation: same as stroke line join `round` + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round + */ + projectRound() { + const projections = []; + if (!this.isSkewed() && this.A.eq(this.T)) { + /* 1 point case without `skew` + When `strokeUniform` is true, scaling has no effect. + So we divide by scale, to remove its effect. + */ + const projection = new Point(1, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar); + projections.push(this.applySkew(this.A.add(projection)), this.applySkew(this.A.subtract(projection))); + } else { + projections.push(...new StrokeLineJoinProjections(this.A, this.T, this.T, this.options).projectRound()); + } + return projections; + } + + /** + * OPEN PATH START/END - Line cap: Square + * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT` + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square + */ + projectSquare() { + const projections = []; + if (this.A.eq(this.T)) { + /* 1 point case without `skew` + When `strokeUniform` is true, scaling has no effect. + So we divide by scale, to remove its effect. + */ + const projection = new Point(1, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar); + projections.push(this.A.add(projection), this.A.subtract(projection)); + } else { + const orthogonalProjection = this.calcOrthogonalProjection(this.A, this.T, this.strokeProjectionMagnitude); + const strokePointingOut = this.scaleUnitVector(getUnitVector(this.createSideVector(this.A, this.T)), -this.strokeProjectionMagnitude); + const projectedA = this.A.add(strokePointingOut); + projections.push(projectedA.add(orthogonalProjection), projectedA.subtract(orthogonalProjection)); + } + return projections.map(p => this.applySkew(p)); + } + projectPoints() { + switch (this.options.strokeLineCap) { + case 'round': + return this.projectRound(); + case 'square': + return this.projectSquare(); + default: + return this.projectButt(); + } + } + project() { + return this.projectPoints().map(point => ({ + originPoint: this.A, + projectedPoint: point + })); + } +} + +/** + * + * Used to calculate object's bounding box + * + * @see https://github.com/fabricjs/fabric.js/pull/8344 + * + */ +const projectStrokeOnPoints = function (points, options) { + let openPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + const projections = []; + if (points.length === 0) { + return projections; + } + + // first we remove duplicate neighboring points + const reduced = points.reduce((reduced, point) => { + if (!reduced[reduced.length - 1].eq(point)) { + reduced.push(new Point(point)); + } + return reduced; + }, [new Point(points[0])]); + if (reduced.length === 1) { + openPath = true; + } else if (!openPath) { + // remove points from end in case they equal the first point + // in order to correctly project the first point + const start = reduced[0]; + const index = findIndexRight(reduced, point => !point.eq(start)); + reduced.splice(index + 1); + } + reduced.forEach((A, index, points) => { + let B, C; + if (index === 0) { + C = points[1]; + B = openPath ? A : points[points.length - 1]; + } else if (index === points.length - 1) { + B = points[index - 1]; + C = openPath ? A : points[0]; + } else { + B = points[index - 1]; + C = points[index + 1]; + } + if (openPath && points.length === 1) { + projections.push(...new StrokeLineCapProjections(A, A, options).project()); + } else if (openPath && (index === 0 || index === points.length - 1)) { + projections.push(...new StrokeLineCapProjections(A, index === 0 ? C : B, options).project()); + } else { + projections.push(...new StrokeLineJoinProjections(A, B, C, options).project()); + } + }); + return projections; +}; + +const cloneStyles = style => { + const newObj = {}; + Object.keys(style).forEach(key => { + newObj[key] = {}; + Object.keys(style[key]).forEach(keyInner => { + newObj[key][keyInner] = _objectSpread2({}, style[key][keyInner]); + }); + }); + return newObj; +}; + +/** + * Capitalizes a string + * @param {String} string String to capitalize + * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized + * and other letters stay untouched, if false first letter is capitalized + * and other letters are converted to lowercase. + * @return {String} Capitalized version of a string + */ +const capitalize = function (string) { + let firstLetterOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return "".concat(string.charAt(0).toUpperCase()).concat(firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); +}; + +/** + * Escapes XML in a string + * @param {String} string String to escape + * @return {String} Escaped version of a string + */ +const escapeXml = string => string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); + +/** + * Divide a string in the user perceived single units + * @param {String} textstring String to escape + * @return {Array} array containing the graphemes + */ +const graphemeSplit = textstring => { + const graphemes = []; + for (let i = 0, chr; i < textstring.length; i++) { + if ((chr = getWholeChar(textstring, i)) === false) { + continue; + } + graphemes.push(chr); + } + return graphemes; +}; + +// taken from mdn in the charAt doc page. +const getWholeChar = (str, i) => { + const code = str.charCodeAt(i); + if (isNaN(code)) { + return ''; // Position not found + } + if (code < 0xd800 || code > 0xdfff) { + return str.charAt(i); + } + + // High surrogate (could change last hex to 0xDB7F to treat high private + // surrogates as single characters) + if (0xd800 <= code && code <= 0xdbff) { + if (str.length <= i + 1) { + throw 'High surrogate without following low surrogate'; + } + const next = str.charCodeAt(i + 1); + if (0xdc00 > next || next > 0xdfff) { + throw 'High surrogate without following low surrogate'; + } + return str.charAt(i) + str.charAt(i + 1); + } + // Low surrogate (0xDC00 <= code && code <= 0xDFFF) + if (i === 0) { + throw 'Low surrogate without preceding high surrogate'; + } + const prev = str.charCodeAt(i - 1); + + // (could change last hex to 0xDB7F to treat high private + // surrogates as single characters) + if (0xd800 > prev || prev > 0xdbff) { + throw 'Low surrogate without preceding high surrogate'; + } + // We can pass over low surrogates now as the second component + // in a pair which we have already processed + return false; +}; + +var lang_string = /*#__PURE__*/Object.freeze({ + __proto__: null, + capitalize: capitalize, + escapeXml: escapeXml, + graphemeSplit: graphemeSplit +}); + +/** + * @param {Object} prevStyle first style to compare + * @param {Object} thisStyle second style to compare + * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties + * @return {boolean} true if the style changed + */ +const hasStyleChanged = function (prevStyle, thisStyle) { + let forTextSpans = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.deltaY !== thisStyle.deltaY || forTextSpans && (prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough); +}; + +/** + * Returns the array form of a text object's inline styles property with styles grouped in ranges + * rather than per character. This format is less verbose, and is better suited for storage + * so it is used in serialization (not during runtime). + * @param {object} styles per character styles for a text object + * @param {String} text the text string that the styles are applied to + * @return {{start: number, end: number, style: object}[]} + */ +const stylesToArray = (styles, text) => { + const textLines = text.split('\n'), + stylesArray = []; + let charIndex = -1, + prevStyle = {}; + // clone style structure to prevent mutation + styles = cloneStyles(styles); + + //loop through each textLine + for (let i = 0; i < textLines.length; i++) { + const chars = graphemeSplit(textLines[i]); + if (!styles[i]) { + //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle + charIndex += chars.length; + prevStyle = {}; + continue; + } + //loop through each character of the current line + for (let c = 0; c < chars.length; c++) { + charIndex++; + const thisStyle = styles[i][c]; + //check if style exists for this character + if (thisStyle && Object.keys(thisStyle).length > 0) { + if (hasStyleChanged(prevStyle, thisStyle, true)) { + stylesArray.push({ + start: charIndex, + end: charIndex + 1, + style: thisStyle + }); + } else { + //if style is the same as previous character, increase end index + stylesArray[stylesArray.length - 1].end++; + } + } + prevStyle = thisStyle || {}; + } + } + return stylesArray; +}; + +/** + * Returns the object form of the styles property with styles that are assigned per + * character rather than grouped by range. This format is more verbose, and is + * only used during runtime (not for serialization/storage) + * @param {Array} styles the serialized form of a text object's styles + * @param {String} text the text string that the styles are applied to + * @return {Object} + */ +const stylesFromArray = (styles, text) => { + if (!Array.isArray(styles)) { + // clone to prevent mutation + return cloneStyles(styles); + } + const textLines = text.split(reNewline), + stylesObject = {}; + let charIndex = -1, + styleIndex = 0; + //loop through each textLine + for (let i = 0; i < textLines.length; i++) { + const chars = graphemeSplit(textLines[i]); + + //loop through each character of the current line + for (let c = 0; c < chars.length; c++) { + charIndex++; + //check if there's a style collection that includes the current character + if (styles[styleIndex] && styles[styleIndex].start <= charIndex && charIndex < styles[styleIndex].end) { + //create object for line index if it doesn't exist + stylesObject[i] = stylesObject[i] || {}; + //assign a style at this character's index + stylesObject[i][c] = _objectSpread2({}, styles[styleIndex].style); + //if character is at the end of the current style collection, move to the next + if (charIndex === styles[styleIndex].end - 1) { + styleIndex++; + } + } + } + } + return stylesObject; +}; + +/** + * Attributes parsed from all SVG elements + * @type array + */ +const SHARED_ATTRIBUTES = ['display', 'transform', FILL, 'fill-opacity', 'fill-rule', 'opacity', STROKE, 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'id', 'paint-order', 'vector-effect', 'instantiated_by_use', 'clip-path']; + +function selectorMatches(element, selector) { + const nodeName = element.nodeName; + const classNames = element.getAttribute('class'); + const id = element.getAttribute('id'); + const azAz = '(?![a-zA-Z\\-]+)'; + let matcher; + // i check if a selector matches slicing away part from it. + // if i get empty string i should match + matcher = new RegExp('^' + nodeName, 'i'); + selector = selector.replace(matcher, ''); + if (id && selector.length) { + matcher = new RegExp('#' + id + azAz, 'i'); + selector = selector.replace(matcher, ''); + } + if (classNames && selector.length) { + const splitClassNames = classNames.split(' '); + for (let i = splitClassNames.length; i--;) { + matcher = new RegExp('\\.' + splitClassNames[i] + azAz, 'i'); + selector = selector.replace(matcher, ''); + } + } + return selector.length === 0; +} + +function doesSomeParentMatch(element, selectors) { + let selector, + parentMatching = true; + while (element.parentElement && element.parentElement.nodeType === 1 && selectors.length) { + if (parentMatching) { + selector = selectors.pop(); + } + element = element.parentElement; + parentMatching = selectorMatches(element, selector); + } + return selectors.length === 0; +} + +/** + * @private + */ + +function elementMatchesRule(element, selectors) { + let parentMatching = true; + // start from rightmost selector. + const firstMatching = selectorMatches(element, selectors.pop()); + if (firstMatching && selectors.length) { + parentMatching = doesSomeParentMatch(element, selectors); + } + return firstMatching && parentMatching && selectors.length === 0; +} + +/** + * @private + */ + +function getGlobalStylesForElement(element) { + let cssRules = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let styles = {}; + for (const rule in cssRules) { + if (elementMatchesRule(element, rule.split(' '))) { + styles = _objectSpread2(_objectSpread2({}, styles), cssRules[rule]); + } + } + return styles; +} + +const normalizeAttr = attr => { + var _attributesMap; + return (_attributesMap = attributesMap[attr]) !== null && _attributesMap !== void 0 ? _attributesMap : attr; +}; + +const regex$1 = new RegExp("(".concat(reNum, ")"), 'gi'); +const cleanupSvgAttribute = attributeValue => attributeValue.replace(regex$1, ' $1 ') +// replace annoying commas and arbitrary whitespace with single spaces +.replace(/,/gi, ' ').replace(/\s+/gi, ' '); + +var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7; + +// == begin transform regexp +const p$1 = "(".concat(reNum, ")"); +const skewX = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1); +const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1); +const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1); +const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1); +const translate = String.raw(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["(translate)(", "(?: ", ")?)"], ["(translate)\\(", "(?: ", ")?\\)"])), p$1, p$1); +const matrix = String.raw(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["(matrix)(", " ", " ", " ", " ", " ", ")"], ["(matrix)\\(", " ", " ", " ", " ", " ", "\\)"])), p$1, p$1, p$1, p$1, p$1, p$1); +const transform = "(?:".concat(matrix, "|").concat(translate, "|").concat(rotate, "|").concat(scale, "|").concat(skewX, "|").concat(skewY, ")"); +const transforms = "(?:".concat(transform, "*)"); +const transformList = String.raw(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["^s*(?:", "?)s*$"], ["^\\s*(?:", "?)\\s*$"])), transforms); +// http://www.w3.org/TR/SVG/coords.html#TransformAttribute +const reTransformList = new RegExp(transformList); +const reTransform = new RegExp(transform); +const reTransformAll = new RegExp(transform, 'g'); +// == end transform regexp + +/** + * Parses "transform" attribute, returning an array of values + * @static + * @function + * @memberOf fabric + * @param {String} attributeValue String containing attribute value + * @return {TTransformMatrix} Array of 6 elements representing transformation matrix + */ +function parseTransformAttribute(attributeValue) { + // first we clean the string + attributeValue = cleanupSvgAttribute(attributeValue) + // remove spaces around front parentheses + .replace(/\s*([()])\s*/gi, '$1'); + + // start with identity matrix + const matrices = []; + + // return if no argument was given or + // an argument does not match transform attribute regexp + if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) { + return [...iMatrix]; + } + for (const match of attributeValue.matchAll(reTransformAll)) { + const transformMatch = reTransform.exec(match[0]); + if (!transformMatch) { + continue; + } + let matrix = iMatrix; + const matchedParams = transformMatch.filter(m => !!m); + const [, operation, ...rawArgs] = matchedParams; + const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map(arg => parseFloat(arg)); + switch (operation) { + case 'translate': + matrix = createTranslateMatrix(arg0, arg1); + break; + case ROTATE: + matrix = createRotateMatrix({ + angle: arg0 + }, { + x: arg1, + y: arg2 + }); + break; + case SCALE: + matrix = createScaleMatrix(arg0, arg1); + break; + case SKEW_X: + matrix = createSkewXMatrix(arg0); + break; + case SKEW_Y: + matrix = createSkewYMatrix(arg0); + break; + case 'matrix': + matrix = [arg0, arg1, arg2, arg3, arg4, arg5]; + break; + } + + // snapshot current matrix into matrices array + matrices.push(matrix); + } + return multiplyTransformMatrixArray(matrices); +} + +function normalizeValue(attr, value, parentAttributes, fontSize) { + const isArray = Array.isArray(value); + let parsed; + let ouputValue = value; + if ((attr === FILL || attr === STROKE) && value === NONE) { + ouputValue = ''; + } else if (attr === 'strokeUniform') { + return value === 'non-scaling-stroke'; + } else if (attr === 'strokeDashArray') { + if (value === NONE) { + ouputValue = null; + } else { + ouputValue = value.replace(/,/g, ' ').split(/\s+/).map(parseFloat); + } + } else if (attr === 'transformMatrix') { + if (parentAttributes && parentAttributes.transformMatrix) { + ouputValue = multiplyTransformMatrices(parentAttributes.transformMatrix, parseTransformAttribute(value)); + } else { + ouputValue = parseTransformAttribute(value); + } + } else if (attr === 'visible') { + ouputValue = value !== NONE && value !== 'hidden'; + // display=none on parent element always takes precedence over child element + if (parentAttributes && parentAttributes.visible === false) { + ouputValue = false; + } + } else if (attr === 'opacity') { + ouputValue = parseFloat(value); + if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') { + ouputValue *= parentAttributes.opacity; + } + } else if (attr === 'textAnchor' /* text-anchor */) { + ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER; + } else if (attr === 'charSpacing') { + // parseUnit returns px and we convert it to em + parsed = parseUnit(value, fontSize) / fontSize * 1000; + } else if (attr === 'paintFirst') { + const fillIndex = value.indexOf(FILL); + const strokeIndex = value.indexOf(STROKE); + ouputValue = FILL; + if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { + ouputValue = STROKE; + } else if (fillIndex === -1 && strokeIndex > -1) { + ouputValue = STROKE; + } + } else if (attr === 'href' || attr === 'xlink:href' || attr === 'font' || attr === 'id') { + return value; + } else if (attr === 'imageSmoothing') { + return value === 'optimizeQuality'; + } else { + parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); + } + return !isArray && isNaN(parsed) ? ouputValue : parsed; +} + +/** + * Parses a short font declaration, building adding its properties to a style object + * @static + * @function + * @memberOf fabric + * @param {String} value font declaration + * @param {Object} oStyle definition + */ +function parseFontDeclaration(value, oStyle) { + const match = value.match(reFontDeclaration); + if (!match) { + return; + } + const fontStyle = match[1], + // font variant is not used + // fontVariant = match[2], + fontWeight = match[3], + fontSize = match[4], + lineHeight = match[5], + fontFamily = match[6]; + if (fontStyle) { + oStyle.fontStyle = fontStyle; + } + if (fontWeight) { + oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); + } + if (fontSize) { + oStyle.fontSize = parseUnit(fontSize); + } + if (fontFamily) { + oStyle.fontFamily = fontFamily; + } + if (lineHeight) { + oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight; + } +} + +/** + * Takes a style object and parses it in one that has only defined values + * and lowercases properties + * @param style + * @param oStyle + */ +function parseStyleObject(style, oStyle) { + Object.entries(style).forEach(_ref => { + let [prop, value] = _ref; + if (value === undefined) { + return; + } + oStyle[prop.toLowerCase()] = value; + }); +} + +/** + * Takes a style string and parses it in one that has only defined values + * and lowercases properties + * @param style + * @param oStyle + */ +function parseStyleString(style, oStyle) { + style.replace(/;\s*$/, '').split(';').forEach(chunk => { + if (!chunk) return; + const [attr, value] = chunk.split(':'); + oStyle[attr.trim().toLowerCase()] = value.trim(); + }); +} + +/** + * Parses "style" attribute, retuning an object with values + * @static + * @memberOf fabric + * @param {SVGElement} element Element to parse + * @return {Object} Objects with values parsed from style attribute of an element + */ +function parseStyleAttribute(element) { + const oStyle = {}, + style = element.getAttribute('style'); + if (!style) { + return oStyle; + } + if (typeof style === 'string') { + parseStyleString(style, oStyle); + } else { + parseStyleObject(style, oStyle); + } + return oStyle; +} + +const colorAttributesMap = { + stroke: 'strokeOpacity', + fill: 'fillOpacity' +}; + +/** + * @private + * @param {Object} attributes Array of attributes to parse + */ + +function setStrokeFillOpacity(attributes) { + const defaults = FabricObject.getDefaults(); + Object.entries(colorAttributesMap).forEach(_ref => { + let [attr, colorAttr] = _ref; + if (typeof attributes[colorAttr] === 'undefined' || attributes[attr] === '') { + return; + } + if (typeof attributes[attr] === 'undefined') { + if (!defaults[attr]) { + return; + } + attributes[attr] = defaults[attr]; + } + if (attributes[attr].indexOf('url(') === 0) { + return; + } + const color = new Color(attributes[attr]); + attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2)).toRgba(); + }); + return attributes; +} + +/** + * Returns an object of attributes' name/value, given element and an array of attribute names; + * Parses parent "g" nodes recursively upwards. + * @param {SVGElement | HTMLElement} element Element to parse + * @param {Array} attributes Array of attributes to parse + * @return {Object} object containing parsed attributes' names/values + */ +function parseAttributes(element, attributes, cssRules) { + if (!element) { + return {}; + } + let parentAttributes = {}, + fontSize, + parentFontSize = DEFAULT_SVG_FONT_SIZE; + + // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards + if (element.parentNode && svgValidParentsRegEx.test(element.parentNode.nodeName)) { + parentAttributes = parseAttributes(element.parentElement, attributes, cssRules); + if (parentAttributes.fontSize) { + fontSize = parentFontSize = parseUnit(parentAttributes.fontSize); + } + } + const ownAttributes = _objectSpread2(_objectSpread2(_objectSpread2({}, attributes.reduce((memo, attr) => { + const value = element.getAttribute(attr); + if (value) { + memo[attr] = value; + } + return memo; + }, {})), getGlobalStylesForElement(element, cssRules)), parseStyleAttribute(element)); + if (ownAttributes[cPath]) { + element.setAttribute(cPath, ownAttributes[cPath]); + } + if (ownAttributes[fSize]) { + // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers. + fontSize = parseUnit(ownAttributes[fSize], parentFontSize); + ownAttributes[fSize] = "".concat(fontSize); + } + + // this should have its own complex type + const normalizedStyle = {}; + for (const attr in ownAttributes) { + const normalizedAttr = normalizeAttr(attr); + const normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize); + normalizedStyle[normalizedAttr] = normalizedValue; + } + if (normalizedStyle && normalizedStyle.font) { + parseFontDeclaration(normalizedStyle.font, normalizedStyle); + } + const mergedAttrs = _objectSpread2(_objectSpread2({}, parentAttributes), normalizedStyle); + return svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : setStrokeFillOpacity(mergedAttrs); +} + +const _excluded$c = ["left", "top", "width", "height", "visible"]; +const rectDefaultValues = { + rx: 0, + ry: 0 +}; +const RECT_PROPS = ['rx', 'ry']; +class Rect extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Rect.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Rect.ownDefaults); + this.setOptions(options); + this._initRxRy(); + } + /** + * Initializes rx/ry attributes + * @private + */ + _initRxRy() { + const { + rx, + ry + } = this; + if (rx && !ry) { + this.ry = rx; + } else if (ry && !rx) { + this.rx = ry; + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const { + width: w, + height: h + } = this; + const x = -w / 2; + const y = -h / 2; + const rx = this.rx ? Math.min(this.rx, w / 2) : 0; + const ry = this.ry ? Math.min(this.ry, h / 2) : 0; + const isRounded = rx !== 0 || ry !== 0; + ctx.beginPath(); + ctx.moveTo(x + rx, y); + ctx.lineTo(x + w - rx, y); + isRounded && ctx.bezierCurveTo(x + w - kRect * rx, y, x + w, y + kRect * ry, x + w, y + ry); + ctx.lineTo(x + w, y + h - ry); + isRounded && ctx.bezierCurveTo(x + w, y + h - kRect * ry, x + w - kRect * rx, y + h, x + w - rx, y + h); + ctx.lineTo(x + rx, y + h); + isRounded && ctx.bezierCurveTo(x + kRect * rx, y + h, x, y + h - kRect * ry, x, y + h - ry); + ctx.lineTo(x, y + ry); + isRounded && ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y); + ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...RECT_PROPS, ...propertiesToInclude]); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const { + width, + height, + rx, + ry + } = this; + return ['\n")]; + } + + /** + * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`) + * @static + * @memberOf Rect + * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement + */ + + /* _FROM_SVG_START_ */ + + /** + * Returns {@link Rect} instance from an SVG element + * @static + * @memberOf Rect + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + left = 0, + top = 0, + width = 0, + height = 0, + visible = true + } = _parseAttributes, + restOfparsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$c); + return new this(_objectSpread2(_objectSpread2(_objectSpread2({}, options), restOfparsedAttributes), {}, { + left, + top, + width, + height, + visible: Boolean(visible && width && height) + })); + } + + /* _FROM_SVG_END_ */ +} +/** + * Horizontal border radius + * @type Number + * @default + */ +/** + * Vertical border radius + * @type Number + * @default + */ +_defineProperty(Rect, "type", 'Rect'); +_defineProperty(Rect, "cacheProperties", [...cacheProperties, ...RECT_PROPS]); +_defineProperty(Rect, "ownDefaults", rectDefaultValues); +_defineProperty(Rect, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'x', 'y', 'rx', 'ry', 'width', 'height']); +classRegistry.setClass(Rect); +classRegistry.setSVGClass(Rect); + +const LAYOUT_TYPE_INITIALIZATION = 'initialization'; +const LAYOUT_TYPE_ADDED = 'added'; +const LAYOUT_TYPE_REMOVED = 'removed'; +const LAYOUT_TYPE_IMPERATIVE = 'imperative'; +const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified'; +const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying'; + +/** + * @returns 2 points, the tl and br corners of the non rotated bounding box of an object + * in the {@link group} plane, taking into account objects that {@link group} is their parent + * but also belong to the active selection. + */ +const getObjectBounds = (destinationGroup, object) => { + const { + strokeUniform, + strokeWidth, + width, + height, + group: currentGroup + } = object; + const t = currentGroup && currentGroup !== destinationGroup ? calcPlaneChangeMatrix(currentGroup.calcTransformMatrix(), destinationGroup.calcTransformMatrix()) : null; + const objectCenter = t ? object.getRelativeCenterPoint().transform(t) : object.getRelativeCenterPoint(); + const accountForStroke = !object['isStrokeAccountedForInDimensions'](); + const strokeUniformVector = strokeUniform && accountForStroke ? sendVectorToPlane(new Point(strokeWidth, strokeWidth), undefined, destinationGroup.calcTransformMatrix()) : ZERO; + const scalingStrokeWidth = !strokeUniform && accountForStroke ? strokeWidth : 0; + const sizeVector = sizeAfterTransform(width + scalingStrokeWidth, height + scalingStrokeWidth, multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true)).add(strokeUniformVector).scalarDivide(2); + return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)]; +}; + +/** + * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout. + * Returning `undefined` signals the `LayoutManager` to skip the layout. + * + * In charge of calculating the bounding box of the passed objects. + */ +class LayoutStrategy { + /** + * Used by the `LayoutManager` to perform layout + * @TODO/fix: if this method is calcResult, should calc unconditionally. + * the condition to not calc should be evaluated by the layoutManager. + * @returns layout result **OR** `undefined` to skip layout + */ + calcLayoutResult(context, objects) { + if (this.shouldPerformLayout(context)) { + return this.calcBoundingBox(objects, context); + } + } + shouldPerformLayout(_ref) { + let { + type, + prevStrategy, + strategy + } = _ref; + return type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_IMPERATIVE || !!prevStrategy && strategy !== prevStrategy; + } + shouldLayoutClipPath(_ref2) { + let { + type, + target: { + clipPath + } + } = _ref2; + return type !== LAYOUT_TYPE_INITIALIZATION && clipPath && !clipPath.absolutePositioned; + } + getInitialSize(context, result) { + return result.size; + } + + /** + * Override this method to customize layout. + */ + calcBoundingBox(objects, context) { + const { + type, + target + } = context; + if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) { + return context.overrides; + } + if (objects.length === 0) { + return; + } + const { + left, + top, + width, + height + } = makeBoundingBoxFromPoints(objects.map(object => getObjectBounds(target, object)).reduce((coords, curr) => coords.concat(curr), [])); + const bboxSize = new Point(width, height); + const bboxLeftTop = new Point(left, top); + const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2)); + if (type === LAYOUT_TYPE_INITIALIZATION) { + const actualSize = this.getInitialSize(context, { + size: bboxSize, + center: bboxCenter + }); + return { + // in `initialization` we do not account for target's transformation matrix + center: bboxCenter, + // TODO: investigate if this is still necessary + relativeCorrection: new Point(0, 0), + size: actualSize + }; + } else { + // we send `relativeCenter` up to group's containing plane + const center = bboxCenter.transform(target.calcOwnMatrix()); + return { + center, + size: bboxSize + }; + } + } +} +/** + * override by subclass for persistence (TS does not support `static abstract`) + */ +_defineProperty(LayoutStrategy, "type", 'strategy'); + +/** + * Layout will adjust the bounding box to fit target's objects. + */ +class FitContentLayout extends LayoutStrategy { + /** + * @override layout on all triggers + * Override at will + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + shouldPerformLayout(context) { + return true; + } +} +_defineProperty(FitContentLayout, "type", 'fit-content'); +classRegistry.setClass(FitContentLayout); + +const _excluded$b = ["strategy"], + _excluded2$3 = ["target", "strategy", "bubbles", "prevStrategy"]; +const LAYOUT_MANAGER = 'layoutManager'; +class LayoutManager { + constructor() { + let strategy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new FitContentLayout(); + _defineProperty(this, "strategy", void 0); + this.strategy = strategy; + this._subscriptions = new Map(); + } + performLayout(context) { + const strictContext = _objectSpread2(_objectSpread2({ + bubbles: true, + strategy: this.strategy + }, context), {}, { + prevStrategy: this._prevLayoutStrategy, + stopPropagation() { + this.bubbles = false; + } + }); + this.onBeforeLayout(strictContext); + const layoutResult = this.getLayoutResult(strictContext); + if (layoutResult) { + this.commitLayout(strictContext, layoutResult); + } + this.onAfterLayout(strictContext, layoutResult); + this._prevLayoutStrategy = strictContext.strategy; + } + + /** + * Attach handlers for events that we know will invalidate the layout when + * performed on child objects ( general transforms ). + * Returns the disposers for later unsubscribing and cleanup + * @param {FabricObject} object + * @param {RegistrationContext & Partial} context + * @returns {VoidFunction[]} disposers remove the handlers + */ + attachHandlers(object, context) { + const { + target + } = context; + return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY, MODIFY_PATH].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? { + type: LAYOUT_TYPE_OBJECT_MODIFIED, + trigger: key, + e, + target + } : { + type: LAYOUT_TYPE_OBJECT_MODIFYING, + trigger: key, + e, + target + }))); + } + + /** + * Subscribe an object to transform events that will trigger a layout change on the parent + * This is important only for interactive groups. + * @param object + * @param context + */ + subscribe(object, context) { + this.unsubscribe(object, context); + const disposers = this.attachHandlers(object, context); + this._subscriptions.set(object, disposers); + } + + /** + * unsubscribe object layout triggers + */ + unsubscribe(object, _context) { + (this._subscriptions.get(object) || []).forEach(d => d()); + this._subscriptions.delete(object); + } + unsubscribeTargets(context) { + context.targets.forEach(object => this.unsubscribe(object, context)); + } + subscribeTargets(context) { + context.targets.forEach(object => this.subscribe(object, context)); + } + onBeforeLayout(context) { + const { + target, + type + } = context; + const { + canvas + } = target; + // handle layout triggers subscription + // @TODO: gate the registration when the group is interactive + if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) { + this.subscribeTargets(context); + } else if (type === LAYOUT_TYPE_REMOVED) { + this.unsubscribeTargets(context); + } + // fire layout event (event will fire only for layouts after initialization layout) + target.fire('layout:before', { + context + }); + canvas && canvas.fire('object:layout:before', { + target, + context + }); + if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) { + const tricklingContext = _objectWithoutProperties(context, _excluded$b); + // traverse the tree + target.forEachObject(object => object.layoutManager && object.layoutManager.performLayout(_objectSpread2(_objectSpread2({}, tricklingContext), {}, { + bubbles: false, + target: object + }))); + } + } + getLayoutResult(context) { + const { + target, + strategy, + type + } = context; + const result = strategy.calcLayoutResult(context, target.getObjects()); + if (!result) { + return; + } + const prevCenter = type === LAYOUT_TYPE_INITIALIZATION ? new Point() : target.getRelativeCenterPoint(); + const { + center: nextCenter, + correction = new Point(), + relativeCorrection = new Point() + } = result; + const offset = prevCenter.subtract(nextCenter).add(correction).transform( + // in `initialization` we do not account for target's transformation matrix + type === LAYOUT_TYPE_INITIALIZATION ? iMatrix : invertTransform(target.calcOwnMatrix()), true).add(relativeCorrection); + return { + result, + prevCenter, + nextCenter, + offset + }; + } + commitLayout(context, layoutResult) { + const { + target + } = context; + const { + result: { + size + }, + nextCenter + } = layoutResult; + // set dimensions + target.set({ + width: size.x, + height: size.y + }); + // layout descendants + this.layoutObjects(context, layoutResult); + // set position + // in `initialization` we do not account for target's transformation matrix + if (context.type === LAYOUT_TYPE_INITIALIZATION) { + var _context$x, _context$y; + // TODO: what about strokeWidth? + target.set({ + left: (_context$x = context.x) !== null && _context$x !== void 0 ? _context$x : nextCenter.x + size.x * resolveOrigin(target.originX), + top: (_context$y = context.y) !== null && _context$y !== void 0 ? _context$y : nextCenter.y + size.y * resolveOrigin(target.originY) + }); + } else { + target.setPositionByOrigin(nextCenter, CENTER, CENTER); + // invalidate + target.setCoords(); + target.set('dirty', true); + } + } + layoutObjects(context, layoutResult) { + const { + target + } = context; + // adjust objects to account for new center + target.forEachObject(object => { + object.group === target && this.layoutObject(context, layoutResult, object); + }); + // adjust clip path to account for new center + context.strategy.shouldLayoutClipPath(context) && this.layoutObject(context, layoutResult, target.clipPath); + } + + /** + * @param {FabricObject} object + * @param {Point} offset + */ + layoutObject(context, _ref, object) { + let { + offset + } = _ref; + // TODO: this is here for cache invalidation. + // verify if this is necessary since we have explicit + // cache invalidation at the end of commitLayout + object.set({ + left: object.left + offset.x, + top: object.top + offset.y + }); + } + onAfterLayout(context, layoutResult) { + const { + target, + strategy, + bubbles, + prevStrategy: _ + } = context, + bubblingContext = _objectWithoutProperties(context, _excluded2$3); + const { + canvas + } = target; + + // fire layout event (event will fire only for layouts after initialization layout) + target.fire('layout:after', { + context, + result: layoutResult + }); + canvas && canvas.fire('object:layout:after', { + context, + result: layoutResult, + target + }); + + // bubble + const parent = target.parent; + if (bubbles && parent !== null && parent !== void 0 && parent.layoutManager) { + // add target to context#path + (bubblingContext.path || (bubblingContext.path = [])).push(target); + // all parents should invalidate their layout + parent.layoutManager.performLayout(_objectSpread2(_objectSpread2({}, bubblingContext), {}, { + target: parent + })); + } + target.set('dirty', true); + } + dispose() { + const { + _subscriptions + } = this; + _subscriptions.forEach(disposers => disposers.forEach(d => d())); + _subscriptions.clear(); + } + toObject() { + return { + type: LAYOUT_MANAGER, + strategy: this.strategy.constructor.type + }; + } + toJSON() { + return this.toObject(); + } +} +classRegistry.setClass(LayoutManager, LAYOUT_MANAGER); + +const _excluded$a = ["type", "objects", "layoutManager"]; +/** + * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case. + * We could have used a boolean in the constructor, as we did previously, but we think the boolean + * would stay in the group's constructor interface and create confusion, therefore it was removed. + * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called. + */ +class NoopLayoutManager extends LayoutManager { + // eslint-disable-next-line @typescript-eslint/no-empty-function + performLayout() {} +} +const groupDefaultValues = { + strokeWidth: 0, + subTargetCheck: false, + interactive: false +}; + +/** + * @fires object:added + * @fires object:removed + * @fires layout:before + * @fires layout:after + */ +class Group extends createCollectionMixin(FabricObject) { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Group.ownDefaults); + } + + /** + * Constructor + * + * @param {FabricObject[]} [objects] instance objects + * @param {Object} [options] Options object + */ + constructor() { + let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + /** + * Used to optimize performance + * set to `false` if you don't need contained objects to be targets of events + * @default + * @type boolean + */ + /** + * Used to allow targeting of object inside groups. + * set to true if you want to select an object inside a group.\ + * **REQUIRES** `subTargetCheck` set to true + * This will be not removed but slowly replaced with a method setInteractive + * that will take care of enabling subTargetCheck and necessary object events. + * There is too much attached to group interactivity to just be evaluated by a + * boolean in the code + * @default + * @deprecated + * @type boolean + */ + /** + * Used internally to optimize performance + * Once an object is selected, instance is rendered without the selected object. + * This way instance is cached only once for the entire interaction with the selected object. + * @private + */ + _defineProperty(this, "_activeObjects", []); + _defineProperty(this, "__objectSelectionTracker", void 0); + _defineProperty(this, "__objectSelectionDisposer", void 0); + Object.assign(this, Group.ownDefaults); + this.setOptions(options); + this.groupInit(objects, options); + } + + /** + * Shared code between group and active selection + * Meant to be used by the constructor. + */ + groupInit(objects, options) { + var _options$layoutManage; + this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller + + this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(this, true); + this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(this, false); + this.forEachObject(object => { + this.enterGroup(object, false); + }); + + // perform initial layout + this.layoutManager = (_options$layoutManage = options.layoutManager) !== null && _options$layoutManage !== void 0 ? _options$layoutManage : new LayoutManager(); + this.layoutManager.performLayout({ + type: LAYOUT_TYPE_INITIALIZATION, + target: this, + targets: [...objects], + // @TODO remove this concept from the layout manager. + // Layout manager will calculate the correct position, + // group options can override it later. + x: options.left, + y: options.top + }); + } + + /** + * Checks if object can enter group and logs relevant warnings + * @private + * @param {FabricObject} object + * @returns + */ + canEnterGroup(object) { + if (object === this || this.isDescendantOf(object)) { + // prevent circular object tree + log('error', 'Group: circular object trees are not supported, this call has no effect'); + return false; + } else if (this._objects.indexOf(object) !== -1) { + // is already in the objects array + log('error', 'Group: duplicate objects are not supported inside group, this call has no effect'); + return false; + } + return true; + } + + /** + * Override this method to enhance performance (for groups with a lot of objects). + * If Overriding, be sure not pass illegal objects to group - it will break your app. + * @private + */ + _filterObjectsBeforeEnteringGroup(objects) { + return objects.filter((object, index, array) => { + // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates) + return this.canEnterGroup(object) && array.indexOf(object) === index; + }); + } + + /** + * Add objects + * @param {...FabricObject[]} objects + */ + add() { + for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { + objects[_key] = arguments[_key]; + } + const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects); + const size = super.add(...allowedObjects); + this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects); + return size; + } + + /** + * Inserts an object into collection at specified index + * @param {FabricObject[]} objects Object to insert + * @param {Number} index Index to insert object at + */ + insertAt(index) { + for (var _len2 = arguments.length, objects = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + objects[_key2 - 1] = arguments[_key2]; + } + const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects); + const size = super.insertAt(index, ...allowedObjects); + this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects); + return size; + } + + /** + * Remove objects + * @param {...FabricObject[]} objects + * @returns {FabricObject[]} removed objects + */ + remove() { + const removed = super.remove(...arguments); + this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed); + return removed; + } + _onObjectAdded(object) { + this.enterGroup(object, true); + this.fire('object:added', { + target: object + }); + object.fire('added', { + target: this + }); + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + _onObjectRemoved(object, removeParentTransform) { + this.exitGroup(object, removeParentTransform); + this.fire('object:removed', { + target: object + }); + object.fire('removed', { + target: this + }); + } + + /** + * @private + * @param {'added'|'removed'} type + * @param {FabricObject[]} targets + */ + _onAfterObjectsChange(type, targets) { + this.layoutManager.performLayout({ + type, + targets, + target: this + }); + } + _onStackOrderChanged() { + this._set('dirty', true); + } + + /** + * @private + * @param {string} key + * @param {*} value + */ + _set(key, value) { + const prev = this[key]; + super._set(key, value); + if (key === 'canvas' && prev !== value) { + (this._objects || []).forEach(object => { + object._set(key, value); + }); + } + return this; + } + + /** + * @private + */ + _shouldSetNestedCoords() { + return this.subTargetCheck; + } + + /** + * Remove all objects + * @returns {FabricObject[]} removed objects + */ + removeAll() { + this._activeObjects = []; + return this.remove(...this._objects); + } + + /** + * keeps track of the selected objects + * @private + */ + __objectSelectionMonitor(selected, _ref) { + let { + target: object + } = _ref; + const activeObjects = this._activeObjects; + if (selected) { + activeObjects.push(object); + this._set('dirty', true); + } else if (activeObjects.length > 0) { + const index = activeObjects.indexOf(object); + if (index > -1) { + activeObjects.splice(index, 1); + this._set('dirty', true); + } + } + } + + /** + * @private + * @param {boolean} watch + * @param {FabricObject} object + */ + _watchObject(watch, object) { + // make sure we listen only once + watch && this._watchObject(false, object); + if (watch) { + object.on('selected', this.__objectSelectionTracker); + object.on('deselected', this.__objectSelectionDisposer); + } else { + object.off('selected', this.__objectSelectionTracker); + object.off('deselected', this.__objectSelectionDisposer); + } + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + enterGroup(object, removeParentTransform) { + object.group && object.group.remove(object); + object._set('parent', this); + this._enterGroup(object, removeParentTransform); + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + _enterGroup(object, removeParentTransform) { + if (removeParentTransform) { + // can this be converted to utils (sendObjectToPlane)? + applyTransformToObject(object, multiplyTransformMatrices(invertTransform(this.calcTransformMatrix()), object.calcTransformMatrix())); + } + this._shouldSetNestedCoords() && object.setCoords(); + object._set('group', this); + object._set('canvas', this.canvas); + this._watchObject(true, object); + const activeObject = this.canvas && this.canvas.getActiveObject && this.canvas.getActiveObject(); + // if we are adding the activeObject in a group + if (activeObject && (activeObject === object || object.isDescendantOf(activeObject))) { + this._activeObjects.push(object); + } + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + exitGroup(object, removeParentTransform) { + this._exitGroup(object, removeParentTransform); + object._set('parent', undefined); + object._set('canvas', undefined); + } + + /** + * Executes the inner fabric logic of exiting a group. + * - Stop watching the object + * - Remove the object from the optimization map this._activeObjects + * - unset the group property of the object + * @protected + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + _exitGroup(object, removeParentTransform) { + object._set('group', undefined); + if (!removeParentTransform) { + applyTransformToObject(object, multiplyTransformMatrices(this.calcTransformMatrix(), object.calcTransformMatrix())); + object.setCoords(); + } + this._watchObject(false, object); + const index = this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1; + if (index > -1) { + this._activeObjects.splice(index, 1); + } + } + + /** + * Decide if the object should cache or not. Create its own cache level + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group is already cached. + * @return {Boolean} + */ + shouldCache() { + const ownCache = FabricObject.prototype.shouldCache.call(this); + if (ownCache) { + for (let i = 0; i < this._objects.length; i++) { + if (this._objects[i].willDrawShadow()) { + this.ownCaching = false; + return false; + } + } + } + return ownCache; + } + + /** + * Check if this object or a child object will cast a shadow + * @return {Boolean} + */ + willDrawShadow() { + if (super.willDrawShadow()) { + return true; + } + for (let i = 0; i < this._objects.length; i++) { + if (this._objects[i].willDrawShadow()) { + return true; + } + } + return false; + } + + /** + * Check if instance or its group are caching, recursively up + * @return {Boolean} + */ + isOnACache() { + return this.ownCaching || !!this.parent && this.parent.isOnACache(); + } + + /** + * Execute the drawing operation for an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawObject(ctx) { + this._renderBackground(ctx); + for (let i = 0; i < this._objects.length; i++) { + var _this$canvas; + // TODO: handle rendering edge case somehow + if ((_this$canvas = this.canvas) !== null && _this$canvas !== void 0 && _this$canvas.preserveObjectStacking && this._objects[i].group !== this) { + ctx.save(); + ctx.transform(...invertTransform(this.calcTransformMatrix())); + this._objects[i].render(ctx); + ctx.restore(); + } else if (this._objects[i].group === this) { + this._objects[i].render(ctx); + } + } + this._drawClipPath(ctx, this.clipPath); + } + + /** + * @override + * @return {Boolean} + */ + setCoords() { + super.setCoords(); + this._shouldSetNestedCoords() && this.forEachObject(object => object.setCoords()); + } + triggerLayout() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.layoutManager.performLayout(_objectSpread2({ + target: this, + type: LAYOUT_TYPE_IMPERATIVE + }, options)); + } + + /** + * Renders instance on a given context + * @param {CanvasRenderingContext2D} ctx context to render instance on + */ + render(ctx) { + this._transformDone = true; + super.render(ctx); + this._transformDone = false; + } + + /** + * + * @private + * @param {'toObject'|'toDatalessObject'} [method] + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @returns {FabricObject[]} serialized objects + */ + __serializeObjects(method, propertiesToInclude) { + const _includeDefaultValues = this.includeDefaultValues; + return this._objects.filter(function (obj) { + return !obj.excludeFromExport; + }).map(function (obj) { + const originalDefaults = obj.includeDefaultValues; + obj.includeDefaultValues = _includeDefaultValues; + const data = obj[method || 'toObject'](propertiesToInclude); + obj.includeDefaultValues = originalDefaults; + // delete data.version; + return data; + }); + } + + /** + * Returns object representation of an instance + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const layoutManager = this.layoutManager.toObject(); + return _objectSpread2(_objectSpread2(_objectSpread2({}, super.toObject(['subTargetCheck', 'interactive', ...propertiesToInclude])), layoutManager.strategy !== 'fit-content' || this.includeDefaultValues ? { + layoutManager + } : {}), {}, { + objects: this.__serializeObjects('toObject', propertiesToInclude) + }); + } + toString() { + return "#"); + } + dispose() { + this.layoutManager.unsubscribeTargets({ + targets: this.getObjects(), + target: this + }); + this._activeObjects = []; + this.forEachObject(object => { + this._watchObject(false, object); + object.dispose(); + }); + super.dispose(); + } + + /** + * @private + */ + _createSVGBgRect(reviver) { + if (!this.backgroundColor) { + return ''; + } + const fillStroke = Rect.prototype._toSVG.call(this); + const commons = fillStroke.indexOf('COMMON_PARTS'); + fillStroke[commons] = 'for="group" '; + const markup = fillStroke.join(''); + return reviver ? reviver(markup) : markup; + } + + /** + * Returns svg representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + _toSVG(reviver) { + const svgString = ['\n']; + const bg = this._createSVGBgRect(reviver); + bg && svgString.push('\t\t', bg); + for (let i = 0; i < this._objects.length; i++) { + svgString.push('\t\t', this._objects[i].toSVG(reviver)); + } + svgString.push('\n'); + return svgString; + } + + /** + * Returns styles-string for svg-export, specific version for group + * @return {String} + */ + getSvgStyles() { + const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? "opacity: ".concat(this.opacity, ";") : '', + visibility = this.visible ? '' : ' visibility: hidden;'; + return [opacity, this.getSvgFilter(), visibility].join(''); + } + + /** + * Returns svg clipPath representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toClipPathSVG(reviver) { + const svgString = []; + const bg = this._createSVGBgRect(reviver); + bg && svgString.push('\t', bg); + for (let i = 0; i < this._objects.length; i++) { + svgString.push('\t', this._objects[i].toClipPathSVG(reviver)); + } + return this._createBaseClipPathSVGMarkup(svgString, { + reviver + }); + } + + /** + * @todo support loading from svg + * @private + * @static + * @memberOf Group + * @param {Object} object Object to create a group from + * @returns {Promise} + */ + static fromObject(_ref2, abortable) { + let { + type, + objects = [], + layoutManager + } = _ref2, + options = _objectWithoutProperties(_ref2, _excluded$a); + return Promise.all([enlivenObjects(objects, abortable), enlivenObjectEnlivables(options, abortable)]).then(_ref3 => { + let [objects, hydratedOptions] = _ref3; + const group = new this(objects, _objectSpread2(_objectSpread2(_objectSpread2({}, options), hydratedOptions), {}, { + layoutManager: new NoopLayoutManager() + })); + if (layoutManager) { + const layoutClass = classRegistry.getClass(layoutManager.type); + const strategyClass = classRegistry.getClass(layoutManager.strategy); + group.layoutManager = new layoutClass(new strategyClass()); + } else { + group.layoutManager = new LayoutManager(); + } + group.layoutManager.subscribeTargets({ + type: LAYOUT_TYPE_INITIALIZATION, + target: group, + targets: group.getObjects() + }); + group.setCoords(); + return group; + }); + } +} +_defineProperty(Group, "type", 'Group'); +_defineProperty(Group, "ownDefaults", groupDefaultValues); +classRegistry.setClass(Group); + +/** + * TODO experiment with different layout manager and svg results ( fixed fit content ) + * Groups SVG elements (usually those retrieved from SVG document) + * @static + * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group + * @return {FabricObject | Group} + */ +const groupSVGElements = (elements, options) => { + if (elements && elements.length === 1) { + return elements[0]; + } + return new Group(elements, options); +}; + +/** + * Finds the scale for the object source to fit inside the object destination, + * keeping aspect ratio intact. + * respect the total allowed area for the cache. + * @param {TSize} source natural unscaled size of the object + * @param {TSize} destination natural unscaled size of the object + * @return {Number} scale factor to apply to source to fit into destination + */ +const findScaleToFit = (source, destination) => Math.min(destination.width / source.width, destination.height / source.height); + +/** + * Finds the scale for the object source to cover entirely the object destination, + * keeping aspect ratio intact. + * respect the total allowed area for the cache. + * @param {TSize} source natural unscaled size of the object + * @param {TSize} destination natural unscaled size of the object + * @return {Number} scale factor to apply to source to cover destination + */ +const findScaleToCover = (source, destination) => Math.max(destination.width / source.width, destination.height / source.height); + +const commaWsp = "\\s*,?\\s*"; + +/** + * p for param + * using "bad naming" here because it makes the regex much easier to read + * p is a number that is preceded by an arbitary number of spaces, maybe 0, + * a comma or not, and then possibly more spaces or not. + */ +const p = "".concat(commaWsp, "(").concat(reNum, ")"); + +// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`; + +// const reLineCommand = `(L) ?(?:${p}${p} ?)+`; + +// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`; + +// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`; + +// const reClosePathCommand = String.raw`(Z)\s*`; + +// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`; + +// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`; + +// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`; + +// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`; + +const reArcCommandPoints = "".concat(p).concat(p).concat(p).concat(commaWsp, "([01])").concat(commaWsp, "([01])").concat(p).concat(p); +// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`; + +// export const rePathCommandGroups = +// `(?:(?:${reMoveToCommand})` + +// `|(?:${reLineCommand})` + +// `|(?:${reHorizontalLineCommand})` + +// `|(?:${reVerticalLineCommand})` + +// `|(?:${reClosePathCommand})` + +// `|(?:${reCubicCurveCommand})` + +// `|(?:${reCubicCurveShortcutCommand})` + +// `|(?:${reQuadraticCurveCommand})` + +// `|(?:${reQuadraticCurveShortcutCommand})` + +// `|(?:${reArcCommand}))`; + +const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*'; + +/** + * Commands that may be repeated + */ +const repeatedCommands = { + m: 'l', + M: 'L' +}; + +/** + * Convert an arc of a rotated ellipse to a Bezier Curve + * @param {TRadian} theta1 start of the arc + * @param {TRadian} theta2 end of the arc + * @param cosTh cosine of the angle of rotation + * @param sinTh sine of the angle of rotation + * @param rx x-axis radius (before rotation) + * @param ry y-axis radius (before rotation) + * @param cx1 center x of the ellipse + * @param cy1 center y of the ellipse + * @param mT + * @param fromX starting point of arc x + * @param fromY starting point of arc y + */ +const segmentToBezier = (theta1, theta2, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) => { + const costh1 = cos(theta1), + sinth1 = sin(theta1), + costh2 = cos(theta2), + sinth2 = sin(theta2), + toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1, + toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1, + cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1), + cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1), + cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2), + cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2); + return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY]; +}; + +/** + * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp} + * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here + * http://mozilla.org/MPL/2.0/ + * @param toX + * @param toY + * @param rx + * @param ry + * @param {number} large 0 or 1 flag + * @param {number} sweep 0 or 1 flag + * @param rotateX + */ +const arcToSegments = (toX, toY, rx, ry, large, sweep, rotateX) => { + if (rx === 0 || ry === 0) { + return []; + } + let fromX = 0, + fromY = 0, + root = 0; + const PI = Math.PI, + theta = rotateX * PiBy180, + sinTheta = sin(theta), + cosTh = cos(theta), + px = 0.5 * (-cosTh * toX - sinTheta * toY), + py = 0.5 * (-cosTh * toY + sinTheta * toX), + rx2 = rx ** 2, + ry2 = ry ** 2, + py2 = py ** 2, + px2 = px ** 2, + pl = rx2 * ry2 - rx2 * py2 - ry2 * px2; + let _rx = Math.abs(rx); + let _ry = Math.abs(ry); + if (pl < 0) { + const s = Math.sqrt(1 - pl / (rx2 * ry2)); + _rx *= s; + _ry *= s; + } else { + root = (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2)); + } + const cx = root * _rx * py / _ry, + cy = -root * _ry * px / _rx, + cx1 = cosTh * cx - sinTheta * cy + toX * 0.5, + cy1 = sinTheta * cx + cosTh * cy + toY * 0.5; + let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry); + let dtheta = calcVectorAngle((px - cx) / _rx, (py - cy) / _ry, (-px - cx) / _rx, (-py - cy) / _ry); + if (sweep === 0 && dtheta > 0) { + dtheta -= 2 * PI; + } else if (sweep === 1 && dtheta < 0) { + dtheta += 2 * PI; + } + + // Convert into cubic bezier segments <= 90deg + const segments = Math.ceil(Math.abs(dtheta / PI * 2)), + result = [], + mDelta = dtheta / segments, + mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2); + let th3 = mTheta + mDelta; + for (let i = 0; i < segments; i++) { + result[i] = segmentToBezier(mTheta, th3, cosTh, sinTheta, _rx, _ry, cx1, cy1, mT, fromX, fromY); + fromX = result[i][5]; + fromY = result[i][6]; + mTheta = th3; + th3 += mDelta; + } + return result; +}; + +/** + * @private + * Calculate the angle between two vectors + * @param ux u endpoint x + * @param uy u endpoint y + * @param vx v endpoint x + * @param vy v endpoint y + */ +const calcVectorAngle = (ux, uy, vx, vy) => { + const ta = Math.atan2(uy, ux), + tb = Math.atan2(vy, vx); + if (tb >= ta) { + return tb - ta; + } else { + return 2 * Math.PI - (ta - tb); + } +}; + +// functions for the Cubic beizer +// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350 +const CB1 = t => t ** 3; +const CB2 = t => 3 * t ** 2 * (1 - t); +const CB3 = t => 3 * t * (1 - t) ** 2; +const CB4 = t => (1 - t) ** 3; + +/** + * Calculate bounding box of a cubic Bezier curve + * Taken from http://jsbin.com/ivomiq/56/edit (no credits available) + * TODO: can we normalize this with the starting points set at 0 and then translated the bbox? + * @param {number} begx starting point + * @param {number} begy + * @param {number} cp1x first control point + * @param {number} cp1y + * @param {number} cp2x second control point + * @param {number} cp2y + * @param {number} endx end of bezier + * @param {number} endy + * @return {TRectBounds} the rectangular bounds + */ +function getBoundsOfCurve(begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy) { + let argsString; + if (config.cachesBoundsOfCurve) { + // eslint-disable-next-line + argsString = [...arguments].join(); + if (cache.boundsOfCurveCache[argsString]) { + return cache.boundsOfCurveCache[argsString]; + } + } + const sqrt = Math.sqrt, + abs = Math.abs, + tvalues = [], + bounds = [[0, 0], [0, 0]]; + let b = 6 * begx - 12 * cp1x + 6 * cp2x; + let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx; + let c = 3 * cp1x - 3 * begx; + for (let i = 0; i < 2; ++i) { + if (i > 0) { + b = 6 * begy - 12 * cp1y + 6 * cp2y; + a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy; + c = 3 * cp1y - 3 * begy; + } + if (abs(a) < 1e-12) { + if (abs(b) < 1e-12) { + continue; + } + const t = -c / b; + if (0 < t && t < 1) { + tvalues.push(t); + } + continue; + } + const b2ac = b * b - 4 * c * a; + if (b2ac < 0) { + continue; + } + const sqrtb2ac = sqrt(b2ac); + const t1 = (-b + sqrtb2ac) / (2 * a); + if (0 < t1 && t1 < 1) { + tvalues.push(t1); + } + const t2 = (-b - sqrtb2ac) / (2 * a); + if (0 < t2 && t2 < 1) { + tvalues.push(t2); + } + } + let j = tvalues.length; + const jlen = j; + const iterator = getPointOnCubicBezierIterator(begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy); + while (j--) { + const { + x, + y + } = iterator(tvalues[j]); + bounds[0][j] = x; + bounds[1][j] = y; + } + bounds[0][jlen] = begx; + bounds[1][jlen] = begy; + bounds[0][jlen + 1] = endx; + bounds[1][jlen + 1] = endy; + const result = [new Point(Math.min(...bounds[0]), Math.min(...bounds[1])), new Point(Math.max(...bounds[0]), Math.max(...bounds[1]))]; + if (config.cachesBoundsOfCurve) { + cache.boundsOfCurveCache[argsString] = result; + } + return result; +} + +/** + * Converts arc to a bunch of cubic Bezier curves + * @param {number} fx starting point x + * @param {number} fy starting point y + * @param {TParsedArcCommand} coords Arc command + */ +const fromArcToBeziers = (fx, fy, _ref) => { + let [_, rx, ry, rot, large, sweep, tx, ty] = _ref; + const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); + for (let i = 0, len = segsNorm.length; i < len; i++) { + segsNorm[i][1] += fx; + segsNorm[i][2] += fy; + segsNorm[i][3] += fx; + segsNorm[i][4] += fy; + segsNorm[i][5] += fx; + segsNorm[i][6] += fy; + } + return segsNorm; +}; + +/** + * This function takes a parsed SVG path and makes it simpler for fabricJS logic. + * Simplification consist of: + * - All commands converted to absolute (lowercase to uppercase) + * - S converted to C + * - T converted to Q + * - A converted to C + * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path` + * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path` + * TODO: figure out how to remove the type assertions in a nice way + */ +const makePathSimpler = path => { + // x and y represent the last point of the path, AKA the previous command point. + // we add them to each relative command to make it an absolute comment. + // we also swap the v V h H with L, because are easier to transform. + let x = 0, + y = 0; + // x1 and y1 represent the last point of the subpath. the subpath is started with + // m or M command. When a z or Z command is drawn, x and y need to be resetted to + // the last x1 and y1. + let x1 = 0, + y1 = 0; + // previous will host the letter of the previous command, to handle S and T. + // controlX and controlY will host the previous reflected control point + const destinationPath = []; + let previous, + // placeholders + controlX = 0, + controlY = 0; + for (const parsedCommand of path) { + const current = [...parsedCommand]; + let converted; + switch (current[0] // first letter + ) { + case 'l': + // lineto, relative + current[1] += x; + current[2] += y; + // falls through + case 'L': + x = current[1]; + y = current[2]; + converted = ['L', x, y]; + break; + case 'h': + // horizontal lineto, relative + current[1] += x; + // falls through + case 'H': + x = current[1]; + converted = ['L', x, y]; + break; + case 'v': + // vertical lineto, relative + current[1] += y; + // falls through + case 'V': + y = current[1]; + converted = ['L', x, y]; + break; + case 'm': + // moveTo, relative + current[1] += x; + current[2] += y; + // falls through + case 'M': + x = current[1]; + y = current[2]; + x1 = current[1]; + y1 = current[2]; + converted = ['M', x, y]; + break; + case 'c': + // bezierCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + current[5] += x; + current[6] += y; + // falls through + case 'C': + controlX = current[3]; + controlY = current[4]; + x = current[5]; + y = current[6]; + converted = ['C', current[1], current[2], controlX, controlY, x, y]; + break; + case 's': + // shorthand cubic bezierCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + // falls through + case 'S': + // would be sScC but since we are swapping sSc for C, we check just that. + if (previous === 'C') { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } else { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + x = current[3]; + y = current[4]; + converted = ['C', controlX, controlY, current[1], current[2], x, y]; + // converted[3] and converted[4] are NOW the second control point. + // we keep it for the next reflection. + controlX = converted[3]; + controlY = converted[4]; + break; + case 'q': + // quadraticCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + // falls through + case 'Q': + controlX = current[1]; + controlY = current[2]; + x = current[3]; + y = current[4]; + converted = ['Q', controlX, controlY, x, y]; + break; + case 't': + // shorthand quadraticCurveTo, relative + current[1] += x; + current[2] += y; + // falls through + case 'T': + if (previous === 'Q') { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } else { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + x = current[1]; + y = current[2]; + converted = ['Q', controlX, controlY, x, y]; + break; + case 'a': + current[6] += x; + current[7] += y; + // falls through + case 'A': + fromArcToBeziers(x, y, current).forEach(b => destinationPath.push(b)); + x = current[6]; + y = current[7]; + break; + case 'z': + case 'Z': + x = x1; + y = y1; + converted = ['Z']; + break; + } + if (converted) { + destinationPath.push(converted); + previous = converted[0]; + } else { + previous = ''; + } + } + return destinationPath; +}; + +// todo verify if we can just use the point class here +/** + * Calc length from point x1,y1 to x2,y2 + * @param {number} x1 starting point x + * @param {number} y1 starting point y + * @param {number} x2 starting point x + * @param {number} y2 starting point y + * @return {number} length of segment + */ +const calcLineLength = (x1, y1, x2, y2) => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); + +/** + * Get an iterator that takes a percentage and returns a point + * @param {number} begx + * @param {number} begy + * @param {number} cp1x + * @param {number} cp1y + * @param {number} cp2x + * @param {number} cp2y + * @param {number} endx + * @param {number} endy + */ +const getPointOnCubicBezierIterator = (begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy) => pct => { + const c1 = CB1(pct), + c2 = CB2(pct), + c3 = CB3(pct), + c4 = CB4(pct); + return new Point(endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4, endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4); +}; +const QB1 = t => t ** 2; +const QB2 = t => 2 * t * (1 - t); +const QB3 = t => (1 - t) ** 2; +const getTangentCubicIterator = (p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) => pct => { + const qb1 = QB1(pct), + qb2 = QB2(pct), + qb3 = QB3(pct), + tangentX = 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)), + tangentY = 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y)); + return Math.atan2(tangentY, tangentX); +}; +const getPointOnQuadraticBezierIterator = (p1x, p1y, p2x, p2y, p3x, p3y) => pct => { + const c1 = QB1(pct), + c2 = QB2(pct), + c3 = QB3(pct); + return new Point(p3x * c1 + p2x * c2 + p1x * c3, p3y * c1 + p2y * c2 + p1y * c3); +}; +const getTangentQuadraticIterator = (p1x, p1y, p2x, p2y, p3x, p3y) => pct => { + const invT = 1 - pct, + tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)), + tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y)); + return Math.atan2(tangentY, tangentX); +}; + +// this will run over a path segment (a cubic or quadratic segment) and approximate it +// with 100 segments. This will good enough to calculate the length of the curve +const pathIterator = (iterator, x1, y1) => { + let tempP = new Point(x1, y1), + tmpLen = 0; + for (let perc = 1; perc <= 100; perc += 1) { + const p = iterator(perc / 100); + tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y); + tempP = p; + } + return tmpLen; +}; + +/** + * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1 + * that correspond to that pixels run over the path. + * The percentage will be then used to find the correct point on the canvas for the path. + * @param {Array} segInfo fabricJS collection of information on a parsed path + * @param {number} distance from starting point, in pixels. + * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point; + */ +const findPercentageForDistance = (segInfo, distance) => { + let perc = 0, + tmpLen = 0, + tempP = { + x: segInfo.x, + y: segInfo.y + }, + p = _objectSpread2({}, tempP), + nextLen, + nextStep = 0.01, + lastPerc = 0; + // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100 + // the path + const iterator = segInfo.iterator, + angleFinder = segInfo.angleFinder; + while (tmpLen < distance && nextStep > 0.0001) { + p = iterator(perc); + lastPerc = perc; + nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y); + // compare tmpLen each cycle with distance, decide next perc to test. + if (nextLen + tmpLen > distance) { + // we discard this step and we make smaller steps. + perc -= nextStep; + nextStep /= 2; + } else { + tempP = p; + perc += nextStep; + tmpLen += nextLen; + } + } + return _objectSpread2(_objectSpread2({}, p), {}, { + angle: angleFinder(lastPerc) + }); +}; + +/** + * Run over a parsed and simplified path and extract some information (length of each command and starting point) + * @param {TSimplePathData} path parsed path commands + * @return {TPathSegmentInfo[]} path commands information + */ +const getPathSegmentsInfo = path => { + let totalLength = 0, + //x2 and y2 are the coords of segment start + //x1 and y1 are the coords of the current point + x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0, + iterator, + tempInfo; + const info = []; + for (const current of path) { + const basicInfo = { + x: x1, + y: y1, + command: current[0], + length: 0 + }; + switch (current[0] //first letter + ) { + case 'M': + tempInfo = basicInfo; + tempInfo.x = x2 = x1 = current[1]; + tempInfo.y = y2 = y1 = current[2]; + break; + case 'L': + tempInfo = basicInfo; + tempInfo.length = calcLineLength(x1, y1, current[1], current[2]); + x1 = current[1]; + y1 = current[2]; + break; + case 'C': + iterator = getPointOnCubicBezierIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]); + tempInfo = basicInfo; + tempInfo.iterator = iterator; + tempInfo.angleFinder = getTangentCubicIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]); + tempInfo.length = pathIterator(iterator, x1, y1); + x1 = current[5]; + y1 = current[6]; + break; + case 'Q': + iterator = getPointOnQuadraticBezierIterator(x1, y1, current[1], current[2], current[3], current[4]); + tempInfo = basicInfo; + tempInfo.iterator = iterator; + tempInfo.angleFinder = getTangentQuadraticIterator(x1, y1, current[1], current[2], current[3], current[4]); + tempInfo.length = pathIterator(iterator, x1, y1); + x1 = current[3]; + y1 = current[4]; + break; + case 'Z': + // we add those in order to ease calculations later + tempInfo = basicInfo; + tempInfo.destX = x2; + tempInfo.destY = y2; + tempInfo.length = calcLineLength(x1, y1, x2, y2); + x1 = x2; + y1 = y2; + break; + } + totalLength += tempInfo.length; + info.push(tempInfo); + } + info.push({ + length: totalLength, + x: x1, + y: y1 + }); + return info; +}; + +/** + * Get the point on the path that is distance along the path + * @param path + * @param distance + * @param infos + */ +const getPointOnPath = function (path, distance) { + let infos = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getPathSegmentsInfo(path); + let i = 0; + while (distance - infos[i].length > 0 && i < infos.length - 2) { + distance -= infos[i].length; + i++; + } + const segInfo = infos[i], + segPercent = distance / segInfo.length, + segment = path[i]; + switch (segInfo.command) { + case 'M': + return { + x: segInfo.x, + y: segInfo.y, + angle: 0 + }; + case 'Z': + return _objectSpread2(_objectSpread2({}, new Point(segInfo.x, segInfo.y).lerp(new Point(segInfo.destX, segInfo.destY), segPercent)), {}, { + angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x) + }); + case 'L': + return _objectSpread2(_objectSpread2({}, new Point(segInfo.x, segInfo.y).lerp(new Point(segment[1], segment[2]), segPercent)), {}, { + angle: Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x) + }); + case 'C': + return findPercentageForDistance(segInfo, distance); + case 'Q': + return findPercentageForDistance(segInfo, distance); + // throw Error('Invalid command'); + } +}; +const rePathCmdAll = new RegExp(rePathCommand, 'gi'); +const regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g'); +const reMyNum = new RegExp(reNum, 'gi'); +const commandLengths = { + m: 2, + l: 2, + h: 1, + v: 1, + c: 6, + s: 4, + q: 4, + t: 2, + a: 7 +}; +/** + * + * @param {string} pathString + * @return {TComplexPathData} An array of SVG path commands + * @example Usage + * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [ + * ['M', 3, 4], + * ['Q', 3, 5, 2, 1, 4, 0], + * ['Q', 9, 12, 2, 1, 4, 0], + * ]; + */ +const parsePath = pathString => { + var _pathString$match; + const chain = []; + const all = (_pathString$match = pathString.match(rePathCmdAll)) !== null && _pathString$match !== void 0 ? _pathString$match : []; + for (const matchStr of all) { + // take match string and save the first letter as the command + const commandLetter = matchStr[0]; + // in case of Z we have very little to do + if (commandLetter === 'z' || commandLetter === 'Z') { + chain.push([commandLetter]); + continue; + } + const commandLength = commandLengths[commandLetter.toLowerCase()]; + let paramArr = []; + if (commandLetter === 'a' || commandLetter === 'A') { + // the arc command ha some peculariaties that requires a special regex other than numbers + // it is possible to avoid using a space between the sweep and large arc flags, making them either + // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum + // reset the regexp + regExpArcCommandPoints.lastIndex = 0; + for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) { + paramArr.push(...out.slice(1)); + } + } else { + paramArr = matchStr.match(reMyNum) || []; + } + + // inspect the length of paramArr, if is longer than commandLength + // we are dealing with repeated commands + for (let i = 0; i < paramArr.length; i += commandLength) { + const newCommand = new Array(commandLength); + const transformedCommand = repeatedCommands[commandLetter]; + newCommand[0] = i > 0 && transformedCommand ? transformedCommand : commandLetter; + for (let j = 0; j < commandLength; j++) { + newCommand[j + 1] = parseFloat(paramArr[i + j]); + } + chain.push(newCommand); + } + } + return chain; +}; + +/** + * + * Converts points to a smooth SVG path + * @param {XY[]} points Array of points + * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value. + * @return {(string|number)[][]} An array of SVG path commands + */ +const getSmoothPathFromPoints = function (points) { + let correction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let p1 = new Point(points[0]), + p2 = new Point(points[1]), + multSignX = 1, + multSignY = 0; + const path = [], + len = points.length, + manyPoints = len > 2; + if (manyPoints) { + multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; + multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; + } + path.push(['M', p1.x - multSignX * correction, p1.y - multSignY * correction]); + let i; + for (i = 1; i < len; i++) { + if (!p1.eq(p2)) { + const midPoint = p1.midPointFrom(p2); + // p1 is our bezier control point + // midpoint is our endpoint + // start point is p(i-1) value. + path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]); + } + p1 = points[i]; + if (i + 1 < points.length) { + p2 = points[i + 1]; + } + } + if (manyPoints) { + multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; + multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; + } + path.push(['L', p1.x + multSignX * correction, p1.y + multSignY * correction]); + return path; +}; + +/** + * Transform a path by transforming each segment. + * it has to be a simplified path or it won't work. + * WARNING: this depends from pathOffset for correct operation + * @param {TSimplePathData} path fabricJS parsed and simplified path commands + * @param {TMat2D} transform matrix that represent the transformation + * @param {Point} [pathOffset] `Path.pathOffset` + * @returns {TSimplePathData} the transformed path + */ +const transformPath = (path, transform, pathOffset) => { + if (pathOffset) { + transform = multiplyTransformMatrices(transform, [1, 0, 0, 1, -pathOffset.x, -pathOffset.y]); + } + return path.map(pathSegment => { + const newSegment = [...pathSegment]; + for (let i = 1; i < pathSegment.length - 1; i += 2) { + // TODO: is there a way to get around casting to any? + const { + x, + y + } = transformPoint({ + x: pathSegment[i], + y: pathSegment[i + 1] + }, transform); + newSegment[i] = x; + newSegment[i + 1] = y; + } + return newSegment; + }); +}; + +/** + * Returns an array of path commands to create a regular polygon + * @param {number} numVertexes + * @param {number} radius + * @returns {TSimplePathData} An array of SVG path commands + */ +const getRegularPolygonPath = (numVertexes, radius) => { + const interiorAngle = Math.PI * 2 / numVertexes; + // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom + // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn + let rotationAdjustment = -halfPI; + if (numVertexes % 2 === 0) { + rotationAdjustment += interiorAngle / 2; + } + const d = new Array(numVertexes + 1); + for (let i = 0; i < numVertexes; i++) { + const rad = i * interiorAngle + rotationAdjustment; + const { + x, + y + } = new Point(cos(rad), sin(rad)).scalarMultiply(radius); + d[i] = [i === 0 ? 'M' : 'L', x, y]; + } + d[numVertexes] = ['Z']; + return d; +}; + +/** + * Join path commands to go back to svg format + * @param {TSimplePathData} pathData fabricJS parsed path commands + * @param {number} fractionDigits number of fraction digits to "leave" + * @return {String} joined path 'M 0 0 L 20 30' + */ +const joinPath = (pathData, fractionDigits) => pathData.map(segment => { + return segment.map((arg, i) => { + if (i === 0) return arg; + return fractionDigits === undefined ? arg : toFixed(arg, fractionDigits); + }).join(' '); +}).join(' '); + +// TODO this file needs to go away, cross browser style support is not fabricjs domain. + +/** + * wrapper for setting element's style + * @param {HTMLElement} element + * @param {Object | string} styles + */ +function setStyle(element, styles) { + const elementStyle = element.style; + if (!elementStyle || !styles) { + return; + } else if (typeof styles === 'string') { + elementStyle.cssText += ';' + styles; + } else { + Object.entries(styles).forEach(_ref => { + let [property, value] = _ref; + return elementStyle.setProperty(property, value); + }); + } +} + +/** + * Merges 2 clip paths into one visually equal clip path + * + * **IMPORTANT**:\ + * Does **NOT** clone the arguments, clone them proir if necessary. + * + * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap. + * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible. + * + * In order to handle the `inverted` property we follow logic described in the following cases:\ + * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\ + * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\ + * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged. + * + * @memberOf fabric.util + * @param {fabric.Object} c1 + * @param {fabric.Object} c2 + * @returns {fabric.Object} merged clip path + */ +const mergeClipPaths = (c1, c2) => { + var _b$group; + let a = c1, + b = c2; + if (a.inverted && !b.inverted) { + // case (2) + a = c2; + b = c1; + } + // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane + sendObjectToPlane(b, (_b$group = b.group) === null || _b$group === void 0 ? void 0 : _b$group.calcTransformMatrix(), a.calcTransformMatrix()); + // assign the `inverted` prop to the wrapping group + const inverted = a.inverted && b.inverted; + if (inverted) { + // case (1) + a.inverted = b.inverted = false; + } + return new Group([a], { + clipPath: b, + inverted + }); +}; + +/** + * Returns random number between 2 specified ones. + * @param {Number} min lower limit + * @param {Number} max upper limit + * @return {Number} random value (between min and max) + */ +const getRandomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +/** + * Cross-browser abstraction for sending XMLHttpRequest + * @deprecated this has to go away, we can use a modern browser method to do the same. + * @param {String} url URL to send XMLHttpRequest to + * @param {Object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @param {Function} options.onComplete Callback to invoke when request is completed + * @return {XMLHttpRequest} request + */ + +function request(url) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const onComplete = options.onComplete || noop, + xhr = new (getFabricWindow().XMLHttpRequest)(), + signal = options.signal, + abort = function () { + xhr.abort(); + }, + removeListener = function () { + signal && signal.removeEventListener('abort', abort); + xhr.onerror = xhr.ontimeout = noop; + }; + if (signal && signal.aborted) { + throw new SignalAbortedError('request'); + } else if (signal) { + signal.addEventListener('abort', abort, { + once: true + }); + } + + /** @ignore */ + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + removeListener(); + onComplete(xhr); + xhr.onreadystatechange = noop; + } + }; + xhr.onerror = xhr.ontimeout = removeListener; + xhr.open('get', url, true); + xhr.send(); + return xhr; +} + +/** + * This function is an helper for svg import. it decompose the transformMatrix + * and assign properties to object. + * untransformed coordinates + * @private + */ +const _assignTransformMatrixProps = object => { + if (object.transformMatrix) { + const { + scaleX, + scaleY, + angle, + skewX + } = qrDecompose(object.transformMatrix); + object.flipX = false; + object.flipY = false; + object.set(SCALE_X, scaleX); + object.set(SCALE_Y, scaleY); + object.angle = angle; + object.skewX = skewX; + object.skewY = 0; + } +}; + +/** + * This function is an helper for svg import. it removes the transform matrix + * and set to object properties that fabricjs can handle + * @private + * @param {Object} preserveAspectRatioOptions + */ +const removeTransformMatrixForSvgParsing = (object, preserveAspectRatioOptions) => { + let center = object._findCenterFromElement(); + if (object.transformMatrix) { + _assignTransformMatrixProps(object); + center = center.transform(object.transformMatrix); + } + delete object.transformMatrix; + if (preserveAspectRatioOptions) { + object.scaleX *= preserveAspectRatioOptions.scaleX; + object.scaleY *= preserveAspectRatioOptions.scaleY; + object.cropX = preserveAspectRatioOptions.cropX; + object.cropY = preserveAspectRatioOptions.cropY; + center.x += preserveAspectRatioOptions.offsetLeft; + center.y += preserveAspectRatioOptions.offsetTop; + object.width = preserveAspectRatioOptions.width; + object.height = preserveAspectRatioOptions.height; + } + object.setPositionByOrigin(center, CENTER, CENTER); +}; + +var index$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + addTransformToObject: addTransformToObject, + animate: animate, + animateColor: animateColor, + applyTransformToObject: applyTransformToObject, + calcAngleBetweenVectors: calcAngleBetweenVectors, + calcDimensionsMatrix: calcDimensionsMatrix, + calcPlaneChangeMatrix: calcPlaneChangeMatrix, + calcVectorRotation: calcVectorRotation, + cancelAnimFrame: cancelAnimFrame, + capValue: capValue, + composeMatrix: composeMatrix, + copyCanvasElement: copyCanvasElement, + cos: cos, + createCanvasElement: createCanvasElement, + createImage: createImage, + createRotateMatrix: createRotateMatrix, + createScaleMatrix: createScaleMatrix, + createSkewXMatrix: createSkewXMatrix, + createSkewYMatrix: createSkewYMatrix, + createTranslateMatrix: createTranslateMatrix, + createVector: createVector, + crossProduct: crossProduct, + degreesToRadians: degreesToRadians, + dotProduct: dotProduct, + ease: easing, + enlivenObjectEnlivables: enlivenObjectEnlivables, + enlivenObjects: enlivenObjects, + findScaleToCover: findScaleToCover, + findScaleToFit: findScaleToFit, + getBoundsOfCurve: getBoundsOfCurve, + getOrthonormalVector: getOrthonormalVector, + getPathSegmentsInfo: getPathSegmentsInfo, + getPointOnPath: getPointOnPath, + getPointer: getPointer, + getRandomInt: getRandomInt, + getRegularPolygonPath: getRegularPolygonPath, + getSmoothPathFromPoints: getSmoothPathFromPoints, + getSvgAttributes: getSvgAttributes, + getUnitVector: getUnitVector, + groupSVGElements: groupSVGElements, + hasStyleChanged: hasStyleChanged, + invertTransform: invertTransform, + isBetweenVectors: isBetweenVectors, + isIdentityMatrix: isIdentityMatrix, + isTouchEvent: isTouchEvent, + isTransparent: isTransparent, + joinPath: joinPath, + loadImage: loadImage, + magnitude: magnitude, + makeBoundingBoxFromPoints: makeBoundingBoxFromPoints, + makePathSimpler: makePathSimpler, + matrixToSVG: matrixToSVG, + mergeClipPaths: mergeClipPaths, + multiplyTransformMatrices: multiplyTransformMatrices, + multiplyTransformMatrixArray: multiplyTransformMatrixArray, + parsePath: parsePath, + parsePreserveAspectRatioAttribute: parsePreserveAspectRatioAttribute, + parseUnit: parseUnit, + pick: pick, + projectStrokeOnPoints: projectStrokeOnPoints, + qrDecompose: qrDecompose, + radiansToDegrees: radiansToDegrees, + removeFromArray: removeFromArray, + removeTransformFromObject: removeTransformFromObject, + removeTransformMatrixForSvgParsing: removeTransformMatrixForSvgParsing, + request: request, + requestAnimFrame: requestAnimFrame, + resetObjectTransform: resetObjectTransform, + rotatePoint: rotatePoint, + rotateVector: rotateVector, + saveObjectTransform: saveObjectTransform, + sendObjectToPlane: sendObjectToPlane, + sendPointToPlane: sendPointToPlane, + sendVectorToPlane: sendVectorToPlane, + setStyle: setStyle, + sin: sin, + sizeAfterTransform: sizeAfterTransform, + string: lang_string, + stylesFromArray: stylesFromArray, + stylesToArray: stylesToArray, + toDataURL: toDataURL, + toFixed: toFixed, + transformPath: transformPath, + transformPoint: transformPoint +}); + +class CanvasDOMManager extends StaticCanvasDOMManager { + constructor(arg0) { + let { + allowTouchScrolling = false, + containerClass = '' + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(arg0); + _defineProperty(this, "upper", void 0); + _defineProperty(this, "container", void 0); + const { + el: lowerCanvasEl + } = this.lower; + const upperCanvasEl = this.createUpperCanvas(); + this.upper = { + el: upperCanvasEl, + ctx: upperCanvasEl.getContext('2d') + }; + this.applyCanvasStyle(lowerCanvasEl, { + allowTouchScrolling + }); + this.applyCanvasStyle(upperCanvasEl, { + allowTouchScrolling, + styles: { + position: 'absolute', + left: '0', + top: '0' + } + }); + const container = this.createContainerElement(); + container.classList.add(containerClass); + if (lowerCanvasEl.parentNode) { + lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl); + } + container.append(lowerCanvasEl, upperCanvasEl); + this.container = container; + } + createUpperCanvas() { + const { + el: lowerCanvasEl + } = this.lower; + const el = createCanvasElement(); + // we assign the same classname of the lowerCanvas + el.className = lowerCanvasEl.className; + // but then we remove the lower-canvas specific className + el.classList.remove('lower-canvas'); + // we add the specific upper-canvas class + el.classList.add('upper-canvas'); + el.setAttribute('data-fabric', 'top'); + el.style.cssText = lowerCanvasEl.style.cssText; + el.setAttribute('draggable', 'true'); + return el; + } + createContainerElement() { + const container = getFabricDocument().createElement('div'); + container.setAttribute('data-fabric', 'wrapper'); + setStyle(container, { + position: 'relative' + }); + makeElementUnselectable(container); + return container; + } + + /** + * @private + * @param {HTMLCanvasElement} element canvas element to apply styles on + */ + applyCanvasStyle(element, options) { + const { + styles, + allowTouchScrolling + } = options; + setStyle(element, _objectSpread2(_objectSpread2({}, styles), {}, { + 'touch-action': allowTouchScrolling ? 'manipulation' : NONE + })); + makeElementUnselectable(element); + } + setDimensions(size, retinaScaling) { + super.setDimensions(size, retinaScaling); + const { + el, + ctx + } = this.upper; + setCanvasDimensions(el, ctx, size, retinaScaling); + } + setCSSDimensions(size) { + super.setCSSDimensions(size); + setCSSDimensions(this.upper.el, size); + setCSSDimensions(this.container, size); + } + cleanupDOM(size) { + const container = this.container, + { + el: lowerCanvasEl + } = this.lower, + { + el: upperCanvasEl + } = this.upper; + super.cleanupDOM(size); + container.removeChild(upperCanvasEl); + container.removeChild(lowerCanvasEl); + if (container.parentNode) { + container.parentNode.replaceChild(lowerCanvasEl, container); + } + } + dispose() { + super.dispose(); + getEnv().dispose(this.upper.el); + // @ts-expect-error disposing + delete this.upper; + // @ts-expect-error disposing + delete this.container; + } +} + +const canvasDefaults = { + uniformScaling: true, + uniScaleKey: 'shiftKey', + centeredScaling: false, + centeredRotation: false, + centeredKey: 'altKey', + altActionKey: 'shiftKey', + selection: true, + selectionKey: 'shiftKey', + selectionColor: 'rgba(100, 100, 255, 0.3)', + selectionDashArray: [], + selectionBorderColor: 'rgba(255, 255, 255, 0.3)', + selectionLineWidth: 1, + selectionFullyContained: false, + hoverCursor: 'move', + moveCursor: 'move', + defaultCursor: 'default', + freeDrawingCursor: 'crosshair', + notAllowedCursor: 'not-allowed', + perPixelTargetFind: false, + targetFindTolerance: 0, + skipTargetFind: false, + stopContextMenu: false, + fireRightClick: false, + fireMiddleClick: false, + enablePointerEvents: false, + containerClass: 'canvas-container', + preserveObjectStacking: false +}; + +/** + * Canvas class + * @class Canvas + * @extends StaticCanvas + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} + * + * @fires object:modified at the end of a transform + * @fires object:rotating while an object is being rotated from the control + * @fires object:scaling while an object is being scaled by controls + * @fires object:moving while an object is being dragged + * @fires object:skewing while an object is being skewed from the controls + * + * @fires before:transform before a transform is is started + * @fires before:selection:cleared + * @fires selection:cleared + * @fires selection:updated + * @fires selection:created + * + * @fires path:created after a drawing operation ends and the path is added + * @fires mouse:down + * @fires mouse:move + * @fires mouse:up + * @fires mouse:down:before on mouse down, before the inner fabric logic runs + * @fires mouse:move:before on mouse move, before the inner fabric logic runs + * @fires mouse:up:before on mouse up, before the inner fabric logic runs + * @fires mouse:over + * @fires mouse:out + * @fires mouse:dblclick whenever a native dbl click event fires on the canvas. + * + * @fires dragover + * @fires dragenter + * @fires dragleave + * @fires drag:enter object drag enter + * @fires drag:leave object drag leave + * @fires drop:before before drop event. Prepare for the drop event (same native event). + * @fires drop + * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event). + * @example + * let a: fabric.Object, b: fabric.Object; + * let flag = false; + * canvas.add(a, b); + * a.on('drop:before', opt => { + * // we want a to accept the drop even though it's below b in the stack + * flag = this.canDrop(opt.e); + * }); + * b.canDrop = function(e) { + * !flag && this.draggableTextDelegate.canDrop(e); + * } + * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black')); + * a.on('drop', opt => { + * opt.e.defaultPrevented // drop occurred + * opt.didDrop // drop occurred on canvas + * opt.target // drop target + * opt.target !== a && a.set('text', 'I lost'); + * }); + * canvas.on('drop:after', opt => { + * // inform user who won + * if(!opt.e.defaultPrevented) { + * // no winners + * } + * else if(!opt.didDrop) { + * // my objects didn't win, some other lucky object + * } + * else { + * // we have a winner it's opt.target!! + * } + * }) + * + * @fires after:render at the end of the render process, receives the context in the callback + * @fires before:render at start the render process, receives the context in the callback + * + * @fires contextmenu:before + * @fires contextmenu + * @example + * let handler; + * targets.forEach(target => { + * target.on('contextmenu:before', opt => { + * // decide which target should handle the event before canvas hijacks it + * if (someCaseHappens && opt.targets.includes(target)) { + * handler = target; + * } + * }); + * target.on('contextmenu', opt => { + * // do something fantastic + * }); + * }); + * canvas.on('contextmenu', opt => { + * if (!handler) { + * // no one takes responsibility, it's always left to me + * // let's show them how it's done! + * } + * }); + * + */ +class SelectableCanvas extends StaticCanvas { + constructor() { + super(...arguments); + // transform config + // selection config + // cursors + // target find config + /** + * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. + * After mousedown, mousemove creates a shape, + * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. + * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} + * @type Boolean + * @default + */ + // event config + /** + * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget + * @type FabricObject[] + */ + _defineProperty(this, "targets", []); + /** + * hold the list of nested targets hovered + * @type FabricObject[] + * @private + */ + _defineProperty(this, "_hoveredTargets", []); + /** + * hold the list of objects to render + * @type FabricObject[] + * @private + */ + _defineProperty(this, "_objectsToRender", void 0); + /** + * hold a reference to a data structure that contains information + * on the current on going transform + * @type + * @private + */ + _defineProperty(this, "_currentTransform", null); + /** + * hold a reference to a data structure used to track the selection + * box on canvas drag + * on the current on going transform + * x, y, deltaX and deltaY are in scene plane + * @type + * @private + */ + _defineProperty(this, "_groupSelector", null); + /** + * internal flag used to understand if the context top requires a cleanup + * in case this is true, the contextTop will be cleared at the next render + * @type boolean + * @private + */ + _defineProperty(this, "contextTopDirty", false); + } + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), SelectableCanvas.ownDefaults); + } + get upperCanvasEl() { + var _this$elements$upper; + return (_this$elements$upper = this.elements.upper) === null || _this$elements$upper === void 0 ? void 0 : _this$elements$upper.el; + } + get contextTop() { + var _this$elements$upper2; + return (_this$elements$upper2 = this.elements.upper) === null || _this$elements$upper2 === void 0 ? void 0 : _this$elements$upper2.ctx; + } + get wrapperEl() { + return this.elements.container; + } + initElements(el) { + this.elements = new CanvasDOMManager(el, { + allowTouchScrolling: this.allowTouchScrolling, + containerClass: this.containerClass + }); + this._createCacheCanvas(); + } + + /** + * @private + * @param {FabricObject} obj Object that was added + */ + _onObjectAdded(obj) { + this._objectsToRender = undefined; + super._onObjectAdded(obj); + } + + /** + * @private + * @param {FabricObject} obj Object that was removed + */ + _onObjectRemoved(obj) { + this._objectsToRender = undefined; + // removing active object should fire "selection:cleared" events + if (obj === this._activeObject) { + this.fire('before:selection:cleared', { + deselected: [obj] + }); + this._discardActiveObject(); + this.fire('selection:cleared', { + deselected: [obj] + }); + obj.fire('deselected', { + target: obj + }); + } + if (obj === this._hoveredTarget) { + this._hoveredTarget = undefined; + this._hoveredTargets = []; + } + super._onObjectRemoved(obj); + } + _onStackOrderChanged() { + this._objectsToRender = undefined; + super._onStackOrderChanged(); + } + + /** + * Divides objects in two groups, one to render immediately + * and one to render as activeGroup. + * @return {Array} objects to render immediately and pushes the other in the activeGroup. + */ + _chooseObjectsToRender() { + const activeObject = this._activeObject; + return !this.preserveObjectStacking && activeObject ? this._objects.filter(object => !object.group && object !== activeObject).concat(activeObject) : this._objects; + } + + /** + * Renders both the top canvas and the secondary container canvas. + */ + renderAll() { + this.cancelRequestedRender(); + if (this.destroyed) { + return; + } + if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) { + this.clearContext(this.contextTop); + this.contextTopDirty = false; + } + if (this.hasLostContext) { + this.renderTopLayer(this.contextTop); + this.hasLostContext = false; + } + !this._objectsToRender && (this._objectsToRender = this._chooseObjectsToRender()); + this.renderCanvas(this.getContext(), this._objectsToRender); + } + + /** + * text selection is rendered by the active text instance during the rendering cycle + */ + renderTopLayer(ctx) { + ctx.save(); + if (this.isDrawingMode && this._isCurrentlyDrawing) { + this.freeDrawingBrush && this.freeDrawingBrush._render(); + this.contextTopDirty = true; + } + // we render the top context - last object + if (this.selection && this._groupSelector) { + this._drawSelection(ctx); + this.contextTopDirty = true; + } + ctx.restore(); + } + + /** + * Method to render only the top canvas. + * Also used to render the group selection box. + * Does not render text selection. + */ + renderTop() { + const ctx = this.contextTop; + this.clearContext(ctx); + this.renderTopLayer(ctx); + // todo: how do i know if the after:render is for the top or normal contex? + this.fire('after:render', { + ctx + }); + } + + /** + * Set the canvas tolerance value for pixel taret find. + * Use only integer numbers. + * @private + */ + setTargetFindTolerance(value) { + value = Math.round(value); + this.targetFindTolerance = value; + const retina = this.getRetinaScaling(); + const size = Math.ceil((value * 2 + 1) * retina); + this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size; + this.pixelFindContext.scale(retina, retina); + } + + /** + * Returns true if object is transparent at a certain location + * Clarification: this is `is target transparent at location X or are controls there` + * @TODO this seems dumb that we treat controls with transparency. we can find controls + * programmatically without painting them, the cache canvas optimization is always valid + * @param {FabricObject} target Object to check + * @param {Number} x Left coordinate in viewport space + * @param {Number} y Top coordinate in viewport space + * @return {Boolean} + */ + isTargetTransparent(target, x, y) { + const tolerance = this.targetFindTolerance; + const ctx = this.pixelFindContext; + this.clearContext(ctx); + ctx.save(); + ctx.translate(-x + tolerance, -y + tolerance); + ctx.transform(...this.viewportTransform); + const selectionBgc = target.selectionBackgroundColor; + target.selectionBackgroundColor = ''; + target.render(ctx); + target.selectionBackgroundColor = selectionBgc; + ctx.restore(); + // our canvas is square, and made around tolerance. + // so tolerance in this case also represent the center of the canvas. + const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling()); + return isTransparent(ctx, enhancedTolerance, enhancedTolerance, enhancedTolerance); + } + + /** + * takes an event and determines if selection key has been pressed + * @private + * @param {TPointerEvent} e Event object + */ + _isSelectionKeyPressed(e) { + const sKey = this.selectionKey; + if (!sKey) { + return false; + } + if (Array.isArray(sKey)) { + return !!sKey.find(key => !!key && e[key] === true); + } else { + return e[sKey]; + } + } + + /** + * @private + * @param {TPointerEvent} e Event object + * @param {FabricObject} target + */ + _shouldClearSelection(e, target) { + const activeObjects = this.getActiveObjects(), + activeObject = this._activeObject; + return !!(!target || target && activeObject && activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && !this._isSelectionKeyPressed(e) || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target); + } + + /** + * This method will take in consideration a modifier key pressed and the control we are + * about to drag, and try to guess the anchor point ( origin ) of the transormation. + * This should be really in the realm of controls, and we should remove specific code for legacy + * embedded actions. + * @TODO this probably deserve discussion/rediscovery and change/refactor + * @private + * @deprecated + * @param {FabricObject} target + * @param {string} action + * @param {boolean} altKey + * @returns {boolean} true if the transformation should be centered + */ + _shouldCenterTransform(target, action, modifierKeyPressed) { + if (!target) { + return; + } + let centerTransform; + if (action === SCALE || action === SCALE_X || action === SCALE_Y || action === RESIZING) { + centerTransform = this.centeredScaling || target.centeredScaling; + } else if (action === ROTATE) { + centerTransform = this.centeredRotation || target.centeredRotation; + } + return centerTransform ? !modifierKeyPressed : modifierKeyPressed; + } + + /** + * Given the control clicked, determine the origin of the transform. + * This is bad because controls can totally have custom names + * should disappear before release 4.0 + * @private + * @deprecated + */ + _getOriginFromCorner(target, controlName) { + const origin = { + x: target.originX, + y: target.originY + }; + if (!controlName) { + return origin; + } + + // is a left control ? + if (['ml', 'tl', 'bl'].includes(controlName)) { + origin.x = RIGHT; + // is a right control ? + } else if (['mr', 'tr', 'br'].includes(controlName)) { + origin.x = LEFT; + } + // is a top control ? + if (['tl', 'mt', 'tr'].includes(controlName)) { + origin.y = BOTTOM; + // is a bottom control ? + } else if (['bl', 'mb', 'br'].includes(controlName)) { + origin.y = TOP; + } + return origin; + } + + /** + * @private + * @param {Event} e Event object + * @param {FabricObject} target + * @param {boolean} [alreadySelected] pass true to setup the active control + */ + _setupCurrentTransform(e, target, alreadySelected) { + var _control$getActionHan; + const pointer = target.group ? + // transform pointer to target's containing coordinate plane + sendPointToPlane(this.getScenePoint(e), undefined, target.group.calcTransformMatrix()) : this.getScenePoint(e); + const { + key: corner = '', + control + } = target.getActiveControl() || {}, + actionHandler = alreadySelected && control ? (_control$getActionHan = control.getActionHandler(e, target, control)) === null || _control$getActionHan === void 0 ? void 0 : _control$getActionHan.bind(control) : dragHandler, + action = getActionFromCorner(alreadySelected, corner, e, target), + altKey = e[this.centeredKey], + origin = this._shouldCenterTransform(target, action, altKey) ? { + x: CENTER, + y: CENTER + } : this._getOriginFromCorner(target, corner), + /** + * relative to target's containing coordinate plane + * both agree on every point + **/ + transform = { + target: target, + action, + actionHandler, + actionPerformed: false, + corner, + scaleX: target.scaleX, + scaleY: target.scaleY, + skewX: target.skewX, + skewY: target.skewY, + offsetX: pointer.x - target.left, + offsetY: pointer.y - target.top, + originX: origin.x, + originY: origin.y, + ex: pointer.x, + ey: pointer.y, + lastX: pointer.x, + lastY: pointer.y, + theta: degreesToRadians(target.angle), + width: target.width, + height: target.height, + shiftKey: e.shiftKey, + altKey, + original: _objectSpread2(_objectSpread2({}, saveObjectTransform(target)), {}, { + originX: origin.x, + originY: origin.y + }) + }; + this._currentTransform = transform; + this.fire('before:transform', { + e, + transform + }); + } + + /** + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor + */ + setCursor(value) { + this.upperCanvasEl.style.cursor = value; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx to draw the selection on + */ + _drawSelection(ctx) { + const { + x, + y, + deltaX, + deltaY + } = this._groupSelector, + start = new Point(x, y).transform(this.viewportTransform), + extent = new Point(x + deltaX, y + deltaY).transform(this.viewportTransform), + strokeOffset = this.selectionLineWidth / 2; + let minX = Math.min(start.x, extent.x), + minY = Math.min(start.y, extent.y), + maxX = Math.max(start.x, extent.x), + maxY = Math.max(start.y, extent.y); + if (this.selectionColor) { + ctx.fillStyle = this.selectionColor; + ctx.fillRect(minX, minY, maxX - minX, maxY - minY); + } + if (!this.selectionLineWidth || !this.selectionBorderColor) { + return; + } + ctx.lineWidth = this.selectionLineWidth; + ctx.strokeStyle = this.selectionBorderColor; + minX += strokeOffset; + minY += strokeOffset; + maxX -= strokeOffset; + maxY -= strokeOffset; + // selection border + // @TODO: is _setLineDash still necessary on modern canvas? + FabricObject.prototype._setLineDash.call(this, ctx, this.selectionDashArray); + ctx.strokeRect(minX, minY, maxX - minX, maxY - minY); + } + + /** + * Method that determines what object we are clicking on + * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target + * or the outside part of the corner. + * @param {Event} e mouse event + * @return {FabricObject | null} the target found + */ + findTarget(e) { + if (this.skipTargetFind) { + return undefined; + } + const pointer = this.getViewportPoint(e), + activeObject = this._activeObject, + aObjects = this.getActiveObjects(); + this.targets = []; + if (activeObject && aObjects.length >= 1) { + if (activeObject.findControl(pointer, isTouchEvent(e))) { + // if we hit the corner of the active object, let's return that. + return activeObject; + } else if (aObjects.length > 1 && + // check pointer is over active selection and possibly perform `subTargetCheck` + this.searchPossibleTargets([activeObject], pointer)) { + // active selection does not select sub targets like normal groups + return activeObject; + } else if (activeObject === this.searchPossibleTargets([activeObject], pointer)) { + // active object is not an active selection + if (!this.preserveObjectStacking) { + return activeObject; + } else { + const subTargets = this.targets; + this.targets = []; + const target = this.searchPossibleTargets(this._objects, pointer); + if (e[this.altSelectionKey] && target && target !== activeObject) { + // alt selection: select active object even though it is not the top most target + // restore targets + this.targets = subTargets; + return activeObject; + } + return target; + } + } + } + return this.searchPossibleTargets(this._objects, pointer); + } + + /** + * Checks if the point is inside the object selection area including padding + * @param {FabricObject} obj Object to test against + * @param {Object} [pointer] point in scene coordinates + * @return {Boolean} true if point is contained within an area of given object + * @private + */ + _pointIsInObjectSelectionArea(obj, point) { + // getCoords will already take care of group de-nesting + let coords = obj.getCoords(); + const viewportZoom = this.getZoom(); + const padding = obj.padding / viewportZoom; + if (padding) { + const [tl, tr, br, bl] = coords; + // what is the angle of the object? + // we could use getTotalAngle, but is way easier to look at it + // from how coords are oriented, since if something went wrong + // at least we are consistent. + const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x), + cosP = cos(angleRadians) * padding, + sinP = sin(angleRadians) * padding, + cosPSinP = cosP + sinP, + cosPMinusSinP = cosP - sinP; + coords = [new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP), new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP), new Point(br.x + cosPMinusSinP, br.y + cosPSinP), new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP)]; + // in case of padding we calculate the new coords on the fly. + // otherwise we have to maintain 2 sets of coordinates for everything. + // we can reiterate on storing them. + // if this is slow, for now the semplification is large and doesn't impact + // rendering. + // the idea behind this is that outside target check we don't need ot know + // where those coords are + } + return Intersection.isPointInPolygon(point, coords); + } + + /** + * Checks point is inside the object selection condition. Either area with padding + * or over pixels if perPixelTargetFind is enabled + * @param {FabricObject} obj Object to test against + * @param {Object} [pointer] point from viewport. + * @return {Boolean} true if point is contained within an area of given object + * @private + */ + _checkTarget(obj, pointer) { + if (obj && obj.visible && obj.evented && this._pointIsInObjectSelectionArea(obj, sendPointToPlane(pointer, undefined, this.viewportTransform))) { + if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { + if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) { + return true; + } + } else { + return true; + } + } + return false; + } + + /** + * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted + * @param {Array} [objects] objects array to look into + * @param {Object} [pointer] x,y object of point coordinates we want to check. + * @return {FabricObject} **top most object from given `objects`** that contains pointer + * @private + */ + _searchPossibleTargets(objects, pointer) { + // Cache all targets where their bounding box contains point. + let i = objects.length; + // Do not check for currently grouped objects, since we check the parent group itself. + // until we call this function specifically to search inside the activeGroup + while (i--) { + const target = objects[i]; + if (this._checkTarget(target, pointer)) { + if (isCollection(target) && target.subTargetCheck) { + const subTarget = this._searchPossibleTargets(target._objects, pointer); + subTarget && this.targets.push(subTarget); + } + return target; + } + } + } + + /** + * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted + * @see {@link _searchPossibleTargets} + * @param {FabricObject[]} [objects] objects array to look into + * @param {Point} [pointer] coordinates from viewport to check. + * @return {FabricObject} **top most object on screen** that contains pointer + */ + searchPossibleTargets(objects, pointer) { + const target = this._searchPossibleTargets(objects, pointer); + + // if we found something in this.targets, and the group is interactive, return the innermost subTarget + // that is still interactive + // TODO: reverify why interactive. the target should be returned always, but selected only + // if interactive. + if (target && isCollection(target) && target.interactive && this.targets[0]) { + /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */ + const targets = this.targets; + for (let i = targets.length - 1; i > 0; i--) { + const t = targets[i]; + if (!(isCollection(t) && t.interactive)) { + // one of the subtargets was not interactive. that is the last subtarget we can return. + // we can't dig more deep; + return t; + } + } + return targets[0]; + } + return target; + } + + /** + * @returns point existing in the same plane as the {@link HTMLCanvasElement}, + * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}. + * This means that changes to the {@link viewportTransform} do not change the values of the point + * and it remains unchanged from the viewer's perspective. + * + * @example + * const scenePoint = sendPointToPlane( + * this.getViewportPoint(e), + * undefined, + * canvas.viewportTransform + * ); + * + */ + getViewportPoint(e) { + if (this._pointer) { + return this._pointer; + } + return this.getPointer(e, true); + } + + /** + * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in). + * This means that changes to the {@link viewportTransform} do not change the values of the point, + * however, from the viewer's perspective, the point is changed. + * + * @example + * const viewportPoint = sendPointToPlane( + * this.getScenePoint(e), + * canvas.viewportTransform + * ); + * + */ + getScenePoint(e) { + if (this._absolutePointer) { + return this._absolutePointer; + } + return this.getPointer(e); + } + + /** + * Returns pointer relative to canvas. + * + * @deprecated This method is deprecated since v6 to protect you from misuse. + * Use {@link getViewportPoint} or {@link getScenePoint} instead. + * + * @param {Event} e + * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene + * @return {Point} + */ + getPointer(e) { + let fromViewport = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const upperCanvasEl = this.upperCanvasEl, + bounds = upperCanvasEl.getBoundingClientRect(); + let pointer = getPointer(e), + boundsWidth = bounds.width || 0, + boundsHeight = bounds.height || 0; + if (!boundsWidth || !boundsHeight) { + if (TOP in bounds && BOTTOM in bounds) { + boundsHeight = Math.abs(bounds.top - bounds.bottom); + } + if (RIGHT in bounds && LEFT in bounds) { + boundsWidth = Math.abs(bounds.right - bounds.left); + } + } + this.calcOffset(); + pointer.x = pointer.x - this._offset.left; + pointer.y = pointer.y - this._offset.top; + if (!fromViewport) { + pointer = sendPointToPlane(pointer, undefined, this.viewportTransform); + } + const retinaScaling = this.getRetinaScaling(); + if (retinaScaling !== 1) { + pointer.x /= retinaScaling; + pointer.y /= retinaScaling; + } + + // If bounds are not available (i.e. not visible), do not apply scale. + const cssScale = boundsWidth === 0 || boundsHeight === 0 ? new Point(1, 1) : new Point(upperCanvasEl.width / boundsWidth, upperCanvasEl.height / boundsHeight); + return pointer.multiply(cssScale); + } + + /** + * Internal use only + * @protected + */ + _setDimensionsImpl(dimensions, options) { + // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract + this._resetTransformEventData(); + super._setDimensionsImpl(dimensions, options); + if (this._isCurrentlyDrawing) { + this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop); + } + } + _createCacheCanvas() { + this.pixelFindCanvasEl = createCanvasElement(); + this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', { + willReadFrequently: true + }); + this.setTargetFindTolerance(this.targetFindTolerance); + } + + /** + * Returns context of top canvas where interactions are drawn + * @returns {CanvasRenderingContext2D} + */ + getTopContext() { + return this.elements.upper.ctx; + } + + /** + * Returns context of canvas where object selection is drawn + * @alias + * @return {CanvasRenderingContext2D} + */ + getSelectionContext() { + return this.elements.upper.ctx; + } + + /** + * Returns <canvas> element on which object selection is drawn + * @return {HTMLCanvasElement} + */ + getSelectionElement() { + return this.elements.upper.el; + } + + /** + * Returns currently active object + * @return {FabricObject | null} active object + */ + getActiveObject() { + return this._activeObject; + } + + /** + * Returns an array with the current selected objects + * @return {FabricObject[]} active objects array + */ + getActiveObjects() { + const active = this._activeObject; + return isActiveSelection(active) ? active.getObjects() : active ? [active] : []; + } + + /** + * @private + * Compares the old activeObject with the current one and fires correct events + * @param {FabricObject[]} oldObjects old activeObject + * @param {TPointerEvent} e mouse event triggering the selection events + */ + _fireSelectionEvents(oldObjects, e) { + let somethingChanged = false, + invalidate = false; + const objects = this.getActiveObjects(), + added = [], + removed = []; + oldObjects.forEach(target => { + if (!objects.includes(target)) { + somethingChanged = true; + target.fire('deselected', { + e, + target + }); + removed.push(target); + } + }); + objects.forEach(target => { + if (!oldObjects.includes(target)) { + somethingChanged = true; + target.fire('selected', { + e, + target + }); + added.push(target); + } + }); + if (oldObjects.length > 0 && objects.length > 0) { + invalidate = true; + somethingChanged && this.fire('selection:updated', { + e, + selected: added, + deselected: removed + }); + } else if (objects.length > 0) { + invalidate = true; + this.fire('selection:created', { + e, + selected: added + }); + } else if (oldObjects.length > 0) { + invalidate = true; + this.fire('selection:cleared', { + e, + deselected: removed + }); + } + invalidate && (this._objectsToRender = undefined); + } + + /** + * Sets given object as the only active object on canvas + * @param {FabricObject} object Object to set as an active one + * @param {TPointerEvent} [e] Event (passed along when firing "object:selected") + * @return {Boolean} true if the object has been selected + */ + setActiveObject(object, e) { + // we can't inline this, since _setActiveObject will change what getActiveObjects returns + const currentActives = this.getActiveObjects(); + const selected = this._setActiveObject(object, e); + this._fireSelectionEvents(currentActives, e); + return selected; + } + + /** + * This is supposed to be equivalent to setActiveObject but without firing + * any event. There is commitment to have this stay this way. + * This is the functional part of setActiveObject. + * @param {Object} object to set as active + * @param {Event} [e] Event (passed along when firing "object:selected") + * @return {Boolean} true if the object has been selected + */ + _setActiveObject(object, e) { + const prevActiveObject = this._activeObject; + if (prevActiveObject === object) { + return false; + } + // after calling this._discardActiveObject, this,_activeObject could be undefined + if (!this._discardActiveObject(e, object) && this._activeObject) { + // refused to deselect + return false; + } + if (object.onSelect({ + e + })) { + return false; + } + this._activeObject = object; + if (isActiveSelection(object) && prevActiveObject !== object) { + object.set('canvas', this); + } + object.setCoords(); + return true; + } + + /** + * This is supposed to be equivalent to discardActiveObject but without firing + * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way. + * This is the functional part of discardActiveObject. + * @param {Event} [e] Event (passed along when firing "object:deselected") + * @param {Object} object the next object to set as active, reason why we are discarding this + * @return {Boolean} true if the active object has been discarded + */ + _discardActiveObject(e, object) { + const obj = this._activeObject; + if (obj) { + // onDeselect return TRUE to cancel selection; + if (obj.onDeselect({ + e, + object + })) { + return false; + } + if (this._currentTransform && this._currentTransform.target === obj) { + this.endCurrentTransform(e); + } + if (isActiveSelection(obj) && obj === this._hoveredTarget) { + this._hoveredTarget = undefined; + } + this._activeObject = undefined; + return true; + } + return false; + } + + /** + * Discards currently active object and fire events. If the function is called by fabric + * as a consequence of a mouse event, the event is passed as a parameter and + * sent to the fire function for the custom events. When used as a method the + * e param does not have any application. + * @param {event} e + * @return {Boolean} true if the active object has been discarded + */ + discardActiveObject(e) { + const currentActives = this.getActiveObjects(), + activeObject = this.getActiveObject(); + if (currentActives.length) { + this.fire('before:selection:cleared', { + e, + deselected: [activeObject] + }); + } + const discarded = this._discardActiveObject(e); + this._fireSelectionEvents(currentActives, e); + return discarded; + } + + /** + * End the current transform. + * You don't usually need to call this method unless you are interrupting a user initiated transform + * because of some other event ( a press of key combination, or something that block the user UX ) + * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event + */ + endCurrentTransform(e) { + const transform = this._currentTransform; + this._finalizeCurrentTransform(e); + if (transform && transform.target) { + // this could probably go inside _finalizeCurrentTransform + transform.target.isMoving = false; + } + this._currentTransform = null; + } + + /** + * @private + * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event + */ + _finalizeCurrentTransform(e) { + const transform = this._currentTransform, + target = transform.target, + options = { + e, + target, + transform, + action: transform.action + }; + if (target._scaling) { + target._scaling = false; + } + target.setCoords(); + if (transform.actionPerformed) { + this.fire('object:modified', options); + target.fire(MODIFIED, options); + } + } + + /** + * Sets viewport transformation of this canvas instance + * @param {Array} vpt a Canvas 2D API transform matrix + */ + setViewportTransform(vpt) { + super.setViewportTransform(vpt); + const activeObject = this._activeObject; + if (activeObject) { + activeObject.setCoords(); + } + } + + /** + * @override clears active selection ref and interactive canvas elements and contexts + */ + destroy() { + // dispose of active selection + const activeObject = this._activeObject; + if (isActiveSelection(activeObject)) { + activeObject.removeAll(); + activeObject.dispose(); + } + delete this._activeObject; + super.destroy(); + + // free resources + + // pixel find canvas + // @ts-expect-error disposing + this.pixelFindContext = null; + // @ts-expect-error disposing + this.pixelFindCanvasEl = undefined; + } + + /** + * Clears all contexts (background, main, top) of an instance + */ + clear() { + // discard active object and fire events + this.discardActiveObject(); + // make sure we clear the active object in case it refused to be discarded + this._activeObject = undefined; + this.clearContext(this.contextTop); + super.clear(); + } + + /** + * Draws objects' controls (borders/controls) + * @param {CanvasRenderingContext2D} ctx Context to render controls on + */ + drawControls(ctx) { + const activeObject = this._activeObject; + if (activeObject) { + activeObject._renderControls(ctx); + } + } + + /** + * @private + */ + _toObject(instance, methodName, propertiesToInclude) { + // If the object is part of the current selection group, it should + // be transformed appropriately + // i.e. it should be serialised as it would appear if the selection group + // were to be destroyed. + const originalProperties = this._realizeGroupTransformOnObject(instance), + object = super._toObject(instance, methodName, propertiesToInclude); + //Undo the damage we did by changing all of its properties + instance.set(originalProperties); + return object; + } + + /** + * Realizes an object's group transformation on it + * @private + * @param {FabricObject} [instance] the object to transform (gets mutated) + * @returns the original values of instance which were changed + */ + _realizeGroupTransformOnObject(instance) { + const { + group + } = instance; + if (group && isActiveSelection(group) && this._activeObject === group) { + const layoutProps = ['angle', 'flipX', 'flipY', LEFT, SCALE_X, SCALE_Y, SKEW_X, SKEW_Y, TOP]; + const originalValues = pick(instance, layoutProps); + addTransformToObject(instance, group.calcOwnMatrix()); + return originalValues; + } else { + return {}; + } + } + + /** + * @private + */ + _setSVGObject(markup, instance, reviver) { + // If the object is in a selection group, simulate what would happen to that + // object when the group is deselected + const originalProperties = this._realizeGroupTransformOnObject(instance); + super._setSVGObject(markup, instance, reviver); + instance.set(originalProperties); + } +} +_defineProperty(SelectableCanvas, "ownDefaults", canvasDefaults); + +/** + * In charge of synchronizing all interactive text instances of a canvas + */ +class TextEditingManager { + constructor(canvas) { + _defineProperty(this, "targets", []); + _defineProperty(this, "__disposer", void 0); + const cb = () => { + const { + hiddenTextarea + } = canvas.getActiveObject() || {}; + hiddenTextarea && hiddenTextarea.focus(); + }; + const el = canvas.upperCanvasEl; + el.addEventListener('click', cb); + this.__disposer = () => el.removeEventListener('click', cb); + } + exitTextEditing() { + this.target = undefined; + this.targets.forEach(target => { + if (target.isEditing) { + target.exitEditing(); + } + }); + } + add(target) { + this.targets.push(target); + } + remove(target) { + this.unregister(target); + removeFromArray(this.targets, target); + } + register(target) { + this.target = target; + } + unregister(target) { + if (target === this.target) { + this.target = undefined; + } + } + onMouseMove(e) { + var _this$target; + ((_this$target = this.target) === null || _this$target === void 0 ? void 0 : _this$target.isEditing) && this.target.updateSelectionOnMouseMove(e); + } + clear() { + this.targets = []; + this.target = undefined; + } + dispose() { + this.clear(); + this.__disposer(); + // @ts-expect-error disposing + delete this.__disposer; + } +} + +const _excluded$9 = ["target", "oldTarget", "fireCanvas", "e"]; +const addEventOptions = { + passive: false +}; +const getEventPoints = (canvas, e) => { + const viewportPoint = canvas.getViewportPoint(e); + const scenePoint = canvas.getScenePoint(e); + return { + viewportPoint, + scenePoint, + pointer: viewportPoint, + absolutePointer: scenePoint + }; +}; + +// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers +// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file. +// few bytes but why give it away. +const addListener = function (el) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + return el.addEventListener(...args); +}; +const removeListener = function (el) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + return el.removeEventListener(...args); +}; +const syntheticEventConfig = { + mouse: { + in: 'over', + out: 'out', + targetIn: 'mouseover', + targetOut: 'mouseout', + canvasIn: 'mouse:over', + canvasOut: 'mouse:out' + }, + drag: { + in: 'enter', + out: 'leave', + targetIn: 'dragenter', + targetOut: 'dragleave', + canvasIn: 'drag:enter', + canvasOut: 'drag:leave' + } +}; +class Canvas extends SelectableCanvas { + constructor(el) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(el, options); + // bind event handlers + /** + * Contains the id of the touch event that owns the fabric transform + * @type Number + * @private + */ + /** + * Holds a reference to a setTimeout timer for event synchronization + * @type number + * @private + */ + /** + * Holds a reference to an object on the canvas that is receiving the drag over event. + * @type FabricObject + * @private + */ + /** + * Holds a reference to an object on the canvas from where the drag operation started + * @type FabricObject + * @private + */ + /** + * Holds a reference to an object on the canvas that is the current drop target + * May differ from {@link _draggedoverTarget} + * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow + * @type FabricObject + * @private + */ + _defineProperty(this, "_isClick", void 0); + _defineProperty(this, "textEditingManager", new TextEditingManager(this)); + ['_onMouseDown', '_onTouchStart', '_onMouseMove', '_onMouseUp', '_onTouchEnd', '_onResize', + // '_onGesture', + // '_onDrag', + // '_onShake', + // '_onLongPress', + // '_onOrientationChange', + '_onMouseWheel', '_onMouseOut', '_onMouseEnter', '_onContextMenu', '_onDoubleClick', '_onDragStart', '_onDragEnd', '_onDragProgress', '_onDragOver', '_onDragEnter', '_onDragLeave', '_onDrop'].forEach(eventHandler => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + this[eventHandler] = this[eventHandler].bind(this); + }); + // register event handlers + this.addOrRemove(addListener, 'add'); + } + + /** + * return an event prefix pointer or mouse. + * @private + */ + _getEventPrefix() { + return this.enablePointerEvents ? 'pointer' : 'mouse'; + } + addOrRemove(functor, _eventjsFunctor) { + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + functor(getWindowFromElement(canvasElement), 'resize', this._onResize); + functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown); + functor(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + functor(canvasElement, "".concat(eventTypePrefix, "out"), this._onMouseOut); + functor(canvasElement, "".concat(eventTypePrefix, "enter"), this._onMouseEnter); + functor(canvasElement, 'wheel', this._onMouseWheel); + functor(canvasElement, 'contextmenu', this._onContextMenu); + functor(canvasElement, 'dblclick', this._onDoubleClick); + functor(canvasElement, 'dragstart', this._onDragStart); + functor(canvasElement, 'dragend', this._onDragEnd); + functor(canvasElement, 'dragover', this._onDragOver); + functor(canvasElement, 'dragenter', this._onDragEnter); + functor(canvasElement, 'dragleave', this._onDragLeave); + functor(canvasElement, 'drop', this._onDrop); + if (!this.enablePointerEvents) { + functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions); + } + // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) { + // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture); + // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag); + // eventjs[eventjsFunctor]( + // canvasElement, + // 'orientation', + // this._onOrientationChange + // ); + // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake); + // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress); + // } + } + + /** + * Removes all event listeners + */ + removeListeners() { + this.addOrRemove(removeListener, 'remove'); + // if you dispose on a mouseDown, before mouse up, you need to clean document to... + const eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + removeListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + removeListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + removeListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + } + + /** + * @private + * @param {Event} [e] Event object fired on wheel event + */ + _onMouseWheel(e) { + this.__onMouseWheel(e); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseOut(e) { + const target = this._hoveredTarget; + const shared = _objectSpread2({ + e + }, getEventPoints(this, e)); + this.fire('mouse:out', _objectSpread2(_objectSpread2({}, shared), {}, { + target + })); + this._hoveredTarget = undefined; + target && target.fire('mouseout', _objectSpread2({}, shared)); + this._hoveredTargets.forEach(nestedTarget => { + this.fire('mouse:out', _objectSpread2(_objectSpread2({}, shared), {}, { + target: nestedTarget + })); + nestedTarget && nestedTarget.fire('mouseout', _objectSpread2({}, shared)); + }); + this._hoveredTargets = []; + } + + /** + * @private + * @param {Event} e Event object fired on mouseenter + */ + _onMouseEnter(e) { + // This find target and consequent 'mouse:over' is used to + // clear old instances on hovered target. + // calling findTarget has the side effect of killing target.__corner. + // as a short term fix we are not firing this if we are currently transforming. + // as a long term fix we need to separate the action of finding a target with the + // side effects we added to it. + if (!this._currentTransform && !this.findTarget(e)) { + this.fire('mouse:over', _objectSpread2({ + e + }, getEventPoints(this, e))); + this._hoveredTarget = undefined; + this._hoveredTargets = []; + } + } + + /** + * supports native like text dragging + * @private + * @param {DragEvent} e + */ + _onDragStart(e) { + this._isClick = false; + const activeObject = this.getActiveObject(); + if (activeObject && activeObject.onDragStart(e)) { + this._dragSource = activeObject; + const options = { + e, + target: activeObject + }; + this.fire('dragstart', options); + activeObject.fire('dragstart', options); + addListener(this.upperCanvasEl, 'drag', this._onDragProgress); + return; + } + stopEvent(e); + } + + /** + * First we clear top context where the effects are being rendered. + * Then we render the effects. + * Doing so will render the correct effect for all cases including an overlap between `source` and `target`. + * @private + */ + _renderDragEffects(e, source, target) { + let dirty = false; + // clear top context + const dropTarget = this._dropTarget; + if (dropTarget && dropTarget !== source && dropTarget !== target) { + dropTarget.clearContextTop(); + dirty = true; + } + source === null || source === void 0 || source.clearContextTop(); + target !== source && (target === null || target === void 0 ? void 0 : target.clearContextTop()); + // render effects + const ctx = this.contextTop; + ctx.save(); + ctx.transform(...this.viewportTransform); + if (source) { + ctx.save(); + source.transform(ctx); + source.renderDragSourceEffect(e); + ctx.restore(); + dirty = true; + } + if (target) { + ctx.save(); + target.transform(ctx); + target.renderDropTargetEffect(e); + ctx.restore(); + dirty = true; + } + ctx.restore(); + dirty && (this.contextTopDirty = true); + } + + /** + * supports native like text dragging + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag + * @private + * @param {DragEvent} e + */ + _onDragEnd(e) { + const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE, + dropTarget = didDrop ? this._activeObject : undefined, + options = { + e, + target: this._dragSource, + subTargets: this.targets, + dragSource: this._dragSource, + didDrop, + dropTarget: dropTarget + }; + removeListener(this.upperCanvasEl, 'drag', this._onDragProgress); + this.fire('dragend', options); + this._dragSource && this._dragSource.fire('dragend', options); + delete this._dragSource; + // we need to call mouse up synthetically because the browser won't + this._onMouseUp(e); + } + + /** + * fire `drag` event on canvas and drag source + * @private + * @param {DragEvent} e + */ + _onDragProgress(e) { + const options = { + e, + target: this._dragSource, + dragSource: this._dragSource, + dropTarget: this._draggedoverTarget + }; + this.fire('drag', options); + this._dragSource && this._dragSource.fire('drag', options); + } + + /** + * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line. + * Override at will + */ + findDragTargets(e) { + this.targets = []; + const target = this._searchPossibleTargets(this._objects, this.getViewportPoint(e)); + return { + target, + targets: [...this.targets] + }; + } + + /** + * prevent default to allow drop event to be fired + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets + * @private + * @param {DragEvent} [e] Event object fired on Event.js shake + */ + _onDragOver(e) { + const eventType = 'dragover'; + const { + target, + targets + } = this.findDragTargets(e); + const dragSource = this._dragSource; + const options = { + e, + target, + subTargets: targets, + dragSource, + canDrop: false, + dropTarget: undefined + }; + let dropTarget; + // fire on canvas + this.fire(eventType, options); + // make sure we fire dragenter events before dragover + // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it + this._fireEnterLeaveEvents(target, options); + if (target) { + if (target.canDrop(e)) { + dropTarget = target; + } + target.fire(eventType, options); + } + // propagate the event to subtargets + for (let i = 0; i < targets.length; i++) { + const subTarget = targets[i]; + // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken) + // TODO: verify if those should loop in inverse order then? + // what is the order of subtargets? + if (subTarget.canDrop(e)) { + dropTarget = subTarget; + } + subTarget.fire(eventType, options); + } + // render drag effects now that relations between source and target is clear + this._renderDragEffects(e, dragSource, dropTarget); + this._dropTarget = dropTarget; + } + + /** + * fire `dragleave` on `dragover` targets + * @private + * @param {Event} [e] Event object fired on Event.js shake + */ + _onDragEnter(e) { + const { + target, + targets + } = this.findDragTargets(e); + const options = { + e, + target, + subTargets: targets, + dragSource: this._dragSource + }; + this.fire('dragenter', options); + // fire dragenter on targets + this._fireEnterLeaveEvents(target, options); + } + + /** + * fire `dragleave` on `dragover` targets + * @private + * @param {Event} [e] Event object fired on Event.js shake + */ + _onDragLeave(e) { + const options = { + e, + target: this._draggedoverTarget, + subTargets: this.targets, + dragSource: this._dragSource + }; + this.fire('dragleave', options); + + // fire dragleave on targets + this._fireEnterLeaveEvents(undefined, options); + this._renderDragEffects(e, this._dragSource); + this._dropTarget = undefined; + // clear targets + this.targets = []; + this._hoveredTargets = []; + } + + /** + * `drop:before` is a an event that allows you to schedule logic + * before the `drop` event. Prefer `drop` event always, but if you need + * to run some drop-disabling logic on an event, since there is no way + * to handle event handlers ordering, use `drop:before` + * @private + * @param {Event} e + */ + _onDrop(e) { + const { + target, + targets + } = this.findDragTargets(e); + const options = this._basicEventHandler('drop:before', _objectSpread2({ + e, + target, + subTargets: targets, + dragSource: this._dragSource + }, getEventPoints(this, e))); + // will be set by the drop target + options.didDrop = false; + // will be set by the drop target, used in case options.target refuses the drop + options.dropTarget = undefined; + // fire `drop` + this._basicEventHandler('drop', options); + // inform canvas of the drop + // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it + // use for side effects + this.fire('drop:after', options); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onContextMenu(e) { + const target = this.findTarget(e), + subTargets = this.targets || []; + const options = this._basicEventHandler('contextmenu:before', { + e, + target, + subTargets + }); + // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves + this.stopContextMenu && stopEvent(e); + this._basicEventHandler('contextmenu', options); + return false; + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onDoubleClick(e) { + this._cacheTransformEventData(e); + this._handleEvent(e, 'dblclick'); + this._resetTransformEventData(); + } + + /** + * Return a the id of an event. + * returns either the pointerId or the identifier or 0 for the mouse event + * @private + * @param {Event} evt Event object + */ + getPointerId(evt) { + const changedTouches = evt.changedTouches; + if (changedTouches) { + return changedTouches[0] && changedTouches[0].identifier; + } + if (this.enablePointerEvents) { + return evt.pointerId; + } + return -1; + } + + /** + * Determines if an event has the id of the event that is considered main + * @private + * @param {evt} event Event object + */ + _isMainEvent(evt) { + if (evt.isPrimary === true) { + return true; + } + if (evt.isPrimary === false) { + return false; + } + if (evt.type === 'touchend' && evt.touches.length === 0) { + return true; + } + if (evt.changedTouches) { + return evt.changedTouches[0].identifier === this.mainTouchId; + } + return true; + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onTouchStart(e) { + e.preventDefault(); + if (this.mainTouchId === undefined) { + this.mainTouchId = this.getPointerId(e); + } + this.__onMouseDown(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(canvasElement); + addListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + addListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + // Unbind mousedown to prevent double triggers from touch devices + removeListener(canvasElement, "".concat(eventTypePrefix, "down"), this._onMouseDown); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDown(e) { + this.__onMouseDown(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + removeListener(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + const doc = getDocumentFromElement(canvasElement); + addListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + addListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onTouchEnd(e) { + if (e.touches.length > 0) { + // if there are still touches stop here + return; + } + this.__onMouseUp(e); + this._resetTransformEventData(); + delete this.mainTouchId; + const eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + removeListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + if (this._willAddMouseDown) { + clearTimeout(this._willAddMouseDown); + } + this._willAddMouseDown = setTimeout(() => { + // Wait 400ms before rebinding mousedown to prevent double triggers + // from touch devices + addListener(this.upperCanvasEl, "".concat(eventTypePrefix, "down"), this._onMouseDown); + this._willAddMouseDown = 0; + }, 400); + } + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUp(e) { + this.__onMouseUp(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + if (this._isMainEvent(e)) { + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + removeListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + addListener(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + } + } + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMove(e) { + const activeObject = this.getActiveObject(); + !this.allowTouchScrolling && (!activeObject || + // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before + // we must not prevent the event's default behavior in order for the window to start dragging + !activeObject.shouldStartDragging(e)) && e.preventDefault && e.preventDefault(); + this.__onMouseMove(e); + } + + /** + * @private + */ + _onResize() { + this.calcOffset(); + this._resetTransformEventData(); + } + + /** + * Decides whether the canvas should be redrawn in mouseup and mousedown events. + * @private + * @param {Object} target + */ + _shouldRender(target) { + const activeObject = this.getActiveObject(); + // if just one of them is available or if they are both but are different objects + // this covers: switch of target, from target to no target, selection of target + // multiSelection with key and mouse + return !!activeObject !== !!target || activeObject && target && activeObject !== target; + } + + /** + * Method that defines the actions when mouse is released on canvas. + * The method resets the currentTransform parameters, store the image corner + * position in the image object and render the canvas on top. + * @private + * @param {Event} e Event object fired on mouseup + */ + __onMouseUp(e) { + var _this$_activeObject; + this._cacheTransformEventData(e); + this._handleEvent(e, 'up:before'); + const transform = this._currentTransform; + const isClick = this._isClick; + const target = this._target; + + // if right/middle click just fire events and return + // target undefined will make the _handleEvent search the target + const { + button + } = e; + if (button) { + (this.fireMiddleClick && button === 1 || this.fireRightClick && button === 2) && this._handleEvent(e, 'up'); + this._resetTransformEventData(); + return; + } + if (this.isDrawingMode && this._isCurrentlyDrawing) { + this._onMouseUpInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + let shouldRender = false; + if (transform) { + this._finalizeCurrentTransform(e); + shouldRender = transform.actionPerformed; + } + if (!isClick) { + const targetWasActive = target === this._activeObject; + this.handleSelection(e); + if (!shouldRender) { + shouldRender = this._shouldRender(target) || !targetWasActive && target === this._activeObject; + } + } + let pointer, corner; + if (target) { + const found = target.findControl(this.getViewportPoint(e), isTouchEvent(e)); + const { + key, + control + } = found || {}; + corner = key; + if (target.selectable && target !== this._activeObject && target.activeOn === 'up') { + this.setActiveObject(target, e); + shouldRender = true; + } else if (control) { + const mouseUpHandler = control.getMouseUpHandler(e, target, control); + if (mouseUpHandler) { + pointer = this.getScenePoint(e); + mouseUpHandler.call(control, e, transform, pointer.x, pointer.y); + } + } + target.isMoving = false; + } + // if we are ending up a transform on a different control or a new object + // fire the original mouse up from the corner that started the transform + if (transform && (transform.target !== target || transform.corner !== corner)) { + const originalControl = transform.target && transform.target.controls[transform.corner], + originalMouseUpHandler = originalControl && originalControl.getMouseUpHandler(e, transform.target, originalControl); + pointer = pointer || this.getScenePoint(e); + originalMouseUpHandler && originalMouseUpHandler.call(originalControl, e, transform, pointer.x, pointer.y); + } + this._setCursorFromEvent(e, target); + this._handleEvent(e, 'up'); + this._groupSelector = null; + this._currentTransform = null; + // reset the target information about which corner is selected + target && (target.__corner = undefined); + if (shouldRender) { + this.requestRenderAll(); + } else if (!isClick && !((_this$_activeObject = this._activeObject) !== null && _this$_activeObject !== void 0 && _this$_activeObject.isEditing)) { + this.renderTop(); + } + } + _basicEventHandler(eventType, options) { + const { + target, + subTargets = [] + } = options; + this.fire(eventType, options); + target && target.fire(eventType, options); + for (let i = 0; i < subTargets.length; i++) { + subTargets[i] !== target && subTargets[i].fire(eventType, options); + } + return options; + } + + /** + * @private + * Handle event firing for target and subtargets + * @param {TPointerEvent} e event from mouse + * @param {TPointerEventNames} eventType + */ + _handleEvent(e, eventType) { + const target = this._target, + targets = this.targets || [], + options = _objectSpread2(_objectSpread2({ + e, + target, + subTargets: targets + }, getEventPoints(this, e)), {}, { + transform: this._currentTransform + }, eventType === 'up:before' || eventType === 'up' ? { + isClick: this._isClick, + currentTarget: this.findTarget(e), + // set by the preceding `findTarget` call + currentSubTargets: this.targets + } : {}); + this.fire("mouse:".concat(eventType), options); + // this may be a little be more complicated of what we want to handle + target && target.fire("mouse".concat(eventType), options); + for (let i = 0; i < targets.length; i++) { + targets[i] !== target && targets[i].fire("mouse".concat(eventType), options); + } + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDownInDrawingMode(e) { + this._isCurrentlyDrawing = true; + if (this.getActiveObject()) { + this.discardActiveObject(e); + this.requestRenderAll(); + } + // TODO: this is a scene point so it should be renamed + const pointer = this.getScenePoint(e); + this.freeDrawingBrush && this.freeDrawingBrush.onMouseDown(pointer, { + e, + pointer + }); + this._handleEvent(e, 'down'); + } + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMoveInDrawingMode(e) { + if (this._isCurrentlyDrawing) { + const pointer = this.getScenePoint(e); + this.freeDrawingBrush && this.freeDrawingBrush.onMouseMove(pointer, { + e, + // this is an absolute pointer, the naming is wrong + pointer + }); + } + this.setCursor(this.freeDrawingCursor); + this._handleEvent(e, 'move'); + } + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUpInDrawingMode(e) { + const pointer = this.getScenePoint(e); + if (this.freeDrawingBrush) { + this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({ + e: e, + // this is an absolute pointer, the naming is wrong + pointer + }); + } else { + this._isCurrentlyDrawing = false; + } + this._handleEvent(e, 'up'); + } + + /** + * Method that defines the actions when mouse is clicked on canvas. + * The method inits the currentTransform parameters and renders all the + * canvas so the current image can be placed on the top canvas and the rest + * in on the container one. + * @private + * @param {Event} e Event object fired on mousedown + */ + __onMouseDown(e) { + this._isClick = true; + this._cacheTransformEventData(e); + this._handleEvent(e, 'down:before'); + let target = this._target; + + // if right/middle click just fire events + const { + button + } = e; + if (button) { + (this.fireMiddleClick && button === 1 || this.fireRightClick && button === 2) && this._handleEvent(e, 'down'); + this._resetTransformEventData(); + return; + } + if (this.isDrawingMode) { + this._onMouseDownInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + + // ignore if some object is being transformed at this moment + if (this._currentTransform) { + return; + } + let shouldRender = this._shouldRender(target); + let grouped = false; + if (this.handleMultiSelection(e, target)) { + // active object might have changed while grouping + target = this._activeObject; + grouped = true; + shouldRender = true; + } else if (this._shouldClearSelection(e, target)) { + this.discardActiveObject(e); + } + // we start a group selector rectangle if + // selection is enabled + // and there is no target, or the following 3 conditions are satisfied: + // target is not selectable ( otherwise we selected it ) + // target is not editing + // target is not already selected ( otherwise we drag ) + if (this.selection && (!target || !target.selectable && !target.isEditing && target !== this._activeObject)) { + const p = this.getScenePoint(e); + this._groupSelector = { + x: p.x, + y: p.y, + deltaY: 0, + deltaX: 0 + }; + } + if (target) { + const alreadySelected = target === this._activeObject; + if (target.selectable && target.activeOn === 'down') { + this.setActiveObject(target, e); + } + const handle = target.findControl(this.getViewportPoint(e), isTouchEvent(e)); + if (target === this._activeObject && (handle || !grouped)) { + this._setupCurrentTransform(e, target, alreadySelected); + const control = handle ? handle.control : undefined, + pointer = this.getScenePoint(e), + mouseDownHandler = control && control.getMouseDownHandler(e, target, control); + mouseDownHandler && mouseDownHandler.call(control, e, this._currentTransform, pointer.x, pointer.y); + } + } + // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering + // run before firing the `down` event to give the dev a chance to populate it themselves + shouldRender && (this._objectsToRender = undefined); + this._handleEvent(e, 'down'); + // we must renderAll so that we update the visuals + shouldRender && this.requestRenderAll(); + } + + /** + * reset cache form common information needed during event processing + * @private + */ + _resetTransformEventData() { + this._target = undefined; + this._pointer = undefined; + this._absolutePointer = undefined; + } + + /** + * Cache common information needed during event processing + * @private + * @param {Event} e Event object fired on event + */ + _cacheTransformEventData(e) { + // reset in order to avoid stale caching + this._resetTransformEventData(); + this._pointer = this.getViewportPoint(e); + this._absolutePointer = sendPointToPlane(this._pointer, undefined, this.viewportTransform); + this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e); + } + + /** + * Method that defines the actions when mouse is hovering the canvas. + * The currentTransform parameter will define whether the user is rotating/scaling/translating + * an image or neither of them (only hovering). A group selection is also possible and would cancel + * all any other type of action. + * In case of an image transformation only the top canvas will be rendered. + * @private + * @param {Event} e Event object fired on mousemove + */ + __onMouseMove(e) { + this._isClick = false; + this._cacheTransformEventData(e); + this._handleEvent(e, 'move:before'); + if (this.isDrawingMode) { + this._onMouseMoveInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + const groupSelector = this._groupSelector; + + // We initially clicked in an empty area, so we draw a box for multiple selection + if (groupSelector) { + const pointer = this.getScenePoint(e); + groupSelector.deltaX = pointer.x - groupSelector.x; + groupSelector.deltaY = pointer.y - groupSelector.y; + this.renderTop(); + } else if (!this._currentTransform) { + const target = this.findTarget(e); + this._setCursorFromEvent(e, target); + this._fireOverOutEvents(e, target); + } else { + this._transformObject(e); + } + this.textEditingManager.onMouseMove(e); + this._handleEvent(e, 'move'); + this._resetTransformEventData(); + } + + /** + * Manage the mouseout, mouseover events for the fabric object on the canvas + * @param {Fabric.Object} target the target where the target from the mousemove event + * @param {Event} e Event object fired on mousemove + * @private + */ + _fireOverOutEvents(e, target) { + const _hoveredTarget = this._hoveredTarget, + _hoveredTargets = this._hoveredTargets, + targets = this.targets, + length = Math.max(_hoveredTargets.length, targets.length); + this.fireSyntheticInOutEvents('mouse', { + e, + target, + oldTarget: _hoveredTarget, + fireCanvas: true + }); + for (let i = 0; i < length; i++) { + this.fireSyntheticInOutEvents('mouse', { + e, + target: targets[i], + oldTarget: _hoveredTargets[i] + }); + } + this._hoveredTarget = target; + this._hoveredTargets = this.targets.concat(); + } + + /** + * Manage the dragEnter, dragLeave events for the fabric objects on the canvas + * @param {Fabric.Object} target the target where the target from the onDrag event + * @param {Object} data Event object fired on dragover + * @private + */ + _fireEnterLeaveEvents(target, data) { + const draggedoverTarget = this._draggedoverTarget, + _hoveredTargets = this._hoveredTargets, + targets = this.targets, + length = Math.max(_hoveredTargets.length, targets.length); + this.fireSyntheticInOutEvents('drag', _objectSpread2(_objectSpread2({}, data), {}, { + target, + oldTarget: draggedoverTarget, + fireCanvas: true + })); + for (let i = 0; i < length; i++) { + this.fireSyntheticInOutEvents('drag', _objectSpread2(_objectSpread2({}, data), {}, { + target: targets[i], + oldTarget: _hoveredTargets[i] + })); + } + this._draggedoverTarget = target; + } + + /** + * Manage the synthetic in/out events for the fabric objects on the canvas + * @param {Fabric.Object} target the target where the target from the supported events + * @param {Object} data Event object fired + * @param {Object} config configuration for the function to work + * @param {String} config.targetName property on the canvas where the old target is stored + * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out + * @param {String} config.evtOut name of the event to fire for out + * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in + * @param {String} config.evtIn name of the event to fire for in + * @private + */ + fireSyntheticInOutEvents(type, _ref) { + let { + target, + oldTarget, + fireCanvas, + e + } = _ref, + data = _objectWithoutProperties(_ref, _excluded$9); + const { + targetIn, + targetOut, + canvasIn, + canvasOut + } = syntheticEventConfig[type]; + const targetChanged = oldTarget !== target; + if (oldTarget && targetChanged) { + const outOpt = _objectSpread2(_objectSpread2({}, data), {}, { + e, + target: oldTarget, + nextTarget: target + }, getEventPoints(this, e)); + fireCanvas && this.fire(canvasOut, outOpt); + oldTarget.fire(targetOut, outOpt); + } + if (target && targetChanged) { + const inOpt = _objectSpread2(_objectSpread2({}, data), {}, { + e, + target, + previousTarget: oldTarget + }, getEventPoints(this, e)); + fireCanvas && this.fire(canvasIn, inOpt); + target.fire(targetIn, inOpt); + } + } + + /** + * Method that defines actions when an Event Mouse Wheel + * @param {Event} e Event object fired on mouseup + */ + __onMouseWheel(e) { + this._cacheTransformEventData(e); + this._handleEvent(e, 'wheel'); + this._resetTransformEventData(); + } + + /** + * @private + * @param {Event} e Event fired on mousemove + */ + _transformObject(e) { + const scenePoint = this.getScenePoint(e), + transform = this._currentTransform, + target = transform.target, + // transform pointer to target's containing coordinate plane + // both pointer and object should agree on every point + localPointer = target.group ? sendPointToPlane(scenePoint, undefined, target.group.calcTransformMatrix()) : scenePoint; + transform.shiftKey = e.shiftKey; + transform.altKey = !!this.centeredKey && e[this.centeredKey]; + this._performTransformAction(e, transform, localPointer); + transform.actionPerformed && this.requestRenderAll(); + } + + /** + * @private + */ + _performTransformAction(e, transform, pointer) { + const { + action, + actionHandler, + target + } = transform; + const actionPerformed = !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y); + actionPerformed && target.setCoords(); + + // this object could be created from the function in the control handlers + if (action === 'drag' && actionPerformed) { + transform.target.isMoving = true; + this.setCursor(transform.target.moveCursor || this.moveCursor); + } + transform.actionPerformed = transform.actionPerformed || actionPerformed; + } + + /** + * Sets the cursor depending on where the canvas is being hovered. + * Note: very buggy in Opera + * @param {Event} e Event object + * @param {Object} target Object that the mouse is hovering, if so. + */ + _setCursorFromEvent(e, target) { + if (!target) { + this.setCursor(this.defaultCursor); + return; + } + let hoverCursor = target.hoverCursor || this.hoverCursor; + const activeSelection = isActiveSelection(this._activeObject) ? this._activeObject : null, + // only show proper corner when group selection is not active + corner = (!activeSelection || target.group !== activeSelection) && + // here we call findTargetCorner always with undefined for the touch parameter. + // we assume that if you are using a cursor you do not need to interact with + // the bigger touch area. + target.findControl(this.getViewportPoint(e)); + if (!corner) { + if (target.subTargetCheck) { + // hoverCursor should come from top-most subTarget, + // so we walk the array backwards + this.targets.concat().reverse().map(_target => { + hoverCursor = _target.hoverCursor || hoverCursor; + }); + } + this.setCursor(hoverCursor); + } else { + const control = corner.control; + this.setCursor(control.cursorStyleHandler(e, control, target)); + } + } + + /** + * ## Handles multiple selection + * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively) + * - sets the active object in case it is not set or in case there is a single active object left under active selection. + * --- + * - If the active object is the active selection we add/remove `target` from it + * - If not, add the active object and `target` to the active selection and make it the active object. + * @private + * @param {TPointerEvent} e Event object + * @param {FabricObject} target target of event to select/deselect + * @returns true if grouping occurred + */ + handleMultiSelection(e, target) { + const activeObject = this._activeObject; + const isAS = isActiveSelection(activeObject); + if ( + // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection. + !!activeObject && this._isSelectionKeyPressed(e) && this.selection && + // on top of that the user also has to hit a target that is selectable. + !!target && target.selectable && ( + // group target and active object only if they are different objects + // else we try to find a subtarget of `ActiveSelection` + activeObject !== target || isAS) && ( + // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection` + // if it is then we want to remove `target` from it + isAS || !target.isDescendantOf(activeObject) && !activeObject.isDescendantOf(target)) && + // target accepts selection + !target.onSelect({ + e + }) && + // make sure we are not on top of a control + !activeObject.getActiveControl()) { + if (isAS) { + const prevActiveObjects = activeObject.getObjects(); + if (target === activeObject) { + const pointer = this.getViewportPoint(e); + target = + // first search active objects for a target to remove + this.searchPossibleTargets(prevActiveObjects, pointer) || + // if not found, search under active selection for a target to add + // `prevActiveObjects` will be searched but we already know they will not be found + this.searchPossibleTargets(this._objects, pointer); + // if nothing is found bail out + if (!target || !target.selectable) { + return false; + } + } + if (target.group === activeObject) { + // `target` is part of active selection => remove it + activeObject.remove(target); + this._hoveredTarget = target; + this._hoveredTargets = [...this.targets]; + // if after removing an object we are left with one only... + if (activeObject.size() === 1) { + // activate last remaining object + // deselecting the active selection will remove the remaining object from it + this._setActiveObject(activeObject.item(0), e); + } + } else { + // `target` isn't part of active selection => add it + activeObject.multiSelectAdd(target); + this._hoveredTarget = activeObject; + this._hoveredTargets = [...this.targets]; + } + this._fireSelectionEvents(prevActiveObjects, e); + } else { + activeObject.exitEditing && activeObject.exitEditing(); + // add the active object and the target to the active selection and set it as the active object + const klass = classRegistry.getClass('ActiveSelection'); + const newActiveSelection = new klass([], { + /** + * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd} + * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref + */ + canvas: this + }); + newActiveSelection.multiSelectAdd(activeObject, target); + this._hoveredTarget = newActiveSelection; + // ISSUE 4115: should we consider subTargets here? + // this._hoveredTargets = []; + // this._hoveredTargets = this.targets.concat(); + this._setActiveObject(newActiveSelection, e); + this._fireSelectionEvents([activeObject], e); + } + return true; + } + return false; + } + + /** + * ## Handles selection + * - selects objects that are contained in (and possibly intersecting) the selection bounding box + * - sets the active object + * --- + * runs on mouse up after a mouse move + */ + handleSelection(e) { + if (!this.selection || !this._groupSelector) { + return false; + } + const { + x, + y, + deltaX, + deltaY + } = this._groupSelector, + point1 = new Point(x, y), + point2 = point1.add(new Point(deltaX, deltaY)), + tl = point1.min(point2), + br = point1.max(point2), + size = br.subtract(tl); + const collectedObjects = this.collectObjects({ + left: tl.x, + top: tl.y, + width: size.x, + height: size.y + }, { + includeIntersecting: !this.selectionFullyContained + }); + const objects = + // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down + // should it be handled as is? + point1.eq(point2) ? collectedObjects[0] ? [collectedObjects[0]] : [] : collectedObjects.length > 1 ? collectedObjects.filter(object => !object.onSelect({ + e + })).reverse() : + // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case + collectedObjects; + + // set active object + if (objects.length === 1) { + // set as active object + this.setActiveObject(objects[0], e); + } else if (objects.length > 1) { + // add to active selection and make it the active object + const klass = classRegistry.getClass('ActiveSelection'); + this.setActiveObject(new klass(objects, { + canvas: this + }), e); + } + + // cleanup + this._groupSelector = null; + return true; + } + + /** + * @override clear {@link textEditingManager} + */ + clear() { + this.textEditingManager.clear(); + super.clear(); + } + + /** + * @override clear {@link textEditingManager} + */ + destroy() { + this.removeListeners(); + this.textEditingManager.dispose(); + super.destroy(); + } +} + +const linearDefaultCoords = { + x1: 0, + y1: 0, + x2: 0, + y2: 0 +}; +const radialDefaultCoords = _objectSpread2(_objectSpread2({}, linearDefaultCoords), {}, { + r1: 0, + r2: 0 +}); + +/** + * + * @param value value to check if NaN + * @param [valueIfNaN] + * @returns `fallback` is `value is NaN + */ +const ifNaN = (value, valueIfNaN) => { + return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value; +}; + +const RE_PERCENT = /^(\d+\.\d+)%|(\d+)%$/; +function isPercent(value) { + return value && RE_PERCENT.test(value); +} + +/** + * + * @param value + * @param valueIfNaN + * @returns ∈ [0, 1] + */ +function parsePercent(value, valueIfNaN) { + const parsed = typeof value === 'number' ? value : typeof value === 'string' ? parseFloat(value) / (isPercent(value) ? 100 : 1) : NaN; + return capValue(0, ifNaN(parsed, valueIfNaN), 1); +} + +const RE_KEY_VALUE_PAIRS = /\s*;\s*/; +const RE_KEY_VALUE = /\s*:\s*/; +function parseColorStop(el, multiplier) { + let colorValue, opacity; + const style = el.getAttribute('style'); + if (style) { + const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS); + if (keyValuePairs[keyValuePairs.length - 1] === '') { + keyValuePairs.pop(); + } + for (let i = keyValuePairs.length; i--;) { + const [key, value] = keyValuePairs[i].split(RE_KEY_VALUE).map(s => s.trim()); + if (key === 'stop-color') { + colorValue = value; + } else if (key === 'stop-opacity') { + opacity = value; + } + } + } + const color = new Color(colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)'); + return { + offset: parsePercent(el.getAttribute('offset'), 0), + color: color.toRgb(), + opacity: ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) * color.getAlpha() * multiplier + }; +} +function parseColorStops(el, opacityAttr) { + const colorStops = [], + colorStopEls = el.getElementsByTagName('stop'), + multiplier = parsePercent(opacityAttr, 1); + for (let i = colorStopEls.length; i--;) { + colorStops.push(parseColorStop(colorStopEls[i], multiplier)); + } + return colorStops; +} + +function parseType(el) { + return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT' ? 'linear' : 'radial'; +} +function parseGradientUnits(el) { + return el.getAttribute('gradientUnits') === 'userSpaceOnUse' ? 'pixels' : 'percentage'; +} + +function convertPercentUnitsToValues(valuesToConvert, _ref) { + let { + width, + height, + gradientUnits + } = _ref; + let finalValue; + return Object.keys(valuesToConvert).reduce((acc, prop) => { + const propValue = valuesToConvert[prop]; + if (propValue === 'Infinity') { + finalValue = 1; + } else if (propValue === '-Infinity') { + finalValue = 0; + } else { + finalValue = typeof propValue === 'string' ? parseFloat(propValue) : propValue; + if (typeof propValue === 'string' && isPercent(propValue)) { + finalValue *= 0.01; + if (gradientUnits === 'pixels') { + // then we need to fix those percentages here in svg parsing + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + finalValue *= width; + } + if (prop === 'y1' || prop === 'y2') { + finalValue *= height; + } + } + } + } + acc[prop] = finalValue; + return acc; + }, {}); +} +function getValue(el, key) { + return el.getAttribute(key); +} +function parseLinearCoords(el) { + return { + x1: getValue(el, 'x1') || 0, + y1: getValue(el, 'y1') || 0, + x2: getValue(el, 'x2') || '100%', + y2: getValue(el, 'y2') || 0 + }; +} +function parseRadialCoords(el) { + return { + x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%', + y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%', + r1: 0, + x2: getValue(el, 'cx') || '50%', + y2: getValue(el, 'cy') || '50%', + r2: getValue(el, 'r') || '50%' + }; +} +function parseCoords(el, size) { + return convertPercentUnitsToValues(parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el), _objectSpread2(_objectSpread2({}, size), {}, { + gradientUnits: parseGradientUnits(el) + })); +} + +/** + * Gradient class + * @class Gradient + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} + */ +class Gradient { + constructor(options) { + const { + type = 'linear', + gradientUnits = 'pixels', + coords = {}, + colorStops = [], + offsetX = 0, + offsetY = 0, + gradientTransform, + id + } = options || {}; + Object.assign(this, { + type, + gradientUnits, + coords: _objectSpread2(_objectSpread2({}, type === 'radial' ? radialDefaultCoords : linearDefaultCoords), coords), + colorStops, + offsetX, + offsetY, + gradientTransform, + id: id ? "".concat(id, "_").concat(uid()) : uid() + }); + } + + /** + * Adds another colorStop + * @param {Record} colorStop Object with offset and color + * @return {Gradient} thisArg + */ + addColorStop(colorStops) { + for (const position in colorStops) { + const color = new Color(colorStops[position]); + this.colorStops.push({ + offset: parseFloat(position), + color: color.toRgb(), + opacity: color.getAlpha() + }); + } + return this; + } + + /** + * Returns object representation of a gradient + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {object} + */ + toObject(propertiesToInclude) { + return _objectSpread2(_objectSpread2({}, pick(this, propertiesToInclude)), {}, { + type: this.type, + coords: _objectSpread2({}, this.coords), + colorStops: this.colorStops.map(colorStop => _objectSpread2({}, colorStop)), + offsetX: this.offsetX, + offsetY: this.offsetY, + gradientUnits: this.gradientUnits, + gradientTransform: this.gradientTransform ? [...this.gradientTransform] : undefined + }); + } + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an gradient + * @param {FabricObject} object Object to create a gradient for + * @return {String} SVG representation of an gradient (linear/radial) + */ + toSVG(object) { + let { + additionalTransform: preTransform + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const markup = [], + transform = this.gradientTransform ? this.gradientTransform.concat() : iMatrix.concat(), + gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox'; + // colorStops must be sorted ascending, and guarded against deep mutations + const colorStops = this.colorStops.map(colorStop => _objectSpread2({}, colorStop)).sort((a, b) => { + return a.offset - b.offset; + }); + let offsetX = -this.offsetX, + offsetY = -this.offsetY; + if (gradientUnits === 'objectBoundingBox') { + offsetX /= object.width; + offsetY /= object.height; + } else { + offsetX += object.width / 2; + offsetY += object.height / 2; + } + // todo what about polygon/polyline? + if (isPath(object) && this.gradientUnits !== 'percentage') { + offsetX -= object.pathOffset.x; + offsetY -= object.pathOffset.y; + } + transform[4] -= offsetX; + transform[5] -= offsetY; + const commonAttributes = ["id=\"SVGID_".concat(this.id, "\""), "gradientUnits=\"".concat(gradientUnits, "\""), "gradientTransform=\"".concat(preTransform ? preTransform + ' ' : '').concat(matrixToSVG(transform), "\""), ''].join(' '); + if (this.type === 'linear') { + const { + x1, + y1, + x2, + y2 + } = this.coords; + markup.push('\n'); + } else if (this.type === 'radial') { + const { + x1, + y1, + x2, + y2, + r1, + r2 + } = this.coords; + const needsSwap = r1 > r2; + // svg radial gradient has just 1 radius. the biggest. + markup.push('\n'); + if (needsSwap) { + // svg goes from internal to external radius. if radius are inverted, swap color stops. + colorStops.reverse(); // mutates array + colorStops.forEach(colorStop => { + colorStop.offset = 1 - colorStop.offset; + }); + } + const minRadius = Math.min(r1, r2); + if (minRadius > 0) { + // i have to shift all colorStops and add new one in 0. + const maxRadius = Math.max(r1, r2), + percentageShift = minRadius / maxRadius; + colorStops.forEach(colorStop => { + colorStop.offset += percentageShift * (1 - colorStop.offset); + }); + } + } + colorStops.forEach(_ref => { + let { + color, + offset, + opacity + } = _ref; + markup.push('\n'); + }); + markup.push(this.type === 'linear' ? '' : '', '\n'); + return markup.join(''); + } + /* _TO_SVG_END_ */ + + /** + * Returns an instance of CanvasGradient + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {CanvasGradient} + */ + toLive(ctx) { + const { + x1, + y1, + x2, + y2, + r1, + r2 + } = this.coords; + const gradient = this.type === 'linear' ? ctx.createLinearGradient(x1, y1, x2, y2) : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2); + this.colorStops.forEach(_ref2 => { + let { + color, + opacity, + offset + } = _ref2; + gradient.addColorStop(offset, typeof opacity !== 'undefined' ? new Color(color).setAlpha(opacity).toRgba() : color); + }); + return gradient; + } + static async fromObject(options) { + const { + colorStops, + gradientTransform + } = options; + return new this(_objectSpread2(_objectSpread2({}, options), {}, { + colorStops: colorStops ? colorStops.map(colorStop => _objectSpread2({}, colorStop)) : undefined, + gradientTransform: gradientTransform ? [...gradientTransform] : undefined + })); + } + + /* _FROM_SVG_START_ */ + /** + * Returns {@link Gradient} instance from an SVG element + * @static + * @memberOf Gradient + * @param {SVGGradientElement} el SVG gradient element + * @param {FabricObject} instance + * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity. + * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients + * that uses gradientUnits as 'userSpaceOnUse' and percentages. + * @return {Gradient} Gradient instance + * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement + * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement + * + * @example + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + */ + static fromElement(el, instance, svgOptions) { + const gradientUnits = parseGradientUnits(el); + const center = instance._findCenterFromElement(); + return new this(_objectSpread2({ + id: el.getAttribute('id') || undefined, + type: parseType(el), + coords: parseCoords(el, { + width: svgOptions.viewBoxWidth || svgOptions.width, + height: svgOptions.viewBoxHeight || svgOptions.height + }), + colorStops: parseColorStops(el, svgOptions.opacity), + gradientUnits, + gradientTransform: parseTransformAttribute(el.getAttribute('gradientTransform') || '') + }, gradientUnits === 'pixels' ? { + offsetX: instance.width / 2 - center.x, + offsetY: instance.height / 2 - center.y + } : { + offsetX: 0, + offsetY: 0 + })); + } + /* _FROM_SVG_END_ */ +} +/** + * Horizontal offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ +/** + * Vertical offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ +/** + * A transform matrix to apply to the gradient before painting. + * Imported from svg gradients, is not applied with the current transform in the center. + * Before this transform is applied, the origin point is at the top left corner of the object + * plus the addition of offsetY and offsetX. + * @type Number[] + * @default null + */ +/** + * coordinates units for coords. + * If `pixels`, the number of coords are in the same unit of width / height. + * If set as `percentage` the coords are still a number, but 1 means 100% of width + * for the X and 100% of the height for the y. It can be bigger than 1 and negative. + * allowed values pixels or percentage. + * @type GradientUnits + * @default 'pixels' + */ +/** + * Gradient type linear or radial + * @type GradientType + * @default 'linear' + */ +/** + * Defines how the gradient is located in space and spread + * @type GradientCoords + */ +/** + * Defines how many colors a gradient has and how they are located on the axis + * defined by coords + * @type GradientCoords + */ +/** + * If true, this object will not be exported during the serialization of a canvas + * @type boolean + */ +/** + * ID used for SVG export functionalities + * @type number | string + */ +_defineProperty(Gradient, "type", 'Gradient'); +classRegistry.setClass(Gradient, 'gradient'); +classRegistry.setClass(Gradient, 'linear'); +classRegistry.setClass(Gradient, 'radial'); + +const _excluded$8 = ["type", "source", "patternTransform"]; + +/** + * @see {@link http://fabricjs.com/patterns demo} + * @see {@link http://fabricjs.com/dynamic-patterns demo} + */ +class Pattern { + /** + * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern' + * or utils like isPattern, or instance of to indentify a pattern in your code. + * Will be removed in future versiones + * @TODO add sustainable warning message + * @type string + * @deprecated + */ + get type() { + return 'pattern'; + } + set type(value) { + log('warn', 'Setting type has no effect', value); + } + + /** + * @type PatternRepeat + * @defaults + */ + + /** + * transform matrix to change the pattern, imported from svgs. + * @todo verify if using the identity matrix as default makes the rest of the code more easy + * @type Array + * @default + */ + + /** + * The actual pixel source of the pattern + */ + + /** + * If true, this object will not be exported during the serialization of a canvas + * @type boolean + */ + + /** + * ID used for SVG export functionalities + * @type number + */ + + /** + * Constructor + * @param {Object} [options] Options object + * @param {option.source} [source] the pattern source, eventually empty or a drawable + */ + constructor(options) { + _defineProperty(this, "repeat", 'repeat'); + /** + * Pattern horizontal offset from object's left/top corner + * @type Number + * @default + */ + _defineProperty(this, "offsetX", 0); + /** + * Pattern vertical offset from object's left/top corner + * @type Number + * @default + */ + _defineProperty(this, "offsetY", 0); + /** + * @type TCrossOrigin + * @default + */ + _defineProperty(this, "crossOrigin", ''); + this.id = uid(); + Object.assign(this, options); + } + + /** + * @returns true if {@link source} is an element + */ + isImageSource() { + return !!this.source && typeof this.source.src === 'string'; + } + + /** + * @returns true if {@link source} is a element + */ + isCanvasSource() { + return !!this.source && !!this.source.toDataURL; + } + sourceToString() { + return this.isImageSource() ? this.source.src : this.isCanvasSource() ? this.source.toDataURL() : ''; + } + + /** + * Returns an instance of CanvasPattern + * @param {CanvasRenderingContext2D} ctx Context to create pattern + * @return {CanvasPattern} + */ + toLive(ctx) { + if ( + // if the image failed to load, return, and allow rest to continue loading + !this.source || + // if an image + this.isImageSource() && (!this.source.complete || this.source.naturalWidth === 0 || this.source.naturalHeight === 0)) { + return null; + } + return ctx.createPattern(this.source, this.repeat); + } + + /** + * Returns object representation of a pattern + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {object} Object representation of a pattern instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const { + repeat, + crossOrigin + } = this; + return _objectSpread2(_objectSpread2({}, pick(this, propertiesToInclude)), {}, { + type: 'pattern', + source: this.sourceToString(), + repeat, + crossOrigin, + offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS), + offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS), + patternTransform: this.patternTransform ? [...this.patternTransform] : null + }); + } + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a pattern + */ + toSVG(_ref) { + let { + width, + height + } = _ref; + const { + source: patternSource, + repeat, + id + } = this, + patternOffsetX = ifNaN(this.offsetX / width, 0), + patternOffsetY = ifNaN(this.offsetY / height, 0), + patternWidth = repeat === 'repeat-y' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetX || 0) : ifNaN(patternSource.width / width, 0), + patternHeight = repeat === 'repeat-x' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetY || 0) : ifNaN(patternSource.height / height, 0); + return [""), ""), "", ''].join('\n'); + } + /* _TO_SVG_END_ */ + + static async fromObject(_ref2, options) { + let { + type, + source, + patternTransform + } = _ref2, + otherOptions = _objectWithoutProperties(_ref2, _excluded$8); + const img = await loadImage(source, _objectSpread2(_objectSpread2({}, options), {}, { + crossOrigin: otherOptions.crossOrigin + })); + return new this(_objectSpread2(_objectSpread2({}, otherOptions), {}, { + patternTransform: patternTransform && patternTransform.slice(0), + source: img + })); + } +} +_defineProperty(Pattern, "type", 'Pattern'); +classRegistry.setClass(Pattern); +// kept for compatibility reason +classRegistry.setClass(Pattern, 'pattern'); + +/** + * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} + */ +class BaseBrush { + /** + * @todo add type + */ + + constructor(canvas) { + /** + * Color of a brush + * @type String + * @default + */ + _defineProperty(this, "color", 'rgb(0, 0, 0)'); + /** + * Width of a brush, has to be a Number, no string literals + * @type Number + * @default + */ + _defineProperty(this, "width", 1); + /** + * Shadow object representing shadow of this shape. + * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), + * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 + * @type Shadow + * @default + */ + _defineProperty(this, "shadow", null); + /** + * Line endings style of a brush (one of "butt", "round", "square") + * @type String + * @default + */ + _defineProperty(this, "strokeLineCap", 'round'); + /** + * Corner style of a brush (one of "bevel", "round", "miter") + * @type String + * @default + */ + _defineProperty(this, "strokeLineJoin", 'round'); + /** + * Maximum miter length (used for strokeLineJoin = "miter") of a brush's + * @type Number + * @default + */ + _defineProperty(this, "strokeMiterLimit", 10); + /** + * Stroke Dash Array. + * @type Array + * @default + */ + _defineProperty(this, "strokeDashArray", null); + /** + * When `true`, the free drawing is limited to the whiteboard size. Default to false. + * @type Boolean + * @default false + */ + _defineProperty(this, "limitedToCanvasSize", false); + this.canvas = canvas; + } + + /** + * @returns true if brush should continue blocking interaction + */ + + /** + * Sets brush styles + * @private + * @param {CanvasRenderingContext2D} ctx + */ + _setBrushStyles(ctx) { + ctx.strokeStyle = this.color; + ctx.lineWidth = this.width; + ctx.lineCap = this.strokeLineCap; + ctx.miterLimit = this.strokeMiterLimit; + ctx.lineJoin = this.strokeLineJoin; + ctx.setLineDash(this.strokeDashArray || []); + } + + /** + * Sets the transformation on given context + * @param {CanvasRenderingContext2D} ctx context to render on + * @private + */ + _saveAndTransform(ctx) { + const v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + } + needsFullRender() { + const color = new Color(this.color); + return color.getAlpha() < 1 || !!this.shadow; + } + + /** + * Sets brush shadow styles + * @private + */ + _setShadow() { + if (!this.shadow || !this.canvas) { + return; + } + const canvas = this.canvas, + shadow = this.shadow, + ctx = canvas.contextTop, + zoom = canvas.getZoom() * canvas.getRetinaScaling(); + ctx.shadowColor = shadow.color; + ctx.shadowBlur = shadow.blur * zoom; + ctx.shadowOffsetX = shadow.offsetX * zoom; + ctx.shadowOffsetY = shadow.offsetY * zoom; + } + + /** + * Removes brush shadow styles + * @private + */ + _resetShadow() { + const ctx = this.canvas.contextTop; + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + } + + /** + * Check is pointer is outside canvas boundaries + * @param {Object} pointer + * @private + */ + _isOutSideCanvas(pointer) { + return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight(); + } +} + +const _excluded$7 = ["path", "left", "top"], + _excluded2$2 = ["d"]; +class Path extends FabricObject { + /** + * Constructor + * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding "command" tokens) + * @param {Partial} [options] Options object + * @return {Path} thisArg + */ + constructor(path) { + let _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + { + path: _, + left, + top + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$7); + super(); + Object.assign(this, Path.ownDefaults); + this.setOptions(options); + this._setPath(path || [], true); + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + + /** + * @private + * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding "command" tokens) + * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box + * @returns {Point} top left position of the bounding box, useful for complementary positioning + */ + _setPath(path, adjustPosition) { + this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path)); + this.setBoundingBox(adjustPosition); + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates, by look at the polyline/polygon points. + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + const bbox = this._calcBoundsFromPath(); + return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render path on + */ + _renderPathCommands(ctx) { + const l = -this.pathOffset.x, + t = -this.pathOffset.y; + ctx.beginPath(); + for (const command of this.path) { + switch (command[0] // first letter + ) { + case 'L': + // lineto, absolute + ctx.lineTo(command[1] + l, command[2] + t); + break; + case 'M': + // moveTo, absolute + ctx.moveTo(command[1] + l, command[2] + t); + break; + case 'C': + // bezierCurveTo, absolute + ctx.bezierCurveTo(command[1] + l, command[2] + t, command[3] + l, command[4] + t, command[5] + l, command[6] + t); + break; + case 'Q': + // quadraticCurveTo, absolute + ctx.quadraticCurveTo(command[1] + l, command[2] + t, command[3] + l, command[4] + t); + break; + case 'Z': + ctx.closePath(); + break; + } + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render path on + */ + _render(ctx) { + this._renderPathCommands(ctx); + this._renderPaintInOrder(ctx); + } + + /** + * Returns string representation of an instance + * @return {string} string representation of an instance + */ + toString() { + return "#"); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), {}, { + path: this.path.map(pathCmd => pathCmd.slice()) + }); + } + + /** + * Returns dataless object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const o = this.toObject(propertiesToInclude); + if (this.sourcePath) { + delete o.path; + o.sourcePath = this.sourcePath; + } + return o; + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const path = joinPath(this.path, config.NUM_FRACTION_DIGITS); + return ['\n")]; + } + + /** + * @private + * @return the path command's translate transform attribute + */ + _getOffsetTransform() { + const digits = config.NUM_FRACTION_DIGITS; + return " translate(".concat(toFixed(-this.pathOffset.x, digits), ", ").concat(toFixed(-this.pathOffset.y, digits), ")"); + } + + /** + * Returns svg clipPath representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {string} svg representation of an instance + */ + toClipPathSVG(reviver) { + const additionalTransform = this._getOffsetTransform(); + return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), { + reviver, + additionalTransform: additionalTransform + }); + } + + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {string} svg representation of an instance + */ + toSVG(reviver) { + const additionalTransform = this._getOffsetTransform(); + return this._createBaseSVGMarkup(this._toSVG(), { + reviver, + additionalTransform: additionalTransform + }); + } + + /** + * Returns number representation of an instance complexity + * @return {number} complexity of this instance + */ + complexity() { + return this.path.length; + } + setDimensions() { + this.setBoundingBox(); + } + setBoundingBox(adjustPosition) { + const { + width, + height, + pathOffset + } = this._calcDimensions(); + this.set({ + width, + height, + pathOffset + }); + // using pathOffset because it match the use case. + // if pathOffset change here we need to use left + width/2 , top + height/2 + adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER); + } + _calcBoundsFromPath() { + const bounds = []; + let subpathStartX = 0, + subpathStartY = 0, + x = 0, + // current x + y = 0; // current y + + for (const command of this.path) { + // current instruction + switch (command[0] // first letter + ) { + case 'L': + // lineto, absolute + x = command[1]; + y = command[2]; + bounds.push({ + x: subpathStartX, + y: subpathStartY + }, { + x, + y + }); + break; + case 'M': + // moveTo, absolute + x = command[1]; + y = command[2]; + subpathStartX = x; + subpathStartY = y; + break; + case 'C': + // bezierCurveTo, absolute + bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[3], command[4], command[5], command[6])); + x = command[5]; + y = command[6]; + break; + case 'Q': + // quadraticCurveTo, absolute + bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[1], command[2], command[3], command[4])); + x = command[3]; + y = command[4]; + break; + case 'Z': + x = subpathStartX; + y = subpathStartY; + break; + } + } + return makeBoundingBoxFromPoints(bounds); + } + + /** + * @private + */ + _calcDimensions() { + const bbox = this._calcBoundsFromPath(); + return _objectSpread2(_objectSpread2({}, bbox), {}, { + pathOffset: new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2) + }); + } + + /** + * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`) + * @static + * @memberOf Path + * @see http://www.w3.org/TR/SVG/paths.html#PathElement + */ + + /** + * Creates an instance of Path from an object + * @static + * @memberOf Path + * @param {Object} object + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(object, { + extraParam: 'path' + }); + } + + /** + * Creates an instance of Path from an SVG element + * @static + * @memberOf Path + * @param {HTMLElement} element to parse + * @param {Partial} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + d + } = _parseAttributes, + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded2$2); + return new this(d, _objectSpread2(_objectSpread2(_objectSpread2({}, parsedAttributes), options), {}, { + // we pass undefined to instruct the constructor to position the object using the bbox + left: undefined, + top: undefined + })); + } +} +/** + * Array of path points + * @type Array + * @default + */ +_defineProperty(Path, "type", 'Path'); +_defineProperty(Path, "cacheProperties", [...cacheProperties, 'path', 'fillRule']); +_defineProperty(Path, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'd']); +classRegistry.setClass(Path); +classRegistry.setSVGClass(Path); + +/* _FROM_SVG_START_ */ + +/** + * @private + * @param {TSimplePathData} pathData SVG path commands + * @returns {boolean} + */ +function isEmptySVGPath(pathData) { + return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0'; +} +class PencilBrush extends BaseBrush { + constructor(canvas) { + super(canvas); + /** + * Discard points that are less than `decimate` pixel distant from each other + * @type Number + * @default 0.4 + */ + _defineProperty(this, "decimate", 0.4); + /** + * Draws a straight line between last recorded point to current pointer + * Used for `shift` functionality + * + * @type boolean + * @default false + */ + _defineProperty(this, "drawStraightLine", false); + /** + * The event modifier key that makes the brush draw a straight line. + * If `null` or 'none' or any other string that is not a modifier key the feature is disabled. + * @type {ModifierKey | undefined | null} + */ + _defineProperty(this, "straightLineKey", 'shiftKey'); + this._points = []; + this._hasStraightLine = false; + } + needsFullRender() { + return super.needsFullRender() || this._hasStraightLine; + } + static drawSegment(ctx, p1, p2) { + const midPoint = p1.midPointFrom(p2); + ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); + return midPoint; + } + + /** + * Invoked on mouse down + * @param {Point} pointer + */ + onMouseDown(pointer, _ref) { + let { + e + } = _ref; + if (!this.canvas._isMainEvent(e)) { + return; + } + this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey]; + this._prepareForDrawing(pointer); + // capture coordinates immediately + // this allows to draw dots (when movement never occurs) + this._addPoint(pointer); + this._render(); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer, _ref2) { + let { + e + } = _ref2; + if (!this.canvas._isMainEvent(e)) { + return; + } + this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey]; + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + if (this._addPoint(pointer) && this._points.length > 1) { + if (this.needsFullRender()) { + // redraw curve + // clear top canvas + this.canvas.clearContext(this.canvas.contextTop); + this._render(); + } else { + const points = this._points, + length = points.length, + ctx = this.canvas.contextTop; + // draw the curve update + this._saveAndTransform(ctx); + if (this.oldEnd) { + ctx.beginPath(); + ctx.moveTo(this.oldEnd.x, this.oldEnd.y); + } + this.oldEnd = PencilBrush.drawSegment(ctx, points[length - 2], points[length - 1]); + ctx.stroke(); + ctx.restore(); + } + } + } + + /** + * Invoked on mouse up + */ + onMouseUp(_ref3) { + let { + e + } = _ref3; + if (!this.canvas._isMainEvent(e)) { + return true; + } + this.drawStraightLine = false; + this.oldEnd = undefined; + this._finalizeAndAddPath(); + return false; + } + + /** + * @private + * @param {Point} pointer Actual mouse position related to the canvas. + */ + _prepareForDrawing(pointer) { + this._reset(); + this._addPoint(pointer); + this.canvas.contextTop.moveTo(pointer.x, pointer.y); + } + + /** + * @private + * @param {Point} point Point to be added to points array + */ + _addPoint(point) { + if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { + return false; + } + if (this.drawStraightLine && this._points.length > 1) { + this._hasStraightLine = true; + this._points.pop(); + } + this._points.push(point); + return true; + } + + /** + * Clear points array and set contextTop canvas style. + * @private + */ + _reset() { + this._points = []; + this._setBrushStyles(this.canvas.contextTop); + this._setShadow(); + this._hasStraightLine = false; + } + + /** + * Draw a smooth path on the topCanvas using quadraticCurveTo + * @private + * @param {CanvasRenderingContext2D} [ctx] + */ + _render() { + let ctx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.canvas.contextTop; + let p1 = this._points[0], + p2 = this._points[1]; + this._saveAndTransform(ctx); + ctx.beginPath(); + //if we only have 2 points in the path and they are the same + //it means that the user only clicked the canvas without moving the mouse + //then we should be drawing a dot. A path isn't drawn between two identical dots + //that's why we set them apart a bit + if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { + const width = this.width / 1000; + p1.x -= width; + p2.x += width; + } + ctx.moveTo(p1.x, p1.y); + for (let i = 1; i < this._points.length; i++) { + // we pick the point between pi + 1 & pi + 2 as the + // end point and p1 as our control point. + PencilBrush.drawSegment(ctx, p1, p2); + p1 = this._points[i]; + p2 = this._points[i + 1]; + } + // Draw last line as a straight line while + // we wait for the next point to be able to calculate + // the bezier control point + ctx.lineTo(p1.x, p1.y); + ctx.stroke(); + ctx.restore(); + } + + /** + * Converts points to SVG path + * @param {Point[]} points Array of points + * @return {TSimplePathData} SVG path commands + */ + convertPointsToSVGPath(points) { + const correction = this.width / 1000; + return getSmoothPathFromPoints(points, correction); + } + + /** + * Creates a Path object to add on canvas + * @param {TSimplePathData} pathData Path data + * @return {Path} Path to add on canvas + */ + createPath(pathData) { + const path = new Path(pathData, { + fill: null, + stroke: this.color, + strokeWidth: this.width, + strokeLineCap: this.strokeLineCap, + strokeMiterLimit: this.strokeMiterLimit, + strokeLineJoin: this.strokeLineJoin, + strokeDashArray: this.strokeDashArray + }); + if (this.shadow) { + this.shadow.affectStroke = true; + path.shadow = new Shadow(this.shadow); + } + return path; + } + + /** + * Decimate points array with the decimate value + */ + decimatePoints(points, distance) { + if (points.length <= 2) { + return points; + } + let lastPoint = points[0], + cDistance; + const zoom = this.canvas.getZoom(), + adjustedDistance = Math.pow(distance / zoom, 2), + l = points.length - 1, + newPoints = [lastPoint]; + for (let i = 1; i < l - 1; i++) { + cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2); + if (cDistance >= adjustedDistance) { + lastPoint = points[i]; + newPoints.push(lastPoint); + } + } + // Add the last point from the original line to the end of the array. + // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point. + newPoints.push(points[l]); + return newPoints; + } + + /** + * On mouseup after drawing the path on contextTop canvas + * we use the points captured to create an new Path object + * and add it to the canvas. + */ + _finalizeAndAddPath() { + const ctx = this.canvas.contextTop; + ctx.closePath(); + if (this.decimate) { + this._points = this.decimatePoints(this._points, this.decimate); + } + const pathData = this.convertPointsToSVGPath(this._points); + if (isEmptySVGPath(pathData)) { + // do not create 0 width/height paths, as they are + // rendered inconsistently across browsers + // Firefox 4, for example, renders a dot, + // whereas Chrome 10 renders nothing + this.canvas.requestRenderAll(); + return; + } + const path = this.createPath(pathData); + this.canvas.clearContext(this.canvas.contextTop); + this.canvas.fire('before:path:created', { + path: path + }); + this.canvas.add(path); + this.canvas.requestRenderAll(); + path.setCoords(); + this._resetShadow(); + + // fire event 'path' created + this.canvas.fire('path:created', { + path: path + }); + } +} + +const _excluded$6 = ["left", "top", "radius"]; +const CIRCLE_PROPS = ['radius', 'startAngle', 'endAngle', 'counterClockwise']; +const circleDefaultValues = { + radius: 0, + startAngle: 0, + endAngle: 360, + counterClockwise: false +}; +class Circle extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Circle.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Circle.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {String} key + * @param {*} value + */ + _set(key, value) { + super._set(key, value); + if (key === 'radius') { + this.setRadius(value); + } + return this; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + */ + _render(ctx) { + ctx.beginPath(); + ctx.arc(0, 0, this.radius, degreesToRadians(this.startAngle), degreesToRadians(this.endAngle), this.counterClockwise); + this._renderPaintInOrder(ctx); + } + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusX() { + return this.get('radius') * this.get(SCALE_X); + } + + /** + * Returns vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusY() { + return this.get('radius') * this.get(SCALE_Y); + } + + /** + * Sets radius of an object (and updates width accordingly) + */ + setRadius(value) { + this.radius = value; + this.set({ + width: value * 2, + height: value * 2 + }); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]); + } + + /* _TO_SVG_START_ */ + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const angle = (this.endAngle - this.startAngle) % 360; + if (angle === 0) { + return ['\n']; + } else { + const { + radius + } = this; + const start = degreesToRadians(this.startAngle), + end = degreesToRadians(this.endAngle), + startX = cos(start) * radius, + startY = sin(start) * radius, + endX = cos(end) * radius, + endY = sin(end) * radius, + largeFlag = angle > 180 ? 1 : 0, + sweepFlag = this.counterClockwise ? 0 : 1; + return ["\n']; + } + } + /* _TO_SVG_END_ */ + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement}) + * @static + * @memberOf Circle + * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement + */ + + /** + * Returns {@link Circle} instance from an SVG element + * @static + * @memberOf Circle + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Partial Circle object to default missing properties on the element. + * @throws {Error} If value of `r` attribute is missing or invalid + */ + static async fromElement(element, options, cssRules) { + const _ref = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + left = 0, + top = 0, + radius = 0 + } = _ref, + otherParsedAttributes = _objectWithoutProperties(_ref, _excluded$6); + + // this probably requires to be fixed for default origins not being top/left. + + return new this(_objectSpread2(_objectSpread2({}, otherParsedAttributes), {}, { + radius, + left: left - radius, + top: top - radius + })); + } + + /* _FROM_SVG_END_ */ + + /** + * @todo how do we declare this?? + */ + static fromObject(object) { + return super._fromObject(object); + } +} +_defineProperty(Circle, "type", 'Circle'); +_defineProperty(Circle, "cacheProperties", [...cacheProperties, ...CIRCLE_PROPS]); +_defineProperty(Circle, "ownDefaults", circleDefaultValues); +_defineProperty(Circle, "ATTRIBUTE_NAMES", ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES]); +classRegistry.setClass(Circle); +classRegistry.setSVGClass(Circle); + +class CircleBrush extends BaseBrush { + constructor(canvas) { + super(canvas); + /** + * Width of a brush + * @type Number + * @default + */ + _defineProperty(this, "width", 10); + this.points = []; + } + + /** + * Invoked inside on mouse down and mouse move + * @param {Point} pointer + */ + drawDot(pointer) { + const point = this.addPoint(pointer), + ctx = this.canvas.contextTop; + this._saveAndTransform(ctx); + this.dot(ctx, point); + ctx.restore(); + } + dot(ctx, point) { + ctx.fillStyle = point.fill; + ctx.beginPath(); + ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); + ctx.closePath(); + ctx.fill(); + } + + /** + * Invoked on mouse down + */ + onMouseDown(pointer) { + this.points = []; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + this.drawDot(pointer); + } + + /** + * Render the full state of the brush + * @private + */ + _render() { + const ctx = this.canvas.contextTop, + points = this.points; + this._saveAndTransform(ctx); + for (let i = 0; i < points.length; i++) { + this.dot(ctx, points[i]); + } + ctx.restore(); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer) { + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + if (this.needsFullRender()) { + this.canvas.clearContext(this.canvas.contextTop); + this.addPoint(pointer); + this._render(); + } else { + this.drawDot(pointer); + } + } + + /** + * Invoked on mouse up + */ + onMouseUp() { + const originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + const circles = []; + for (let i = 0; i < this.points.length; i++) { + const point = this.points[i], + circle = new Circle({ + radius: point.radius, + left: point.x, + top: point.y, + originX: CENTER, + originY: CENTER, + fill: point.fill + }); + this.shadow && (circle.shadow = new Shadow(this.shadow)); + circles.push(circle); + } + const group = new Group(circles, { + canvas: this.canvas + }); + this.canvas.fire('before:path:created', { + path: group + }); + this.canvas.add(group); + this.canvas.fire('path:created', { + path: group + }); + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.requestRenderAll(); + } + + /** + * @param {Object} pointer + * @return {Point} Just added pointer point + */ + addPoint(_ref) { + let { + x, + y + } = _ref; + const pointerPoint = { + x, + y, + radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, + fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba() + }; + this.points.push(pointerPoint); + return pointerPoint; + } +} + +/** + * + * @param rects + * @returns + */ +function getUniqueRects(rects) { + const uniqueRects = {}; + const uniqueRectsArray = []; + for (let i = 0, key; i < rects.length; i++) { + key = "".concat(rects[i].left).concat(rects[i].top); + if (!uniqueRects[key]) { + uniqueRects[key] = true; + uniqueRectsArray.push(rects[i]); + } + } + return uniqueRectsArray; +} +class SprayBrush extends BaseBrush { + /** + * Constructor + * @param {Canvas} canvas + * @return {SprayBrush} Instance of a spray brush + */ + constructor(canvas) { + super(canvas); + /** + * Width of a spray + * @type Number + * @default + */ + _defineProperty(this, "width", 10); + /** + * Density of a spray (number of dots per chunk) + * @type Number + * @default + */ + _defineProperty(this, "density", 20); + /** + * Width of spray dots + * @type Number + * @default + */ + _defineProperty(this, "dotWidth", 1); + /** + * Width variance of spray dots + * @type Number + * @default + */ + _defineProperty(this, "dotWidthVariance", 1); + /** + * Whether opacity of a dot should be random + * @type Boolean + * @default + */ + _defineProperty(this, "randomOpacity", false); + /** + * Whether overlapping dots (rectangles) should be removed (for performance reasons) + * @type Boolean + * @default + */ + _defineProperty(this, "optimizeOverlapping", true); + this.sprayChunks = []; + this.sprayChunk = []; + } + + /** + * Invoked on mouse down + * @param {Point} pointer + */ + onMouseDown(pointer) { + this.sprayChunks = []; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + this.addSprayChunk(pointer); + this.renderChunck(this.sprayChunk); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer) { + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + this.addSprayChunk(pointer); + this.renderChunck(this.sprayChunk); + } + + /** + * Invoked on mouse up + */ + onMouseUp() { + const originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + const rects = []; + for (let i = 0; i < this.sprayChunks.length; i++) { + const sprayChunk = this.sprayChunks[i]; + for (let j = 0; j < sprayChunk.length; j++) { + const chunck = sprayChunk[j]; + const rect = new Rect({ + width: chunck.width, + height: chunck.width, + left: chunck.x + 1, + top: chunck.y + 1, + originX: CENTER, + originY: CENTER, + fill: this.color + }); + rects.push(rect); + } + } + const group = new Group(this.optimizeOverlapping ? getUniqueRects(rects) : rects, { + objectCaching: true, + subTargetCheck: false, + interactive: false + }); + this.shadow && group.set('shadow', new Shadow(this.shadow)); + this.canvas.fire('before:path:created', { + path: group + }); + this.canvas.add(group); + this.canvas.fire('path:created', { + path: group + }); + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.requestRenderAll(); + } + renderChunck(sprayChunck) { + const ctx = this.canvas.contextTop; + ctx.fillStyle = this.color; + this._saveAndTransform(ctx); + for (let i = 0; i < sprayChunck.length; i++) { + const point = sprayChunck[i]; + ctx.globalAlpha = point.opacity; + ctx.fillRect(point.x, point.y, point.width, point.width); + } + ctx.restore(); + } + + /** + * Render all spray chunks + */ + _render() { + const ctx = this.canvas.contextTop; + ctx.fillStyle = this.color; + this._saveAndTransform(ctx); + for (let i = 0; i < this.sprayChunks.length; i++) { + this.renderChunck(this.sprayChunks[i]); + } + ctx.restore(); + } + + /** + * @param {Point} pointer + */ + addSprayChunk(pointer) { + this.sprayChunk = []; + const radius = this.width / 2; + for (let i = 0; i < this.density; i++) { + this.sprayChunk.push({ + x: getRandomInt(pointer.x - radius, pointer.x + radius), + y: getRandomInt(pointer.y - radius, pointer.y + radius), + width: this.dotWidthVariance ? getRandomInt( + // bottom clamp width to 1 + Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance) : this.dotWidth, + opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1 + }); + } + this.sprayChunks.push(this.sprayChunk); + } +} + +class PatternBrush extends PencilBrush { + constructor(canvas) { + super(canvas); + } + getPatternSrc() { + const dotWidth = 20, + dotDistance = 5, + patternCanvas = createCanvasElement(), + patternCtx = patternCanvas.getContext('2d'); + patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; + if (patternCtx) { + patternCtx.fillStyle = this.color; + patternCtx.beginPath(); + patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); + patternCtx.closePath(); + patternCtx.fill(); + } + return patternCanvas; + } + + /** + * Creates "pattern" instance property + * @param {CanvasRenderingContext2D} ctx + */ + getPattern(ctx) { + return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat'); + } + + /** + * Sets brush styles + * @param {CanvasRenderingContext2D} ctx + */ + _setBrushStyles(ctx) { + super._setBrushStyles(ctx); + const pattern = this.getPattern(ctx); + pattern && (ctx.strokeStyle = pattern); + } + + /** + * Creates path + */ + createPath(pathData) { + const path = super.createPath(pathData), + topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2); + path.stroke = new Pattern({ + source: this.source || this.getPatternSrc(), + offsetX: -topLeft.x, + offsetY: -topLeft.y + }); + return path; + } +} + +const _excluded$5 = ["x1", "y1", "x2", "y2"], + _excluded2$1 = ["x1", "y1", "x2", "y2"]; +// @TODO this code is terrible and Line should be a special case of polyline. + +const coordProps = ['x1', 'x2', 'y1', 'y2']; +class Line extends FabricObject { + /** + * Constructor + * @param {Array} [points] Array of points + * @param {Object} [options] Options object + * @return {Line} thisArg + */ + constructor() { + let [x1, y1, x2, y2] = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0, 0, 0]; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, Line.ownDefaults); + this.setOptions(options); + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + this._setWidthHeight(); + const { + left, + top + } = options; + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + + /** + * @private + * @param {Object} [options] Options + */ + _setWidthHeight() { + const { + x1, + y1, + x2, + y2 + } = this; + this.width = Math.abs(x2 - x1); + this.height = Math.abs(y2 - y1); + const { + left, + top, + width, + height + } = makeBoundingBoxFromPoints([{ + x: x1, + y: y1 + }, { + x: x2, + y: y2 + }]); + const position = new Point(left + width / 2, top + height / 2); + this.setPositionByOrigin(position, CENTER, CENTER); + } + + /** + * @private + * @param {String} key + * @param {*} value + */ + _set(key, value) { + super._set(key, value); + if (coordProps.includes(key)) { + // this doesn't make sense very much, since setting x1 when top or left + // are already set, is just going to show a strange result since the + // line will move way more than the developer expect. + // in fabric5 it worked only when the line didn't have extra transformations, + // in fabric6 too. With extra transform they behave bad in different ways. + // This needs probably a good rework or a tutorial if you have to create a dynamic line + this._setWidthHeight(); + } + return this; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + ctx.beginPath(); + const p = this.calcLinePoints(); + ctx.moveTo(p.x1, p.y1); + ctx.lineTo(p.x2, p.y2); + ctx.lineWidth = this.strokeWidth; + + // TODO: test this + // make sure setting "fill" changes color of a line + // (by copying fillStyle to strokeStyle, since line is stroked, not filled) + const origStrokeStyle = ctx.strokeStyle; + if (isFiller(this.stroke)) { + ctx.strokeStyle = this.stroke.toLive(ctx); + } else { + var _this$stroke; + ctx.strokeStyle = (_this$stroke = this.stroke) !== null && _this$stroke !== void 0 ? _this$stroke : ctx.fillStyle; + } + this.stroke && this._renderStroke(ctx); + ctx.strokeStyle = origStrokeStyle; + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2); + } + + /** + * Returns object representation of an instance + * @method toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), this.calcLinePoints()); + } + + /* + * Calculate object dimensions from its properties + * @private + */ + _getNonTransformedDimensions() { + const dim = super._getNonTransformedDimensions(); + if (this.strokeLineCap === 'butt') { + if (this.width === 0) { + dim.y -= this.strokeWidth; + } + if (this.height === 0) { + dim.x -= this.strokeWidth; + } + } + return dim; + } + + /** + * Recalculates line points given width and height + * Those points are simply placed around the center, + * This is not useful outside internal render functions and svg output + * Is not meant to be for the developer. + * @private + */ + calcLinePoints() { + const { + x1: _x1, + x2: _x2, + y1: _y1, + y2: _y2, + width, + height + } = this; + const xMult = _x1 <= _x2 ? -1 : 1, + yMult = _y1 <= _y2 ? -1 : 1, + x1 = xMult * width / 2, + y1 = yMult * height / 2, + x2 = xMult * -width / 2, + y2 = yMult * -height / 2; + return { + x1, + x2, + y1, + y2 + }; + } + + /* _FROM_SVG_START_ */ + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const { + x1, + x2, + y1, + y2 + } = this.calcLinePoints(); + return ['\n")]; + } + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement}) + * @static + * @memberOf Line + * @see http://www.w3.org/TR/SVG/shapes.html#LineElement + */ + + /** + * Returns Line instance from an SVG element + * @static + * @memberOf Line + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + * @param {Function} [callback] callback function invoked after parsing + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0 + } = _parseAttributes, + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$5); + return new this([x1, y1, x2, y2], parsedAttributes); + } + + /* _FROM_SVG_END_ */ + + /** + * Returns Line instance from an object representation + * @static + * @memberOf Line + * @param {Object} object Object to create an instance from + * @returns {Promise} + */ + static fromObject(_ref) { + let { + x1, + y1, + x2, + y2 + } = _ref, + object = _objectWithoutProperties(_ref, _excluded2$1); + return this._fromObject(_objectSpread2(_objectSpread2({}, object), {}, { + points: [x1, y1, x2, y2] + }), { + extraParam: 'points' + }); + } +} +/** + * x value or first line edge + * @type number + * @default + */ +/** + * y value or first line edge + * @type number + * @default + */ +/** + * x value or second line edge + * @type number + * @default + */ +/** + * y value or second line edge + * @type number + * @default + */ +_defineProperty(Line, "type", 'Line'); +_defineProperty(Line, "cacheProperties", [...cacheProperties, ...coordProps]); +_defineProperty(Line, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat(coordProps)); +classRegistry.setClass(Line); +classRegistry.setSVGClass(Line); + +const triangleDefaultValues = { + width: 100, + height: 100 +}; +class Triangle extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Triangle.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Triangle.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const widthBy2 = this.width / 2, + heightBy2 = this.height / 2; + ctx.beginPath(); + ctx.moveTo(-widthBy2, heightBy2); + ctx.lineTo(0, -heightBy2); + ctx.lineTo(widthBy2, heightBy2); + ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const widthBy2 = this.width / 2, + heightBy2 = this.height / 2, + points = "".concat(-widthBy2, " ").concat(heightBy2, ",0 ").concat(-heightBy2, ",").concat(widthBy2, " ").concat(heightBy2); + return ['']; + } +} +_defineProperty(Triangle, "type", 'Triangle'); +_defineProperty(Triangle, "ownDefaults", triangleDefaultValues); +classRegistry.setClass(Triangle); +classRegistry.setSVGClass(Triangle); + +const ellipseDefaultValues = { + rx: 0, + ry: 0 +}; +const ELLIPSE_PROPS = ['rx', 'ry']; +class Ellipse extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Ellipse.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Ellipse.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {String} key + * @param {*} value + * @return {Ellipse} thisArg + */ + _set(key, value) { + super._set(key, value); + switch (key) { + case 'rx': + this.rx = value; + this.set('width', value * 2); + break; + case 'ry': + this.ry = value; + this.set('height', value * 2); + break; + } + return this; + } + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRx() { + return this.get('rx') * this.get(SCALE_X); + } + + /** + * Returns Vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRy() { + return this.get('ry') * this.get(SCALE_Y); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + return ['\n")]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + */ + _render(ctx) { + ctx.beginPath(); + ctx.save(); + ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); + ctx.arc(0, 0, this.rx, 0, twoMathPi, false); + ctx.restore(); + this._renderPaintInOrder(ctx); + } + + /* _FROM_SVG_START_ */ + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement}) + * @static + * @memberOf Ellipse + * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement + */ + + /** + * Returns {@link Ellipse} instance from an SVG element + * @static + * @memberOf Ellipse + * @param {HTMLElement} element Element to parse + * @return {Ellipse} + */ + static async fromElement(element, options, cssRules) { + const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules); + parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; + parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; + return new this(parsedAttributes); + } + + /* _FROM_SVG_END_ */ +} +/** + * Horizontal radius + * @type Number + * @default + */ +/** + * Vertical radius + * @type Number + * @default + */ +_defineProperty(Ellipse, "type", 'Ellipse'); +_defineProperty(Ellipse, "cacheProperties", [...cacheProperties, ...ELLIPSE_PROPS]); +_defineProperty(Ellipse, "ownDefaults", ellipseDefaultValues); +_defineProperty(Ellipse, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry']); +classRegistry.setClass(Ellipse); +classRegistry.setSVGClass(Ellipse); + +/** + * Parses "points" attribute, returning an array of values + * @static + * @memberOf fabric + * @param {String} points points attribute string + * @return {Array} array of points + */ +function parsePointsAttribute(points) { + // points attribute is required and must not be empty + if (!points) { + return []; + } + + // replace commas with whitespace and remove bookending whitespace + const pointsSplit = points.replace(/,/g, ' ').trim().split(/\s+/); + const parsedPoints = []; + for (let i = 0; i < pointsSplit.length; i += 2) { + parsedPoints.push({ + x: parseFloat(pointsSplit[i]), + y: parseFloat(pointsSplit[i + 1]) + }); + } + + // odd number of points is an error + // if (parsedPoints.length % 2 !== 0) { + // return null; + // } + return parsedPoints; +} + +const _excluded$4 = ["left", "top"]; +const polylineDefaultValues = { + /** + * @deprecated transient option soon to be removed in favor of a different design + */ + exactBoundingBox: false +}; +class Polyline extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Polyline.ownDefaults); + } + + /** + * A list of properties that if changed trigger a recalculation of dimensions + * @todo check if you really need to recalculate for all cases + */ + + /** + * Constructor + * @param {Array} points Array of points (where each point is an object with x and y) + * @param {Object} [options] Options object + * @return {Polyline} thisArg + * @example + * var poly = new Polyline([ + * { x: 10, y: 10 }, + * { x: 50, y: 30 }, + * { x: 40, y: 70 }, + * { x: 60, y: 50 }, + * { x: 100, y: 150 }, + * { x: 40, y: 100 } + * ], { + * stroke: 'red', + * left: 100, + * top: 100 + * }); + */ + constructor() { + let points = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + _defineProperty(this, "strokeDiff", void 0); + Object.assign(this, Polyline.ownDefaults); + this.setOptions(options); + this.points = points; + const { + left, + top + } = options; + this.initialized = true; + this.setBoundingBox(true); + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + isOpen() { + return true; + } + _projectStrokeOnPoints(options) { + return projectStrokeOnPoints(this.points, options, this.isOpen()); + } + + /** + * Calculate the polygon bounding box + * @private + */ + _calcDimensions(options) { + options = _objectSpread2({ + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + strokeLineCap: this.strokeLineCap, + strokeLineJoin: this.strokeLineJoin, + strokeMiterLimit: this.strokeMiterLimit, + strokeUniform: this.strokeUniform, + strokeWidth: this.strokeWidth + }, options || {}); + const points = this.exactBoundingBox ? this._projectStrokeOnPoints(options).map(projection => projection.projectedPoint) : this.points; + if (points.length === 0) { + return { + left: 0, + top: 0, + width: 0, + height: 0, + pathOffset: new Point(), + strokeOffset: new Point(), + strokeDiff: new Point() + }; + } + const bbox = makeBoundingBoxFromPoints(points), + // Remove scale effect, since it's applied after + matrix = calcDimensionsMatrix(_objectSpread2(_objectSpread2({}, options), {}, { + scaleX: 1, + scaleY: 1 + })), + bboxNoStroke = makeBoundingBoxFromPoints(this.points.map(p => transformPoint(p, matrix, true))), + scale = new Point(this.scaleX, this.scaleY); + let offsetX = bbox.left + bbox.width / 2, + offsetY = bbox.top + bbox.height / 2; + if (this.exactBoundingBox) { + offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX)); + // Order of those assignments is important. + // offsetY relies on offsetX being already changed by the line above + offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY)); + } + return _objectSpread2(_objectSpread2({}, bbox), {}, { + pathOffset: new Point(offsetX, offsetY), + strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top).subtract(new Point(bbox.left, bbox.top)).multiply(scale), + strokeDiff: new Point(bbox.width, bbox.height).subtract(new Point(bboxNoStroke.width, bboxNoStroke.height)).multiply(scale) + }); + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates, by look at the polyline/polygon points. + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + const bbox = makeBoundingBoxFromPoints(this.points); + return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2); + } + setDimensions() { + this.setBoundingBox(); + } + setBoundingBox(adjustPosition) { + const { + left, + top, + width, + height, + pathOffset, + strokeOffset, + strokeDiff + } = this._calcDimensions(); + this.set({ + width, + height, + pathOffset, + strokeOffset, + strokeDiff + }); + adjustPosition && this.setPositionByOrigin(new Point(left + width / 2, top + height / 2), CENTER, CENTER); + } + + /** + * @deprecated intermidiate method to be removed, do not use + */ + isStrokeAccountedForInDimensions() { + return this.exactBoundingBox; + } + + /** + * @override stroke is taken in account in size + */ + _getNonTransformedDimensions() { + return this.exactBoundingBox ? + // TODO: fix this + new Point(this.width, this.height) : super._getNonTransformedDimensions(); + } + + /** + * @override stroke and skewing are taken into account when projecting stroke on points, + * therefore we don't want the default calculation to account for skewing as well. + * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion. + * + * @private + */ + _getTransformedDimensions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (this.exactBoundingBox) { + let size; + /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because + the stroke projections are affected. + When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on + projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/ + if (Object.keys(options).some(key => this.strokeUniform || this.constructor.layoutProperties.includes(key))) { + var _options$width, _options$height; + const { + width, + height + } = this._calcDimensions(options); + size = new Point((_options$width = options.width) !== null && _options$width !== void 0 ? _options$width : width, (_options$height = options.height) !== null && _options$height !== void 0 ? _options$height : height); + } else { + var _options$width2, _options$height2; + size = new Point((_options$width2 = options.width) !== null && _options$width2 !== void 0 ? _options$width2 : this.width, (_options$height2 = options.height) !== null && _options$height2 !== void 0 ? _options$height2 : this.height); + } + return size.multiply(new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY)); + } else { + return super._getTransformedDimensions(options); + } + } + + /** + * Recalculates dimensions when changing skew and scale + * @private + */ + _set(key, value) { + const changed = this.initialized && this[key] !== value; + const output = super._set(key, value); + if (this.exactBoundingBox && changed && ((key === SCALE_X || key === SCALE_Y) && this.strokeUniform && this.constructor.layoutProperties.includes('strokeUniform') || this.constructor.layoutProperties.includes(key))) { + this.setDimensions(); + } + return output; + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), {}, { + points: this.points.map(_ref => { + let { + x, + y + } = _ref; + return { + x, + y + }; + }) + }); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const points = [], + diffX = this.pathOffset.x, + diffY = this.pathOffset.y, + NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS; + for (let i = 0, len = this.points.length; i < len; i++) { + points.push(toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '); + } + return ["<".concat(this.constructor.type.toLowerCase(), " "), 'COMMON_PARTS', "points=\"".concat(points.join(''), "\" />\n")]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const len = this.points.length, + x = this.pathOffset.x, + y = this.pathOffset.y; + if (!len || isNaN(this.points[len - 1].y)) { + // do not draw if no points or odd points + // NaN comes from parseFloat of a empty string in parser + return; + } + ctx.beginPath(); + ctx.moveTo(this.points[0].x - x, this.points[0].y - y); + for (let i = 0; i < len; i++) { + const point = this.points[i]; + ctx.lineTo(point.x - x, point.y - y); + } + !this.isOpen() && ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity() { + return this.points.length; + } + + /* _FROM_SVG_START_ */ + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement}) + * @static + * @memberOf Polyline + * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement + */ + + /** + * Returns Polyline instance from an SVG element + * @static + * @memberOf Polyline + * @param {HTMLElement} element Element to parser + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const points = parsePointsAttribute(element.getAttribute('points')), + _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$4); + return new this(points, _objectSpread2(_objectSpread2({}, parsedAttributes), options)); + } + + /* _FROM_SVG_END_ */ + + /** + * Returns Polyline instance from an object representation + * @static + * @memberOf Polyline + * @param {Object} object Object to create an instance from + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(object, { + extraParam: 'points' + }); + } +} +/** + * Points array + * @type Array + * @default + */ +/** + * WARNING: Feature in progress + * Calculate the exact bounding box taking in account strokeWidth on acute angles + * this will be turned to true by default on fabric 6.0 + * maybe will be left in as an optimization since calculations may be slow + * @deprecated transient option soon to be removed in favor of a different design + * @type Boolean + * @default false + */ +_defineProperty(Polyline, "ownDefaults", polylineDefaultValues); +_defineProperty(Polyline, "type", 'Polyline'); +_defineProperty(Polyline, "layoutProperties", [SKEW_X, SKEW_Y, 'strokeLineCap', 'strokeLineJoin', 'strokeMiterLimit', 'strokeWidth', 'strokeUniform', 'points']); +_defineProperty(Polyline, "cacheProperties", [...cacheProperties, 'points']); +_defineProperty(Polyline, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES]); +classRegistry.setClass(Polyline); +classRegistry.setSVGClass(Polyline); + +class Polygon extends Polyline { + isOpen() { + return false; + } +} +_defineProperty(Polygon, "ownDefaults", polylineDefaultValues); +_defineProperty(Polygon, "type", 'Polygon'); +classRegistry.setClass(Polygon); +classRegistry.setSVGClass(Polygon); + +const fontProperties = ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle']; +const textDecorationProperties = ['underline', 'overline', 'linethrough']; +const textLayoutProperties = [...fontProperties, 'lineHeight', 'text', 'charSpacing', 'textAlign', 'styles', 'path', 'pathStartOffset', 'pathSide', 'pathAlign']; +const additionalProps = [...textLayoutProperties, ...textDecorationProperties, 'textBackgroundColor', 'direction']; +const styleProperties = [...fontProperties, ...textDecorationProperties, STROKE, 'strokeWidth', FILL, 'deltaY', 'textBackgroundColor']; + +// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype +// regexes, list of properties that are not suppose to change by instances, magic consts. +// this will be a separated effort +const textDefaultValues = { + _reNewline: reNewline, + _reSpacesAndTabs: /[ \t\r]/g, + _reSpaceAndTab: /[ \t\r]/, + _reWords: /\S+/g, + fontSize: 40, + fontWeight: 'normal', + fontFamily: 'Times New Roman', + underline: false, + overline: false, + linethrough: false, + textAlign: LEFT, + fontStyle: 'normal', + lineHeight: 1.16, + superscript: { + size: 0.6, + // fontSize factor + baseline: -0.35 // baseline-shift factor (upwards) + }, + subscript: { + size: 0.6, + // fontSize factor + baseline: 0.11 // baseline-shift factor (downwards) + }, + textBackgroundColor: '', + stroke: null, + shadow: null, + path: undefined, + pathStartOffset: 0, + pathSide: LEFT, + pathAlign: 'baseline', + _fontSizeFraction: 0.222, + offsets: { + underline: 0.1, + linethrough: -0.315, + overline: -0.88 + }, + _fontSizeMult: 1.13, + charSpacing: 0, + deltaY: 0, + direction: 'ltr', + CACHE_FONT_SIZE: 400, + MIN_TEXT_WIDTH: 2 +}; +const JUSTIFY = 'justify'; +const JUSTIFY_LEFT = 'justify-left'; +const JUSTIFY_RIGHT = 'justify-right'; +const JUSTIFY_CENTER = 'justify-center'; + +class StyledText extends FabricObject { + /** + * Returns true if object has no styling or no styling in a line + * @param {Number} lineIndex , lineIndex is on wrapped lines. + * @return {Boolean} + */ + isEmptyStyles(lineIndex) { + if (!this.styles) { + return true; + } + if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { + return true; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + line: this.styles[lineIndex] + }; + for (const p1 in obj) { + for (const p2 in obj[p1]) { + // eslint-disable-next-line no-unused-vars + for (const p3 in obj[p1][p2]) { + return false; + } + } + } + return true; + } + + /** + * Returns true if object has a style property or has it ina specified line + * This function is used to detect if a text will use a particular property or not. + * @param {String} property to check for + * @param {Number} lineIndex to check the style on + * @return {Boolean} + */ + styleHas(property, lineIndex) { + if (!this.styles) { + return false; + } + if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { + return false; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + 0: this.styles[lineIndex] + }; + // eslint-disable-next-line + for (const p1 in obj) { + // eslint-disable-next-line + for (const p2 in obj[p1]) { + if (typeof obj[p1][p2][property] !== 'undefined') { + return true; + } + } + } + return false; + } + + /** + * Check if characters in a text have a value for a property + * whose value matches the textbox's value for that property. If so, + * the character-level property is deleted. If the character + * has no other properties, then it is also deleted. Finally, + * if the line containing that character has no other characters + * then it also is deleted. + * + * @param {string} property The property to compare between characters and text. + */ + cleanStyle(property) { + if (!this.styles) { + return false; + } + const obj = this.styles; + let stylesCount = 0, + letterCount, + stylePropertyValue, + allStyleObjectPropertiesMatch = true, + graphemeCount = 0; + for (const p1 in obj) { + letterCount = 0; + for (const p2 in obj[p1]) { + const styleObject = obj[p1][p2] || {}, + stylePropertyHasBeenSet = styleObject[property] !== undefined; + stylesCount++; + if (stylePropertyHasBeenSet) { + if (!stylePropertyValue) { + stylePropertyValue = styleObject[property]; + } else if (styleObject[property] !== stylePropertyValue) { + allStyleObjectPropertiesMatch = false; + } + if (styleObject[property] === this[property]) { + delete styleObject[property]; + } + } else { + allStyleObjectPropertiesMatch = false; + } + if (Object.keys(styleObject).length !== 0) { + letterCount++; + } else { + delete obj[p1][p2]; + } + } + if (letterCount === 0) { + delete obj[p1]; + } + } + // if every grapheme has the same style set then + // delete those styles and set it on the parent + for (let i = 0; i < this._textLines.length; i++) { + graphemeCount += this._textLines[i].length; + } + if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { + // @ts-expect-error conspiracy theory of TS + this[property] = stylePropertyValue; + this.removeStyle(property); + } + } + + /** + * Remove a style property or properties from all individual character styles + * in a text object. Deletes the character style object if it contains no other style + * props. Deletes a line style object if it contains no other character styles. + * + * @param {String} props The property to remove from character styles. + */ + removeStyle(property) { + if (!this.styles) { + return; + } + const obj = this.styles; + let line, lineNum, charNum; + for (lineNum in obj) { + line = obj[lineNum]; + for (charNum in line) { + delete line[charNum][property]; + if (Object.keys(line[charNum]).length === 0) { + delete line[charNum]; + } + } + if (Object.keys(line).length === 0) { + delete obj[lineNum]; + } + } + } + _extendStyles(index, style) { + const { + lineIndex, + charIndex + } = this.get2DCursorLocation(index); + if (!this._getLineStyle(lineIndex)) { + this._setLineStyle(lineIndex); + } + const newStyle = pickBy(_objectSpread2(_objectSpread2({}, this._getStyleDeclaration(lineIndex, charIndex)), style), value => value !== undefined); + + // finally assign to the old position the new style + this._setStyleDeclaration(lineIndex, charIndex, newStyle); + } + + /** + * Gets style of a current selection/cursor (at the start position) + * @param {Number} startIndex Start index to get styles at + * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1 + * @param {Boolean} [complete] get full style or not + * @return {Array} styles an array with one, zero or more Style objects + */ + getSelectionStyles(startIndex, endIndex, complete) { + const styles = []; + for (let i = startIndex; i < (endIndex || startIndex); i++) { + styles.push(this.getStyleAtPosition(i, complete)); + } + return styles; + } + + /** + * Gets style of a current selection/cursor position + * @param {Number} position to get styles at + * @param {Boolean} [complete] full style if true + * @return {Object} style Style object at a specified index + * @private + */ + getStyleAtPosition(position, complete) { + const { + lineIndex, + charIndex + } = this.get2DCursorLocation(position); + return complete ? this.getCompleteStyleDeclaration(lineIndex, charIndex) : this._getStyleDeclaration(lineIndex, charIndex); + } + + /** + * Sets style of a current selection, if no selection exist, do not set anything. + * @param {Object} styles Styles object + * @param {Number} startIndex Start index to get styles at + * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1 + */ + setSelectionStyles(styles, startIndex, endIndex) { + for (let i = startIndex; i < (endIndex || startIndex); i++) { + this._extendStyles(i, styles); + } + /* not included in _extendStyles to avoid clearing cache more than once */ + this._forceClearCache = true; + } + + /** + * Get a reference, not a clone, to the style object for a given character, + * if no style is set for a line or char, return a new empty object. + * This is tricky and confusing because when you get an empty object you can't + * determine if it is a reference or a new one. + * @TODO this should always return a reference or always a clone or undefined when necessary. + * @protected + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined + */ + _getStyleDeclaration(lineIndex, charIndex) { + var _lineStyle$charIndex; + const lineStyle = this.styles && this.styles[lineIndex]; + return lineStyle ? (_lineStyle$charIndex = lineStyle[charIndex]) !== null && _lineStyle$charIndex !== void 0 ? _lineStyle$charIndex : {} : {}; + } + + /** + * return a new object that contains all the style property for a character + * the object returned is newly created + * @param {Number} lineIndex of the line where the character is + * @param {Number} charIndex position of the character on the line + * @return {Object} style object + */ + getCompleteStyleDeclaration(lineIndex, charIndex) { + return _objectSpread2(_objectSpread2({}, pick(this, this.constructor._styleProperties)), this._getStyleDeclaration(lineIndex, charIndex)); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {Object} style + * @private + */ + _setStyleDeclaration(lineIndex, charIndex, style) { + this.styles[lineIndex][charIndex] = style; + } + + /** + * + * @param {Number} lineIndex + * @param {Number} charIndex + * @private + */ + _deleteStyleDeclaration(lineIndex, charIndex) { + delete this.styles[lineIndex][charIndex]; + } + + /** + * @param {Number} lineIndex + * @return {Boolean} if the line exists or not + * @private + */ + _getLineStyle(lineIndex) { + return !!this.styles[lineIndex]; + } + + /** + * Set the line style to an empty object so that is initialized + * @param {Number} lineIndex + * @private + */ + _setLineStyle(lineIndex) { + this.styles[lineIndex] = {}; + } + _deleteLineStyle(lineIndex) { + delete this.styles[lineIndex]; + } +} +_defineProperty(StyledText, "_styleProperties", styleProperties); + +const multipleSpacesRegex = / +/g; +const dblQuoteRegex = /"/g; +function createSVGInlineRect(color, left, top, width, height) { + return "\t\t".concat(createSVGRect(color, { + left, + top, + width, + height + }), "\n"); +} +class TextSVGExportMixin extends FabricObjectSVGExportMixin { + _toSVG() { + const offsets = this._getSVGLeftTopOffsets(), + textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); + return this._wrapSVGTextAndBg(textAndBg); + } + toSVG(reviver) { + return this._createBaseSVGMarkup(this._toSVG(), { + reviver, + noStyle: true, + withShadow: true + }); + } + _getSVGLeftTopOffsets() { + return { + textLeft: -this.width / 2, + textTop: -this.height / 2, + lineTop: this.getHeightOfLine(0) + }; + } + _wrapSVGTextAndBg(_ref) { + let { + textBgRects, + textSpans + } = _ref; + const noShadow = true, + textDecoration = this.getSvgTextDecoration(this); + return [textBgRects.join(''), '\t\t', textSpans.join(''), '\n']; + } + + /** + * @private + * @param {Number} textTopOffset Text top offset + * @param {Number} textLeftOffset Text left offset + * @return {Object} + */ + _getSVGTextAndBg(textTopOffset, textLeftOffset) { + const textSpans = [], + textBgRects = []; + let height = textTopOffset, + lineOffset; + + // bounding-box background + this.backgroundColor && textBgRects.push(...createSVGInlineRect(this.backgroundColor, -this.width / 2, -this.height / 2, this.width, this.height)); + + // text and text-background + for (let i = 0, len = this._textLines.length; i < len; i++) { + lineOffset = this._getLineLeftOffset(i); + if (this.direction === 'rtl') { + lineOffset += this.width; + } + if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) { + this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height); + } + this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height); + height += this.getHeightOfLine(i); + } + return { + textSpans, + textBgRects + }; + } + _createTextCharSpan(char, styleDecl, left, top) { + const styleProps = this.getSvgSpanStyles(styleDecl, char !== char.trim() || !!char.match(multipleSpacesRegex)), + fillStyles = styleProps ? "style=\"".concat(styleProps, "\"") : '', + dy = styleDecl.deltaY, + dySpan = dy ? " dy=\"".concat(toFixed(dy, config.NUM_FRACTION_DIGITS), "\" ") : ''; + return "").concat(escapeXml(char), ""); + } + _setSVGTextLineText(textSpans, lineIndex, textLeftOffset, textTopOffset) { + const lineHeight = this.getHeightOfLine(lineIndex), + isJustify = this.textAlign.includes(JUSTIFY), + line = this._textLines[lineIndex]; + let actualStyle, + nextStyle, + charsToRender = '', + charBox, + style, + boxWidth = 0, + timeToRender; + textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; + for (let i = 0, len = line.length - 1; i <= len; i++) { + timeToRender = i === len || this.charSpacing; + charsToRender += line[i]; + charBox = this.__charBounds[lineIndex][i]; + if (boxWidth === 0) { + textLeftOffset += charBox.kernedWidth - charBox.width; + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; + } + if (isJustify && !timeToRender) { + if (this._reSpaceAndTab.test(line[i])) { + timeToRender = true; + } + } + if (!timeToRender) { + // if we have charSpacing, we render char by char + actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); + nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); + timeToRender = hasStyleChanged(actualStyle, nextStyle, true); + } + if (timeToRender) { + style = this._getStyleDeclaration(lineIndex, i); + textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset)); + charsToRender = ''; + actualStyle = nextStyle; + if (this.direction === 'rtl') { + textLeftOffset -= boxWidth; + } else { + textLeftOffset += boxWidth; + } + boxWidth = 0; + } + } + } + _setSVGTextLineBg(textBgRects, i, leftOffset, textTopOffset) { + const line = this._textLines[i], + heightOfLine = this.getHeightOfLine(i) / this.lineHeight; + let boxWidth = 0, + boxStart = 0, + currentColor, + lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); + for (let j = 0; j < line.length; j++) { + const { + left, + width, + kernedWidth + } = this.__charBounds[i][j]; + currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); + if (currentColor !== lastColor) { + lastColor && textBgRects.push(...createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine)); + boxStart = left; + boxWidth = width; + lastColor = currentColor; + } else { + boxWidth += kernedWidth; + } + } + currentColor && textBgRects.push(...createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine)); + } + + /** + * @deprecated unused + */ + _getSVGLineTopOffset(lineIndex) { + let lineTopOffset = 0, + j; + for (j = 0; j < lineIndex; j++) { + lineTopOffset += this.getHeightOfLine(j); + } + const lastHeight = this.getHeightOfLine(j); + return { + lineTop: lineTopOffset, + offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) + }; + } + + /** + * Returns styles-string for svg-export + * @param {Boolean} skipShadow a boolean to skip shadow filter output + * @return {String} + */ + getSvgStyles(skipShadow) { + return "".concat(super.getSvgStyles(skipShadow), " white-space: pre;"); + } + + /** + * Returns styles-string for svg-export + * @param {Object} style the object from which to retrieve style properties + * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. + * @return {String} + */ + getSvgSpanStyles(style, useWhiteSpace) { + const { + fontFamily, + strokeWidth, + stroke, + fill, + fontSize, + fontStyle, + fontWeight, + deltaY + } = style; + const textDecoration = this.getSvgTextDecoration(style); + return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? "stroke-width: ".concat(strokeWidth, "; ") : '', fontFamily ? "font-family: ".concat(!fontFamily.includes("'") && !fontFamily.includes('"') ? "'".concat(fontFamily, "'") : fontFamily, "; ") : '', fontSize ? "font-size: ".concat(fontSize, "px; ") : '', fontStyle ? "font-style: ".concat(fontStyle, "; ") : '', fontWeight ? "font-weight: ".concat(fontWeight, "; ") : '', textDecoration ? "text-decoration: ".concat(textDecoration, "; ") : textDecoration, fill ? colorPropToSVG(FILL, fill) : '', deltaY ? "baseline-shift: ".concat(-deltaY, "; ") : '', useWhiteSpace ? 'white-space: pre; ' : ''].join(''); + } + + /** + * Returns text-decoration property for svg-export + * @param {Object} style the object from which to retrieve style properties + * @return {String} + */ + getSvgTextDecoration(style) { + return ['overline', 'underline', 'line-through'].filter(decoration => style[decoration.replace('-', '')]).join(' '); + } +} + +const _excluded$3 = ["textAnchor", "textDecoration", "dx", "dy", "top", "left", "fontSize", "strokeWidth"]; +let measuringContext; + +/** + * Return a context for measurement of text string. + * if created it gets stored for reuse + */ +function getMeasuringContext() { + if (!measuringContext) { + const canvas = createCanvasElement(); + canvas.width = canvas.height = 0; + measuringContext = canvas.getContext('2d'); + } + return measuringContext; +} + +/** + * Measure and return the info of a single grapheme. + * needs the the info of previous graphemes already filled + * Override to customize measuring + */ + +// @TODO this is not complete + +/** + * Text class + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} + */ +class FabricText extends StyledText { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), FabricText.ownDefaults); + } + constructor(text, options) { + super(); + /** + * contains characters bounding boxes + * This variable is considered to be protected. + * But for how mixins are implemented right now, we can't leave it private + * @protected + */ + _defineProperty(this, "__charBounds", []); + Object.assign(this, FabricText.ownDefaults); + this.setOptions(options); + if (!this.styles) { + this.styles = {}; + } + this.text = text; + this.initialized = true; + if (this.path) { + this.setPathInfo(); + } + this.initDimensions(); + this.setCoords(); + } + + /** + * If text has a path, it will add the extra information needed + * for path and text calculations + */ + setPathInfo() { + const path = this.path; + if (path) { + path.segmentsInfo = getPathSegmentsInfo(path.path); + } + } + + /** + * @private + * Divides text into lines of text and lines of graphemes. + */ + _splitText() { + const newLines = this._splitTextIntoLines(this.text); + this.textLines = newLines.lines; + this._textLines = newLines.graphemeLines; + this._unwrappedTextLines = newLines._unwrappedLines; + this._text = newLines.graphemeText; + return newLines; + } + + /** + * Initialize or update text dimensions. + * Updates this.width and this.height with the proper values. + * Does not return dimensions. + */ + initDimensions() { + this._splitText(); + this._clearCache(); + this.dirty = true; + if (this.path) { + this.width = this.path.width; + this.height = this.path.height; + } else { + this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH; + this.height = this.calcTextHeight(); + } + if (this.textAlign.includes(JUSTIFY)) { + // once text is measured we need to make space fatter to make justified text. + this.enlargeSpaces(); + } + } + + /** + * Enlarge space boxes and shift the others + */ + enlargeSpaces() { + let diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; + for (let i = 0, len = this._textLines.length; i < len; i++) { + if (this.textAlign !== JUSTIFY && (i === len - 1 || this.isEndOfWrapping(i))) { + continue; + } + accumulatedSpace = 0; + line = this._textLines[i]; + currentLineWidth = this.getLineWidth(i); + if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) { + numberOfSpaces = spaces.length; + diffSpace = (this.width - currentLineWidth) / numberOfSpaces; + for (let j = 0; j <= line.length; j++) { + charBound = this.__charBounds[i][j]; + if (this._reSpaceAndTab.test(line[j])) { + charBound.width += diffSpace; + charBound.kernedWidth += diffSpace; + charBound.left += accumulatedSpace; + accumulatedSpace += diffSpace; + } else { + charBound.left += accumulatedSpace; + } + } + } + } + } + + /** + * Detect if the text line is ended with an hard break + * text and itext do not have wrapping, return false + * @return {Boolean} + */ + isEndOfWrapping(lineIndex) { + return lineIndex === this._textLines.length - 1; + } + + /** + * Detect if a line has a linebreak and so we need to account for it when moving + * and counting style. + * It return always 1 for text and Itext. Textbox has its own implementation + * @return Number + */ + + missingNewlineOffset(_lineIndex) { + return 1; + } + + /** + * Returns 2d representation (lineIndex and charIndex) of cursor + * @param {Number} selectionStart + * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. + */ + get2DCursorLocation(selectionStart, skipWrapping) { + const lines = skipWrapping ? this._unwrappedTextLines : this._textLines; + let i; + for (i = 0; i < lines.length; i++) { + if (selectionStart <= lines[i].length) { + return { + lineIndex: i, + charIndex: selectionStart + }; + } + selectionStart -= lines[i].length + this.missingNewlineOffset(i, skipWrapping); + } + return { + lineIndex: i - 1, + charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart + }; + } + + /** + * Returns string representation of an instance + * @return {String} String representation of text object + */ + toString() { + return "#"); + } + + /** + * Return the dimension and the zoom level needed to create a cache canvas + * big enough to host the object to be cached. + * @private + * @param {Object} dim.x width of object to be cached + * @param {Object} dim.y height of object to be cached + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _getCacheCanvasDimensions() { + const dims = super._getCacheCanvasDimensions(); + const fontSize = this.fontSize; + dims.width += fontSize * dims.zoomX; + dims.height += fontSize * dims.zoomY; + return dims; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const path = this.path; + path && !path.isNotVisible() && path._render(ctx); + this._setTextStyles(ctx); + this._renderTextLinesBackground(ctx); + this._renderTextDecoration(ctx, 'underline'); + this._renderText(ctx); + this._renderTextDecoration(ctx, 'overline'); + this._renderTextDecoration(ctx, 'linethrough'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderText(ctx) { + if (this.paintFirst === STROKE) { + this._renderTextStroke(ctx); + this._renderTextFill(ctx); + } else { + this._renderTextFill(ctx); + this._renderTextStroke(ctx); + } + } + + /** + * Set the font parameter of the context with the object properties or with charStyle + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Object} [charStyle] object with font style properties + * @param {String} [charStyle.fontFamily] Font Family + * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix ) + * @param {String} [charStyle.fontWeight] Font weight + * @param {String} [charStyle.fontStyle] Font style (italic|normal) + */ + _setTextStyles(ctx, charStyle, forMeasuring) { + ctx.textBaseline = 'alphabetic'; + if (this.path) { + switch (this.pathAlign) { + case CENTER: + ctx.textBaseline = 'middle'; + break; + case 'ascender': + ctx.textBaseline = TOP; + break; + case 'descender': + ctx.textBaseline = BOTTOM; + break; + } + } + ctx.font = this._getFontDeclaration(charStyle, forMeasuring); + } + + /** + * calculate and return the text Width measuring each line. + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {Number} Maximum width of Text object + */ + calcTextWidth() { + let maxWidth = this.getLineWidth(0); + for (let i = 1, len = this._textLines.length; i < len; i++) { + const currentLineWidth = this.getLineWidth(i); + if (currentLineWidth > maxWidth) { + maxWidth = currentLineWidth; + } + } + return maxWidth; + } + + /** + * @private + * @param {String} method Method name ("fillText" or "strokeText") + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Text to render + * @param {Number} left Left position of text + * @param {Number} top Top position of text + * @param {Number} lineIndex Index of a line in a text + */ + _renderTextLine(method, ctx, line, left, top, lineIndex) { + this._renderChars(method, ctx, line, left, top, lineIndex); + } + + /** + * Renders the text background for lines, taking care of style + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextLinesBackground(ctx) { + if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) { + return; + } + const originalFill = ctx.fillStyle, + leftOffset = this._getLeftOffset(); + let lineTopOffset = this._getTopOffset(); + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i); + if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) { + lineTopOffset += heightOfLine; + continue; + } + const jlen = this._textLines[i].length; + const lineLeftOffset = this._getLineLeftOffset(i); + let boxWidth = 0; + let boxStart = 0; + let drawStart; + let currentColor; + let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); + for (let j = 0; j < jlen; j++) { + // at this point charbox are either standard or full with pathInfo if there is a path. + const charBox = this.__charBounds[i][j]; + currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); + if (this.path) { + ctx.save(); + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + ctx.fillStyle = currentColor; + currentColor && ctx.fillRect(-charBox.width / 2, -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), charBox.width, heightOfLine / this.lineHeight); + ctx.restore(); + } else if (currentColor !== lastColor) { + drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = lastColor; + lastColor && ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight); + boxStart = charBox.left; + boxWidth = charBox.width; + lastColor = currentColor; + } else { + boxWidth += charBox.kernedWidth; + } + } + if (currentColor && !this.path) { + drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = currentColor; + ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight); + } + lineTopOffset += heightOfLine; + } + ctx.fillStyle = originalFill; + // if there is text background color no + // other shadows should be casted + this._removeShadow(ctx); + } + + /** + * measure and return the width of a single character. + * possibly overridden to accommodate different measure logic or + * to hook some external lib for character measurement + * @private + * @param {String} _char, char to be measured + * @param {Object} charStyle style of char to be measured + * @param {String} [previousChar] previous char + * @param {Object} [prevCharStyle] style of previous char + */ + _measureChar(_char, charStyle, previousChar, prevCharStyle) { + const fontCache = cache.getFontCache(charStyle), + fontDeclaration = this._getFontDeclaration(charStyle), + couple = previousChar + _char, + stylesAreEqual = previousChar && fontDeclaration === this._getFontDeclaration(prevCharStyle), + fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE; + let width, coupleWidth, previousWidth, kernedWidth; + if (previousChar && fontCache[previousChar] !== undefined) { + previousWidth = fontCache[previousChar]; + } + if (fontCache[_char] !== undefined) { + kernedWidth = width = fontCache[_char]; + } + if (stylesAreEqual && fontCache[couple] !== undefined) { + coupleWidth = fontCache[couple]; + kernedWidth = coupleWidth - previousWidth; + } + if (width === undefined || previousWidth === undefined || coupleWidth === undefined) { + const ctx = getMeasuringContext(); + // send a TRUE to specify measuring font size CACHE_FONT_SIZE + this._setTextStyles(ctx, charStyle, true); + if (width === undefined) { + kernedWidth = width = ctx.measureText(_char).width; + fontCache[_char] = width; + } + if (previousWidth === undefined && stylesAreEqual && previousChar) { + previousWidth = ctx.measureText(previousChar).width; + fontCache[previousChar] = previousWidth; + } + if (stylesAreEqual && coupleWidth === undefined) { + // we can measure the kerning couple and subtract the width of the previous character + coupleWidth = ctx.measureText(couple).width; + fontCache[couple] = coupleWidth; + // safe to use the non-null since if undefined we defined it before. + kernedWidth = coupleWidth - previousWidth; + } + } + return { + width: width * fontMultiplier, + kernedWidth: kernedWidth * fontMultiplier + }; + } + + /** + * Computes height of character at given position + * @param {Number} line the line index number + * @param {Number} _char the character index number + * @return {Number} fontSize of the character + */ + getHeightOfChar(line, _char) { + return this.getValueOfPropertyAt(line, _char, 'fontSize'); + } + + /** + * measure a text line measuring all characters. + * @param {Number} lineIndex line number + */ + measureLine(lineIndex) { + const lineInfo = this._measureLine(lineIndex); + if (this.charSpacing !== 0) { + lineInfo.width -= this._getWidthOfCharSpacing(); + } + if (lineInfo.width < 0) { + lineInfo.width = 0; + } + return lineInfo; + } + + /** + * measure every grapheme of a line, populating __charBounds + * @param {Number} lineIndex + * @return {Object} object.width total width of characters + * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs + */ + _measureLine(lineIndex) { + let width = 0, + prevGrapheme, + graphemeInfo; + const reverse = this.pathSide === RIGHT, + path = this.path, + line = this._textLines[lineIndex], + llength = line.length, + lineBounds = new Array(llength); + this.__charBounds[lineIndex] = lineBounds; + for (let i = 0; i < llength; i++) { + const grapheme = line[i]; + graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme); + lineBounds[i] = graphemeInfo; + width += graphemeInfo.kernedWidth; + prevGrapheme = grapheme; + } + // this latest bound box represent the last character of the line + // to simplify cursor handling in interactive mode. + lineBounds[llength] = { + left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0, + width: 0, + kernedWidth: 0, + height: this.fontSize, + deltaY: 0 + }; + if (path && path.segmentsInfo) { + let positionInPath = 0; + const totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length; + switch (this.textAlign) { + case LEFT: + positionInPath = reverse ? totalPathLength - width : 0; + break; + case CENTER: + positionInPath = (totalPathLength - width) / 2; + break; + case RIGHT: + positionInPath = reverse ? 0 : totalPathLength - width; + break; + //todo - add support for justify + } + positionInPath += this.pathStartOffset * (reverse ? -1 : 1); + for (let i = reverse ? llength - 1 : 0; reverse ? i >= 0 : i < llength; reverse ? i-- : i++) { + graphemeInfo = lineBounds[i]; + if (positionInPath > totalPathLength) { + positionInPath %= totalPathLength; + } else if (positionInPath < 0) { + positionInPath += totalPathLength; + } + // it would probably much faster to send all the grapheme position for a line + // and calculate path position/angle at once. + this._setGraphemeOnPath(positionInPath, graphemeInfo); + positionInPath += graphemeInfo.kernedWidth; + } + } + return { + width: width, + numOfSpaces: 0 + }; + } + + /** + * Calculate the angle and the left,top position of the char that follow a path. + * It appends it to graphemeInfo to be reused later at rendering + * @private + * @param {Number} positionInPath to be measured + * @param {GraphemeBBox} graphemeInfo current grapheme box information + * @param {Object} startingPoint position of the point + */ + _setGraphemeOnPath(positionInPath, graphemeInfo) { + const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2, + path = this.path; + + // we are at currentPositionOnPath. we want to know what point on the path is. + const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo); + graphemeInfo.renderLeft = info.x - path.pathOffset.x; + graphemeInfo.renderTop = info.y - path.pathOffset.y; + graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0); + } + + /** + * + * @param {String} grapheme to be measured + * @param {Number} lineIndex index of the line where the char is + * @param {Number} charIndex position in the line + * @param {String} [prevGrapheme] character preceding the one to be measured + * @returns {GraphemeBBox} grapheme bbox + */ + _getGraphemeBox(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) { + const style = this.getCompleteStyleDeclaration(lineIndex, charIndex), + prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : {}, + info = this._measureChar(grapheme, style, prevGrapheme, prevStyle); + let kernedWidth = info.kernedWidth, + width = info.width, + charSpacing; + if (this.charSpacing !== 0) { + charSpacing = this._getWidthOfCharSpacing(); + width += charSpacing; + kernedWidth += charSpacing; + } + const box = { + width, + left: 0, + height: style.fontSize, + kernedWidth, + deltaY: style.deltaY + }; + if (charIndex > 0 && !skipLeft) { + const previousBox = this.__charBounds[lineIndex][charIndex - 1]; + box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width; + } + return box; + } + + /** + * Calculate height of line at 'lineIndex' + * @param {Number} lineIndex index of line to calculate + * @return {Number} + */ + getHeightOfLine(lineIndex) { + if (this.__lineHeights[lineIndex]) { + return this.__lineHeights[lineIndex]; + } + + // char 0 is measured before the line cycle because it needs to char + // emptylines + let maxHeight = this.getHeightOfChar(lineIndex, 0); + for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) { + maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight); + } + return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; + } + + /** + * Calculate text box height + */ + calcTextHeight() { + let lineHeight, + height = 0; + for (let i = 0, len = this._textLines.length; i < len; i++) { + lineHeight = this.getHeightOfLine(i); + height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight; + } + return height; + } + + /** + * @private + * @return {Number} Left offset + */ + _getLeftOffset() { + return this.direction === 'ltr' ? -this.width / 2 : this.width / 2; + } + + /** + * @private + * @return {Number} Top offset + */ + _getTopOffset() { + return -this.height / 2; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} method Method name ("fillText" or "strokeText") + */ + _renderTextCommon(ctx, method) { + ctx.save(); + let lineHeights = 0; + const left = this._getLeftOffset(), + top = this._getTopOffset(); + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i), + maxHeight = heightOfLine / this.lineHeight, + leftOffset = this._getLineLeftOffset(i); + this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset, top + lineHeights + maxHeight, i); + lineHeights += heightOfLine; + } + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextFill(ctx) { + if (!this.fill && !this.styleHas(FILL)) { + return; + } + this._renderTextCommon(ctx, 'fillText'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextStroke(ctx) { + if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { + return; + } + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + ctx.save(); + this._setLineDash(ctx, this.strokeDashArray); + ctx.beginPath(); + this._renderTextCommon(ctx, 'strokeText'); + ctx.closePath(); + ctx.restore(); + } + + /** + * @private + * @param {String} method fillText or strokeText. + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} line Content of the line, splitted in an array by grapheme + * @param {Number} left + * @param {Number} top + * @param {Number} lineIndex + */ + _renderChars(method, ctx, line, left, top, lineIndex) { + const lineHeight = this.getHeightOfLine(lineIndex), + isJustify = this.textAlign.includes(JUSTIFY), + path = this.path, + shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path, + isLtr = this.direction === 'ltr', + sign = this.direction === 'ltr' ? 1 : -1, + // this was changed in the PR #7674 + // currentDirection = ctx.canvas.getAttribute('dir'); + currentDirection = ctx.direction; + let actualStyle, + nextStyle, + charsToRender = '', + charBox, + boxWidth = 0, + timeToRender, + drawingLeft; + ctx.save(); + if (currentDirection !== this.direction) { + ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); + ctx.direction = isLtr ? 'ltr' : 'rtl'; + ctx.textAlign = isLtr ? LEFT : RIGHT; + } + top -= lineHeight * this._fontSizeFraction / this.lineHeight; + if (shortCut) { + // render all the line in one pass without checking + // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex); + this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top); + ctx.restore(); + return; + } + for (let i = 0, len = line.length - 1; i <= len; i++) { + timeToRender = i === len || this.charSpacing || path; + charsToRender += line[i]; + charBox = this.__charBounds[lineIndex][i]; + if (boxWidth === 0) { + left += sign * (charBox.kernedWidth - charBox.width); + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; + } + if (isJustify && !timeToRender) { + if (this._reSpaceAndTab.test(line[i])) { + timeToRender = true; + } + } + if (!timeToRender) { + // if we have charSpacing, we render char by char + actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); + nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); + timeToRender = hasStyleChanged(actualStyle, nextStyle, false); + } + if (timeToRender) { + if (path) { + ctx.save(); + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0); + ctx.restore(); + } else { + drawingLeft = left; + this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top); + } + charsToRender = ''; + actualStyle = nextStyle; + left += sign * boxWidth; + boxWidth = 0; + } + } + ctx.restore(); + } + + /** + * This function try to patch the missing gradientTransform on canvas gradients. + * transforming a context to transform the gradient, is going to transform the stroke too. + * we want to transform the gradient but not the stroke operation, so we create + * a transformed gradient on a pattern and then we use the pattern instead of the gradient. + * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size + * is limited. + * @private + * @param {TFiller} filler a fabric gradient instance + * @return {CanvasPattern} a pattern to use as fill/stroke style + */ + _applyPatternGradientTransformText(filler) { + const pCanvas = createCanvasElement(), + // TODO: verify compatibility with strokeUniform + width = this.width + this.strokeWidth, + height = this.height + this.strokeWidth, + pCtx = pCanvas.getContext('2d'); + pCanvas.width = width; + pCanvas.height = height; + pCtx.beginPath(); + pCtx.moveTo(0, 0); + pCtx.lineTo(width, 0); + pCtx.lineTo(width, height); + pCtx.lineTo(0, height); + pCtx.closePath(); + pCtx.translate(width / 2, height / 2); + pCtx.fillStyle = filler.toLive(pCtx); + this._applyPatternGradientTransform(pCtx, filler); + pCtx.fill(); + return pCtx.createPattern(pCanvas, 'no-repeat'); + } + handleFiller(ctx, property, filler) { + let offsetX, offsetY; + if (isFiller(filler)) { + if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) { + // need to transform gradient in a pattern. + // this is a slow process. If you are hitting this codepath, and the object + // is not using caching, you should consider switching it on. + // we need a canvas as big as the current object caching canvas. + offsetX = -this.width / 2; + offsetY = -this.height / 2; + ctx.translate(offsetX, offsetY); + ctx[property] = this._applyPatternGradientTransformText(filler); + return { + offsetX, + offsetY + }; + } else { + // is a simple gradient or pattern + ctx[property] = filler.toLive(ctx); + return this._applyPatternGradientTransform(ctx, filler); + } + } else { + // is a color + ctx[property] = filler; + } + return { + offsetX: 0, + offsetY: 0 + }; + } + + /** + * This function prepare the canvas for a stroke style, and stroke and strokeWidth + * need to be sent in as defined + * @param {CanvasRenderingContext2D} ctx + * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined + * @returns + */ + _setStrokeStyles(ctx, _ref) { + let { + stroke, + strokeWidth + } = _ref; + ctx.lineWidth = strokeWidth; + ctx.lineCap = this.strokeLineCap; + ctx.lineDashOffset = this.strokeDashOffset; + ctx.lineJoin = this.strokeLineJoin; + ctx.miterLimit = this.strokeMiterLimit; + return this.handleFiller(ctx, 'strokeStyle', stroke); + } + + /** + * This function prepare the canvas for a ill style, and fill + * need to be sent in as defined + * @param {CanvasRenderingContext2D} ctx + * @param {CompleteTextStyleDeclaration} style with ill defined + * @returns + */ + _setFillStyles(ctx, _ref2) { + let { + fill + } = _ref2; + return this.handleFiller(ctx, 'fillStyle', fill); + } + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {String} _char + * @param {Number} left Left coordinate + * @param {Number} top Top coordinate + * @param {Number} lineHeight Height of the line + */ + _renderChar(method, ctx, lineIndex, charIndex, _char, left, top) { + const decl = this._getStyleDeclaration(lineIndex, charIndex), + fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex), + shouldFill = method === 'fillText' && fullDecl.fill, + shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth; + if (!shouldStroke && !shouldFill) { + return; + } + ctx.save(); + ctx.font = this._getFontDeclaration(fullDecl); + if (decl.textBackgroundColor) { + this._removeShadow(ctx); + } + if (decl.deltaY) { + top += decl.deltaY; + } + if (shouldFill) { + const fillOffsets = this._setFillStyles(ctx, fullDecl); + ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY); + } + if (shouldStroke) { + const strokeOffsets = this._setStrokeStyles(ctx, fullDecl); + ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY); + } + ctx.restore(); + } + + /** + * Turns the character into a 'superior figure' (i.e. 'superscript') + * @param {Number} start selection start + * @param {Number} end selection end + */ + setSuperscript(start, end) { + this._setScript(start, end, this.superscript); + } + + /** + * Turns the character into an 'inferior figure' (i.e. 'subscript') + * @param {Number} start selection start + * @param {Number} end selection end + */ + setSubscript(start, end) { + this._setScript(start, end, this.subscript); + } + + /** + * Applies 'schema' at given position + * @private + * @param {Number} start selection start + * @param {Number} end selection end + * @param {Number} schema + */ + _setScript(start, end, schema) { + const loc = this.get2DCursorLocation(start, true), + fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'), + dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'), + style = { + fontSize: fontSize * schema.size, + deltaY: dy + fontSize * schema.baseline + }; + this.setSelectionStyles(style, start, end); + } + + /** + * @private + * @param {Number} lineIndex index text line + * @return {Number} Line left offset + */ + _getLineLeftOffset(lineIndex) { + const lineWidth = this.getLineWidth(lineIndex), + lineDiff = this.width - lineWidth, + textAlign = this.textAlign, + direction = this.direction, + isEndOfWrapping = this.isEndOfWrapping(lineIndex); + let leftOffset = 0; + if (textAlign === JUSTIFY || textAlign === JUSTIFY_CENTER && !isEndOfWrapping || textAlign === JUSTIFY_RIGHT && !isEndOfWrapping || textAlign === JUSTIFY_LEFT && !isEndOfWrapping) { + return 0; + } + if (textAlign === CENTER) { + leftOffset = lineDiff / 2; + } + if (textAlign === RIGHT) { + leftOffset = lineDiff; + } + if (textAlign === JUSTIFY_CENTER) { + leftOffset = lineDiff / 2; + } + if (textAlign === JUSTIFY_RIGHT) { + leftOffset = lineDiff; + } + if (direction === 'rtl') { + if (textAlign === RIGHT || textAlign === JUSTIFY || textAlign === JUSTIFY_RIGHT) { + leftOffset = 0; + } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) { + leftOffset = -lineDiff; + } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) { + leftOffset = -lineDiff / 2; + } + } + return leftOffset; + } + + /** + * @private + */ + _clearCache() { + this._forceClearCache = false; + this.__lineWidths = []; + this.__lineHeights = []; + this.__charBounds = []; + } + + /** + * Measure a single line given its index. Used to calculate the initial + * text bounding box. The values are calculated and stored in __lineWidths cache. + * @private + * @param {Number} lineIndex line number + * @return {Number} Line width + */ + getLineWidth(lineIndex) { + if (this.__lineWidths[lineIndex] !== undefined) { + return this.__lineWidths[lineIndex]; + } + const { + width + } = this.measureLine(lineIndex); + this.__lineWidths[lineIndex] = width; + return width; + } + _getWidthOfCharSpacing() { + if (this.charSpacing !== 0) { + return this.fontSize * this.charSpacing / 1000; + } + return 0; + } + + /** + * Retrieves the value of property at given character position + * @param {Number} lineIndex the line number + * @param {Number} charIndex the character number + * @param {String} property the property name + * @returns the value of 'property' + */ + getValueOfPropertyAt(lineIndex, charIndex, property) { + var _charStyle$property; + const charStyle = this._getStyleDeclaration(lineIndex, charIndex); + return (_charStyle$property = charStyle[property]) !== null && _charStyle$property !== void 0 ? _charStyle$property : this[property]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextDecoration(ctx, type) { + if (!this[type] && !this.styleHas(type)) { + return; + } + let topOffset = this._getTopOffset(); + const leftOffset = this._getLeftOffset(), + path = this.path, + charSpacing = this._getWidthOfCharSpacing(), + offsetY = this.offsets[type]; + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i); + if (!this[type] && !this.styleHas(type, i)) { + topOffset += heightOfLine; + continue; + } + const line = this._textLines[i]; + const maxHeight = heightOfLine / this.lineHeight; + const lineLeftOffset = this._getLineLeftOffset(i); + let boxStart = 0; + let boxWidth = 0; + let lastDecoration = this.getValueOfPropertyAt(i, 0, type); + let lastFill = this.getValueOfPropertyAt(i, 0, FILL); + let currentDecoration; + let currentFill; + const top = topOffset + maxHeight * (1 - this._fontSizeFraction); + let size = this.getHeightOfChar(i, 0); + let dy = this.getValueOfPropertyAt(i, 0, 'deltaY'); + for (let j = 0, jlen = line.length; j < jlen; j++) { + const charBox = this.__charBounds[i][j]; + currentDecoration = this.getValueOfPropertyAt(i, j, type); + currentFill = this.getValueOfPropertyAt(i, j, FILL); + const currentSize = this.getHeightOfChar(i, j); + const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY'); + if (path && currentDecoration && currentFill) { + ctx.save(); + // bug? verify lastFill is a valid fill here. + ctx.fillStyle = lastFill; + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + ctx.fillRect(-charBox.kernedWidth / 2, offsetY * currentSize + currentDy, charBox.kernedWidth, this.fontSize / 15); + ctx.restore(); + } else if ((currentDecoration !== lastDecoration || currentFill !== lastFill || currentSize !== size || currentDy !== dy) && boxWidth > 0) { + let drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + if (lastDecoration && lastFill) { + // bug? verify lastFill is a valid fill here. + ctx.fillStyle = lastFill; + ctx.fillRect(drawStart, top + offsetY * size + dy, boxWidth, this.fontSize / 15); + } + boxStart = charBox.left; + boxWidth = charBox.width; + lastDecoration = currentDecoration; + lastFill = currentFill; + size = currentSize; + dy = currentDy; + } else { + boxWidth += charBox.kernedWidth; + } + } + let drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = currentFill; + currentDecoration && currentFill && ctx.fillRect(drawStart, top + offsetY * size + dy, boxWidth - charSpacing, this.fontSize / 15); + topOffset += heightOfLine; + } + // if there is text background color no + // other shadows should be casted + this._removeShadow(ctx); + } + + /** + * return font declaration string for canvas context + * @param {Object} [styleObject] object + * @returns {String} font declaration formatted for canvas context. + */ + _getFontDeclaration() { + let { + fontFamily = this.fontFamily, + fontStyle = this.fontStyle, + fontWeight = this.fontWeight, + fontSize = this.fontSize + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let forMeasuring = arguments.length > 1 ? arguments[1] : undefined; + const parsedFontFamily = fontFamily.includes("'") || fontFamily.includes('"') || fontFamily.includes(',') || FabricText.genericFonts.includes(fontFamily.toLowerCase()) ? fontFamily : "\"".concat(fontFamily, "\""); + return [fontStyle, fontWeight, "".concat(forMeasuring ? this.CACHE_FONT_SIZE : fontSize, "px"), parsedFontFamily].join(' '); + } + + /** + * Renders text instance on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + if (!this.visible) { + return; + } + if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { + return; + } + if (this._forceClearCache) { + this.initDimensions(); + } + super.render(ctx); + } + + /** + * Override this method to customize grapheme splitting + * @todo the util `graphemeSplit` needs to be injectable in some way. + * is more comfortable to inject the correct util rather than having to override text + * in the middle of the prototype chain + * @param {string} value + * @returns {string[]} array of graphemes + */ + graphemeSplit(value) { + return graphemeSplit(value); + } + + /** + * Returns the text as an array of lines. + * @param {String} text text to split + * @returns Lines in the text + */ + _splitTextIntoLines(text) { + const lines = text.split(this._reNewline), + newLines = new Array(lines.length), + newLine = ['\n']; + let newText = []; + for (let i = 0; i < lines.length; i++) { + newLines[i] = this.graphemeSplit(lines[i]); + newText = newText.concat(newLines[i], newLine); + } + newText.pop(); + return { + _unwrappedLines: newLines, + lines: lines, + graphemeText: newText, + graphemeLines: newLines + }; + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject([...additionalProps, ...propertiesToInclude])), {}, { + styles: stylesToArray(this.styles, this.text) + }, this.path ? { + path: this.path.toObject() + } : {}); + } + set(key, value) { + const { + textLayoutProperties + } = this.constructor; + super.set(key, value); + let needsDims = false; + let isAddingPath = false; + if (typeof key === 'object') { + for (const _key in key) { + if (_key === 'path') { + this.setPathInfo(); + } + needsDims = needsDims || textLayoutProperties.includes(_key); + isAddingPath = isAddingPath || _key === 'path'; + } + } else { + needsDims = textLayoutProperties.includes(key); + isAddingPath = key === 'path'; + } + if (isAddingPath) { + this.setPathInfo(); + } + if (needsDims && this.initialized) { + this.initDimensions(); + this.setCoords(); + } + return this; + } + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity() { + return 1; + } + /** + * Returns FabricText instance from an SVG element (not yet implemented) + * @static + * @memberOf Text + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const parsedAttributes = parseAttributes(element, FabricText.ATTRIBUTE_NAMES, cssRules); + const _options$parsedAttrib = _objectSpread2(_objectSpread2({}, options), parsedAttributes), + { + textAnchor = LEFT, + textDecoration = '', + dx = 0, + dy = 0, + top = 0, + left = 0, + fontSize = DEFAULT_SVG_FONT_SIZE, + strokeWidth = 1 + } = _options$parsedAttrib, + restOfOptions = _objectWithoutProperties(_options$parsedAttrib, _excluded$3); + const textContent = (element.textContent || '').replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); + + // this code here is probably the usual issue for SVG center find + // this can later looked at again and probably removed. + + const text = new this(textContent, _objectSpread2({ + left: left + dx, + top: top + dy, + underline: textDecoration.includes('underline'), + overline: textDecoration.includes('overline'), + linethrough: textDecoration.includes('line-through'), + // we initialize this as 0 + strokeWidth: 0, + fontSize + }, restOfOptions)), + textHeightScaleFactor = text.getScaledHeight() / text.height, + lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, + scaledDiff = lineHeightDiff * textHeightScaleFactor, + textHeight = text.getScaledHeight() + scaledDiff; + let offX = 0; + /* + Adjust positioning: + x/y attributes in SVG correspond to the bottom-left corner of text bounding box + fabric output by default at top, left. + */ + if (textAnchor === CENTER) { + offX = text.getScaledWidth() / 2; + } + if (textAnchor === RIGHT) { + offX = text.getScaledWidth(); + } + text.set({ + left: text.left - offX, + top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight, + strokeWidth + }); + return text; + } + + /* _FROM_SVG_END_ */ + + /** + * Returns FabricText instance from an object representation + * @param {Object} object plain js Object to create an instance from + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(_objectSpread2(_objectSpread2({}, object), {}, { + styles: stylesFromArray(object.styles || {}, object.text) + }), { + extraParam: 'text' + }); + } +} +/** + * Properties that requires a text layout recalculation when changed + * @type string[] + * @protected + */ +_defineProperty(FabricText, "textLayoutProperties", textLayoutProperties); +_defineProperty(FabricText, "cacheProperties", [...cacheProperties, ...additionalProps]); +_defineProperty(FabricText, "ownDefaults", textDefaultValues); +_defineProperty(FabricText, "type", 'Text'); +_defineProperty(FabricText, "genericFonts", ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']); +/* _FROM_SVG_START_ */ +/** + * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement}) + * @static + * @memberOf Text + * @see: http://www.w3.org/TR/SVG/text.html#TextElement + */ +_defineProperty(FabricText, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat('x', 'y', 'dx', 'dy', 'font-family', 'font-style', 'font-weight', 'font-size', 'letter-spacing', 'text-decoration', 'text-anchor')); +applyMixins(FabricText, [TextSVGExportMixin]); +classRegistry.setClass(FabricText); +classRegistry.setSVGClass(FabricText); + +/** + * #### Dragging IText/Textbox Lifecycle + * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection} + * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection + * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session + * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur + * - canvas fires relevant drag events that are handled by the handlers defined in this scope + * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior + * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown` + */ +class DraggableTextDelegate { + constructor(target) { + _defineProperty(this, "target", void 0); + _defineProperty(this, "__mouseDownInPlace", false); + _defineProperty(this, "__dragStartFired", false); + _defineProperty(this, "__isDraggingOver", false); + _defineProperty(this, "__dragStartSelection", void 0); + _defineProperty(this, "__dragImageDisposer", void 0); + _defineProperty(this, "_dispose", void 0); + this.target = target; + const disposers = [this.target.on('dragenter', this.dragEnterHandler.bind(this)), this.target.on('dragover', this.dragOverHandler.bind(this)), this.target.on('dragleave', this.dragLeaveHandler.bind(this)), this.target.on('dragend', this.dragEndHandler.bind(this)), this.target.on('drop', this.dropHandler.bind(this))]; + this._dispose = () => { + disposers.forEach(d => d()); + this._dispose = undefined; + }; + } + isPointerOverSelection(e) { + const target = this.target; + const newSelection = target.getSelectionStartFromPointer(e); + return target.isEditing && newSelection >= target.selectionStart && newSelection <= target.selectionEnd && target.selectionStart < target.selectionEnd; + } + + /** + * @public override this method to disable dragging and default to mousedown logic + */ + start(e) { + return this.__mouseDownInPlace = this.isPointerOverSelection(e); + } + + /** + * @public override this method to disable dragging without discarding selection + */ + isActive() { + return this.__mouseDownInPlace; + } + + /** + * Ends interaction and sets cursor in case of a click + * @returns true if was active + */ + end(e) { + const active = this.isActive(); + if (active && !this.__dragStartFired) { + // mousedown has been blocked since `active` is true => cursor has not been set. + // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection. + // meaning this is actually a click, `active` is a false positive. + this.target.setCursorByClick(e); + this.target.initDelayedCursor(true); + } + this.__mouseDownInPlace = false; + this.__dragStartFired = false; + this.__isDraggingOver = false; + return active; + } + getDragStartSelection() { + return this.__dragStartSelection; + } + + /** + * Override to customize the drag image + * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage + */ + setDragImage(e, _ref) { + var _e$dataTransfer; + let { + selectionStart, + selectionEnd + } = _ref; + const target = this.target; + const canvas = target.canvas; + const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1); + const boundaries = target._getCursorBoundaries(selectionStart); + const selectionPosition = new Point(boundaries.left + boundaries.leftOffset, boundaries.top + boundaries.topOffset).multiply(flipFactor); + const pos = selectionPosition.transform(target.calcTransformMatrix()); + const pointer = canvas.getScenePoint(e); + const diff = pointer.subtract(pos); + const retinaScaling = target.getCanvasRetinaScaling(); + const bbox = target.getBoundingRect(); + const correction = pos.subtract(new Point(bbox.left, bbox.top)); + const vpt = canvas.viewportTransform; + const offset = correction.add(diff).transform(vpt, true); + // prepare instance for drag image snapshot by making all non selected text invisible + const bgc = target.backgroundColor; + const styles = cloneStyles(target.styles); + target.backgroundColor = ''; + const styleOverride = { + stroke: 'transparent', + fill: 'transparent', + textBackgroundColor: 'transparent' + }; + target.setSelectionStyles(styleOverride, 0, selectionStart); + target.setSelectionStyles(styleOverride, selectionEnd, target.text.length); + target.dirty = true; + const dragImage = target.toCanvasElement({ + enableRetinaScaling: canvas.enableRetinaScaling, + viewportTransform: true + }); + // restore values + target.backgroundColor = bgc; + target.styles = styles; + target.dirty = true; + // position drag image offscreen + setStyle(dragImage, { + position: 'fixed', + left: "".concat(-dragImage.width, "px"), + border: NONE, + width: "".concat(dragImage.width / retinaScaling, "px"), + height: "".concat(dragImage.height / retinaScaling, "px") + }); + this.__dragImageDisposer && this.__dragImageDisposer(); + this.__dragImageDisposer = () => { + dragImage.remove(); + }; + getDocumentFromElement(e.target || this.target.hiddenTextarea).body.appendChild(dragImage); + (_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 || _e$dataTransfer.setDragImage(dragImage, offset.x, offset.y); + } + + /** + * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source + */ + onDragStart(e) { + this.__dragStartFired = true; + const target = this.target; + const active = this.isActive(); + if (active && e.dataTransfer) { + const selection = this.__dragStartSelection = { + selectionStart: target.selectionStart, + selectionEnd: target.selectionEnd + }; + const value = target._text.slice(selection.selectionStart, selection.selectionEnd).join(''); + const data = _objectSpread2({ + text: target.text, + value + }, selection); + e.dataTransfer.setData('text/plain', value); + e.dataTransfer.setData('application/fabric', JSON.stringify({ + value: value, + styles: target.getSelectionStyles(selection.selectionStart, selection.selectionEnd, true) + })); + e.dataTransfer.effectAllowed = 'copyMove'; + this.setDragImage(e, data); + } + target.abortCursorAnimation(); + return active; + } + + /** + * use {@link targetCanDrop} to respect overriding + * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target + */ + canDrop(e) { + if (this.target.editable && !this.target.getActiveControl() && !e.defaultPrevented) { + if (this.isActive() && this.__dragStartSelection) { + // drag source trying to drop over itself + // allow dropping only outside of drag start selection + const index = this.target.getSelectionStartFromPointer(e); + const dragStartSelection = this.__dragStartSelection; + return index < dragStartSelection.selectionStart || index > dragStartSelection.selectionEnd; + } + return true; + } + return false; + } + + /** + * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly + */ + targetCanDrop(e) { + return this.target.canDrop(e); + } + dragEnterHandler(_ref2) { + let { + e + } = _ref2; + const canDrop = this.targetCanDrop(e); + if (!this.__isDraggingOver && canDrop) { + this.__isDraggingOver = true; + } + } + dragOverHandler(ev) { + const { + e + } = ev; + const canDrop = this.targetCanDrop(e); + if (!this.__isDraggingOver && canDrop) { + this.__isDraggingOver = true; + } else if (this.__isDraggingOver && !canDrop) { + // drop state has changed + this.__isDraggingOver = false; + } + if (this.__isDraggingOver) { + // can be dropped, inform browser + e.preventDefault(); + // inform event subscribers + ev.canDrop = true; + ev.dropTarget = this.target; + } + } + dragLeaveHandler() { + if (this.__isDraggingOver || this.isActive()) { + this.__isDraggingOver = false; + } + } + + /** + * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer} + * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop + */ + dropHandler(ev) { + var _e$dataTransfer2; + const { + e + } = ev; + const didDrop = e.defaultPrevented; + this.__isDraggingOver = false; + // inform browser that the drop has been accepted + e.preventDefault(); + let insert = (_e$dataTransfer2 = e.dataTransfer) === null || _e$dataTransfer2 === void 0 ? void 0 : _e$dataTransfer2.getData('text/plain'); + if (insert && !didDrop) { + const target = this.target; + const canvas = target.canvas; + let insertAt = target.getSelectionStartFromPointer(e); + const { + styles + } = e.dataTransfer.types.includes('application/fabric') ? JSON.parse(e.dataTransfer.getData('application/fabric')) : {}; + const trailing = insert[Math.max(0, insert.length - 1)]; + const selectionStartOffset = 0; + // drag and drop in same instance + if (this.__dragStartSelection) { + const selectionStart = this.__dragStartSelection.selectionStart; + const selectionEnd = this.__dragStartSelection.selectionEnd; + if (insertAt > selectionStart && insertAt <= selectionEnd) { + insertAt = selectionStart; + } else if (insertAt > selectionEnd) { + insertAt -= selectionEnd - selectionStart; + } + target.removeChars(selectionStart, selectionEnd); + // prevent `dragend` from handling event + delete this.__dragStartSelection; + } + // remove redundant line break + if (target._reNewline.test(trailing) && (target._reNewline.test(target._text[insertAt]) || insertAt === target._text.length)) { + insert = insert.trimEnd(); + } + // inform subscribers + ev.didDrop = true; + ev.dropTarget = target; + // finalize + target.insertChars(insert, styles, insertAt); + // can this part be moved in an outside event? andrea to check. + canvas.setActiveObject(target); + target.enterEditing(e); + target.selectionStart = Math.min(insertAt + selectionStartOffset, target._text.length); + target.selectionEnd = Math.min(target.selectionStart + insert.length, target._text.length); + target.hiddenTextarea.value = target.text; + target._updateTextarea(); + target.hiddenTextarea.focus(); + target.fire(CHANGED, { + index: insertAt + selectionStartOffset, + action: 'drop' + }); + canvas.fire('text:changed', { + target + }); + canvas.contextTopDirty = true; + canvas.requestRenderAll(); + } + } + + /** + * fired only on the drag source after drop (if occurred) + * handle changes to the drag source in case of a drop on another object or a cancellation + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag + */ + dragEndHandler(_ref3) { + let { + e + } = _ref3; + if (this.isActive() && this.__dragStartFired) { + // once the drop event finishes we check if we need to change the drag source + // if the drag source received the drop we bail out since the drop handler has already handled logic + if (this.__dragStartSelection) { + var _e$dataTransfer3; + const target = this.target; + const canvas = this.target.canvas; + const { + selectionStart, + selectionEnd + } = this.__dragStartSelection; + const dropEffect = ((_e$dataTransfer3 = e.dataTransfer) === null || _e$dataTransfer3 === void 0 ? void 0 : _e$dataTransfer3.dropEffect) || NONE; + if (dropEffect === NONE) { + // pointer is back over selection + target.selectionStart = selectionStart; + target.selectionEnd = selectionEnd; + target._updateTextarea(); + target.hiddenTextarea.focus(); + } else { + target.clearContextTop(); + if (dropEffect === 'move') { + target.removeChars(selectionStart, selectionEnd); + target.selectionStart = target.selectionEnd = selectionStart; + target.hiddenTextarea && (target.hiddenTextarea.value = target.text); + target._updateTextarea(); + target.fire(CHANGED, { + index: selectionStart, + action: 'dragend' + }); + canvas.fire('text:changed', { + target + }); + canvas.requestRenderAll(); + } + target.exitEditing(); + } + } + } + this.__dragImageDisposer && this.__dragImageDisposer(); + delete this.__dragImageDisposer; + delete this.__dragStartSelection; + this.__isDraggingOver = false; + } + dispose() { + this._dispose && this._dispose(); + } +} + +/** + * extend this regex to support non english languages + * + * - ` ` Matches a SPACE character (char code 32). + * - `\n` Matches a LINE FEED character (char code 10). + * - `\.` Matches a "." character (char code 46). + * - `,` Matches a "," character (char code 44). + * - `;` Matches a ";" character (char code 59). + * - `!` Matches a "!" character (char code 33). + * - `\?` Matches a "?" character (char code 63). + * - `\-` Matches a "-" character (char code 45). + */ +// eslint-disable-next-line no-useless-escape +const reNonWord = /[ \n\.,;!\?\-]/; +class ITextBehavior extends FabricText { + constructor() { + super(...arguments); + /** + * Helps determining when the text is in composition, so that the cursor + * rendering is altered. + */ + _defineProperty(this, "_currentCursorOpacity", 1); + } + /** + * Initializes all the interactive behavior of IText + */ + initBehavior() { + this._tick = this._tick.bind(this); + this._onTickComplete = this._onTickComplete.bind(this); + this.updateSelectionOnMouseMove = this.updateSelectionOnMouseMove.bind(this); + } + onDeselect(options) { + this.isEditing && this.exitEditing(); + this.selected = false; + return super.onDeselect(options); + } + + /** + * @private + */ + _animateCursor(_ref) { + let { + toValue, + duration, + delay, + onComplete + } = _ref; + return animate({ + startValue: this._currentCursorOpacity, + endValue: toValue, + duration, + delay, + onComplete, + abort: () => !this.canvas || + // we do not want to animate a selection, only cursor + this.selectionStart !== this.selectionEnd, + onChange: value => { + this._currentCursorOpacity = value; + this.renderCursorOrSelection(); + } + }); + } + + /** + * changes the cursor from visible to invisible + */ + _tick(delay) { + this._currentTickState = this._animateCursor({ + toValue: 0, + duration: this.cursorDuration / 2, + delay: Math.max(delay || 0, 100), + onComplete: this._onTickComplete + }); + } + + /** + * Changes the cursor from invisible to visible + */ + _onTickComplete() { + var _this$_currentTickCom; + (_this$_currentTickCom = this._currentTickCompleteState) === null || _this$_currentTickCom === void 0 || _this$_currentTickCom.abort(); + this._currentTickCompleteState = this._animateCursor({ + toValue: 1, + duration: this.cursorDuration, + onComplete: this._tick + }); + } + + /** + * Initializes delayed cursor + */ + initDelayedCursor(restart) { + this.abortCursorAnimation(); + this._tick(restart ? 0 : this.cursorDelay); + } + + /** + * Aborts cursor animation, clears all timeouts and clear textarea context if necessary + */ + abortCursorAnimation() { + let shouldClear = false; + [this._currentTickState, this._currentTickCompleteState].forEach(cursorAnimation => { + if (cursorAnimation && !cursorAnimation.isDone()) { + shouldClear = true; + cursorAnimation.abort(); + } + }); + this._currentCursorOpacity = 1; + + // make sure we clear context even if instance is not editing + if (shouldClear) { + this.clearContextTop(); + } + } + + /** + * Restart tue cursor animation if either is in complete state ( between animations ) + * or if it never started before + */ + restartCursorIfNeeded() { + if ([this._currentTickState, this._currentTickCompleteState].some(cursorAnimation => !cursorAnimation || cursorAnimation.isDone())) { + this.initDelayedCursor(); + } + } + + /** + * Selects entire text + */ + selectAll() { + this.selectionStart = 0; + this.selectionEnd = this._text.length; + this._fireSelectionChanged(); + this._updateTextarea(); + return this; + } + + /** + * Returns selected text + * @return {String} + */ + getSelectedText() { + return this._text.slice(this.selectionStart, this.selectionEnd).join(''); + } + + /** + * Find new selection index representing start of current word according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findWordBoundaryLeft(startFrom) { + let offset = 0, + index = startFrom - 1; + + // remove space before cursor first + if (this._reSpace.test(this._text[index])) { + while (this._reSpace.test(this._text[index])) { + offset++; + index--; + } + } + while (/\S/.test(this._text[index]) && index > -1) { + offset++; + index--; + } + return startFrom - offset; + } + + /** + * Find new selection index representing end of current word according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findWordBoundaryRight(startFrom) { + let offset = 0, + index = startFrom; + + // remove space after cursor first + if (this._reSpace.test(this._text[index])) { + while (this._reSpace.test(this._text[index])) { + offset++; + index++; + } + } + while (/\S/.test(this._text[index]) && index < this._text.length) { + offset++; + index++; + } + return startFrom + offset; + } + + /** + * Find new selection index representing start of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryLeft(startFrom) { + let offset = 0, + index = startFrom - 1; + while (!/\n/.test(this._text[index]) && index > -1) { + offset++; + index--; + } + return startFrom - offset; + } + + /** + * Find new selection index representing end of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryRight(startFrom) { + let offset = 0, + index = startFrom; + while (!/\n/.test(this._text[index]) && index < this._text.length) { + offset++; + index++; + } + return startFrom + offset; + } + + /** + * Finds index corresponding to beginning or end of a word + * @param {Number} selectionStart Index of a character + * @param {Number} direction 1 or -1 + * @return {Number} Index of the beginning or end of a word + */ + searchWordBoundary(selectionStart, direction) { + const text = this._text; + // if we land on a space we move the cursor backwards + // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break + let index = selectionStart > 0 && this._reSpace.test(text[selectionStart]) && (direction === -1 || !reNewline.test(text[selectionStart - 1])) ? selectionStart - 1 : selectionStart, + _char = text[index]; + while (index > 0 && index < text.length && !reNonWord.test(_char)) { + index += direction; + _char = text[index]; + } + if (direction === -1 && reNonWord.test(_char)) { + index++; + } + return index; + } + + /** + * TODO fix: selectionStart set as 0 will be ignored? + * Selects a word based on the index + * @param {Number} selectionStart Index of a character + */ + selectWord(selectionStart) { + selectionStart = selectionStart || this.selectionStart; + // search backwards + const newSelectionStart = this.searchWordBoundary(selectionStart, -1), + // search forward + newSelectionEnd = Math.max(newSelectionStart, this.searchWordBoundary(selectionStart, 1)); + this.selectionStart = newSelectionStart; + this.selectionEnd = newSelectionEnd; + this._fireSelectionChanged(); + this._updateTextarea(); + this.renderCursorOrSelection(); + } + + /** + * TODO fix: selectionStart set as 0 will be ignored? + * Selects a line based on the index + * @param {Number} selectionStart Index of a character + */ + selectLine(selectionStart) { + selectionStart = selectionStart || this.selectionStart; + const newSelectionStart = this.findLineBoundaryLeft(selectionStart), + newSelectionEnd = this.findLineBoundaryRight(selectionStart); + this.selectionStart = newSelectionStart; + this.selectionEnd = newSelectionEnd; + this._fireSelectionChanged(); + this._updateTextarea(); + return this; + } + + /** + * Enters editing state + */ + enterEditing(e) { + if (this.isEditing || !this.editable) { + return; + } + if (this.canvas) { + this.canvas.calcOffset(); + this.canvas.textEditingManager.exitTextEditing(); + } + this.isEditing = true; + this.initHiddenTextarea(); + this.hiddenTextarea.focus(); + this.hiddenTextarea.value = this.text; + this._updateTextarea(); + this._saveEditingProps(); + this._setEditingProps(); + this._textBeforeEdit = this.text; + this._tick(); + this.fire('editing:entered', e ? { + e + } : undefined); + this._fireSelectionChanged(); + if (this.canvas) { + this.canvas.fire('text:editing:entered', { + target: this, + e + }); + this.canvas.requestRenderAll(); + } + } + + /** + * called by {@link Canvas#textEditingManager} + */ + updateSelectionOnMouseMove(e) { + if (this.getActiveControl()) { + return; + } + const el = this.hiddenTextarea; + // regain focus + getDocumentFromElement(el).activeElement !== el && el.focus(); + const newSelectionStart = this.getSelectionStartFromPointer(e), + currentStart = this.selectionStart, + currentEnd = this.selectionEnd; + if ((newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) && (currentStart === newSelectionStart || currentEnd === newSelectionStart)) { + return; + } + if (newSelectionStart > this.__selectionStartOnMouseDown) { + this.selectionStart = this.__selectionStartOnMouseDown; + this.selectionEnd = newSelectionStart; + } else { + this.selectionStart = newSelectionStart; + this.selectionEnd = this.__selectionStartOnMouseDown; + } + if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) { + this._fireSelectionChanged(); + this._updateTextarea(); + this.renderCursorOrSelection(); + } + } + + /** + * @private + */ + _setEditingProps() { + this.hoverCursor = 'text'; + if (this.canvas) { + this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; + } + this.borderColor = this.editingBorderColor; + this.hasControls = this.selectable = false; + this.lockMovementX = this.lockMovementY = true; + } + + /** + * convert from textarea to grapheme indexes + */ + fromStringToGraphemeSelection(start, end, text) { + const smallerTextStart = text.slice(0, start), + graphemeStart = this.graphemeSplit(smallerTextStart).length; + if (start === end) { + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + }; + } + const smallerTextEnd = text.slice(start, end), + graphemeEnd = this.graphemeSplit(smallerTextEnd).length; + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + graphemeEnd + }; + } + + /** + * convert from fabric to textarea values + */ + fromGraphemeToStringSelection(start, end, graphemes) { + const smallerTextStart = graphemes.slice(0, start), + graphemeStart = smallerTextStart.join('').length; + if (start === end) { + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + }; + } + const smallerTextEnd = graphemes.slice(start, end), + graphemeEnd = smallerTextEnd.join('').length; + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + graphemeEnd + }; + } + + /** + * @private + */ + _updateTextarea() { + this.cursorOffsetCache = {}; + if (!this.hiddenTextarea) { + return; + } + if (!this.inCompositionMode) { + const newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text); + this.hiddenTextarea.selectionStart = newSelection.selectionStart; + this.hiddenTextarea.selectionEnd = newSelection.selectionEnd; + } + this.updateTextareaPosition(); + } + + /** + * @private + */ + updateFromTextArea() { + if (!this.hiddenTextarea) { + return; + } + this.cursorOffsetCache = {}; + const textarea = this.hiddenTextarea; + this.text = textarea.value; + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + const newSelection = this.fromStringToGraphemeSelection(textarea.selectionStart, textarea.selectionEnd, textarea.value); + this.selectionEnd = this.selectionStart = newSelection.selectionEnd; + if (!this.inCompositionMode) { + this.selectionStart = newSelection.selectionStart; + } + this.updateTextareaPosition(); + } + + /** + * @private + */ + updateTextareaPosition() { + if (this.selectionStart === this.selectionEnd) { + const style = this._calcTextareaPosition(); + this.hiddenTextarea.style.left = style.left; + this.hiddenTextarea.style.top = style.top; + } + } + + /** + * @private + * @return {Object} style contains style for hiddenTextarea + */ + _calcTextareaPosition() { + if (!this.canvas) { + return { + left: '1px', + top: '1px' + }; + } + const desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart, + boundaries = this._getCursorBoundaries(desiredPosition), + cursorLocation = this.get2DCursorLocation(desiredPosition), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex, + charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight, + leftOffset = boundaries.leftOffset, + retinaScaling = this.getCanvasRetinaScaling(), + upperCanvas = this.canvas.upperCanvasEl, + upperCanvasWidth = upperCanvas.width / retinaScaling, + upperCanvasHeight = upperCanvas.height / retinaScaling, + maxWidth = upperCanvasWidth - charHeight, + maxHeight = upperCanvasHeight - charHeight; + const p = new Point(boundaries.left + leftOffset, boundaries.top + boundaries.topOffset + charHeight).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new Point(upperCanvas.clientWidth / upperCanvasWidth, upperCanvas.clientHeight / upperCanvasHeight)); + if (p.x < 0) { + p.x = 0; + } + if (p.x > maxWidth) { + p.x = maxWidth; + } + if (p.y < 0) { + p.y = 0; + } + if (p.y > maxHeight) { + p.y = maxHeight; + } + + // add canvas offset on document + p.x += this.canvas._offset.left; + p.y += this.canvas._offset.top; + return { + left: "".concat(p.x, "px"), + top: "".concat(p.y, "px"), + fontSize: "".concat(charHeight, "px"), + charHeight: charHeight + }; + } + + /** + * @private + */ + _saveEditingProps() { + this._savedProps = { + hasControls: this.hasControls, + borderColor: this.borderColor, + lockMovementX: this.lockMovementX, + lockMovementY: this.lockMovementY, + hoverCursor: this.hoverCursor, + selectable: this.selectable, + defaultCursor: this.canvas && this.canvas.defaultCursor, + moveCursor: this.canvas && this.canvas.moveCursor + }; + } + + /** + * @private + */ + _restoreEditingProps() { + if (!this._savedProps) { + return; + } + this.hoverCursor = this._savedProps.hoverCursor; + this.hasControls = this._savedProps.hasControls; + this.borderColor = this._savedProps.borderColor; + this.selectable = this._savedProps.selectable; + this.lockMovementX = this._savedProps.lockMovementX; + this.lockMovementY = this._savedProps.lockMovementY; + if (this.canvas) { + this.canvas.defaultCursor = this._savedProps.defaultCursor || this.canvas.defaultCursor; + this.canvas.moveCursor = this._savedProps.moveCursor || this.canvas.moveCursor; + } + delete this._savedProps; + } + + /** + * runs the actual logic that exits from editing state, see {@link exitEditing} + */ + _exitEditing() { + const hiddenTextarea = this.hiddenTextarea; + this.selected = false; + this.isEditing = false; + if (hiddenTextarea) { + hiddenTextarea.blur && hiddenTextarea.blur(); + hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); + } + this.hiddenTextarea = null; + this.abortCursorAnimation(); + this.selectionStart !== this.selectionEnd && this.clearContextTop(); + } + + /** + * Exits from editing state and fires relevant events + */ + exitEditing() { + const isTextChanged = this._textBeforeEdit !== this.text; + this._exitEditing(); + this.selectionEnd = this.selectionStart; + this._restoreEditingProps(); + if (this._forceClearCache) { + this.initDimensions(); + this.setCoords(); + } + this.fire('editing:exited'); + isTextChanged && this.fire(MODIFIED); + if (this.canvas) { + this.canvas.fire('text:editing:exited', { + target: this + }); + // todo: evaluate add an action to this event + isTextChanged && this.canvas.fire('object:modified', { + target: this + }); + } + return this; + } + + /** + * @private + */ + _removeExtraneousStyles() { + for (const prop in this.styles) { + if (!this._textLines[prop]) { + delete this.styles[prop]; + } + } + } + + /** + * remove and reflow a style block from start to end. + * @param {Number} start linear start position for removal (included in removal) + * @param {Number} end linear end position for removal ( excluded from removal ) + */ + removeStyleFromTo(start, end) { + const { + lineIndex: lineStart, + charIndex: charStart + } = this.get2DCursorLocation(start, true), + { + lineIndex: lineEnd, + charIndex: charEnd + } = this.get2DCursorLocation(end, true); + if (lineStart !== lineEnd) { + // step1 remove the trailing of lineStart + if (this.styles[lineStart]) { + for (let i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) { + delete this.styles[lineStart][i]; + } + } + // step2 move the trailing of lineEnd to lineStart if needed + if (this.styles[lineEnd]) { + for (let i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) { + const styleObj = this.styles[lineEnd][i]; + if (styleObj) { + this.styles[lineStart] || (this.styles[lineStart] = {}); + this.styles[lineStart][charStart + i - charEnd] = styleObj; + } + } + } + // step3 detects lines will be completely removed. + for (let i = lineStart + 1; i <= lineEnd; i++) { + delete this.styles[i]; + } + // step4 shift remaining lines. + this.shiftLineStyles(lineEnd, lineStart - lineEnd); + } else { + // remove and shift left on the same line + if (this.styles[lineStart]) { + const styleObj = this.styles[lineStart]; + const diff = charEnd - charStart; + for (let i = charStart; i < charEnd; i++) { + delete styleObj[i]; + } + for (const char in this.styles[lineStart]) { + const numericChar = parseInt(char, 10); + if (numericChar >= charEnd) { + styleObj[numericChar - diff] = styleObj[char]; + delete styleObj[char]; + } + } + } + } + } + + /** + * Shifts line styles up or down + * @param {Number} lineIndex Index of a line + * @param {Number} offset Can any number? + */ + shiftLineStyles(lineIndex, offset) { + const clonedStyles = Object.assign({}, this.styles); + for (const line in this.styles) { + const numericLine = parseInt(line, 10); + if (numericLine > lineIndex) { + this.styles[numericLine + offset] = clonedStyles[numericLine]; + if (!clonedStyles[numericLine - offset]) { + delete this.styles[numericLine]; + } + } + } + } + + /** + * Handle insertion of more consecutive style lines for when one or more + * newlines gets added to the text. Since current style needs to be shifted + * first we shift the current style of the number lines needed, then we add + * new lines from the last to the first. + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Number} qty number of lines to add + * @param {Array} copiedStyle Array of objects styles + */ + insertNewlineStyleObject(lineIndex, charIndex, qty, copiedStyle) { + const newLineStyles = {}; + const originalLineLength = this._unwrappedTextLines[lineIndex].length; + const isEndOfLine = originalLineLength === charIndex; + let someStyleIsCarryingOver = false; + qty || (qty = 1); + this.shiftLineStyles(lineIndex, qty); + const currentCharStyle = this.styles[lineIndex] ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1] : undefined; + + // we clone styles of all chars + // after cursor onto the current line + for (const index in this.styles[lineIndex]) { + const numIndex = parseInt(index, 10); + if (numIndex >= charIndex) { + someStyleIsCarryingOver = true; + newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; + // remove lines from the previous line since they're on a new line now + if (!(isEndOfLine && charIndex === 0)) { + delete this.styles[lineIndex][index]; + } + } + } + let styleCarriedOver = false; + if (someStyleIsCarryingOver && !isEndOfLine) { + // if is end of line, the extra style we copied + // is probably not something we want + this.styles[lineIndex + qty] = newLineStyles; + styleCarriedOver = true; + } + if (styleCarriedOver || originalLineLength > charIndex) { + // skip the last line of since we already prepared it. + // or contains text without style that we don't want to style + // just because it changed lines + qty--; + } + // for the all the lines or all the other lines + // we clone current char style onto the next (otherwise empty) line + while (qty > 0) { + if (copiedStyle && copiedStyle[qty - 1]) { + this.styles[lineIndex + qty] = { + 0: _objectSpread2({}, copiedStyle[qty - 1]) + }; + } else if (currentCharStyle) { + this.styles[lineIndex + qty] = { + 0: _objectSpread2({}, currentCharStyle) + }; + } else { + delete this.styles[lineIndex + qty]; + } + qty--; + } + this._forceClearCache = true; + } + + /** + * Inserts style object for a given line/char index + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Number} quantity number Style object to insert, if given + * @param {Array} copiedStyle array of style objects + */ + insertCharStyleObject(lineIndex, charIndex, quantity, copiedStyle) { + if (!this.styles) { + this.styles = {}; + } + const currentLineStyles = this.styles[lineIndex], + currentLineStylesCloned = currentLineStyles ? _objectSpread2({}, currentLineStyles) : {}; + quantity || (quantity = 1); + // shift all char styles by quantity forward + // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 + for (const index in currentLineStylesCloned) { + const numericIndex = parseInt(index, 10); + if (numericIndex >= charIndex) { + currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; + // only delete the style if there was nothing moved there + if (!currentLineStylesCloned[numericIndex - quantity]) { + delete currentLineStyles[numericIndex]; + } + } + } + this._forceClearCache = true; + if (copiedStyle) { + while (quantity--) { + if (!Object.keys(copiedStyle[quantity]).length) { + continue; + } + if (!this.styles[lineIndex]) { + this.styles[lineIndex] = {}; + } + this.styles[lineIndex][charIndex + quantity] = _objectSpread2({}, copiedStyle[quantity]); + } + return; + } + if (!currentLineStyles) { + return; + } + const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1]; + while (newStyle && quantity--) { + this.styles[lineIndex][charIndex + quantity] = _objectSpread2({}, newStyle); + } + } + + /** + * Inserts style object(s) + * @param {Array} insertedText Characters at the location where style is inserted + * @param {Number} start cursor index for inserting style + * @param {Array} [copiedStyle] array of style objects to insert. + */ + insertNewStyleBlock(insertedText, start, copiedStyle) { + const cursorLoc = this.get2DCursorLocation(start, true), + addedLines = [0]; + let linesLength = 0; + // get an array of how many char per lines are being added. + for (let i = 0; i < insertedText.length; i++) { + if (insertedText[i] === '\n') { + linesLength++; + addedLines[linesLength] = 0; + } else { + addedLines[linesLength]++; + } + } + // for the first line copy the style from the current char position. + if (addedLines[0] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle); + copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); + } + linesLength && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength); + let i; + for (i = 1; i < linesLength; i++) { + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } else if (copiedStyle) { + // this test is required in order to close #6841 + // when a pasted buffer begins with a newline then + // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0] + // may be undefined for some reason + if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) { + this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0]; + } + } + copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); + } + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } + } + + /** + * Removes characters from start/end + * start/end ar per grapheme position in _text array. + * + * @param {Number} start + * @param {Number} end default to start + 1 + */ + removeChars(start) { + let end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : start + 1; + this.removeStyleFromTo(start, end); + this._text.splice(start, end - start); + this.text = this._text.join(''); + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + this._removeExtraneousStyles(); + } + + /** + * insert characters at start position, before start position. + * start equal 1 it means the text get inserted between actual grapheme 0 and 1 + * if style array is provided, it must be as the same length of text in graphemes + * if end is provided and is bigger than start, old text is replaced. + * start/end ar per grapheme position in _text array. + * + * @param {String} text text to insert + * @param {Array} style array of style objects + * @param {Number} start + * @param {Number} end default to start + 1 + */ + insertChars(text, style, start) { + let end = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : start; + if (end > start) { + this.removeStyleFromTo(start, end); + } + const graphemes = this.graphemeSplit(text); + this.insertNewStyleBlock(graphemes, start, style); + this._text = [...this._text.slice(0, start), ...graphemes, ...this._text.slice(end)]; + this.text = this._text.join(''); + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + this._removeExtraneousStyles(); + } + + /** + * Set the selectionStart and selectionEnd according to the new position of cursor + * mimic the key - mouse navigation when shift is pressed. + */ + setSelectionStartEndWithShift(start, end, newSelection) { + if (newSelection <= start) { + if (end === start) { + this._selectionDirection = LEFT; + } else if (this._selectionDirection === RIGHT) { + this._selectionDirection = LEFT; + this.selectionEnd = start; + } + this.selectionStart = newSelection; + } else if (newSelection > start && newSelection < end) { + if (this._selectionDirection === RIGHT) { + this.selectionEnd = newSelection; + } else { + this.selectionStart = newSelection; + } + } else { + // newSelection is > selection start and end + if (end === start) { + this._selectionDirection = RIGHT; + } else if (this._selectionDirection === LEFT) { + this._selectionDirection = RIGHT; + this.selectionStart = end; + } + this.selectionEnd = newSelection; + } + } +} + +class ITextKeyBehavior extends ITextBehavior { + /** + * For functionalities on keyDown + * Map a special key to a function of the instance/prototype + * If you need different behavior for ESC or TAB or arrows, you have to change + * this map setting the name of a function that you build on the IText or + * your prototype. + * the map change will affect all Instances unless you need for only some text Instances + * in that case you have to clone this object and assign your Instance. + * this.keysMap = Object.assign({}, this.keysMap); + * The function must be in IText.prototype.myFunction And will receive event as args[0] + */ + + /** + * For functionalities on keyUp + ctrl || cmd + */ + + /** + * For functionalities on keyDown + ctrl || cmd + */ + + /** + * DOM container to append the hiddenTextarea. + * An alternative to attaching to the document.body. + * Useful to reduce laggish redraw of the full document.body tree and + * also with modals event capturing that won't let the textarea take focus. + * @type HTMLElement + * @default + */ + + /** + * Initializes hidden textarea (needed to bring up keyboard in iOS) + */ + initHiddenTextarea() { + const doc = this.canvas && getDocumentFromElement(this.canvas.getElement()) || getFabricDocument(); + const textarea = doc.createElement('textarea'); + Object.entries({ + autocapitalize: 'off', + autocorrect: 'off', + autocomplete: 'off', + spellcheck: 'false', + 'data-fabric': 'textarea', + wrap: 'off' + }).map(_ref => { + let [attribute, value] = _ref; + return textarea.setAttribute(attribute, value); + }); + const { + top, + left, + fontSize + } = this._calcTextareaPosition(); + // line-height: 1px; was removed from the style to fix this: + // https://bugs.chromium.org/p/chromium/issues/detail?id=870966 + textarea.style.cssText = "position: absolute; top: ".concat(top, "; left: ").concat(left, "; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ").concat(fontSize, ";"); + (this.hiddenTextareaContainer || doc.body).appendChild(textarea); + Object.entries({ + blur: 'blur', + keydown: 'onKeyDown', + keyup: 'onKeyUp', + input: 'onInput', + copy: 'copy', + cut: 'copy', + paste: 'paste', + compositionstart: 'onCompositionStart', + compositionupdate: 'onCompositionUpdate', + compositionend: 'onCompositionEnd' + }).map(_ref2 => { + let [eventName, handler] = _ref2; + return textarea.addEventListener(eventName, this[handler].bind(this)); + }); + this.hiddenTextarea = textarea; + } + + /** + * Override this method to customize cursor behavior on textbox blur + */ + blur() { + this.abortCursorAnimation(); + } + + /** + * Handles keydown event + * only used for arrows and combination of modifier keys. + * @param {KeyboardEvent} e Event object + */ + onKeyDown(e) { + if (!this.isEditing) { + return; + } + const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; + if (e.keyCode in keyMap) { + // @ts-expect-error legacy method calling pattern + this[keyMap[e.keyCode]](e); + } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) { + // @ts-expect-error legacy method calling pattern + this[this.ctrlKeysMapDown[e.keyCode]](e); + } else { + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + if (e.keyCode >= 33 && e.keyCode <= 40) { + // if i press an arrow key just update selection + this.inCompositionMode = false; + this.clearContextTop(); + this.renderCursorOrSelection(); + } else { + this.canvas && this.canvas.requestRenderAll(); + } + } + + /** + * Handles keyup event + * We handle KeyUp because ie11 and edge have difficulties copy/pasting + * if a copy/cut event fired, keyup is dismissed + * @param {KeyboardEvent} e Event object + */ + onKeyUp(e) { + if (!this.isEditing || this._copyDone || this.inCompositionMode) { + this._copyDone = false; + return; + } + if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) { + // @ts-expect-error legacy method calling pattern + this[this.ctrlKeysMapUp[e.keyCode]](e); + } else { + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + this.canvas && this.canvas.requestRenderAll(); + } + + /** + * Handles onInput event + * @param {Event} e Event object + */ + onInput(e) { + const fromPaste = this.fromPaste; + this.fromPaste = false; + e && e.stopPropagation(); + if (!this.isEditing) { + return; + } + const updateAndFire = () => { + this.updateFromTextArea(); + this.fire(CHANGED); + if (this.canvas) { + this.canvas.fire('text:changed', { + target: this + }); + this.canvas.requestRenderAll(); + } + }; + if (this.hiddenTextarea.value === '') { + this.styles = {}; + updateAndFire(); + return; + } + // decisions about style changes. + const nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText, + charCount = this._text.length, + nextCharCount = nextText.length, + selectionStart = this.selectionStart, + selectionEnd = this.selectionEnd, + selection = selectionStart !== selectionEnd; + let copiedStyle, + removedText, + charDiff = nextCharCount - charCount, + removeFrom, + removeTo; + const textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); + const backDelete = selectionStart > textareaSelection.selectionStart; + if (selection) { + removedText = this._text.slice(selectionStart, selectionEnd); + charDiff += selectionEnd - selectionStart; + } else if (nextCharCount < charCount) { + if (backDelete) { + removedText = this._text.slice(selectionEnd + charDiff, selectionEnd); + } else { + removedText = this._text.slice(selectionStart, selectionStart - charDiff); + } + } + const insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); + if (removedText && removedText.length) { + if (insertedText.length) { + // let's copy some style before deleting. + // we want to copy the style before the cursor OR the style at the cursor if selection + // is bigger than 0. + copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); + // now duplicate the style one for each inserted text. + copiedStyle = insertedText.map(() => + // this return an array of references, but that is fine since we are + // copying the style later. + copiedStyle[0]); + } + if (selection) { + removeFrom = selectionStart; + removeTo = selectionEnd; + } else if (backDelete) { + // detect differences between forwardDelete and backDelete + removeFrom = selectionEnd - removedText.length; + removeTo = selectionEnd; + } else { + removeFrom = selectionEnd; + removeTo = selectionEnd + removedText.length; + } + this.removeStyleFromTo(removeFrom, removeTo); + } + if (insertedText.length) { + const { + copyPasteData + } = getEnv(); + if (fromPaste && insertedText.join('') === copyPasteData.copiedText && !config.disableStyleCopyPaste) { + copiedStyle = copyPasteData.copiedTextStyle; + } + this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle); + } + updateAndFire(); + } + + /** + * Composition start + */ + onCompositionStart() { + this.inCompositionMode = true; + } + + /** + * Composition end + */ + onCompositionEnd() { + this.inCompositionMode = false; + } + onCompositionUpdate(_ref3) { + let { + target + } = _ref3; + const { + selectionStart, + selectionEnd + } = target; + this.compositionStart = selectionStart; + this.compositionEnd = selectionEnd; + this.updateTextareaPosition(); + } + + /** + * Copies selected text + */ + copy() { + if (this.selectionStart === this.selectionEnd) { + //do not cut-copy if no selection + return; + } + const { + copyPasteData + } = getEnv(); + copyPasteData.copiedText = this.getSelectedText(); + if (!config.disableStyleCopyPaste) { + copyPasteData.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true); + } else { + copyPasteData.copiedTextStyle = undefined; + } + this._copyDone = true; + } + + /** + * Pastes text + */ + paste() { + this.fromPaste = true; + } + + /** + * Finds the width in pixels before the cursor on the same line + * @private + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {Number} widthBeforeCursor width before cursor + */ + _getWidthBeforeCursor(lineIndex, charIndex) { + let widthBeforeCursor = this._getLineLeftOffset(lineIndex), + bound; + if (charIndex > 0) { + bound = this.__charBounds[lineIndex][charIndex - 1]; + widthBeforeCursor += bound.left + bound.width; + } + return widthBeforeCursor; + } + + /** + * Gets start offset of a selection + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getDownCursorOffset(e, isRight) { + const selectionProp = this._getSelectionForOffset(e, isRight), + cursorLocation = this.get2DCursorLocation(selectionProp), + lineIndex = cursorLocation.lineIndex; + // if on last line, down cursor goes to end of line + if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { + // move to the end of a text + return this._text.length - selectionProp; + } + const charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), + textAfterCursor = this._textLines[lineIndex].slice(charIndex); + return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex); + } + + /** + * private + * Helps finding if the offset should be counted from Start or End + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + _getSelectionForOffset(e, isRight) { + if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { + return this.selectionEnd; + } else { + return this.selectionStart; + } + } + + /** + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getUpCursorOffset(e, isRight) { + const selectionProp = this._getSelectionForOffset(e, isRight), + cursorLocation = this.get2DCursorLocation(selectionProp), + lineIndex = cursorLocation.lineIndex; + if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { + // if on first line, up cursor goes to start of line + return -selectionProp; + } + const charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), + textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), + missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); + // return a negative offset + return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset); + } + + /** + * for a given width it founds the matching character. + * @private + */ + _getIndexOnLine(lineIndex, width) { + const line = this._textLines[lineIndex], + lineLeftOffset = this._getLineLeftOffset(lineIndex); + let widthOfCharsOnLine = lineLeftOffset, + indexOnLine = 0, + charWidth, + foundMatch; + for (let j = 0, jlen = line.length; j < jlen; j++) { + charWidth = this.__charBounds[lineIndex][j].width; + widthOfCharsOnLine += charWidth; + if (widthOfCharsOnLine > width) { + foundMatch = true; + const leftEdge = widthOfCharsOnLine - charWidth, + rightEdge = widthOfCharsOnLine, + offsetFromLeftEdge = Math.abs(leftEdge - width), + offsetFromRightEdge = Math.abs(rightEdge - width); + indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; + break; + } + } + + // reached end + if (!foundMatch) { + indexOnLine = line.length - 1; + } + return indexOnLine; + } + + /** + * Moves cursor down + * @param {KeyboardEvent} e Event object + */ + moveCursorDown(e) { + if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { + return; + } + this._moveCursorUpOrDown('Down', e); + } + + /** + * Moves cursor up + * @param {KeyboardEvent} e Event object + */ + moveCursorUp(e) { + if (this.selectionStart === 0 && this.selectionEnd === 0) { + return; + } + this._moveCursorUpOrDown('Up', e); + } + + /** + * Moves cursor up or down, fires the events + * @param {String} direction 'Up' or 'Down' + * @param {KeyboardEvent} e Event object + */ + _moveCursorUpOrDown(direction, e) { + const offset = this["get".concat(direction, "CursorOffset")](e, this._selectionDirection === RIGHT); + if (e.shiftKey) { + this.moveCursorWithShift(offset); + } else { + this.moveCursorWithoutShift(offset); + } + if (offset !== 0) { + const max = this.text.length; + this.selectionStart = capValue(0, this.selectionStart, max); + this.selectionEnd = capValue(0, this.selectionEnd, max); + // TODO fix: abort and init should be an alternative depending + // on selectionStart/End being equal or different + this.abortCursorAnimation(); + this.initDelayedCursor(); + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Moves cursor with shift + * @param {Number} offset + */ + moveCursorWithShift(offset) { + const newSelection = this._selectionDirection === LEFT ? this.selectionStart + offset : this.selectionEnd + offset; + this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); + return offset !== 0; + } + + /** + * Moves cursor up without shift + * @param {Number} offset + */ + moveCursorWithoutShift(offset) { + if (offset < 0) { + this.selectionStart += offset; + this.selectionEnd = this.selectionStart; + } else { + this.selectionEnd += offset; + this.selectionStart = this.selectionEnd; + } + return offset !== 0; + } + + /** + * Moves cursor left + * @param {KeyboardEvent} e Event object + */ + moveCursorLeft(e) { + if (this.selectionStart === 0 && this.selectionEnd === 0) { + return; + } + this._moveCursorLeftOrRight('Left', e); + } + + /** + * @private + * @return {Boolean} true if a change happened + * + * @todo refactor not to use method name composition + */ + _move(e, prop, direction) { + let newValue; + if (e.altKey) { + newValue = this["findWordBoundary".concat(direction)](this[prop]); + } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) { + newValue = this["findLineBoundary".concat(direction)](this[prop]); + } else { + this[prop] += direction === 'Left' ? -1 : 1; + return true; + } + if (typeof newValue !== 'undefined' && this[prop] !== newValue) { + this[prop] = newValue; + return true; + } + return false; + } + + /** + * @private + */ + _moveLeft(e, prop) { + return this._move(e, prop, 'Left'); + } + + /** + * @private + */ + _moveRight(e, prop) { + return this._move(e, prop, 'Right'); + } + + /** + * Moves cursor left without keeping selection + * @param {KeyboardEvent} e + */ + moveCursorLeftWithoutShift(e) { + let change = true; + this._selectionDirection = LEFT; + + // only move cursor when there is no selection, + // otherwise we discard it, and leave cursor on same place + if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) { + change = this._moveLeft(e, 'selectionStart'); + } + this.selectionEnd = this.selectionStart; + return change; + } + + /** + * Moves cursor left while keeping selection + * @param {KeyboardEvent} e + */ + moveCursorLeftWithShift(e) { + if (this._selectionDirection === RIGHT && this.selectionStart !== this.selectionEnd) { + return this._moveLeft(e, 'selectionEnd'); + } else if (this.selectionStart !== 0) { + this._selectionDirection = LEFT; + return this._moveLeft(e, 'selectionStart'); + } + } + + /** + * Moves cursor right + * @param {KeyboardEvent} e Event object + */ + moveCursorRight(e) { + if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { + return; + } + this._moveCursorLeftOrRight('Right', e); + } + + /** + * Moves cursor right or Left, fires event + * @param {String} direction 'Left', 'Right' + * @param {KeyboardEvent} e Event object + */ + _moveCursorLeftOrRight(direction, e) { + const actionName = "moveCursor".concat(direction).concat(e.shiftKey ? 'WithShift' : 'WithoutShift'); + this._currentCursorOpacity = 1; + if (this[actionName](e)) { + // TODO fix: abort and init should be an alternative depending + // on selectionStart/End being equal or different + this.abortCursorAnimation(); + this.initDelayedCursor(); + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Moves cursor right while keeping selection + * @param {KeyboardEvent} e + */ + moveCursorRightWithShift(e) { + if (this._selectionDirection === LEFT && this.selectionStart !== this.selectionEnd) { + return this._moveRight(e, 'selectionStart'); + } else if (this.selectionEnd !== this._text.length) { + this._selectionDirection = RIGHT; + return this._moveRight(e, 'selectionEnd'); + } + } + + /** + * Moves cursor right without keeping selection + * @param {KeyboardEvent} e Event object + */ + moveCursorRightWithoutShift(e) { + let changed = true; + this._selectionDirection = RIGHT; + if (this.selectionStart === this.selectionEnd) { + changed = this._moveRight(e, 'selectionStart'); + this.selectionEnd = this.selectionStart; + } else { + this.selectionStart = this.selectionEnd; + } + return changed; + } +} + +/** + * `LEFT_CLICK === 0` + */ +const notALeftClick = e => !!e.button; +class ITextClickBehavior extends ITextKeyBehavior { + constructor() { + super(...arguments); + _defineProperty(this, "draggableTextDelegate", void 0); + } + initBehavior() { + // Initializes event handlers related to cursor or selection + this.on('mousedown', this._mouseDownHandler); + this.on('mousedown:before', this._mouseDownHandlerBefore); + this.on('mouseup', this.mouseUpHandler); + this.on('mousedblclick', this.doubleClickHandler); + this.on('tripleclick', this.tripleClickHandler); + + // Initializes "dbclick" event handler + this.__lastClickTime = +new Date(); + // for triple click + this.__lastLastClickTime = +new Date(); + this.__lastPointer = {}; + this.on('mousedown', this.onMouseDown); + + // @ts-expect-error in reality it is an IText instance + this.draggableTextDelegate = new DraggableTextDelegate(this); + super.initBehavior(); + } + + /** + * If this method returns true a mouse move operation over a text selection + * will not prevent the native mouse event allowing the browser to start a drag operation. + * shouldStartDragging can be read 'do not prevent default for mouse move event' + * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false + * @returns + */ + shouldStartDragging() { + return this.draggableTextDelegate.isActive(); + } + + /** + * @public override this method to control whether instance should/shouldn't become a drag source, + * @see also {@link DraggableTextDelegate#isActive} + * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false + * @returns {boolean} should handle event + */ + onDragStart(e) { + return this.draggableTextDelegate.onDragStart(e); + } + + /** + * @public override this method to control whether instance should/shouldn't become a drop target + */ + canDrop(e) { + return this.draggableTextDelegate.canDrop(e); + } + + /** + * Default event handler to simulate triple click + * @private + */ + onMouseDown(options) { + if (!this.canvas) { + return; + } + this.__newClickTime = +new Date(); + const newPointer = options.pointer; + if (this.isTripleClick(newPointer)) { + this.fire('tripleclick', options); + stopEvent(options.e); + } + this.__lastLastClickTime = this.__lastClickTime; + this.__lastClickTime = this.__newClickTime; + this.__lastPointer = newPointer; + this.__lastSelected = this.selected && !this.getActiveControl(); + } + isTripleClick(newPointer) { + return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y; + } + + /** + * Default handler for double click, select a word + */ + doubleClickHandler(options) { + if (!this.isEditing) { + return; + } + this.selectWord(this.getSelectionStartFromPointer(options.e)); + } + + /** + * Default handler for triple click, select a line + */ + tripleClickHandler(options) { + if (!this.isEditing) { + return; + } + this.selectLine(this.getSelectionStartFromPointer(options.e)); + } + + /** + * Default event handler for the basic functionalities needed on _mouseDown + * can be overridden to do something different. + * Scope of this implementation is: find the click position, set selectionStart + * find selectionEnd, initialize the drawing of either cursor or selection area + * initializing a mousedDown on a text area will cancel fabricjs knowledge of + * current compositionMode. It will be set to false. + */ + _mouseDownHandler(_ref) { + let { + e + } = _ref; + if (!this.canvas || !this.editable || notALeftClick(e) || this.getActiveControl()) { + return; + } + if (this.draggableTextDelegate.start(e)) { + return; + } + this.canvas.textEditingManager.register(this); + if (this.selected) { + this.inCompositionMode = false; + this.setCursorByClick(e); + } + if (this.isEditing) { + this.__selectionStartOnMouseDown = this.selectionStart; + if (this.selectionStart === this.selectionEnd) { + this.abortCursorAnimation(); + } + this.renderCursorOrSelection(); + } + } + + /** + * Default event handler for the basic functionalities needed on mousedown:before + * can be overridden to do something different. + * Scope of this implementation is: verify the object is already selected when mousing down + */ + _mouseDownHandlerBefore(_ref2) { + let { + e + } = _ref2; + if (!this.canvas || !this.editable || notALeftClick(e)) { + return; + } + // we want to avoid that an object that was selected and then becomes unselectable, + // may trigger editing mode in some way. + this.selected = this === this.canvas._activeObject; + } + + /** + * standard handler for mouse up, overridable + * @private + */ + mouseUpHandler(_ref3) { + let { + e, + transform + } = _ref3; + const didDrag = this.draggableTextDelegate.end(e); + if (this.canvas) { + this.canvas.textEditingManager.unregister(this); + const activeObject = this.canvas._activeObject; + if (activeObject && activeObject !== this) { + // avoid running this logic when there is an active object + // this because is possible with shift click and fast clicks, + // to rapidly deselect and reselect this object and trigger an enterEdit + return; + } + } + if (!this.editable || this.group && !this.group.interactive || transform && transform.actionPerformed || notALeftClick(e) || didDrag) { + return; + } + if (this.__lastSelected && !this.getActiveControl()) { + this.selected = false; + this.__lastSelected = false; + this.enterEditing(e); + if (this.selectionStart === this.selectionEnd) { + this.initDelayedCursor(true); + } else { + this.renderCursorOrSelection(); + } + } else { + this.selected = true; + } + } + + /** + * Changes cursor location in a text depending on passed pointer (x/y) object + * @param {TPointerEvent} e Event object + */ + setCursorByClick(e) { + const newSelection = this.getSelectionStartFromPointer(e), + start = this.selectionStart, + end = this.selectionEnd; + if (e.shiftKey) { + this.setSelectionStartEndWithShift(start, end, newSelection); + } else { + this.selectionStart = newSelection; + this.selectionEnd = newSelection; + } + if (this.isEditing) { + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Returns index of a character corresponding to where an object was clicked + * @param {TPointerEvent} e Event object + * @return {Number} Index of a character + */ + getSelectionStartFromPointer(e) { + const mouseOffset = this.canvas.getScenePoint(e).transform(invertTransform(this.calcTransformMatrix())).add(new Point(-this._getLeftOffset(), -this._getTopOffset())); + let height = 0, + charIndex = 0, + lineIndex = 0; + for (let i = 0; i < this._textLines.length; i++) { + if (height <= mouseOffset.y) { + height += this.getHeightOfLine(i); + lineIndex = i; + if (i > 0) { + charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1); + } + } else { + break; + } + } + const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex)); + let width = lineLeftOffset; + const charLength = this._textLines[lineIndex].length; + const chars = this.__charBounds[lineIndex]; + for (let j = 0; j < charLength; j++) { + // i removed something about flipX here, check. + const charWidth = chars[j].kernedWidth; + const widthAfter = width + charWidth; + if (mouseOffset.x <= widthAfter) { + // if the pointer is closer to the end of the char we increment charIndex + // in order to position the cursor after the char + if (Math.abs(mouseOffset.x - widthAfter) <= Math.abs(mouseOffset.x - width)) { + charIndex++; + } + break; + } + width = widthAfter; + charIndex++; + } + return Math.min( + // if object is horizontally flipped, mirror cursor location from the end + this.flipX ? charLength - charIndex : charIndex, this._text.length); + } +} + +const MOVE_CURSOR_UP = 'moveCursorUp'; +const MOVE_CURSOR_DOWN = 'moveCursorDown'; +const MOVE_CURSOR_LEFT = 'moveCursorLeft'; +const MOVE_CURSOR_RIGHT = 'moveCursorRight'; +const EXIT_EDITING = 'exitEditing'; + +// @TODO look into import { Key } from 'ts-key-enum'; +// and transition from keyCode to Key +// also reduce string duplication +const keysMap = { + 9: EXIT_EDITING, + 27: EXIT_EDITING, + 33: MOVE_CURSOR_UP, + 34: MOVE_CURSOR_DOWN, + 35: MOVE_CURSOR_RIGHT, + 36: MOVE_CURSOR_LEFT, + 37: MOVE_CURSOR_LEFT, + 38: MOVE_CURSOR_UP, + 39: MOVE_CURSOR_RIGHT, + 40: MOVE_CURSOR_DOWN +}; +const keysMapRtl = { + 9: EXIT_EDITING, + 27: EXIT_EDITING, + 33: MOVE_CURSOR_UP, + 34: MOVE_CURSOR_DOWN, + 35: MOVE_CURSOR_LEFT, + 36: MOVE_CURSOR_RIGHT, + 37: MOVE_CURSOR_RIGHT, + 38: MOVE_CURSOR_UP, + 39: MOVE_CURSOR_LEFT, + 40: MOVE_CURSOR_DOWN +}; + +/** + * For functionalities on keyUp + ctrl || cmd + */ +const ctrlKeysMapUp = { + 67: 'copy', + // there was a reason this wasn't deleted. for now leave it here + 88: 'cut' +}; + +/** + * For functionalities on keyDown + ctrl || cmd + */ +const ctrlKeysMapDown = { + 65: 'selectAll' +}; + +// Declare IText protected properties to workaround TS +const protectedDefaultValues = { + _selectionDirection: null, + _reSpace: /\s|\r?\n/, + inCompositionMode: false +}; +const iTextDefaultValues = _objectSpread2({ + selectionStart: 0, + selectionEnd: 0, + selectionColor: 'rgba(17,119,255,0.3)', + isEditing: false, + editable: true, + editingBorderColor: 'rgba(102,153,255,0.25)', + cursorWidth: 2, + cursorColor: '', + cursorDelay: 1000, + cursorDuration: 600, + caching: true, + hiddenTextareaContainer: null, + keysMap, + keysMapRtl, + ctrlKeysMapDown, + ctrlKeysMapUp +}, protectedDefaultValues); + +// @TODO this is not complete + +/** + * @fires changed + * @fires selection:changed + * @fires editing:entered + * @fires editing:exited + * @fires dragstart + * @fires drag drag event firing on the drag source + * @fires dragend + * @fires copy + * @fires cut + * @fires paste + * + * #### Supported key combinations + * ``` + * Move cursor: left, right, up, down + * Select character: shift + left, shift + right + * Select text vertically: shift + up, shift + down + * Move cursor by word: alt + left, alt + right + * Select words: shift + alt + left, shift + alt + right + * Move cursor to line start/end: cmd + left, cmd + right or home, end + * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end + * Jump to start/end of text: cmd + up, cmd + down + * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown + * Delete character: backspace + * Delete word: alt + backspace + * Delete line: cmd + backspace + * Forward delete: delete + * Copy text: ctrl/cmd + c + * Paste text: ctrl/cmd + v + * Cut text: ctrl/cmd + x + * Select entire text: ctrl/cmd + a + * Quit editing tab or esc + * ``` + * + * #### Supported mouse/touch combination + * ``` + * Position cursor: click/touch + * Create selection: click/touch & drag + * Create selection: click & shift + click + * Select word: double click + * Select line: triple click + * ``` + */ +class IText extends ITextClickBehavior { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), IText.ownDefaults); + } + get type() { + const type = super.type; + // backward compatibility + return type === 'itext' ? 'i-text' : type; + } + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + */ + constructor(text, options) { + super(text, _objectSpread2(_objectSpread2({}, IText.ownDefaults), options)); + this.initBehavior(); + } + + /** + * While editing handle differently + * @private + * @param {string} key + * @param {*} value + */ + _set(key, value) { + if (this.isEditing && this._savedProps && key in this._savedProps) { + // @ts-expect-error irritating TS + this._savedProps[key] = value; + return this; + } + if (key === 'canvas') { + this.canvas instanceof Canvas && this.canvas.textEditingManager.remove(this); + value instanceof Canvas && value.textEditingManager.add(this); + } + return super._set(key, value); + } + + /** + * Sets selection start (left boundary of a selection) + * @param {Number} index Index to set selection start to + */ + setSelectionStart(index) { + index = Math.max(index, 0); + this._updateAndFire('selectionStart', index); + } + + /** + * Sets selection end (right boundary of a selection) + * @param {Number} index Index to set selection end to + */ + setSelectionEnd(index) { + index = Math.min(index, this.text.length); + this._updateAndFire('selectionEnd', index); + } + + /** + * @private + * @param {String} property 'selectionStart' or 'selectionEnd' + * @param {Number} index new position of property + */ + _updateAndFire(property, index) { + if (this[property] !== index) { + this._fireSelectionChanged(); + this[property] = index; + } + this._updateTextarea(); + } + + /** + * Fires the even of selection changed + * @private + */ + _fireSelectionChanged() { + this.fire('selection:changed'); + this.canvas && this.canvas.fire('text:selection:changed', { + target: this + }); + } + + /** + * Initialize text dimensions. Render all text on given context + * or on a offscreen canvas to get the text width with measureText. + * Updates this.width and this.height with the proper values. + * Does not return dimensions. + * @private + */ + initDimensions() { + this.isEditing && this.initDelayedCursor(); + super.initDimensions(); + } + + /** + * Gets style of a current selection/cursor (at the start position) + * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used. + * @param {Number} startIndex Start index to get styles at + * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1 + * @param {Boolean} [complete] get full style or not + * @return {Array} styles an array with one, zero or more Style objects + */ + getSelectionStyles() { + let startIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart || 0; + let endIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selectionEnd; + let complete = arguments.length > 2 ? arguments[2] : undefined; + return super.getSelectionStyles(startIndex, endIndex, complete); + } + + /** + * Sets style of a current selection, if no selection exist, do not set anything. + * @param {Object} [styles] Styles object + * @param {Number} [startIndex] Start index to get styles at + * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 + */ + setSelectionStyles(styles) { + let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selectionStart || 0; + let endIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.selectionEnd; + return super.setSelectionStyles(styles, startIndex, endIndex); + } + + /** + * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) + * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. + * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. + */ + get2DCursorLocation() { + let selectionStart = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart; + let skipWrapping = arguments.length > 1 ? arguments[1] : undefined; + return super.get2DCursorLocation(selectionStart, skipWrapping); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + super.render(ctx); + // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor + // the correct position but not at every cursor animation. + this.cursorOffsetCache = {}; + this.renderCursorOrSelection(); + } + + /** + * @override block cursor/selection logic while rendering the exported canvas + * @todo this workaround should be replaced with a more robust solution + */ + toCanvasElement(options) { + const isEditing = this.isEditing; + this.isEditing = false; + const canvas = super.toCanvasElement(options); + this.isEditing = isEditing; + return canvas; + } + + /** + * Renders cursor or selection (depending on what exists) + * it does on the contextTop. If contextTop is not available, do nothing. + */ + renderCursorOrSelection() { + if (!this.isEditing) { + return; + } + const ctx = this.clearContextTop(true); + if (!ctx) { + return; + } + const boundaries = this._getCursorBoundaries(); + if (this.selectionStart === this.selectionEnd) { + this.renderCursor(ctx, boundaries); + } else { + this.renderSelection(ctx, boundaries); + } + this.canvas.contextTopDirty = true; + ctx.restore(); + } + + /** + * Returns cursor boundaries (left, top, leftOffset, topOffset) + * left/top are left/top of entire text box + * leftOffset/topOffset are offset from that left/top point of a text box + * @private + * @param {number} [index] index from start + * @param {boolean} [skipCaching] + */ + _getCursorBoundaries() { + let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart; + let skipCaching = arguments.length > 1 ? arguments[1] : undefined; + const left = this._getLeftOffset(), + top = this._getTopOffset(), + offsets = this._getCursorBoundariesOffsets(index, skipCaching); + return { + left: left, + top: top, + leftOffset: offsets.left, + topOffset: offsets.top + }; + } + + /** + * Caches and returns cursor left/top offset relative to instance's center point + * @private + * @param {number} index index from start + * @param {boolean} [skipCaching] + */ + _getCursorBoundariesOffsets(index, skipCaching) { + if (skipCaching) { + return this.__getCursorBoundariesOffsets(index); + } + if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) { + return this.cursorOffsetCache; + } + return this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index); + } + + /** + * Calculates cursor left/top offset relative to instance's center point + * @private + * @param {number} index index from start + */ + __getCursorBoundariesOffsets(index) { + let topOffset = 0, + leftOffset = 0; + const { + charIndex, + lineIndex + } = this.get2DCursorLocation(index); + for (let i = 0; i < lineIndex; i++) { + topOffset += this.getHeightOfLine(i); + } + const lineLeftOffset = this._getLineLeftOffset(lineIndex); + const bound = this.__charBounds[lineIndex][charIndex]; + bound && (leftOffset = bound.left); + if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) { + leftOffset -= this._getWidthOfCharSpacing(); + } + const boundaries = { + top: topOffset, + left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0) + }; + if (this.direction === 'rtl') { + if (this.textAlign === RIGHT || this.textAlign === JUSTIFY || this.textAlign === JUSTIFY_RIGHT) { + boundaries.left *= -1; + } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) { + boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0); + } else if (this.textAlign === CENTER || this.textAlign === JUSTIFY_CENTER) { + boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0); + } + } + return boundaries; + } + + /** + * Renders cursor on context Top, outside the animation cycle, on request + * Used for the drag/drop effect. + * If contextTop is not available, do nothing. + */ + renderCursorAt(selectionStart) { + const boundaries = this._getCursorBoundaries(selectionStart, true); + this._renderCursor(this.canvas.contextTop, boundaries, selectionStart); + } + + /** + * Renders cursor + * @param {Object} boundaries + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderCursor(ctx, boundaries) { + this._renderCursor(ctx, boundaries, this.selectionStart); + } + _renderCursor(ctx, boundaries, selectionStart) { + const cursorLocation = this.get2DCursorLocation(selectionStart), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0, + charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'), + multiplier = this.getObjectScaling().x * this.canvas.getZoom(), + cursorWidth = this.cursorWidth / multiplier, + dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'), + topOffset = boundaries.topOffset + (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - charHeight * (1 - this._fontSizeFraction); + if (this.inCompositionMode) { + // TODO: investigate why there isn't a return inside the if, + // and why can't happen at the top of the function + this.renderSelection(ctx, boundaries); + } + ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, FILL); + ctx.globalAlpha = this._currentCursorOpacity; + ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top + dy, cursorWidth, charHeight); + } + + /** + * Renders text selection + * @param {Object} boundaries Object with left/top/leftOffset/topOffset + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderSelection(ctx, boundaries) { + const selection = { + selectionStart: this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, + selectionEnd: this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd + }; + this._renderSelection(ctx, selection, boundaries); + } + + /** + * Renders drag start text selection + */ + renderDragSourceEffect() { + const dragStartSelection = this.draggableTextDelegate.getDragStartSelection(); + this._renderSelection(this.canvas.contextTop, dragStartSelection, this._getCursorBoundaries(dragStartSelection.selectionStart, true)); + } + renderDropTargetEffect(e) { + const dragSelection = this.getSelectionStartFromPointer(e); + this.renderCursorAt(dragSelection); + } + + /** + * Renders text selection + * @private + * @param {{ selectionStart: number, selectionEnd: number }} selection + * @param {Object} boundaries Object with left/top/leftOffset/topOffset + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + _renderSelection(ctx, selection, boundaries) { + const selectionStart = selection.selectionStart, + selectionEnd = selection.selectionEnd, + isJustify = this.textAlign.includes(JUSTIFY), + start = this.get2DCursorLocation(selectionStart), + end = this.get2DCursorLocation(selectionEnd), + startLine = start.lineIndex, + endLine = end.lineIndex, + startChar = start.charIndex < 0 ? 0 : start.charIndex, + endChar = end.charIndex < 0 ? 0 : end.charIndex; + for (let i = startLine; i <= endLine; i++) { + const lineOffset = this._getLineLeftOffset(i) || 0; + let lineHeight = this.getHeightOfLine(i), + realLineHeight = 0, + boxStart = 0, + boxEnd = 0; + if (i === startLine) { + boxStart = this.__charBounds[startLine][startChar].left; + } + if (i >= startLine && i < endLine) { + boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? + } else if (i === endLine) { + if (endChar === 0) { + boxEnd = this.__charBounds[endLine][endChar].left; + } else { + const charSpacing = this._getWidthOfCharSpacing(); + boxEnd = this.__charBounds[endLine][endChar - 1].left + this.__charBounds[endLine][endChar - 1].width - charSpacing; + } + } + realLineHeight = lineHeight; + if (this.lineHeight < 1 || i === endLine && this.lineHeight > 1) { + lineHeight /= this.lineHeight; + } + let drawStart = boundaries.left + lineOffset + boxStart, + drawHeight = lineHeight, + extraTop = 0; + const drawWidth = boxEnd - boxStart; + if (this.inCompositionMode) { + ctx.fillStyle = this.compositionColor || 'black'; + drawHeight = 1; + extraTop = lineHeight; + } else { + ctx.fillStyle = this.selectionColor; + } + if (this.direction === 'rtl') { + if (this.textAlign === RIGHT || this.textAlign === JUSTIFY || this.textAlign === JUSTIFY_RIGHT) { + drawStart = this.width - drawStart - drawWidth; + } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) { + drawStart = boundaries.left + lineOffset - boxEnd; + } else if (this.textAlign === CENTER || this.textAlign === JUSTIFY_CENTER) { + drawStart = boundaries.left + lineOffset - boxEnd; + } + } + ctx.fillRect(drawStart, boundaries.top + boundaries.topOffset + extraTop, drawWidth, drawHeight); + boundaries.topOffset += realLineHeight; + } + } + + /** + * High level function to know the height of the cursor. + * the currentChar is the one that precedes the cursor + * Returns fontSize of char at the current cursor + * Unused from the library, is for the end user + * @return {Number} Character font size + */ + getCurrentCharFontSize() { + const cp = this._getCurrentCharIndex(); + return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize'); + } + + /** + * High level function to know the color of the cursor. + * the currentChar is the one that precedes the cursor + * Returns color (fill) of char at the current cursor + * if the text object has a pattern or gradient for filler, it will return that. + * Unused by the library, is for the end user + * @return {String | TFiller} Character color (fill) + */ + getCurrentCharColor() { + const cp = this._getCurrentCharIndex(); + return this.getValueOfPropertyAt(cp.l, cp.c, FILL); + } + + /** + * Returns the cursor position for the getCurrent.. functions + * @private + */ + _getCurrentCharIndex() { + const cursorPosition = this.get2DCursorLocation(this.selectionStart, true), + charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0; + return { + l: cursorPosition.lineIndex, + c: charIndex + }; + } + dispose() { + this._exitEditing(); + this.draggableTextDelegate.dispose(); + super.dispose(); + } +} +/** + * Index where text selection starts (or where cursor is when there is no selection) + * @type Number + * @default + */ +/** + * Index where text selection ends + * @type Number + * @default + */ +/** + * Color of text selection + * @type String + * @default + */ +/** + * Indicates whether text is in editing mode + * @type Boolean + * @default + */ +/** + * Indicates whether a text can be edited + * @type Boolean + * @default + */ +/** + * Border color of text object while it's in editing mode + * @type String + * @default + */ +/** + * Width of cursor (in px) + * @type Number + * @default + */ +/** + * Color of text cursor color in editing mode. + * if not set (default) will take color from the text. + * if set to a color value that fabric can understand, it will + * be used instead of the color of the text at the current position. + * @type String + * @default + */ +/** + * Delay between cursor blink (in ms) + * @type Number + * @default + */ +/** + * Duration of cursor fade in (in ms) + * @type Number + * @default + */ +/** + * Indicates whether internal text char widths can be cached + * @type Boolean + * @default + */ +_defineProperty(IText, "ownDefaults", iTextDefaultValues); +_defineProperty(IText, "type", 'IText'); +classRegistry.setClass(IText); +// legacy +classRegistry.setClass(IText, 'i-text'); + +// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype +// regexes, list of properties that are not suppose to change by instances, magic consts. +// this will be a separated effort +const textboxDefaultValues = { + minWidth: 20, + dynamicMinWidth: 2, + lockScalingFlip: true, + noScaleCache: false, + _wordJoiners: /[ \t\r]/, + splitByGrapheme: false +}; + +// @TODO this is not complete + +/** + * Textbox class, based on IText, allows the user to resize the text rectangle + * and wraps lines automatically. Textboxes have their Y scaling locked, the + * user can only change width. Height is adjusted automatically based on the + * wrapping of lines. + */ +class Textbox extends IText { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Textbox.ownDefaults); + } + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + */ + constructor(text, options) { + super(text, _objectSpread2(_objectSpread2({}, Textbox.ownDefaults), options)); + } + + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults object + */ + static createControls() { + return { + controls: createTextboxDefaultControls() + }; + } + + /** + * Unlike superclass's version of this function, Textbox does not update + * its width. + * @private + * @override + */ + initDimensions() { + if (!this.initialized) { + return; + } + this.isEditing && this.initDelayedCursor(); + this._clearCache(); + // clear dynamicMinWidth as it will be different after we re-wrap line + this.dynamicMinWidth = 0; + // wrap lines + this._styleMap = this._generateStyleMap(this._splitText()); + // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap + if (this.dynamicMinWidth > this.width) { + this._set('width', this.dynamicMinWidth); + } + if (this.textAlign.includes(JUSTIFY)) { + // once text is measured we need to make space fatter to make justified text. + this.enlargeSpaces(); + } + // clear cache and re-calculate height + this.height = this.calcTextHeight(); + } + + /** + * Generate an object that translates the style object so that it is + * broken up by visual lines (new lines and automatic wrapping). + * The original text styles object is broken up by actual lines (new lines only), + * which is only sufficient for Text / IText + * @private + */ + _generateStyleMap(textInfo) { + let realLineCount = 0, + realLineCharCount = 0, + charCount = 0; + const map = {}; + for (let i = 0; i < textInfo.graphemeLines.length; i++) { + if (textInfo.graphemeText[charCount] === '\n' && i > 0) { + realLineCharCount = 0; + charCount++; + realLineCount++; + } else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) { + // this case deals with space's that are removed from end of lines when wrapping + realLineCharCount++; + charCount++; + } + map[i] = { + line: realLineCount, + offset: realLineCharCount + }; + charCount += textInfo.graphemeLines[i].length; + realLineCharCount += textInfo.graphemeLines[i].length; + } + return map; + } + + /** + * Returns true if object has a style property or has it on a specified line + * @param {Number} lineIndex + * @return {Boolean} + */ + styleHas(property, lineIndex) { + if (this._styleMap && !this.isWrapping) { + const map = this._styleMap[lineIndex]; + if (map) { + lineIndex = map.line; + } + } + return super.styleHas(property, lineIndex); + } + + /** + * Returns true if object has no styling or no styling in a line + * @param {Number} lineIndex , lineIndex is on wrapped lines. + * @return {Boolean} + */ + isEmptyStyles(lineIndex) { + if (!this.styles) { + return true; + } + let offset = 0, + nextLineIndex = lineIndex + 1, + nextOffset, + shouldLimit = false; + const map = this._styleMap[lineIndex], + mapNextLine = this._styleMap[lineIndex + 1]; + if (map) { + lineIndex = map.line; + offset = map.offset; + } + if (mapNextLine) { + nextLineIndex = mapNextLine.line; + shouldLimit = nextLineIndex === lineIndex; + nextOffset = mapNextLine.offset; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + line: this.styles[lineIndex] + }; + for (const p1 in obj) { + for (const p2 in obj[p1]) { + const p2Number = parseInt(p2, 10); + if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset)) { + // eslint-disable-next-line no-unused-vars + for (const p3 in obj[p1][p2]) { + return false; + } + } + } + } + return true; + } + + /** + * @protected + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined + */ + _getStyleDeclaration(lineIndex, charIndex) { + if (this._styleMap && !this.isWrapping) { + const map = this._styleMap[lineIndex]; + if (!map) { + return {}; + } + lineIndex = map.line; + charIndex = map.offset + charIndex; + } + return super._getStyleDeclaration(lineIndex, charIndex); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {Object} style + * @private + */ + _setStyleDeclaration(lineIndex, charIndex, style) { + const map = this._styleMap[lineIndex]; + super._setStyleDeclaration(map.line, map.offset + charIndex, style); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @private + */ + _deleteStyleDeclaration(lineIndex, charIndex) { + const map = this._styleMap[lineIndex]; + super._deleteStyleDeclaration(map.line, map.offset + charIndex); + } + + /** + * probably broken need a fix + * Returns the real style line that correspond to the wrapped lineIndex line + * Used just to verify if the line does exist or not. + * @param {Number} lineIndex + * @returns {Boolean} if the line exists or not + * @private + */ + _getLineStyle(lineIndex) { + const map = this._styleMap[lineIndex]; + return !!this.styles[map.line]; + } + + /** + * Set the line style to an empty object so that is initialized + * @param {Number} lineIndex + * @param {Object} style + * @private + */ + _setLineStyle(lineIndex) { + const map = this._styleMap[lineIndex]; + super._setLineStyle(map.line); + } + + /** + * Wraps text using the 'width' property of Textbox. First this function + * splits text on newlines, so we preserve newlines entered by the user. + * Then it wraps each line using the width of the Textbox by calling + * _wrapLine(). + * @param {Array} lines The string array of text that is split into lines + * @param {Number} desiredWidth width you want to wrap to + * @returns {Array} Array of lines + */ + _wrapText(lines, desiredWidth) { + this.isWrapping = true; + // extract all thewords and the widths to optimally wrap lines. + const data = this.getGraphemeDataForRender(lines); + const wrapped = []; + for (let i = 0; i < data.wordsData.length; i++) { + wrapped.push(...this._wrapLine(i, desiredWidth, data)); + } + this.isWrapping = false; + return wrapped; + } + + /** + * For each line of text terminated by an hard line stop, + * measure each word width and extract the largest word from all. + * The returned words here are the one that at the end will be rendered. + * @param {string[]} lines the lines we need to measure + * + */ + getGraphemeDataForRender(lines) { + const splitByGrapheme = this.splitByGrapheme, + infix = splitByGrapheme ? '' : ' '; + let largestWordWidth = 0; + const data = lines.map((line, lineIndex) => { + let offset = 0; + const wordsOrGraphemes = splitByGrapheme ? this.graphemeSplit(line) : this.wordSplit(line); + if (wordsOrGraphemes.length === 0) { + return [{ + word: [], + width: 0 + }]; + } + return wordsOrGraphemes.map(word => { + // if using splitByGrapheme words are already in graphemes. + const graphemeArray = splitByGrapheme ? [word] : this.graphemeSplit(word); + const width = this._measureWord(graphemeArray, lineIndex, offset); + largestWordWidth = Math.max(width, largestWordWidth); + offset += graphemeArray.length + infix.length; + return { + word: graphemeArray, + width + }; + }); + }); + return { + wordsData: data, + largestWordWidth + }; + } + + /** + * Helper function to measure a string of text, given its lineIndex and charIndex offset + * It gets called when charBounds are not available yet. + * Override if necessary + * Use with {@link Textbox#wordSplit} + * + * @param {CanvasRenderingContext2D} ctx + * @param {String} text + * @param {number} lineIndex + * @param {number} charOffset + * @returns {number} + */ + _measureWord(word, lineIndex) { + let charOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let width = 0, + prevGrapheme; + const skipLeft = true; + for (let i = 0, len = word.length; i < len; i++) { + const box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft); + width += box.kernedWidth; + prevGrapheme = word[i]; + } + return width; + } + + /** + * Override this method to customize word splitting + * Use with {@link Textbox#_measureWord} + * @param {string} value + * @returns {string[]} array of words + */ + wordSplit(value) { + return value.split(this._wordJoiners); + } + + /** + * Wraps a line of text using the width of the Textbox as desiredWidth + * and leveraging the known width o words from GraphemeData + * @private + * @param {Number} lineIndex + * @param {Number} desiredWidth width you want to wrap the line to + * @param {GraphemeData} graphemeData an object containing all the lines' words width. + * @param {Number} reservedSpace space to remove from wrapping for custom functionalities + * @returns {Array} Array of line(s) into which the given text is wrapped + * to. + */ + _wrapLine(lineIndex, desiredWidth, _ref) { + let { + largestWordWidth, + wordsData + } = _ref; + let reservedSpace = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + const additionalSpace = this._getWidthOfCharSpacing(), + splitByGrapheme = this.splitByGrapheme, + graphemeLines = [], + infix = splitByGrapheme ? '' : ' '; + let lineWidth = 0, + line = [], + // spaces in different languages? + offset = 0, + infixWidth = 0, + lineJustStarted = true; + desiredWidth -= reservedSpace; + const maxWidth = Math.max(desiredWidth, largestWordWidth, this.dynamicMinWidth); + // layout words + const data = wordsData[lineIndex]; + offset = 0; + let i; + for (i = 0; i < data.length; i++) { + const { + word, + width: wordWidth + } = data[i]; + offset += word.length; + lineWidth += infixWidth + wordWidth - additionalSpace; + if (lineWidth > maxWidth && !lineJustStarted) { + graphemeLines.push(line); + line = []; + lineWidth = wordWidth; + lineJustStarted = true; + } else { + lineWidth += additionalSpace; + } + if (!lineJustStarted && !splitByGrapheme) { + line.push(infix); + } + line = line.concat(word); + infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset); + offset++; + lineJustStarted = false; + } + i && graphemeLines.push(line); + + // TODO: this code is probably not necessary anymore. + // it can be moved out of this function since largestWordWidth is now + // known in advance + if (largestWordWidth + reservedSpace > this.dynamicMinWidth) { + this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace; + } + return graphemeLines; + } + + /** + * Detect if the text line is ended with an hard break + * text and itext do not have wrapping, return false + * @param {Number} lineIndex text to split + * @return {Boolean} + */ + isEndOfWrapping(lineIndex) { + if (!this._styleMap[lineIndex + 1]) { + // is last line, return true; + return true; + } + if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { + // this is last line before a line break, return true; + return true; + } + return false; + } + + /** + * Detect if a line has a linebreak and so we need to account for it when moving + * and counting style. + * This is important only for splitByGrapheme at the end of wrapping. + * If we are not wrapping the offset is always 1 + * @return Number + */ + missingNewlineOffset(lineIndex, skipWrapping) { + if (this.splitByGrapheme && !skipWrapping) { + return this.isEndOfWrapping(lineIndex) ? 1 : 0; + } + return 1; + } + + /** + * Gets lines of text to render in the Textbox. This function calculates + * text wrapping on the fly every time it is called. + * @param {String} text text to split + * @returns {Array} Array of lines in the Textbox. + * @override + */ + _splitTextIntoLines(text) { + const newText = super._splitTextIntoLines(text), + graphemeLines = this._wrapText(newText.lines, this.width), + lines = new Array(graphemeLines.length); + for (let i = 0; i < graphemeLines.length; i++) { + lines[i] = graphemeLines[i].join(''); + } + newText.lines = lines; + newText.graphemeLines = graphemeLines; + return newText; + } + getMinWidth() { + return Math.max(this.minWidth, this.dynamicMinWidth); + } + _removeExtraneousStyles() { + const linesToKeep = new Map(); + for (const prop in this._styleMap) { + const propNumber = parseInt(prop, 10); + if (this._textLines[propNumber]) { + const lineIndex = this._styleMap[prop].line; + linesToKeep.set("".concat(lineIndex), true); + } + } + for (const prop in this.styles) { + if (!linesToKeep.has(prop)) { + delete this.styles[prop]; + } + } + } + + /** + * Returns object representation of an instance + * @method toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]); + } +} +/** + * Minimum width of textbox, in pixels. + * @type Number + * @default + */ +/** + * Minimum calculated width of a textbox, in pixels. + * fixed to 2 so that an empty textbox cannot go to 0 + * and is still selectable without text. + * @type Number + * @default + */ +/** + * Use this boolean property in order to split strings that have no white space concept. + * this is a cheap way to help with chinese/japanese + * @type Boolean + * @since 2.6.0 + */ +_defineProperty(Textbox, "type", 'Textbox'); +_defineProperty(Textbox, "textLayoutProperties", [...IText.textLayoutProperties, 'width']); +_defineProperty(Textbox, "ownDefaults", textboxDefaultValues); +classRegistry.setClass(Textbox); + +/** + * Layout will adjust the bounding box to match the clip path bounding box. + */ +class ClipPathLayout extends LayoutStrategy { + shouldPerformLayout(context) { + return !!context.target.clipPath && super.shouldPerformLayout(context); + } + shouldLayoutClipPath() { + return false; + } + calcLayoutResult(context, objects) { + const { + target + } = context; + const { + clipPath, + group + } = target; + if (!clipPath || !this.shouldPerformLayout(context)) { + return; + } + // TODO: remove stroke calculation from this case + const { + width, + height + } = makeBoundingBoxFromPoints(getObjectBounds(target, clipPath)); + const size = new Point(width, height); + if (clipPath.absolutePositioned) { + // we want the center point to exist in group's containing plane + const clipPathCenter = sendPointToPlane(clipPath.getRelativeCenterPoint(), undefined, group ? group.calcTransformMatrix() : undefined); + return { + center: clipPathCenter, + size + }; + } else { + // we want the center point to exist in group's containing plane, so we send it upwards + const clipPathCenter = clipPath.getRelativeCenterPoint().transform(target.calcOwnMatrix(), true); + if (this.shouldPerformLayout(context)) { + // the clip path is positioned relative to the group's center which is affected by the bbox + // so we first calculate the bbox + const { + center = new Point(), + correction = new Point() + } = this.calcBoundingBox(objects, context) || {}; + return { + center: center.add(clipPathCenter), + correction: correction.subtract(clipPathCenter), + size + }; + } else { + return { + center: target.getRelativeCenterPoint().add(clipPathCenter), + size + }; + } + } + } +} +_defineProperty(ClipPathLayout, "type", 'clip-path'); +classRegistry.setClass(ClipPathLayout); + +/** + * Layout will keep target's initial size. + */ +class FixedLayout extends LayoutStrategy { + /** + * @override respect target's initial size + */ + getInitialSize(_ref, _ref2) { + let { + target + } = _ref; + let { + size + } = _ref2; + return new Point(target.width || size.x, target.height || size.y); + } +} +_defineProperty(FixedLayout, "type", 'fixed'); +classRegistry.setClass(FixedLayout); + +/** + * Today the LayoutManager class also takes care of subscribing event handlers + * to update the group layout when the group is interactive and a transform is applied + * to a child object. + * The ActiveSelection is never interactive, but it could contain objects from + * groups that are. + * The standard LayoutManager would subscribe the children of the activeSelection to + * perform layout changes to the active selection itself, what we need instead is that + * the transformation applied to the active selection will trigger changes to the + * original group of the children ( the one referenced under the parent property ) + * This subclass of the LayoutManager has a single duty to fill the gap of this difference.` + */ +class ActiveSelectionLayoutManager extends LayoutManager { + subscribeTargets(context) { + const activeSelection = context.target; + const parents = context.targets.reduce((parents, target) => { + target.parent && parents.add(target.parent); + return parents; + }, new Set()); + parents.forEach(parent => { + parent.layoutManager.subscribeTargets({ + target: parent, + targets: [activeSelection] + }); + }); + } + + /** + * unsubscribe from parent only if all its children were deselected + */ + unsubscribeTargets(context) { + const activeSelection = context.target; + const selectedObjects = activeSelection.getObjects(); + const parents = context.targets.reduce((parents, target) => { + target.parent && parents.add(target.parent); + return parents; + }, new Set()); + parents.forEach(parent => { + !selectedObjects.some(object => object.parent === parent) && parent.layoutManager.unsubscribeTargets({ + target: parent, + targets: [activeSelection] + }); + }); + } +} + +const activeSelectionDefaultValues = { + multiSelectionStacking: 'canvas-stacking' +}; + +/** + * Used by Canvas to manage selection. + * + * @example + * class MyActiveSelection extends ActiveSelection { + * ... + * } + * + * // override the default `ActiveSelection` class + * classRegistry.setClass(MyActiveSelection) + */ +class ActiveSelection extends Group { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), ActiveSelection.ownDefaults); + } + + /** + * The ActiveSelection needs to use the ActiveSelectionLayoutManager + * or selections on interactive groups may be broken + */ + + /** + * controls how selected objects are added during a multiselection event + * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order + * - `selection-order` adds the selected object to the top of the stack, + * meaning that the stack is ordered by the order in which objects were selected + * @default `canvas-stacking` + */ + + constructor() { + let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, ActiveSelection.ownDefaults); + this.setOptions(options); + const { + left, + top, + layoutManager + } = options; + this.groupInit(objects, { + left, + top, + layoutManager: layoutManager !== null && layoutManager !== void 0 ? layoutManager : new ActiveSelectionLayoutManager() + }); + } + + /** + * @private + */ + _shouldSetNestedCoords() { + return true; + } + + /** + * @private + * @override we don't want the selection monitor to be active + */ + __objectSelectionMonitor() { + // noop + } + + /** + * Adds objects with respect to {@link multiSelectionStacking} + * @param targets object to add to selection + */ + multiSelectAdd() { + for (var _len = arguments.length, targets = new Array(_len), _key = 0; _key < _len; _key++) { + targets[_key] = arguments[_key]; + } + if (this.multiSelectionStacking === 'selection-order') { + this.add(...targets); + } else { + // respect object stacking as it is on canvas + // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf` + targets.forEach(target => { + const index = this._objects.findIndex(obj => obj.isInFrontOf(target)); + const insertAt = index === -1 ? + // `target` is in front of all other objects + this.size() : index; + this.insertAt(insertAt, target); + }); + } + } + + /** + * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree + */ + canEnterGroup(object) { + if (this.getObjects().some(o => o.isDescendantOf(object) || object.isDescendantOf(o))) { + // prevent circular object tree + log('error', 'ActiveSelection: circular object trees are not supported, this call has no effect'); + return false; + } + return super.canEnterGroup(object); + } + + /** + * Change an object so that it can be part of an active selection. + * this method is called by multiselectAdd from canvas code. + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + enterGroup(object, removeParentTransform) { + // This condition check that the object has currently a group, and the group + // is also its parent, meaning that is not in an active selection, but is + // in a normal group. + if (object.parent && object.parent === object.group) { + // Disconnect the object from the group functionalities, but keep the ref parent intact + // for later re-enter + object.parent._exitGroup(object); + // in this case the object is probably inside an active selection. + } else if (object.group && object.parent !== object.group) { + // in this case group.remove will also clear the old parent reference. + object.group.remove(object); + } + // enter the active selection from a render perspective + // the object will be in the objects array of both the ActiveSelection and the Group + // but referenced in the group's _activeObjects so that it won't be rendered twice. + this._enterGroup(object, removeParentTransform); + } + + /** + * we want objects to retain their canvas ref when exiting instance + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + exitGroup(object, removeParentTransform) { + this._exitGroup(object, removeParentTransform); + // return to parent + object.parent && object.parent._enterGroup(object, true); + } + + /** + * @private + * @param {'added'|'removed'} type + * @param {FabricObject[]} targets + */ + _onAfterObjectsChange(type, targets) { + super._onAfterObjectsChange(type, targets); + const groups = new Set(); + targets.forEach(object => { + const { + parent + } = object; + parent && groups.add(parent); + }); + if (type === LAYOUT_TYPE_REMOVED) { + // invalidate groups' layout and mark as dirty + groups.forEach(group => { + group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets); + }); + } else { + // mark groups as dirty + groups.forEach(group => { + group._set('dirty', true); + }); + } + } + + /** + * @override remove all objects + */ + onDeselect() { + this.removeAll(); + return false; + } + + /** + * Returns string representation of a group + * @return {String} + */ + toString() { + return "#"); + } + + /** + * Decide if the object should cache or not. Create its own cache level + * objectCaching is a global flag, wins over everything + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * @return {Boolean} + */ + shouldCache() { + return false; + } + + /** + * Check if this group or its parent group are caching, recursively up + * @return {Boolean} + */ + isOnACache() { + return false; + } + + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Object} [styleOverride] properties to override the object style + * @param {Object} [childrenOverride] properties to override the children overrides + */ + _renderControls(ctx, styleOverride, childrenOverride) { + ctx.save(); + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + const options = _objectSpread2(_objectSpread2({ + hasControls: false + }, childrenOverride), {}, { + forActiveSelection: true + }); + for (let i = 0; i < this._objects.length; i++) { + this._objects[i]._renderControls(ctx, options); + } + super._renderControls(ctx, styleOverride); + ctx.restore(); + } +} +_defineProperty(ActiveSelection, "type", 'ActiveSelection'); +_defineProperty(ActiveSelection, "ownDefaults", activeSelectionDefaultValues); +classRegistry.setClass(ActiveSelection); +classRegistry.setClass(ActiveSelection, 'activeSelection'); + +/** + * Canvas 2D filter backend. + */ + +class Canvas2dFilterBackend { + constructor() { + /** + * Experimental. This object is a sort of repository of help layers used to avoid + * of recreating them during frequent filtering. If you are previewing a filter with + * a slider you probably do not want to create help layers every filter step. + * in this object there will be appended some canvases, created once, resized sometimes + * cleared never. Clearing is left to the developer. + **/ + _defineProperty(this, "resources", {}); + } + /** + * Apply a set of filters against a source image and draw the filtered output + * to the provided destination canvas. + * + * @param {EnhancedFilter} filters The filter to apply. + * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. + * @param {Number} sourceWidth The width of the source input. + * @param {Number} sourceHeight The height of the source input. + * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. + */ + applyFilters(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) { + const ctx = targetCanvas.getContext('2d'); + if (!ctx) { + return; + } + ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); + const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); + const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); + const pipelineState = { + sourceWidth, + sourceHeight, + imageData, + originalEl: sourceElement, + originalImageData, + canvasEl: targetCanvas, + ctx, + filterBackend: this + }; + filters.forEach(filter => { + filter.applyTo(pipelineState); + }); + const { + imageData: imageDataPostFilter + } = pipelineState; + if (imageDataPostFilter.width !== sourceWidth || imageDataPostFilter.height !== sourceHeight) { + targetCanvas.width = imageDataPostFilter.width; + targetCanvas.height = imageDataPostFilter.height; + } + ctx.putImageData(imageDataPostFilter, 0, 0); + return pipelineState; + } +} + +class WebGLFilterBackend { + constructor() { + let { + tileSize = config.textureSize + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** + * Define ... + **/ + _defineProperty(this, "aPosition", new Float32Array([0, 0, 0, 1, 1, 0, 1, 1])); + /** + * Experimental. This object is a sort of repository of help layers used to avoid + * of recreating them during frequent filtering. If you are previewing a filter with + * a slider you probably do not want to create help layers every filter step. + * in this object there will be appended some canvases, created once, resized sometimes + * cleared never. Clearing is left to the developer. + **/ + _defineProperty(this, "resources", {}); + this.tileSize = tileSize; + this.setupGLContext(tileSize, tileSize); + this.captureGPUInfo(); + } + + /** + * Setup a WebGL context suitable for filtering, and bind any needed event handlers. + */ + setupGLContext(width, height) { + this.dispose(); + this.createWebGLCanvas(width, height); + } + + /** + * Create a canvas element and associated WebGL context and attaches them as + * class properties to the GLFilterBackend class. + */ + createWebGLCanvas(width, height) { + const canvas = createCanvasElement(); + canvas.width = width; + canvas.height = height; + const glOptions = { + alpha: true, + premultipliedAlpha: false, + depth: false, + stencil: false, + antialias: false + }, + gl = canvas.getContext('webgl', glOptions); + if (!gl) { + return; + } + gl.clearColor(0, 0, 0, 0); + // this canvas can fire webglcontextlost and webglcontextrestored + this.canvas = canvas; + this.gl = gl; + } + + /** + * Attempts to apply the requested filters to the source provided, drawing the filtered output + * to the provided target canvas. + * + * @param {Array} filters The filters to apply. + * @param {TexImageSource} source The source to be filtered. + * @param {Number} width The width of the source input. + * @param {Number} height The height of the source input. + * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. + * @param {String|undefined} cacheKey A key used to cache resources related to the source. If + * omitted, caching will be skipped. + */ + applyFilters(filters, source, width, height, targetCanvas, cacheKey) { + const gl = this.gl; + const ctx = targetCanvas.getContext('2d'); + if (!gl || !ctx) { + return; + } + let cachedTexture; + if (cacheKey) { + cachedTexture = this.getCachedTexture(cacheKey, source); + } + const pipelineState = { + originalWidth: source.width || + // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state? + source.originalWidth || 0, + originalHeight: source.height || + // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state? + source.originalHeight || 0, + sourceWidth: width, + sourceHeight: height, + destinationWidth: width, + destinationHeight: height, + context: gl, + sourceTexture: this.createTexture(gl, width, height, !cachedTexture ? source : undefined), + targetTexture: this.createTexture(gl, width, height), + originalTexture: cachedTexture || this.createTexture(gl, width, height, !cachedTexture ? source : undefined), + passes: filters.length, + webgl: true, + aPosition: this.aPosition, + programCache: this.programCache, + pass: 0, + filterBackend: this, + targetCanvas: targetCanvas + }; + const tempFbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); + filters.forEach(filter => { + filter && filter.applyTo(pipelineState); + }); + resizeCanvasIfNeeded(pipelineState); + this.copyGLTo2D(gl, pipelineState); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(pipelineState.sourceTexture); + gl.deleteTexture(pipelineState.targetTexture); + gl.deleteFramebuffer(tempFbo); + ctx.setTransform(1, 0, 0, 1, 0, 0); + return pipelineState; + } + + /** + * Detach event listeners, remove references, and clean up caches. + */ + dispose() { + if (this.canvas) { + // we are disposing, we don't care about the fact + // that the canvas shouldn't be null. + // @ts-expect-error disposing + this.canvas = null; + // @ts-expect-error disposing + this.gl = null; + } + this.clearWebGLCaches(); + } + + /** + * Wipe out WebGL-related caches. + */ + clearWebGLCaches() { + this.programCache = {}; + this.textureCache = {}; + } + + /** + * Create a WebGL texture object. + * + * Accepts specific dimensions to initialize the texture to or a source image. + * + * @param {WebGLRenderingContext} gl The GL context to use for creating the texture. + * @param {number} width The width to initialize the texture at. + * @param {number} height The height to initialize the texture. + * @param {TexImageSource} textureImageSource A source for the texture data. + * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture. + * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR + * @returns {WebGLTexture} + */ + createTexture(gl, width, height, textureImageSource, filter) { + const { + NEAREST, + TEXTURE_2D, + RGBA, + UNSIGNED_BYTE, + CLAMP_TO_EDGE, + TEXTURE_MAG_FILTER, + TEXTURE_MIN_FILTER, + TEXTURE_WRAP_S, + TEXTURE_WRAP_T + } = gl; + const texture = gl.createTexture(); + gl.bindTexture(TEXTURE_2D, texture); + gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST); + gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST); + gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + if (textureImageSource) { + gl.texImage2D(TEXTURE_2D, 0, RGBA, RGBA, UNSIGNED_BYTE, textureImageSource); + } else { + gl.texImage2D(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, UNSIGNED_BYTE, null); + } + return texture; + } + + /** + * Can be optionally used to get a texture from the cache array + * + * If an existing texture is not found, a new texture is created and cached. + * + * @param {String} uniqueId A cache key to use to find an existing texture. + * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the + * texture cache entry if one does not already exist. + */ + getCachedTexture(uniqueId, textureImageSource, filter) { + const { + textureCache + } = this; + if (textureCache[uniqueId]) { + return textureCache[uniqueId]; + } else { + const texture = this.createTexture(this.gl, textureImageSource.width, textureImageSource.height, textureImageSource, filter); + if (texture) { + textureCache[uniqueId] = texture; + } + return texture; + } + } + + /** + * Clear out cached resources related to a source image that has been + * filtered previously. + * + * @param {String} cacheKey The cache key provided when the source image was filtered. + */ + evictCachesForKey(cacheKey) { + if (this.textureCache[cacheKey]) { + this.gl.deleteTexture(this.textureCache[cacheKey]); + delete this.textureCache[cacheKey]; + } + } + + /** + * Copy an input WebGL canvas on to an output 2D canvas. + * + * The WebGL canvas is assumed to be upside down, with the top-left pixel of the + * desired output image appearing in the bottom-left corner of the WebGL canvas. + * + * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. + * @param {Object} pipelineState The 2D target canvas to copy on to. + */ + copyGLTo2D(gl, pipelineState) { + const glCanvas = gl.canvas, + targetCanvas = pipelineState.targetCanvas, + ctx = targetCanvas.getContext('2d'); + if (!ctx) { + return; + } + ctx.translate(0, targetCanvas.height); // move it down again + ctx.scale(1, -1); // vertical flip + // where is my image on the big glcanvas? + const sourceY = glCanvas.height - targetCanvas.height; + ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height); + } + + /** + * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData + * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra). + * + * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. + * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. + * @param {Object} pipelineState The 2D target canvas to copy on to. + */ + copyGLTo2DPutImageData(gl, pipelineState) { + const targetCanvas = pipelineState.targetCanvas, + ctx = targetCanvas.getContext('2d'), + dWidth = pipelineState.destinationWidth, + dHeight = pipelineState.destinationHeight, + numBytes = dWidth * dHeight * 4; + if (!ctx) { + return; + } + const u8 = new Uint8Array(this.imageBuffer, 0, numBytes); + const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); + gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); + const imgData = new ImageData(u8Clamped, dWidth, dHeight); + ctx.putImageData(imgData, 0, 0); + } + + /** + * Attempt to extract GPU information strings from a WebGL context. + * + * Useful information when debugging or blacklisting specific GPUs. + * + * @returns {Object} A GPU info object with renderer and vendor strings. + */ + captureGPUInfo() { + if (this.gpuInfo) { + return this.gpuInfo; + } + const gl = this.gl, + gpuInfo = { + renderer: '', + vendor: '' + }; + if (!gl) { + return gpuInfo; + } + const ext = gl.getExtension('WEBGL_debug_renderer_info'); + if (ext) { + const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); + const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); + if (renderer) { + gpuInfo.renderer = renderer.toLowerCase(); + } + if (vendor) { + gpuInfo.vendor = vendor.toLowerCase(); + } + } + this.gpuInfo = gpuInfo; + return gpuInfo; + } +} +function resizeCanvasIfNeeded(pipelineState) { + const targetCanvas = pipelineState.targetCanvas, + width = targetCanvas.width, + height = targetCanvas.height, + dWidth = pipelineState.destinationWidth, + dHeight = pipelineState.destinationHeight; + if (width !== dWidth || height !== dHeight) { + targetCanvas.width = dWidth; + targetCanvas.height = dHeight; + } +} + +let filterBackend; + +/** + * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend + */ +function initFilterBackend() { + const { + WebGLProbe + } = getEnv(); + WebGLProbe.queryWebGL(createCanvasElement()); + if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) { + return new WebGLFilterBackend({ + tileSize: config.textureSize + }); + } else { + return new Canvas2dFilterBackend(); + } +} + +/** + * Get the current fabricJS filter backend or initialize one if not available yet + * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior), + * pass `false` to get the backend ref without mutating it + */ +function getFilterBackend() { + let strict = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + if (!filterBackend && strict) { + filterBackend = initFilterBackend(); + } + return filterBackend; +} +function setFilterBackend(backend) { + filterBackend = backend; +} + +const _excluded$2 = ["filters", "resizeFilter", "src", "crossOrigin", "type"]; + +// @todo Would be nice to have filtering code not imported directly. + +const imageDefaultValues = { + strokeWidth: 0, + srcFromAttribute: false, + minimumScaleTrigger: 0.5, + cropX: 0, + cropY: 0, + imageSmoothing: true +}; +const IMAGE_PROPS = ['cropX', 'cropY']; + +/** + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} + */ +class FabricImage extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), FabricImage.ownDefaults); + } + /** + * Constructor + * Image can be initialized with any canvas drawable or a string. + * The string should be a url and will be loaded as an image. + * Canvas and Image element work out of the box, while videos require extra code to work. + * Please check video element events for seeking. + * @param {ImageSource | string} element Image element + * @param {Object} [options] Options object + */ + + constructor(arg0, options) { + super(); + /** + * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`. + * This allows for relative urls as image src. + * @since 2.7.0 + * @type Boolean + * @default false + */ + /** + * private + * contains last value of scaleX to detect + * if the Image got resized after the last Render + * @type Number + */ + _defineProperty(this, "_lastScaleX", 1); + /** + * private + * contains last value of scaleY to detect + * if the Image got resized after the last Render + * @type Number + */ + _defineProperty(this, "_lastScaleY", 1); + /** + * private + * contains last value of scaling applied by the apply filter chain + * @type Number + */ + _defineProperty(this, "_filterScalingX", 1); + /** + * private + * contains last value of scaling applied by the apply filter chain + * @type Number + */ + _defineProperty(this, "_filterScalingY", 1); + this.filters = []; + Object.assign(this, FabricImage.ownDefaults); + this.setOptions(options); + this.cacheKey = "texture".concat(uid()); + this.setElement(typeof arg0 === 'string' ? (this.canvas && getDocumentFromElement(this.canvas.getElement()) || getFabricDocument()).getElementById(arg0) : arg0, options); + } + + /** + * Returns image element which this instance if based on + */ + getElement() { + return this._element; + } + + /** + * Sets image element for this instance to a specified one. + * If filters defined they are applied to new image. + * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. + * @param {HTMLImageElement} element + * @param {Partial} [size] Options object + */ + setElement(element) { + let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.removeTexture(this.cacheKey); + this.removeTexture("".concat(this.cacheKey, "_filtered")); + this._element = element; + this._originalElement = element; + this._setWidthHeight(size); + element.classList.add(FabricImage.CSS_CANVAS); + if (this.filters.length !== 0) { + this.applyFilters(); + } + // resizeFilters work on the already filtered copy. + // we need to apply resizeFilters AFTER normal filters. + // applyResizeFilters is run more often than normal filters + // and is triggered by user interactions rather than dev code + if (this.resizeFilter) { + this.applyResizeFilters(); + } + } + + /** + * Delete a single texture if in webgl mode + */ + removeTexture(key) { + const backend = getFilterBackend(false); + if (backend instanceof WebGLFilterBackend) { + backend.evictCachesForKey(key); + } + } + + /** + * Delete textures, reference to elements and eventually JSDOM cleanup + */ + dispose() { + super.dispose(); + this.removeTexture(this.cacheKey); + this.removeTexture("".concat(this.cacheKey, "_filtered")); + this._cacheContext = null; + ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach(elementKey => { + const el = this[elementKey]; + el && getEnv().dispose(el); + // @ts-expect-error disposing + this[elementKey] = undefined; + }); + } + + /** + * Get the crossOrigin value (of the corresponding image element) + */ + getCrossOrigin() { + return this._originalElement && (this._originalElement.crossOrigin || null); + } + + /** + * Returns original size of an image + */ + getOriginalSize() { + const element = this.getElement(); + if (!element) { + return { + width: 0, + height: 0 + }; + } + return { + width: element.naturalWidth || element.width, + height: element.naturalHeight || element.height + }; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _stroke(ctx) { + if (!this.stroke || this.strokeWidth === 0) { + return; + } + const w = this.width / 2, + h = this.height / 2; + ctx.beginPath(); + ctx.moveTo(-w, -h); + ctx.lineTo(w, -h); + ctx.lineTo(w, h); + ctx.lineTo(-w, h); + ctx.lineTo(-w, -h); + ctx.closePath(); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const filters = []; + this.filters.forEach(filterObj => { + filterObj && filters.push(filterObj.toObject()); + }); + return _objectSpread2(_objectSpread2({}, super.toObject([...IMAGE_PROPS, ...propertiesToInclude])), {}, { + src: this.getSrc(), + crossOrigin: this.getCrossOrigin(), + filters + }, this.resizeFilter ? { + resizeFilter: this.resizeFilter.toObject() + } : {}); + } + + /** + * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height. + * @return {Boolean} + */ + hasCrop() { + return !!this.cropX || !!this.cropY || this.width < this._element.width || this.height < this._element.height; + } + + /** + * Returns svg representation of an instance + * @return {string[]} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const imageMarkup = [], + element = this._element, + x = -this.width / 2, + y = -this.height / 2; + let svgString = [], + strokeSvg = [], + clipPath = '', + imageRendering = ''; + if (!element) { + return []; + } + if (this.hasCrop()) { + const clipPathId = uid(); + svgString.push('\n', '\t\n', '\n'); + clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" '; + } + if (!this.imageSmoothing) { + imageRendering = ' image-rendering="optimizeSpeed"'; + } + imageMarkup.push('\t element with actual transformation, then offsetting object to the top/left + // so that object's center aligns with container's left/top + , "\" width=\"").concat(element.width || element.naturalWidth, "\" height=\"").concat(element.height || element.naturalHeight, "\"").concat(imageRendering).concat(clipPath, ">\n")); + if (this.stroke || this.strokeDashArray) { + const origFill = this.fill; + this.fill = null; + strokeSvg = ["\t\n")]; + this.fill = origFill; + } + if (this.paintFirst !== FILL) { + svgString = svgString.concat(strokeSvg, imageMarkup); + } else { + svgString = svgString.concat(imageMarkup, strokeSvg); + } + return svgString; + } + + /** + * Returns source of an image + * @param {Boolean} filtered indicates if the src is needed for svg + * @return {String} Source of an image + */ + getSrc(filtered) { + const element = filtered ? this._element : this._originalElement; + if (element) { + if (element.toDataURL) { + return element.toDataURL(); + } + if (this.srcFromAttribute) { + return element.getAttribute('src') || ''; + } else { + return element.src; + } + } else { + return this.src || ''; + } + } + + /** + * Alias for getSrc + * @param filtered + * @deprecated + */ + getSvgSrc(filtered) { + return this.getSrc(filtered); + } + + /** + * Loads and sets source of an image\ + * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking + * @param {String} src Source string (URL) + * @param {LoadImageOptions} [options] Options object + */ + setSrc(src) { + let { + crossOrigin, + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return loadImage(src, { + crossOrigin, + signal + }).then(img => { + typeof crossOrigin !== 'undefined' && this.set({ + crossOrigin + }); + this.setElement(img); + }); + } + + /** + * Returns string representation of an instance + * @return {String} String representation of an instance + */ + toString() { + return "#"); + } + applyResizeFilters() { + const filter = this.resizeFilter, + minimumScale = this.minimumScaleTrigger, + objectScale = this.getTotalObjectScaling(), + scaleX = objectScale.x, + scaleY = objectScale.y, + elementToFilter = this._filteredEl || this._originalElement; + if (this.group) { + this.set('dirty', true); + } + if (!filter || scaleX > minimumScale && scaleY > minimumScale) { + this._element = elementToFilter; + this._filterScalingX = 1; + this._filterScalingY = 1; + this._lastScaleX = scaleX; + this._lastScaleY = scaleY; + return; + } + const canvasEl = createCanvasElement(), + sourceWidth = elementToFilter.width, + sourceHeight = elementToFilter.height; + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; + this._element = canvasEl; + this._lastScaleX = filter.scaleX = scaleX; + this._lastScaleY = filter.scaleY = scaleY; + getFilterBackend().applyFilters([filter], elementToFilter, sourceWidth, sourceHeight, this._element); + this._filterScalingX = canvasEl.width / this._originalElement.width; + this._filterScalingY = canvasEl.height / this._originalElement.height; + } + + /** + * Applies filters assigned to this image (from "filters" array) or from filter param + * @method applyFilters + * @param {Array} filters to be applied + * @param {Boolean} forResizing specify if the filter operation is a resize operation + */ + applyFilters() { + let filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.filters || []; + filters = filters.filter(filter => filter && !filter.isNeutralState()); + this.set('dirty', true); + + // needs to clear out or WEBGL will not resize correctly + this.removeTexture("".concat(this.cacheKey, "_filtered")); + if (filters.length === 0) { + this._element = this._originalElement; + // this is unsafe and needs to be rethinkend + this._filteredEl = undefined; + this._filterScalingX = 1; + this._filterScalingY = 1; + return; + } + const imgElement = this._originalElement, + sourceWidth = imgElement.naturalWidth || imgElement.width, + sourceHeight = imgElement.naturalHeight || imgElement.height; + if (this._element === this._originalElement) { + // if the _element a reference to _originalElement + // we need to create a new element to host the filtered pixels + const canvasEl = createCanvasElement(); + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; + this._element = canvasEl; + this._filteredEl = canvasEl; + } else if (this._filteredEl) { + // if the _element is it own element, + // and we also have a _filteredEl, then we clean up _filteredEl + // and we assign it to _element. + // in this way we invalidate the eventual old resize filtered element + this._element = this._filteredEl; + this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); + // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y + this._lastScaleX = 1; + this._lastScaleY = 1; + } + getFilterBackend().applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element); + if (this._originalElement.width !== this._element.width || this._originalElement.height !== this._element.height) { + this._filterScalingX = this._element.width / this._originalElement.width; + this._filterScalingY = this._element.height / this._originalElement.height; + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + ctx.imageSmoothingEnabled = this.imageSmoothing; + if (this.isMoving !== true && this.resizeFilter && this._needsResize()) { + this.applyResizeFilters(); + } + this._stroke(ctx); + this._renderPaintInOrder(ctx); + } + + /** + * Paint the cached copy of the object on the target context. + * it will set the imageSmoothing for the draw operation + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawCacheOnCanvas(ctx) { + ctx.imageSmoothingEnabled = this.imageSmoothing; + super.drawCacheOnCanvas(ctx); + } + + /** + * Decide if the object should cache or not. Create its own cache level + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * This is the special image version where we would like to avoid caching where possible. + * Essentially images do not benefit from caching. They may require caching, and in that + * case we do it. Also caching an image usually ends in a loss of details. + * A full performance audit should be done. + * @return {Boolean} + */ + shouldCache() { + return this.needsItsOwnCache(); + } + _renderFill(ctx) { + const elementToDraw = this._element; + if (!elementToDraw) { + return; + } + const scaleX = this._filterScalingX, + scaleY = this._filterScalingY, + w = this.width, + h = this.height, + // crop values cannot be lesser than 0. + cropX = Math.max(this.cropX, 0), + cropY = Math.max(this.cropY, 0), + elWidth = elementToDraw.naturalWidth || elementToDraw.width, + elHeight = elementToDraw.naturalHeight || elementToDraw.height, + sX = cropX * scaleX, + sY = cropY * scaleY, + // the width height cannot exceed element width/height, starting from the crop offset. + sW = Math.min(w * scaleX, elWidth - sX), + sH = Math.min(h * scaleY, elHeight - sY), + x = -w / 2, + y = -h / 2, + maxDestW = Math.min(w, elWidth / scaleX - cropX), + maxDestH = Math.min(h, elHeight / scaleY - cropY); + elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); + } + + /** + * needed to check if image needs resize + * @private + */ + _needsResize() { + const scale = this.getTotalObjectScaling(); + return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY; + } + + /** + * @private + * @deprecated unused + */ + _resetWidthHeight() { + this.set(this.getOriginalSize()); + } + + /** + * @private + * Set the width and the height of the image object, using the element or the + * options. + */ + _setWidthHeight() { + let { + width, + height + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const size = this.getOriginalSize(); + this.width = width || size.width; + this.height = height || size.height; + } + + /** + * Calculate offset for center and scale factor for the image in order to respect + * the preserveAspectRatio attribute + * @private + */ + parsePreserveAspectRatioAttribute() { + const pAR = parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''), + pWidth = this.width, + pHeight = this.height, + parsedAttributes = { + width: pWidth, + height: pHeight + }; + let rWidth = this._element.width, + rHeight = this._element.height, + scaleX = 1, + scaleY = 1, + offsetLeft = 0, + offsetTop = 0, + cropX = 0, + cropY = 0, + offset; + if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) { + if (pAR.meetOrSlice === 'meet') { + scaleX = scaleY = findScaleToFit(this._element, parsedAttributes); + offset = (pWidth - rWidth * scaleX) / 2; + if (pAR.alignX === 'Min') { + offsetLeft = -offset; + } + if (pAR.alignX === 'Max') { + offsetLeft = offset; + } + offset = (pHeight - rHeight * scaleY) / 2; + if (pAR.alignY === 'Min') { + offsetTop = -offset; + } + if (pAR.alignY === 'Max') { + offsetTop = offset; + } + } + if (pAR.meetOrSlice === 'slice') { + scaleX = scaleY = findScaleToCover(this._element, parsedAttributes); + offset = rWidth - pWidth / scaleX; + if (pAR.alignX === 'Mid') { + cropX = offset / 2; + } + if (pAR.alignX === 'Max') { + cropX = offset; + } + offset = rHeight - pHeight / scaleY; + if (pAR.alignY === 'Mid') { + cropY = offset / 2; + } + if (pAR.alignY === 'Max') { + cropY = offset; + } + rWidth = pWidth / scaleX; + rHeight = pHeight / scaleY; + } + } else { + scaleX = pWidth / rWidth; + scaleY = pHeight / rHeight; + } + return { + width: rWidth, + height: rHeight, + scaleX, + scaleY, + offsetLeft, + offsetTop, + cropX, + cropY + }; + } + + /** + * Default CSS class name for canvas + * @static + * @type String + * @default + */ + + /** + * Creates an instance of FabricImage from its object representation + * @static + * @param {Object} object Object to create an instance from + * @param {object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(_ref, options) { + let { + filters: f, + resizeFilter: rf, + src, + crossOrigin, + type + } = _ref, + object = _objectWithoutProperties(_ref, _excluded$2); + return Promise.all([loadImage(src, _objectSpread2(_objectSpread2({}, options), {}, { + crossOrigin + })), f && enlivenObjects(f, options), + // TODO: redundant - handled by enlivenObjectEnlivables + rf && enlivenObjects([rf], options), enlivenObjectEnlivables(object, options)]).then(_ref2 => { + let [el, filters = [], [resizeFilter] = [], hydratedProps = {}] = _ref2; + return new this(el, _objectSpread2(_objectSpread2({}, object), {}, { + // TODO: this creates a difference between image creation and restoring from JSON + src, + filters, + resizeFilter + }, hydratedProps)); + }); + } + + /** + * Creates an instance of Image from an URL string + * @static + * @param {String} url URL to create an image from + * @param {LoadImageOptions} [options] Options object + * @returns {Promise} + */ + static fromURL(url) { + let { + crossOrigin = null, + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let imageOptions = arguments.length > 2 ? arguments[2] : undefined; + return loadImage(url, { + crossOrigin, + signal + }).then(img => new this(img, imageOptions)); + } + + /** + * Returns {@link FabricImage} instance from an SVG element + * @static + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @param {Function} callback Callback to execute when Image object is created + */ + static async fromElement(element) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let cssRules = arguments.length > 2 ? arguments[2] : undefined; + const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules); + return this.fromURL(parsedAttributes['xlink:href'], options, parsedAttributes).catch(err => { + log('log', 'Unable to parse Image', err); + return null; + }); + } +} +_defineProperty(FabricImage, "type", 'Image'); +_defineProperty(FabricImage, "cacheProperties", [...cacheProperties, ...IMAGE_PROPS]); +_defineProperty(FabricImage, "ownDefaults", imageDefaultValues); +_defineProperty(FabricImage, "CSS_CANVAS", 'canvas-img'); +/** + * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement}) + * @static + * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} + */ +_defineProperty(FabricImage, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'x', 'y', 'width', 'height', 'preserveAspectRatio', 'xlink:href', 'crossOrigin', 'image-rendering']); +classRegistry.setClass(FabricImage); +classRegistry.setSVGClass(FabricImage); + +/** + * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements + */ +function applyViewboxTransform(element) { + if (!svgViewBoxElementsRegEx.test(element.nodeName)) { + return {}; + } + const viewBoxAttr = element.getAttribute('viewBox'); + let scaleX = 1; + let scaleY = 1; + let minX = 0; + let minY = 0; + let matrix; + let el; + const widthAttr = element.getAttribute('width'); + const heightAttr = element.getAttribute('height'); + const x = element.getAttribute('x') || 0; + const y = element.getAttribute('y') || 0; + const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr); + const missingViewBox = !goodViewbox; + const missingDimAttr = !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'; + let translateMatrix = ''; + let widthDiff = 0; + let heightDiff = 0; + if (missingViewBox) { + if ((x || y) && element.parentNode && element.parentNode.nodeName !== '#document') { + translateMatrix = ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') '; + matrix = (element.getAttribute('transform') || '') + translateMatrix; + element.setAttribute('transform', matrix); + element.removeAttribute('x'); + element.removeAttribute('y'); + } + } + if (missingViewBox && missingDimAttr) { + return { + width: 0, + height: 0 + }; + } + const parsedDim = { + width: 0, + height: 0 + }; + if (missingViewBox) { + parsedDim.width = parseUnit(widthAttr); + parsedDim.height = parseUnit(heightAttr); + // set a transform for elements that have x y and are inner(only) SVGs + return parsedDim; + } + const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue); + minX = -parseFloat(pasedViewBox[1]); + minY = -parseFloat(pasedViewBox[2]); + const viewBoxWidth = parseFloat(pasedViewBox[3]); + const viewBoxHeight = parseFloat(pasedViewBox[4]); + parsedDim.minX = minX; + parsedDim.minY = minY; + parsedDim.viewBoxWidth = viewBoxWidth; + parsedDim.viewBoxHeight = viewBoxHeight; + if (!missingDimAttr) { + parsedDim.width = parseUnit(widthAttr); + parsedDim.height = parseUnit(heightAttr); + scaleX = parsedDim.width / viewBoxWidth; + scaleY = parsedDim.height / viewBoxHeight; + } else { + parsedDim.width = viewBoxWidth; + parsedDim.height = viewBoxHeight; + } + + // default is to preserve aspect ratio + const preserveAspectRatio = parsePreserveAspectRatioAttribute(element.getAttribute('preserveAspectRatio') || ''); + if (preserveAspectRatio.alignX !== NONE) { + //translate all container for the effect of Mid, Min, Max + if (preserveAspectRatio.meetOrSlice === 'meet') { + scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; + // calculate additional translation to move the viewbox + } + if (preserveAspectRatio.meetOrSlice === 'slice') { + scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY; + // calculate additional translation to move the viewbox + } + widthDiff = parsedDim.width - viewBoxWidth * scaleX; + heightDiff = parsedDim.height - viewBoxHeight * scaleX; + if (preserveAspectRatio.alignX === 'Mid') { + widthDiff /= 2; + } + if (preserveAspectRatio.alignY === 'Mid') { + heightDiff /= 2; + } + if (preserveAspectRatio.alignX === 'Min') { + widthDiff = 0; + } + if (preserveAspectRatio.alignY === 'Min') { + heightDiff = 0; + } + } + if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { + return parsedDim; + } + if ((x || y) && element.parentNode.nodeName !== '#document') { + translateMatrix = ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') '; + } + matrix = translateMatrix + ' matrix(' + scaleX + ' 0' + ' 0 ' + scaleY + ' ' + (minX * scaleX + widthDiff) + ' ' + (minY * scaleY + heightDiff) + ') '; + // seems unused. + // parsedDim.viewboxTransform = parseTransformAttribute(matrix); + if (element.nodeName === 'svg') { + el = element.ownerDocument.createElementNS(svgNS, 'g'); + // element.firstChild != null + while (element.firstChild) { + el.appendChild(element.firstChild); + } + element.appendChild(el); + } else { + el = element; + el.removeAttribute('x'); + el.removeAttribute('y'); + matrix = el.getAttribute('transform') + matrix; + } + el.setAttribute('transform', matrix); + return parsedDim; +} + +const getTagName = node => node.tagName.replace('svg:', ''); + +const svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors); +function hasInvalidAncestor(element) { + let _element = element; + while (_element && (_element = _element.parentElement)) { + if (_element && _element.nodeName && svgInvalidAncestorsRegEx.test(getTagName(_element)) && !_element.getAttribute('instantiated_by_use')) { + return true; + } + } + return false; +} + +function getMultipleNodes(doc, nodeNames) { + let nodeName, + nodeArray = [], + nodeList, + i, + len; + for (i = 0, len = nodeNames.length; i < len; i++) { + nodeName = nodeNames[i]; + nodeList = doc.getElementsByTagNameNS('http://www.w3.org/2000/svg', nodeName); + nodeArray = nodeArray.concat(Array.from(nodeList)); + } + return nodeArray; +} + +function parseUseDirectives(doc) { + const nodelist = getMultipleNodes(doc, ['use', 'svg:use']); + const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform']; + for (const useElement of nodelist) { + const useAttributes = useElement.attributes; + const useAttrMap = {}; + for (const attr of useAttributes) { + attr.value && (useAttrMap[attr.name] = attr.value); + } + const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1); + if (xlink === '') { + return; + } + const referencedElement = doc.getElementById(xlink); + if (referencedElement === null) { + // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink + return; + } + let clonedOriginal = referencedElement.cloneNode(true); + const originalAttributes = clonedOriginal.attributes; + const originalAttrMap = {}; + for (const attr of originalAttributes) { + attr.value && (originalAttrMap[attr.name] = attr.value); + } + + // Transform attribute needs to be merged in a particular way + const { + x = 0, + y = 0, + transform = '' + } = useAttrMap; + const currentTrans = "".concat(transform, " ").concat(originalAttrMap.transform || '', " translate(").concat(x, ", ").concat(y, ")"); + applyViewboxTransform(clonedOriginal); + if (/^svg$/i.test(clonedOriginal.nodeName)) { + // if is an SVG, create a group and apply all the attributes on top of it + const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g'); + Object.entries(originalAttrMap).forEach(_ref => { + let [name, value] = _ref; + return el3.setAttributeNS(svgNS, name, value); + }); + el3.append(...clonedOriginal.childNodes); + clonedOriginal = el3; + } + for (const attr of useAttributes) { + if (!attr) { + continue; + } + const { + name, + value + } = attr; + if (skipAttributes.includes(name)) { + continue; + } + if (name === 'style') { + // when use has a style, merge the two styles, with the ref being priority (not use) + // priority is by feature. an attribute for fill on the original element + // will overwrite the fill in style or attribute for tha use + const styleRecord = {}; + parseStyleString(value, styleRecord); + // cleanup styleRecord from attributes of original + Object.entries(originalAttrMap).forEach(_ref2 => { + let [name, value] = _ref2; + styleRecord[name] = value; + }); + // now we can put in the style of the original that will overwrite the original attributes + parseStyleString(originalAttrMap.style || '', styleRecord); + const mergedStyles = Object.entries(styleRecord).map(entry => entry.join(':')).join(';'); + clonedOriginal.setAttribute(name, mergedStyles); + } else { + // set the attribute from use element only if the original does not have it already + !originalAttrMap[name] && clonedOriginal.setAttribute(name, value); + } + } + clonedOriginal.setAttribute('transform', currentTrans); + clonedOriginal.setAttribute('instantiated_by_use', '1'); + clonedOriginal.removeAttribute('id'); + useElement.parentNode.replaceChild(clonedOriginal, useElement); + } +} + +const gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy']; +const xlinkAttr = 'xlink:href'; +function recursivelyParseGradientsXlink(doc, gradient) { + var _gradient$getAttribut; + const xLink = ((_gradient$getAttribut = gradient.getAttribute(xlinkAttr)) === null || _gradient$getAttribut === void 0 ? void 0 : _gradient$getAttribut.slice(1)) || '', + referencedGradient = doc.getElementById(xLink); + if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) { + recursivelyParseGradientsXlink(doc, referencedGradient); + } + if (referencedGradient) { + gradientsAttrs.forEach(attr => { + const value = referencedGradient.getAttribute(attr); + if (!gradient.hasAttribute(attr) && value) { + gradient.setAttribute(attr, value); + } + }); + if (!gradient.children.length) { + const referenceClone = referencedGradient.cloneNode(true); + while (referenceClone.firstChild) { + gradient.appendChild(referenceClone.firstChild); + } + } + } + gradient.removeAttribute(xlinkAttr); +} + +const tagArray = ['linearGradient', 'radialGradient', 'svg:linearGradient', 'svg:radialGradient']; + +/** + * Parses an SVG document, returning all of the gradient declarations found in it + * @param {SVGDocument} doc SVG document to parse + * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element + */ +function getGradientDefs(doc) { + const elList = getMultipleNodes(doc, tagArray); + const gradientDefs = {}; + let j = elList.length; + while (j--) { + const el = elList[j]; + if (el.getAttribute('xlink:href')) { + recursivelyParseGradientsXlink(doc, el); + } + const id = el.getAttribute('id'); + if (id) { + gradientDefs[id] = el; + } + } + return gradientDefs; +} + +/** + * Returns CSS rules for a given SVG document + * @param {HTMLElement} doc SVG document to parse + * @return {Object} CSS rules of this document + */ +function getCSSRules(doc) { + const styles = doc.getElementsByTagName('style'); + let i; + let len; + const allRules = {}; + + // very crude parsing of style contents + for (i = 0, len = styles.length; i < len; i++) { + const styleContents = (styles[i].textContent || '').replace( + // remove comments + /\/\*[\s\S]*?\*\//g, ''); + if (styleContents.trim() === '') { + continue; + } + // recovers all the rule in this form `body { style code... }` + // rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); + styleContents.split('}') + // remove empty rules and remove everything if we didn't split in at least 2 pieces + .filter((rule, index, array) => array.length > 1 && rule.trim()) + // at this point we have hopefully an array of rules `body { style code... ` + .forEach(rule => { + // if there is more than one opening bracket and the rule starts with '@', it is likely + // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below + // can not handle it. + if ((rule.match(/{/g) || []).length > 1 && rule.trim().startsWith('@')) { + return; + } + const match = rule.split('{'), + ruleObj = {}, + declaration = match[1].trim(), + propertyValuePairs = declaration.split(';').filter(function (pair) { + return pair.trim(); + }); + for (i = 0, len = propertyValuePairs.length; i < len; i++) { + const pair = propertyValuePairs[i].split(':'), + property = pair[0].trim(), + value = pair[1].trim(); + ruleObj[property] = value; + } + rule = match[0].trim(); + rule.split(',').forEach(_rule => { + _rule = _rule.replace(/^svg/i, '').trim(); + if (_rule === '') { + return; + } + allRules[_rule] = _objectSpread2(_objectSpread2({}, allRules[_rule] || {}), ruleObj); + }); + }); + } + return allRules; +} + +const findTag = el => classRegistry.getSVGClass(getTagName(el).toLowerCase()); +class ElementsParser { + constructor(elements, options, reviver, doc, clipPaths) { + this.elements = elements; + this.options = options; + this.reviver = reviver; + this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g; + this.doc = doc; + this.clipPaths = clipPaths; + this.gradientDefs = getGradientDefs(doc); + this.cssRules = getCSSRules(doc); + } + parse() { + return Promise.all(this.elements.map(element => this.createObject(element))); + } + async createObject(el) { + const klass = findTag(el); + if (klass) { + const obj = await klass.fromElement(el, this.options, this.cssRules); + this.resolveGradient(obj, el, FILL); + this.resolveGradient(obj, el, STROKE); + if (obj instanceof FabricImage && obj._originalElement) { + removeTransformMatrixForSvgParsing(obj, obj.parsePreserveAspectRatioAttribute()); + } else { + removeTransformMatrixForSvgParsing(obj); + } + await this.resolveClipPath(obj, el); + this.reviver && this.reviver(el, obj); + return obj; + } + return null; + } + extractPropertyDefinition(obj, property, storage) { + const value = obj[property], + regex = this.regexUrl; + if (!regex.test(value)) { + return undefined; + } + // verify: can we remove the 'g' flag? and remove lastIndex changes? + regex.lastIndex = 0; + // we passed the regex test, so we know is not null; + const id = regex.exec(value)[1]; + regex.lastIndex = 0; + // @todo fix this + return storage[id]; + } + resolveGradient(obj, el, property) { + const gradientDef = this.extractPropertyDefinition(obj, property, this.gradientDefs); + if (gradientDef) { + const opacityAttr = el.getAttribute(property + '-opacity'); + const gradient = Gradient.fromElement(gradientDef, obj, _objectSpread2(_objectSpread2({}, this.options), {}, { + opacity: opacityAttr + })); + obj.set(property, gradient); + } + } + + // TODO: resolveClipPath could be run once per clippath with minor work per object. + // is a refactor that i m not sure is worth on this code + async resolveClipPath(obj, usingElement) { + const clipPathElements = this.extractPropertyDefinition(obj, 'clipPath', this.clipPaths); + if (clipPathElements) { + const objTransformInv = invertTransform(obj.calcTransformMatrix()); + const clipPathTag = clipPathElements[0].parentElement; + let clipPathOwner = usingElement; + while (clipPathOwner.parentElement && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) { + clipPathOwner = clipPathOwner.parentElement; + } + // move the clipPath tag as sibling to the real element that is using it + clipPathOwner.parentElement.appendChild(clipPathTag); + + // this multiplication order could be opposite. + // but i don't have an svg to test it + // at the first SVG that has a transform on both places and is misplaced + // try to invert this multiplication order + const finalTransform = parseTransformAttribute("".concat(clipPathOwner.getAttribute('transform') || '', " ").concat(clipPathTag.getAttribute('originalTransform') || '')); + clipPathTag.setAttribute('transform', "matrix(".concat(finalTransform.join(','), ")")); + const container = await Promise.all(clipPathElements.map(clipPathElement => { + return findTag(clipPathElement).fromElement(clipPathElement, this.options, this.cssRules).then(enlivedClippath => { + removeTransformMatrixForSvgParsing(enlivedClippath); + enlivedClippath.fillRule = enlivedClippath.clipRule; + delete enlivedClippath.clipRule; + return enlivedClippath; + }); + })); + const clipPath = container.length === 1 ? container[0] : new Group(container); + const gTransform = multiplyTransformMatrices(objTransformInv, clipPath.calcTransformMatrix()); + if (clipPath.clipPath) { + await this.resolveClipPath(clipPath, clipPathOwner); + } + const { + scaleX, + scaleY, + angle, + skewX, + translateX, + translateY + } = qrDecompose(gTransform); + clipPath.set({ + flipX: false, + flipY: false + }); + clipPath.set({ + scaleX, + scaleY, + angle, + skewX, + skewY: 0 + }); + clipPath.setPositionByOrigin(new Point(translateX, translateY), CENTER, CENTER); + obj.clipPath = clipPath; + } else { + // if clip-path does not resolve to any element, delete the property. + delete obj.clipPath; + return; + } + } +} + +const isValidSvgTag = el => svgValidTagNamesRegEx.test(getTagName(el)); +const createEmptyResponse = () => ({ + objects: [], + elements: [], + options: {}, + allElements: [] +}); + +/** + * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback + * @static + * @function + * @memberOf fabric + * @param {HTMLElement} doc SVG document to parse + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @return {SVGParsingOutput} + * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + */ +async function parseSVGDocument(doc, reviver) { + let { + crossOrigin, + signal + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (signal && signal.aborted) { + log('log', new SignalAbortedError('parseSVGDocument')); + // this is an unhappy path, we dont care about speed + return createEmptyResponse(); + } + const documentElement = doc.documentElement; + parseUseDirectives(doc); + const descendants = Array.from(documentElement.getElementsByTagName('*')), + options = _objectSpread2(_objectSpread2({}, applyViewboxTransform(documentElement)), {}, { + crossOrigin, + signal + }); + const elements = descendants.filter(el => { + applyViewboxTransform(el); + return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement + }); + if (!elements || elements && !elements.length) { + return _objectSpread2(_objectSpread2({}, createEmptyResponse()), {}, { + options, + allElements: descendants + }); + } + const localClipPaths = {}; + descendants.filter(el => getTagName(el) === 'clipPath').forEach(el => { + el.setAttribute('originalTransform', el.getAttribute('transform') || ''); + const id = el.getAttribute('id'); + localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(el => isValidSvgTag(el)); + }); + + // Precedence of rules: style > class > attribute + const elementParser = new ElementsParser(elements, options, reviver, doc, localClipPaths); + const instances = await elementParser.parse(); + return { + objects: instances, + elements, + options, + allElements: descendants + }; +} + +/** + * Takes string corresponding to an SVG document, and parses it into a set of fabric objects + * @memberOf fabric + * @param {String} string representing the svg + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + */ +function loadSVGFromString(string, reviver, options) { + const parser = new (getFabricWindow().DOMParser)(), + // should we use `image/svg+xml` here? + doc = parser.parseFromString(string.trim(), 'text/xml'); + return parseSVGDocument(doc, reviver, options); +} + +/** + * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. + * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) + * @memberOf fabric + * @param {string} url where the SVG is + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + */ +function loadSVGFromURL(url, reviver) { + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // need to handle error properly + return new Promise((resolve, reject) => { + const onComplete = r => { + const xml = r.responseXML; + if (xml) { + resolve(xml); + } + reject(); + }; + request(url.replace(/^\n\s*/, '').trim(), { + onComplete, + signal: options.signal + }); + }).then(parsedDoc => parseSVGDocument(parsedDoc, reviver, options)).catch(() => { + // this is an unhappy path, we dont care about speed + return createEmptyResponse(); + }); +} + +const ACTION_NAME$1 = MODIFY_POLY; +/** + * This function locates the controls. + * It'll be used both for drawing and for interaction. + */ +const createPolyPositionHandler = pointIndex => { + return function (dim, finalMatrix, polyObject) { + const { + points, + pathOffset + } = polyObject; + return new Point(points[pointIndex]).subtract(pathOffset).transform(multiplyTransformMatrices(polyObject.getViewportTransform(), polyObject.calcTransformMatrix())); + }; +}; + +/** + * This function defines what the control does. + * It'll be called on every mouse move after a control has been clicked and is being dragged. + * The function receives as argument the mouse event, the current transform object + * and the current position in canvas coordinate `transform.target` is a reference to the + * current object being transformed. + */ +const polyActionHandler = (eventData, transform, x, y) => { + const { + target, + pointIndex + } = transform; + const poly = target; + const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, poly.calcOwnMatrix()); + poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset); + poly.setDimensions(); + return true; +}; + +/** + * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`. + */ +const factoryPolyActionHandler = (pointIndex, fn) => { + return function (eventData, transform, x, y) { + const poly = transform.target, + anchorPoint = new Point(poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1]), + anchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()), + actionPerformed = fn(eventData, _objectSpread2(_objectSpread2({}, transform), {}, { + pointIndex + }), x, y); + const newAnchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()); + const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane); + poly.left -= diff.x; + poly.top -= diff.y; + return actionPerformed; + }; +}; +const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler)); +function createPolyControls(arg0) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const controls = {}; + for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) { + controls["p".concat(idx)] = new Control(_objectSpread2({ + actionName: ACTION_NAME$1, + positionHandler: createPolyPositionHandler(idx), + actionHandler: createPolyActionHandler(idx) + }, options)); + } + return controls; +} + +const ACTION_NAME = 'modifyPath'; +const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => { + const { + path, + pathOffset + } = pathObject; + const command = path[commandIndex]; + return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix())); +}; +const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => { + const { + path, + pathOffset + } = pathObject; + const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1]; + const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]); + const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix()); + const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix()); + path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x; + path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y; + pathObject.setDimensions(); + const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix()); + const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane); + pathObject.left -= diff.x; + pathObject.top -= diff.y; + pathObject.set('dirty', true); + return true; +}; + +/** + * This function locates the controls. + * It'll be used both for drawing and for interaction. + */ +function pathPositionHandler(dim, finalMatrix, pathObject) { + const { + commandIndex, + pointIndex + } = this; + return calcPathPointPosition(pathObject, commandIndex, pointIndex); +} + +/** + * This function defines what the control does. + * It'll be called on every mouse move after a control has been clicked and is being dragged. + * The function receives as argument the mouse event, the current transform object + * and the current position in canvas coordinate `transform.target` is a reference to the + * current object being transformed. + */ +function pathActionHandler(eventData, transform, x, y) { + const { + target + } = transform; + const { + commandIndex, + pointIndex + } = this; + const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex); + { + fireEvent(this.actionName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), {}, { + commandIndex, + pointIndex + })); + } + return actionPerformed; +} +const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1; +class PathPointControl extends Control { + constructor(options) { + super(options); + } + render(ctx, left, top, styleOverride, fabricObject) { + const overrides = _objectSpread2(_objectSpread2({}, styleOverride), {}, { + cornerColor: this.controlFill, + cornerStrokeColor: this.controlStroke, + transparentCorners: !this.controlFill + }); + super.render(ctx, left, top, overrides, fabricObject); + } +} +class PathControlPointControl extends PathPointControl { + constructor(options) { + super(options); + } + render(ctx, left, top, styleOverride, fabricObject) { + const { + path + } = fabricObject; + const { + commandIndex, + pointIndex, + connectToCommandIndex, + connectToPointIndex + } = this; + ctx.save(); + ctx.strokeStyle = this.controlStroke; + if (this.connectionDashArray) { + ctx.setLineDash(this.connectionDashArray); + } + const [commandType] = path[commandIndex]; + const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex); + if (commandType === 'Q') { + // one control point connects to 2 points + const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2); + ctx.moveTo(point2.x, point2.y); + ctx.lineTo(left, top); + } else { + ctx.moveTo(left, top); + } + ctx.lineTo(point.x, point.y); + ctx.stroke(); + ctx.restore(); + super.render(ctx, left, top, styleOverride, fabricObject); + } +} +const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)(_objectSpread2(_objectSpread2({ + commandIndex: commandIndexPos, + pointIndex: pointIndexPos, + actionName: ACTION_NAME, + positionHandler: pathPositionHandler, + actionHandler: pathActionHandler, + connectToCommandIndex, + connectToPointIndex +}, options), isControlPoint ? options.controlPointStyle : options.pointStyle)); +function createPathControls(path) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const controls = {}; + let previousCommandType = 'M'; + path.path.forEach((command, commandIndex) => { + const commandType = command[0]; + if (commandType !== 'Z') { + controls["c_".concat(commandIndex, "_").concat(commandType)] = createControl(commandIndex, command.length - 2, false, options); + } + switch (commandType) { + case 'C': + controls["c_".concat(commandIndex, "_C_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType)); + controls["c_".concat(commandIndex, "_C_CP_2")] = createControl(commandIndex, 3, true, options, commandIndex, 5); + break; + case 'Q': + controls["c_".concat(commandIndex, "_Q_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex, 3); + break; + } + previousCommandType = commandType; + }); + return controls; +} + +var index = /*#__PURE__*/Object.freeze({ + __proto__: null, + changeWidth: changeWidth, + createObjectDefaultControls: createObjectDefaultControls, + createPathControls: createPathControls, + createPolyActionHandler: createPolyActionHandler, + createPolyControls: createPolyControls, + createPolyPositionHandler: createPolyPositionHandler, + createResizeControls: createResizeControls, + createTextboxDefaultControls: createTextboxDefaultControls, + dragHandler: dragHandler, + factoryPolyActionHandler: factoryPolyActionHandler, + getLocalPoint: getLocalPoint, + polyActionHandler: polyActionHandler, + renderCircleControl: renderCircleControl, + renderSquareControl: renderSquareControl, + rotationStyleHandler: rotationStyleHandler, + rotationWithSnapping: rotationWithSnapping, + scaleCursorStyleHandler: scaleCursorStyleHandler, + scaleOrSkewActionName: scaleOrSkewActionName, + scaleSkewCursorStyleHandler: scaleSkewCursorStyleHandler, + scalingEqually: scalingEqually, + scalingX: scalingX, + scalingXOrSkewingY: scalingXOrSkewingY, + scalingY: scalingY, + scalingYOrSkewingX: scalingYOrSkewingX, + skewCursorStyleHandler: skewCursorStyleHandler, + skewHandlerX: skewHandlerX, + skewHandlerY: skewHandlerY, + wrapWithFireEvent: wrapWithFireEvent, + wrapWithFixedAnchor: wrapWithFixedAnchor +}); + +const isWebGLPipelineState = options => { + return options.webgl !== undefined; +}; + +/** + * Pick a method to copy data from GL context to 2d canvas. In some browsers using + * drawImage should be faster, but is also bugged for a small combination of old hardware + * and drivers. + * putImageData is faster than drawImage for that specific operation. + */ +const isPutImageFaster = (width, height) => { + const targetCanvas = createCanvasElement(); + const sourceCanvas = createCanvasElement(); + const gl = sourceCanvas.getContext('webgl'); + // eslint-disable-next-line no-undef + const imageBuffer = new ArrayBuffer(width * height * 4); + const testContext = { + imageBuffer: imageBuffer + }; + const testPipelineState = { + destinationWidth: width, + destinationHeight: height, + targetCanvas: targetCanvas + }; + let startTime; + targetCanvas.width = width; + targetCanvas.height = height; + startTime = getFabricWindow().performance.now(); + WebGLFilterBackend.prototype.copyGLTo2D.call(testContext, gl, testPipelineState); + const drawImageTime = getFabricWindow().performance.now() - startTime; + startTime = getFabricWindow().performance.now(); + WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(testContext, gl, testPipelineState); + const putImageDataTime = getFabricWindow().performance.now() - startTime; + return drawImageTime > putImageDataTime; +}; + +const highPsourceCode = "precision highp float"; +const identityFragmentShader = "\n ".concat(highPsourceCode, ";\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }"); +const vertexSource$1 = "\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }"; + +const _excluded$1 = ["type"], + _excluded2 = ["type"]; +const regex = new RegExp(highPsourceCode, 'g'); +class BaseFilter { + /** + * Filter type + * @param {String} type + * @default + */ + get type() { + return this.constructor.type; + } + + /** + * The class type. Used to identify which class this is. + * This is used for serialization purposes and internally it can be used + * to identify classes. As a developer you could use `instance of Class` + * but to avoid importing all the code and blocking tree shaking we try + * to avoid doing that. + */ + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor() { + let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + options = _objectWithoutProperties(_ref, _excluded$1); + Object.assign(this, this.constructor.defaults, options); + } + getFragmentSource() { + return identityFragmentShader; + } + getVertexSource() { + return vertexSource$1; + } + + /** + * Compile this filter's shader program. + * + * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation. + * @param {String} fragmentSource fragmentShader source for compilation + * @param {String} vertexSource vertexShader source for compilation + */ + createProgram(gl) { + let fragmentSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFragmentSource(); + let vertexSource = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getVertexSource(); + const { + WebGLProbe: { + GLPrecision = 'highp' + } + } = getEnv(); + if (GLPrecision !== 'highp') { + fragmentSource = fragmentSource.replace(regex, highPsourceCode.replace('highp', GLPrecision)); + } + const vertexShader = gl.createShader(gl.VERTEX_SHADER); + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + const program = gl.createProgram(); + if (!vertexShader || !fragmentShader || !program) { + throw new FabricError('Vertex, fragment shader or program creation error'); + } + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { + throw new FabricError("Vertex shader compile error for ".concat(this.type, ": ").concat(gl.getShaderInfoLog(vertexShader))); + } + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + throw new FabricError("Fragment shader compile error for ".concat(this.type, ": ").concat(gl.getShaderInfoLog(fragmentShader))); + } + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + throw new FabricError("Shader link error for \"".concat(this.type, "\" ").concat(gl.getProgramInfoLog(program))); + } + const uniformLocations = this.getUniformLocations(gl, program) || {}; + uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); + uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); + return { + program, + attributeLocations: this.getAttributeLocations(gl, program), + uniformLocations + }; + } + + /** + * Return a map of attribute names to WebGLAttributeLocation objects. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {WebGLShaderProgram} program The shader program from which to take attribute locations. + * @returns {Object} A map of attribute names to attribute locations. + */ + getAttributeLocations(gl, program) { + return { + aPosition: gl.getAttribLocation(program, 'aPosition') + }; + } + + /** + * Return a map of uniform names to WebGLUniformLocation objects. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {WebGLShaderProgram} program The shader program from which to take uniform locations. + * @returns {Object} A map of uniform names to uniform locations. + */ + getUniformLocations(gl, program) { + const locations = this.constructor.uniformLocations; + const uniformLocations = {}; + for (let i = 0; i < locations.length; i++) { + uniformLocations[locations[i]] = gl.getUniformLocation(program, locations[i]); + } + return uniformLocations; + } + + /** + * Send attribute data from this filter to its shader program on the GPU. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {Object} attributeLocations A map of shader attribute names to their locations. + */ + sendAttributeData(gl, attributeLocations, aPositionData) { + const attributeLocation = attributeLocations.aPosition; + const buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.enableVertexAttribArray(attributeLocation); + gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); + gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); + } + _setupFrameBuffer(options) { + const gl = options.context; + if (options.passes > 1) { + const width = options.destinationWidth; + const height = options.destinationHeight; + if (options.sourceWidth !== width || options.sourceHeight !== height) { + gl.deleteTexture(options.targetTexture); + options.targetTexture = options.filterBackend.createTexture(gl, width, height); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, options.targetTexture, 0); + } else { + // draw last filter on canvas and not to framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.finish(); + } + } + _swapTextures(options) { + options.passes--; + options.pass++; + const temp = options.targetTexture; + options.targetTexture = options.sourceTexture; + options.sourceTexture = temp; + } + + /** + * Generic isNeutral implementation for one parameter based filters. + * Used only in image applyFilters to discard filters that will not have an effect + * on the image + * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter ) + * @param {Object} options + **/ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isNeutralState(options) { + return false; + } + + /** + * Apply this filter to the input image data provided. + * + * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + this._setupFrameBuffer(options); + this.applyToWebGL(options); + this._swapTextures(options); + } else { + this.applyTo2d(options); + } + } + applyTo2d(_options) { + // override by subclass + } + + /** + * Returns a string that represent the current selected shader code for the filter. + * Used to force recompilation when parameters change or to retrieve the shader from cache + * @type string + **/ + getCacheKey() { + return this.type; + } + + /** + * Retrieves the cached shader. + * @param {Object} options + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + * @return {WebGLProgram} the compiled program shader + */ + retrieveShader(options) { + const key = this.getCacheKey(); + if (!options.programCache[key]) { + options.programCache[key] = this.createProgram(options.context); + } + return options.programCache[key]; + } + + /** + * Apply this filter using webgl. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.originalTexture The texture of the original input image. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyToWebGL(options) { + const gl = options.context; + const shader = this.retrieveShader(options); + if (options.pass === 0 && options.originalTexture) { + gl.bindTexture(gl.TEXTURE_2D, options.originalTexture); + } else { + gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); + } + gl.useProgram(shader.program); + this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); + gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); + gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); + this.sendUniformData(gl, shader.uniformLocations); + gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + bindAdditionalTexture(gl, texture, textureUnit) { + gl.activeTexture(textureUnit); + gl.bindTexture(gl.TEXTURE_2D, texture); + // reset active texture to 0 as usual + gl.activeTexture(gl.TEXTURE0); + } + unbindAdditionalTexture(gl, textureUnit) { + gl.activeTexture(textureUnit); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0); + } + + /** + * Send uniform data from this filter to its shader program on the GPU. + * + * Intended to be overridden by subclasses. + * + * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program. + * @param {Object} _uniformLocations A map of shader uniform names to their locations. + */ + sendUniformData(_gl, _uniformLocations) { + // override by subclass + } + + /** + * If needed by a 2d filter, this functions can create an helper canvas to be used + * remember that options.targetCanvas is available for use till end of chain. + */ + createHelpLayer(options) { + if (!options.helpLayer) { + const helpLayer = createCanvasElement(); + helpLayer.width = options.sourceWidth; + helpLayer.height = options.sourceHeight; + options.helpLayer = helpLayer; + } + } + + /** + * Returns object representation of an instance + * It will automatically export the default values of a filter, + * stored in the static defaults property. + * @return {Object} Object representation of an instance + */ + toObject() { + const defaultKeys = Object.keys(this.constructor.defaults || {}); + return _objectSpread2({ + type: this.type + }, defaultKeys.reduce((acc, key) => { + acc[key] = this[key]; + return acc; + }, {})); + } + + /** + * Returns a JSON representation of an instance + * @return {Object} JSON + */ + toJSON() { + // delegate, not alias + return this.toObject(); + } + static async fromObject(_ref2, _options) { + let filterOptions = _objectWithoutProperties(_ref2, _excluded2); + return new this(filterOptions); + } +} +_defineProperty(BaseFilter, "type", 'BaseFilter'); +/** + * Contains the uniform locations for the fragment shader. + * uStepW and uStepH are handled by the BaseFilter, each filter class + * needs to specify all the one that are needed + */ +_defineProperty(BaseFilter, "uniformLocations", []); + +const blendColorFragmentSource = { + multiply: 'gl_FragColor.rgb *= uColor.rgb;\n', + screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n', + add: 'gl_FragColor.rgb += uColor.rgb;\n', + difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n', + subtract: 'gl_FragColor.rgb -= uColor.rgb;\n', + lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n', + darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n', + exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n', + overlay: "\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n ", + tint: "\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n " +}; + +const blendColorDefaultValues = { + color: '#F95C63', + mode: 'multiply', + alpha: 1 +}; + +/** + * Color Blend filter class + * @example + * const filter = new BlendColor({ + * color: '#000', + * mode: 'multiply' + * }); + * + * const filter = new BlendImage({ + * image: fabricImageObject, + * mode: 'multiply' + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class BlendColor extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ".concat(blendColorFragmentSource[this.mode], "\n }\n }\n "); + } + + /** + * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const source = new Color(this.color).getSource(); + const tr = source[0] * this.alpha; + const tg = source[1] * this.alpha; + const tb = source[2] * this.alpha; + const alpha1 = 1 - this.alpha; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + switch (this.mode) { + case 'multiply': + data[i] = r * tr / 255; + data[i + 1] = g * tg / 255; + data[i + 2] = b * tb / 255; + break; + case 'screen': + data[i] = 255 - (255 - r) * (255 - tr) / 255; + data[i + 1] = 255 - (255 - g) * (255 - tg) / 255; + data[i + 2] = 255 - (255 - b) * (255 - tb) / 255; + break; + case 'add': + data[i] = r + tr; + data[i + 1] = g + tg; + data[i + 2] = b + tb; + break; + case 'difference': + data[i] = Math.abs(r - tr); + data[i + 1] = Math.abs(g - tg); + data[i + 2] = Math.abs(b - tb); + break; + case 'subtract': + data[i] = r - tr; + data[i + 1] = g - tg; + data[i + 2] = b - tb; + break; + case 'darken': + data[i] = Math.min(r, tr); + data[i + 1] = Math.min(g, tg); + data[i + 2] = Math.min(b, tb); + break; + case 'lighten': + data[i] = Math.max(r, tr); + data[i + 1] = Math.max(g, tg); + data[i + 2] = Math.max(b, tb); + break; + case 'overlay': + data[i] = tr < 128 ? 2 * r * tr / 255 : 255 - 2 * (255 - r) * (255 - tr) / 255; + data[i + 1] = tg < 128 ? 2 * g * tg / 255 : 255 - 2 * (255 - g) * (255 - tg) / 255; + data[i + 2] = tb < 128 ? 2 * b * tb / 255 : 255 - 2 * (255 - b) * (255 - tb) / 255; + break; + case 'exclusion': + data[i] = tr + r - 2 * tr * r / 255; + data[i + 1] = tg + g - 2 * tg * g / 255; + data[i + 2] = tb + b - 2 * tb * b / 255; + break; + case 'tint': + data[i] = tr + r * alpha1; + data[i + 1] = tg + g * alpha1; + data[i + 2] = tb + b * alpha1; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const source = new Color(this.color).getSource(); + source[0] = this.alpha * source[0] / 255; + source[1] = this.alpha * source[1] / 255; + source[2] = this.alpha * source[2] / 255; + source[3] = this.alpha; + gl.uniform4fv(uniformLocations.uColor, source); + } +} +/** + * Color to make the blend operation with. default to a reddish color since black or white + * gives always strong result. + * @type String + * @default + **/ +/** + * Blend mode for the filter: one of multiply, add, difference, screen, subtract, + * darken, lighten, overlay, exclusion, tint. + * @type String + * @default + **/ +/** + * alpha value. represent the strength of the blend color operation. + * @type Number + * @default + **/ +_defineProperty(BlendColor, "defaults", blendColorDefaultValues); +_defineProperty(BlendColor, "type", 'BlendColor'); +_defineProperty(BlendColor, "uniformLocations", ['uColor']); +classRegistry.setClass(BlendColor); + +const fragmentSource$c = { + multiply: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n ", + mask: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n " +}; +const vertexSource = "\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n "; + +const _excluded = ["type", "image"]; +const blendImageDefaultValues = { + mode: 'multiply', + alpha: 1 +}; + +/** + * Image Blend filter class + * @example + * const filter = new filters.BlendColor({ + * color: '#000', + * mode: 'multiply' + * }); + * + * const filter = new BlendImage({ + * image: fabricImageObject, + * mode: 'multiply' + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class BlendImage extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return fragmentSource$c[this.mode]; + } + getVertexSource() { + return vertexSource; + } + applyToWebGL(options) { + const gl = options.context, + texture = this.createTexture(options.filterBackend, this.image); + this.bindAdditionalTexture(gl, texture, gl.TEXTURE1); + super.applyToWebGL(options); + this.unbindAdditionalTexture(gl, gl.TEXTURE1); + } + createTexture(backend, image) { + return backend.getCachedTexture(image.cacheKey, image.getElement()); + } + + /** + * Calculate a transformMatrix to adapt the image to blend over + * @param {Object} options + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + calculateMatrix() { + const image = this.image, + { + width, + height + } = image.getElement(); + return [1 / image.scaleX, 0, 0, 0, 1 / image.scaleY, 0, -image.left / width, -image.top / height, 1]; + } + + /** + * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data, + width, + height + }, + filterBackend: { + resources + } + } = _ref; + const image = this.image; + if (!resources.blendImage) { + resources.blendImage = createCanvasElement(); + } + const canvas1 = resources.blendImage; + const context = canvas1.getContext('2d'); + if (canvas1.width !== width || canvas1.height !== height) { + canvas1.width = width; + canvas1.height = height; + } else { + context.clearRect(0, 0, width, height); + } + context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top); + context.drawImage(image.getElement(), 0, 0, width, height); + const blendData = context.getImageData(0, 0, width, height).data; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + const a = data[i + 3]; + const tr = blendData[i]; + const tg = blendData[i + 1]; + const tb = blendData[i + 2]; + const ta = blendData[i + 3]; + switch (this.mode) { + case 'multiply': + data[i] = r * tr / 255; + data[i + 1] = g * tg / 255; + data[i + 2] = b * tb / 255; + data[i + 3] = a * ta / 255; + break; + case 'mask': + data[i + 3] = ta; + break; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const matrix = this.calculateMatrix(); + gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1. + gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix); + } + + /** + * Returns object representation of an instance + * TODO: Handle the possibility of missing image better. + * As of now a BlendImage filter without image can't be used with fromObject + * @return {Object} Object representation of an instance + */ + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + image: this.image && this.image.toObject() + }); + } + + /** + * Create filter instance from an object representation + * @static + * @param {object} object Object to create an instance from + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static async fromObject(_ref2, options) { + let { + type, + image + } = _ref2, + filterOptions = _objectWithoutProperties(_ref2, _excluded); + return FabricImage.fromObject(image, options).then(enlivedImage => new this(_objectSpread2(_objectSpread2({}, filterOptions), {}, { + image: enlivedImage + }))); + } +} +/** + * Image to make the blend operation with. + **/ +/** + * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will + * multiply the values of each channel (R, G, B, and A) of the filter image by + * their corresponding values in the base image. 'mask' will only look at the + * alpha channel of the filter image, and apply those values to the base + * image's alpha channel. + * @type String + * @default + **/ +/** + * alpha value. represent the strength of the blend image operation. + * not implemented. + **/ +_defineProperty(BlendImage, "type", 'BlendImage'); +_defineProperty(BlendImage, "defaults", blendImageDefaultValues); +_defineProperty(BlendImage, "uniformLocations", ['uTransformMatrix', 'uImage']); +classRegistry.setClass(BlendImage); + +const fragmentSource$b = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n "; + +const blurDefaultValues = { + blur: 0 +}; + +/** + * Blur filter class + * @example + * const filter = new Blur({ + * blur: 0.5 + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Blur extends BaseFilter { + getFragmentSource() { + return fragmentSource$b; + } + applyTo(options) { + if (isWebGLPipelineState(options)) { + // this aspectRatio is used to give the same blur to vertical and horizontal + this.aspectRatio = options.sourceWidth / options.sourceHeight; + options.passes++; + this._setupFrameBuffer(options); + this.horizontal = true; + this.applyToWebGL(options); + this._swapTextures(options); + this._setupFrameBuffer(options); + this.horizontal = false; + this.applyToWebGL(options); + this._swapTextures(options); + } else { + this.applyTo2d(options); + } + } + applyTo2d(options) { + options.imageData = this.simpleBlur(options); + } + simpleBlur(_ref) { + let { + ctx, + imageData, + filterBackend: { + resources + } + } = _ref; + const { + width, + height + } = imageData; + if (!resources.blurLayer1) { + resources.blurLayer1 = createCanvasElement(); + resources.blurLayer2 = createCanvasElement(); + } + const canvas1 = resources.blurLayer1; + const canvas2 = resources.blurLayer2; + if (canvas1.width !== width || canvas1.height !== height) { + canvas2.width = canvas1.width = width; + canvas2.height = canvas1.height = height; + } + const ctx1 = canvas1.getContext('2d'), + ctx2 = canvas2.getContext('2d'), + nSamples = 15, + blur = this.blur * 0.06 * 0.5; + let random, percent, j, i; + + // load first canvas + ctx1.putImageData(imageData, 0, 0); + ctx2.clearRect(0, 0, width, height); + for (i = -nSamples; i <= nSamples; i++) { + random = (Math.random() - 0.5) / 4; + percent = i / nSamples; + j = blur * percent * width + random; + ctx2.globalAlpha = 1 - Math.abs(percent); + ctx2.drawImage(canvas1, j, random); + ctx1.drawImage(canvas2, 0, 0); + ctx2.globalAlpha = 1; + ctx2.clearRect(0, 0, canvas2.width, canvas2.height); + } + for (i = -nSamples; i <= nSamples; i++) { + random = (Math.random() - 0.5) / 4; + percent = i / nSamples; + j = blur * percent * height + random; + ctx2.globalAlpha = 1 - Math.abs(percent); + ctx2.drawImage(canvas1, random, j); + ctx1.drawImage(canvas2, 0, 0); + ctx2.globalAlpha = 1; + ctx2.clearRect(0, 0, canvas2.width, canvas2.height); + } + ctx.drawImage(canvas1, 0, 0); + const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height); + ctx1.globalAlpha = 1; + ctx1.clearRect(0, 0, canvas1.width, canvas1.height); + return newImageData; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const delta = this.chooseRightDelta(); + gl.uniform2fv(uniformLocations.uDelta, delta); + } + isNeutralState() { + return this.blur === 0; + } + + /** + * choose right value of image percentage to blur with + * @returns {Array} a numeric array with delta values + */ + chooseRightDelta() { + let blurScale = 1; + const delta = [0, 0]; + if (this.horizontal) { + if (this.aspectRatio > 1) { + // image is wide, i want to shrink radius horizontal + blurScale = 1 / this.aspectRatio; + } + } else { + if (this.aspectRatio < 1) { + // image is tall, i want to shrink radius vertical + blurScale = this.aspectRatio; + } + } + const blur = blurScale * this.blur * 0.12; + if (this.horizontal) { + delta[0] = blur; + } else { + delta[1] = blur; + } + return delta; + } +} +/** + * blur value, in percentage of image dimensions. + * specific to keep the image blur constant at different resolutions + * range between 0 and 1. + * @type Number + * @default + */ +_defineProperty(Blur, "type", 'Blur'); +_defineProperty(Blur, "defaults", blurDefaultValues); +_defineProperty(Blur, "uniformLocations", ['uDelta']); +classRegistry.setClass(Blur); + +const fragmentSource$a = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n"; + +const brightnessDefaultValues = { + brightness: 0 +}; + +/** + * Brightness filter class + * @example + * const filter = new Brightness({ + * brightness: 0.05 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Brightness extends BaseFilter { + getFragmentSource() { + return fragmentSource$a; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const brightness = Math.round(this.brightness * 255); + for (let i = 0; i < data.length; i += 4) { + data[i] = data[i] + brightness; + data[i + 1] = data[i + 1] + brightness; + data[i + 2] = data[i + 2] + brightness; + } + } + isNeutralState() { + return this.brightness === 0; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uBrightness, this.brightness); + } +} +/** + * Brightness value, from -1 to 1. + * translated to -255 to 255 for 2d + * 0.0039215686 is the part of 1 that get translated to 1 in 2d + * @param {Number} brightness + * @default + */ +_defineProperty(Brightness, "type", 'Brightness'); +_defineProperty(Brightness, "defaults", brightnessDefaultValues); +_defineProperty(Brightness, "uniformLocations", ['uBrightness']); +classRegistry.setClass(Brightness); + +const fragmentSource$9 = "\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }"; + +const colorMatrixDefaultValues = { + matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], + colorsOnly: true +}; + +/** + * Color Matrix filter class + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} + * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo} + * @example Kodachrome filter + * const filter = new ColorMatrix({ + * matrix: [ + 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, + -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, + -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, + 0, 0, 0, 1, 0 + ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class ColorMatrix extends BaseFilter { + getFragmentSource() { + return fragmentSource$9; + } + + /** + * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(options) { + const imageData = options.imageData, + data = imageData.data, + m = this.matrix, + colorsOnly = this.colorsOnly; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + if (colorsOnly) { + data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; + data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; + data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; + } else { + const a = data[i + 3]; + data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; + data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; + data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; + data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const m = this.matrix, + matrix = [m[0], m[1], m[2], m[3], m[5], m[6], m[7], m[8], m[10], m[11], m[12], m[13], m[15], m[16], m[17], m[18]], + constants = [m[4], m[9], m[14], m[19]]; + gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix); + gl.uniform4fv(uniformLocations.uConstants, constants); + } + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + matrix: [...this.matrix] + }); + } +} +/** + * Colormatrix for pixels. + * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning + * outside the -1, 1 range. + * 0.0039215686 is the part of 1 that get translated to 1 in 2d + * @param {Array} matrix array of 20 numbers. + * @default + */ +/** + * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario + * to save some calculation + * @type Boolean + * @default true + */ +_defineProperty(ColorMatrix, "type", 'ColorMatrix'); +_defineProperty(ColorMatrix, "defaults", colorMatrixDefaultValues); +_defineProperty(ColorMatrix, "uniformLocations", ['uColorMatrix', 'uConstants']); +classRegistry.setClass(ColorMatrix); + +function createColorMatrixFilter(key, matrix) { + var _Class; + const newClass = (_Class = class newClass extends ColorMatrix { + //@ts-expect-error TS wants matrix to be exported. + toObject() { + return { + type: this.type, + colorsOnly: this.colorsOnly + }; + } + }, _defineProperty(_Class, "type", key), _defineProperty(_Class, "defaults", { + colorsOnly: false, + matrix + }), _Class); + classRegistry.setClass(newClass, key); + return newClass; +} +const Brownie = createColorMatrixFilter('Brownie', [0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0]); +const Vintage = createColorMatrixFilter('Vintage', [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0]); +const Kodachrome = createColorMatrixFilter('Kodachrome', [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0]); +const Technicolor = createColorMatrixFilter('Technicolor', [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0]); +const Polaroid = createColorMatrixFilter('Polaroid', [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0]); +const Sepia = createColorMatrixFilter('Sepia', [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0]); +const BlackWhite = createColorMatrixFilter('BlackWhite', [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]); + +/** + * A container class that knows how to apply a sequence of filters to an input image. + */ +class Composed extends BaseFilter { + constructor() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + super(options); + this.subFilters = options.subFilters || []; + } + + /** + * Apply this container's filters to the input image provided. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be applied. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + options.passes += this.subFilters.length - 1; + } + this.subFilters.forEach(filter => { + filter.applyTo(options); + }); + } + + /** + * Serialize this filter into JSON. + * @returns {Object} A JSON representation of this filter. + */ + //@ts-expect-error TS doesn't like this toObject + toObject() { + return { + type: this.type, + subFilters: this.subFilters.map(filter => filter.toObject()) + }; + } + isNeutralState() { + return !this.subFilters.some(filter => !filter.isNeutralState()); + } + + /** + * Deserialize a JSON definition of a ComposedFilter into a concrete instance. + * @static + * @param {oject} object Object to create an instance from + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(object, options) { + return Promise.all((object.subFilters || []).map(filter => classRegistry.getClass(filter.type).fromObject(filter, options))).then(enlivedFilters => new this({ + subFilters: enlivedFilters + })); + } +} +/** + * A non sparse array of filters to apply + */ +_defineProperty(Composed, "type", 'Composed'); +classRegistry.setClass(Composed); + +const fragmentSource$8 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }"; + +const contrastDefaultValues = { + contrast: 0 +}; + +/** + * Contrast filter class + * @example + * const filter = new Contrast({ + * contrast: 0.25 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Contrast extends BaseFilter { + getFragmentSource() { + return fragmentSource$8; + } + isNeutralState() { + return this.contrast === 0; + } + + /** + * Apply the Contrast operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const contrast = Math.floor(this.contrast * 255), + contrastF = 259 * (contrast + 255) / (255 * (259 - contrast)); + for (let i = 0; i < data.length; i += 4) { + data[i] = contrastF * (data[i] - 128) + 128; + data[i + 1] = contrastF * (data[i + 1] - 128) + 128; + data[i + 2] = contrastF * (data[i + 2] - 128) + 128; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uContrast, this.contrast); + } +} +/** + * contrast value, range from -1 to 1. + * @param {Number} contrast + * @default 0 + */ +_defineProperty(Contrast, "type", 'Contrast'); +_defineProperty(Contrast, "defaults", contrastDefaultValues); +_defineProperty(Contrast, "uniformLocations", ['uContrast']); +classRegistry.setClass(Contrast); + +const fragmentSource$7 = { + Convolute_3_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_3_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_5_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_5_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_7_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_7_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_9_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_9_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n " +}; + +const convoluteDefaultValues = { + opaque: false, + matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0] +}; + +/** + * Adapted from html5rocks article + * @example Sharpen filter + * const filter = new Convolute({ + * matrix: [ 0, -1, 0, + * -1, 5, -1, + * 0, -1, 0 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Blur filter + * const filter = new Convolute({ + * matrix: [ 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Emboss filter + * const filter = new Convolute({ + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Emboss filter with opaqueness + * const filter = new Convolute({ + * opaque: true, + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Convolute extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(Math.sqrt(this.matrix.length), "_").concat(this.opaque ? 1 : 0); + } + getFragmentSource() { + return fragmentSource$7[this.getCacheKey()]; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(options) { + const imageData = options.imageData, + data = imageData.data, + weights = this.matrix, + side = Math.round(Math.sqrt(weights.length)), + halfSide = Math.floor(side / 2), + sw = imageData.width, + sh = imageData.height, + output = options.ctx.createImageData(sw, sh), + dst = output.data, + // go through the destination image pixels + alphaFac = this.opaque ? 1 : 0; + let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy; + for (y = 0; y < sh; y++) { + for (x = 0; x < sw; x++) { + dstOff = (y * sw + x) * 4; + // calculate the weighed sum of the source image pixels that + // fall under the convolution matrix + r = 0; + g = 0; + b = 0; + a = 0; + for (cy = 0; cy < side; cy++) { + for (cx = 0; cx < side; cx++) { + scy = y + cy - halfSide; + scx = x + cx - halfSide; + + // eslint-disable-next-line max-depth + if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) { + continue; + } + srcOff = (scy * sw + scx) * 4; + wt = weights[cy * side + cx]; + r += data[srcOff] * wt; + g += data[srcOff + 1] * wt; + b += data[srcOff + 2] * wt; + // eslint-disable-next-line max-depth + if (!alphaFac) { + a += data[srcOff + 3] * wt; + } + } + } + dst[dstOff] = r; + dst[dstOff + 1] = g; + dst[dstOff + 2] = b; + if (!alphaFac) { + dst[dstOff + 3] = a; + } else { + dst[dstOff + 3] = data[dstOff + 3]; + } + } + } + options.imageData = output; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1fv(uniformLocations.uMatrix, this.matrix); + } + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + opaque: this.opaque, + matrix: [...this.matrix] + }); + } +} +/* + * Opaque value (true/false) + */ +/* + * matrix for the filter, max 9x9 + */ +_defineProperty(Convolute, "type", 'Convolute'); +_defineProperty(Convolute, "defaults", convoluteDefaultValues); +_defineProperty(Convolute, "uniformLocations", ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize']); +classRegistry.setClass(Convolute); + +const fragmentSource$6 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n"; + +const GAMMA = 'Gamma'; +const gammaDefaultValues = { + gamma: [1, 1, 1] +}; + +/** + * Gamma filter class + * @example + * const filter = new Gamma({ + * gamma: [1, 0.5, 2.1] + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Gamma extends BaseFilter { + getFragmentSource() { + return fragmentSource$6; + } + constructor() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + super(options); + this.gamma = options.gamma || this.constructor.defaults.gamma.concat(); + } + + /** + * Apply the Gamma operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const gamma = this.gamma, + rInv = 1 / gamma[0], + gInv = 1 / gamma[1], + bInv = 1 / gamma[2]; + if (!this.rgbValues) { + this.rgbValues = { + r: new Uint8Array(256), + g: new Uint8Array(256), + b: new Uint8Array(256) + }; + } + + // This is an optimization - pre-compute a look-up table for each color channel + // instead of performing these pow calls for each pixel in the image. + const rgb = this.rgbValues; + for (let i = 0; i < 256; i++) { + rgb.r[i] = Math.pow(i / 255, rInv) * 255; + rgb.g[i] = Math.pow(i / 255, gInv) * 255; + rgb.b[i] = Math.pow(i / 255, bInv) * 255; + } + for (let i = 0; i < data.length; i += 4) { + data[i] = rgb.r[data[i]]; + data[i + 1] = rgb.g[data[i + 1]]; + data[i + 2] = rgb.b[data[i + 2]]; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform3fv(uniformLocations.uGamma, this.gamma); + } + isNeutralState() { + const { + gamma + } = this; + return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1; + } + toObject() { + return { + type: GAMMA, + gamma: this.gamma.concat() + }; + } +} +/** + * Gamma array value, from 0.01 to 2.2. + * @param {Array} gamma + * @default + */ +_defineProperty(Gamma, "type", GAMMA); +_defineProperty(Gamma, "defaults", gammaDefaultValues); +_defineProperty(Gamma, "uniformLocations", ['uGamma']); +classRegistry.setClass(Gamma); + +const fragmentSource$5 = { + average: "\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n ", + lightness: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n ", + luminosity: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n " +}; + +const grayscaleDefaultValues = { + mode: 'average' +}; + +/** + * Grayscale image filter class + * @example + * const filter = new Grayscale(); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Grayscale extends BaseFilter { + /** + * Apply the Grayscale operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + for (let i = 0, value; i < data.length; i += 4) { + switch (this.mode) { + case 'average': + value = (data[i] + data[i + 1] + data[i + 2]) / 3; + break; + case 'lightness': + value = (Math.min(data[i], data[i + 1], data[i + 2]) + Math.max(data[i], data[i + 1], data[i + 2])) / 2; + break; + case 'luminosity': + value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2]; + break; + } + data[i] = value; + data[i + 1] = value; + data[i + 2] = value; + } + } + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return fragmentSource$5[this.mode]; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const mode = 1; + gl.uniform1i(uniformLocations.uMode, mode); + } + + /** + * Grayscale filter isNeutralState implementation + * The filter is never neutral + * on the image + **/ + isNeutralState() { + return false; + } +} +_defineProperty(Grayscale, "type", 'Grayscale'); +_defineProperty(Grayscale, "defaults", grayscaleDefaultValues); +_defineProperty(Grayscale, "uniformLocations", ['uMode']); +classRegistry.setClass(Grayscale); + +const hueRotationDefaultValues = { + rotation: 0 +}; + +/** + * HueRotation filter class + * @example + * const filter = new HueRotation({ + * rotation: -0.5 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class HueRotation extends ColorMatrix { + calculateMatrix() { + const rad = this.rotation * Math.PI, + cosine = cos(rad), + sine = sin(rad), + aThird = 1 / 3, + aThirdSqtSin = Math.sqrt(aThird) * sine, + OneMinusCos = 1 - cosine; + this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]; + this.matrix[0] = cosine + OneMinusCos / 3; + this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[6] = cosine + aThird * OneMinusCos; + this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[12] = cosine + aThird * OneMinusCos; + } + isNeutralState() { + return this.rotation === 0; + } + applyTo(options) { + this.calculateMatrix(); + super.applyTo(options); + } + + //@ts-expect-error TS and classes with different methods + toObject() { + return { + type: this.type, + rotation: this.rotation + }; + } +} +/** + * HueRotation value, from -1 to 1. + */ +_defineProperty(HueRotation, "type", 'HueRotation'); +_defineProperty(HueRotation, "defaults", hueRotationDefaultValues); +classRegistry.setClass(HueRotation); + +const fragmentSource$4 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n"; + +const invertDefaultValues = { + alpha: false, + invert: true +}; + +/** + * @example + * const filter = new Invert(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ +class Invert extends BaseFilter { + /** + * Apply the Invert operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + for (let i = 0; i < data.length; i += 4) { + data[i] = 255 - data[i]; + data[i + 1] = 255 - data[i + 1]; + data[i + 2] = 255 - data[i + 2]; + if (this.alpha) { + data[i + 3] = 255 - data[i + 3]; + } + } + } + getFragmentSource() { + return fragmentSource$4; + } + + /** + * Invert filter isNeutralState implementation + * Used only in image applyFilters to discard filters that will not have an effect + * on the image + * @param {Object} options + **/ + isNeutralState() { + return !this.invert; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1i(uniformLocations.uInvert, Number(this.invert)); + gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha)); + } +} +/** + * Invert also alpha. + * @param {Boolean} alpha + * @default + **/ +/** + * Filter invert. if false, does nothing + * @param {Boolean} invert + * @default + */ +_defineProperty(Invert, "type", 'Invert'); +_defineProperty(Invert, "defaults", invertDefaultValues); +_defineProperty(Invert, "uniformLocations", ['uInvert', 'uAlpha']); +classRegistry.setClass(Invert); + +const fragmentSource$3 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n"; + +const noiseDefaultValues = { + noise: 0 +}; + +/** + * Noise filter class + * @example + * const filter = new Noise({ + * noise: 700 + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Noise extends BaseFilter { + getFragmentSource() { + return fragmentSource$3; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const noise = this.noise; + for (let i = 0; i < data.length; i += 4) { + const rand = (0.5 - Math.random()) * noise; + data[i] += rand; + data[i + 1] += rand; + data[i + 2] += rand; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uNoise, this.noise / 255); + gl.uniform1f(uniformLocations.uSeed, Math.random()); + } + isNeutralState() { + return this.noise === 0; + } +} +/** + * Noise value, from + * @param {Number} noise + * @default + */ +_defineProperty(Noise, "type", 'Noise'); +_defineProperty(Noise, "defaults", noiseDefaultValues); +_defineProperty(Noise, "uniformLocations", ['uNoise', 'uSeed']); +classRegistry.setClass(Noise); + +const fragmentSource$2 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n"; + +const pixelateDefaultValues = { + blocksize: 4 +}; + +/** + * Pixelate filter class + * @example + * const filter = new Pixelate({ + * blocksize: 8 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Pixelate extends BaseFilter { + /** + * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data, + width, + height + } + } = _ref; + for (let i = 0; i < height; i += this.blocksize) { + for (let j = 0; j < width; j += this.blocksize) { + const index = i * 4 * width + j * 4; + const r = data[index]; + const g = data[index + 1]; + const b = data[index + 2]; + const a = data[index + 3]; + for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) { + for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) { + const index = _i * 4 * width + _j * 4; + data[index] = r; + data[index + 1] = g; + data[index + 2] = b; + data[index + 3] = a; + } + } + } + } + } + + /** + * Indicate when the filter is not gonna apply changes to the image + **/ + isNeutralState() { + return this.blocksize === 1; + } + getFragmentSource() { + return fragmentSource$2; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uBlocksize, this.blocksize); + } +} +_defineProperty(Pixelate, "type", 'Pixelate'); +_defineProperty(Pixelate, "defaults", pixelateDefaultValues); +_defineProperty(Pixelate, "uniformLocations", ['uBlocksize']); +classRegistry.setClass(Pixelate); + +const fragmentShader = "\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n"; + +const removeColorDefaultValues = { + color: '#FFFFFF', + distance: 0.02, + useAlpha: false +}; + +/** + * Remove white filter class + * @example + * const filter = new RemoveColor({ + * threshold: 0.2, + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class RemoveColor extends BaseFilter { + getFragmentSource() { + return fragmentShader; + } + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const distance = this.distance * 255, + source = new Color(this.color).getSource(), + lowC = [source[0] - distance, source[1] - distance, source[2] - distance], + highC = [source[0] + distance, source[1] + distance, source[2] + distance]; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + if (r > lowC[0] && g > lowC[1] && b > lowC[2] && r < highC[0] && g < highC[1] && b < highC[2]) { + data[i + 3] = 0; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const source = new Color(this.color).getSource(), + distance = this.distance, + lowC = [0 + source[0] / 255 - distance, 0 + source[1] / 255 - distance, 0 + source[2] / 255 - distance, 1], + highC = [source[0] / 255 + distance, source[1] / 255 + distance, source[2] / 255 + distance, 1]; + gl.uniform4fv(uniformLocations.uLow, lowC); + gl.uniform4fv(uniformLocations.uHigh, highC); + } +} +/** + * Color to remove, in any format understood by {@link Color}. + * @param {String} type + * @default + */ +/** + * distance to actual color, as value up or down from each r,g,b + * between 0 and 1 + **/ +/** + * For color to remove inside distance, use alpha channel for a smoother deletion + * NOT IMPLEMENTED YET + **/ +_defineProperty(RemoveColor, "type", 'RemoveColor'); +_defineProperty(RemoveColor, "defaults", removeColorDefaultValues); +_defineProperty(RemoveColor, "uniformLocations", ['uLow', 'uHigh']); +classRegistry.setClass(RemoveColor); + +const resizeDefaultValues = { + resizeType: 'hermite', + scaleX: 1, + scaleY: 1, + lanczosLobes: 3 +}; +/** + * Resize image filter class + * @example + * const filter = new Resize(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ +class Resize extends BaseFilter { + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]); + gl.uniform1fv(uniformLocations.uTaps, this.taps); + } + getFilterWindow() { + const scale = this.tempScale; + return Math.ceil(this.lanczosLobes / scale); + } + getCacheKey() { + const filterWindow = this.getFilterWindow(); + return "".concat(this.type, "_").concat(filterWindow); + } + getFragmentSource() { + const filterWindow = this.getFilterWindow(); + return this.generateShader(filterWindow); + } + getTaps() { + const lobeFunction = this.lanczosCreate(this.lanczosLobes), + scale = this.tempScale, + filterWindow = this.getFilterWindow(), + taps = new Array(filterWindow); + for (let i = 1; i <= filterWindow; i++) { + taps[i - 1] = lobeFunction(i * scale); + } + return taps; + } + + /** + * Generate vertex and shader sources from the necessary steps numbers + * @param {Number} filterWindow + */ + generateShader(filterWindow) { + const offsets = new Array(filterWindow); + for (let i = 1; i <= filterWindow; i++) { + offsets[i - 1] = "".concat(i, ".0 * uDelta"); + } + return "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[".concat(filterWindow, "];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ").concat(offsets.map((offset, i) => "\n color += texture2D(uTexture, vTexCoord + ".concat(offset, ") * uTaps[").concat(i, "] + texture2D(uTexture, vTexCoord - ").concat(offset, ") * uTaps[").concat(i, "];\n sum += 2.0 * uTaps[").concat(i, "];\n ")).join('\n'), "\n gl_FragColor = color / sum;\n }\n "); + } + applyToForWebgl(options) { + options.passes++; + this.width = options.sourceWidth; + this.horizontal = true; + this.dW = Math.round(this.width * this.scaleX); + this.dH = options.sourceHeight; + this.tempScale = this.dW / this.width; + this.taps = this.getTaps(); + options.destinationWidth = this.dW; + super.applyTo(options); + options.sourceWidth = options.destinationWidth; + this.height = options.sourceHeight; + this.horizontal = false; + this.dH = Math.round(this.height * this.scaleY); + this.tempScale = this.dH / this.height; + this.taps = this.getTaps(); + options.destinationHeight = this.dH; + super.applyTo(options); + options.sourceHeight = options.destinationHeight; + } + + /** + * Apply the resize filter to the image + * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + this.applyToForWebgl(options); + } else { + this.applyTo2d(options); + } + } + isNeutralState() { + return this.scaleX === 1 && this.scaleY === 1; + } + lanczosCreate(lobes) { + return x => { + if (x >= lobes || x <= -lobes) { + return 0.0; + } + if (x < 1.1920929e-7 && x > -1.1920929e-7) { + return 1.0; + } + x *= Math.PI; + const xx = x / lobes; + return Math.sin(x) / x * Math.sin(xx) / xx; + }; + } + applyTo2d(options) { + const imageData = options.imageData, + scaleX = this.scaleX, + scaleY = this.scaleY; + this.rcpScaleX = 1 / scaleX; + this.rcpScaleY = 1 / scaleY; + const oW = imageData.width; + const oH = imageData.height; + const dW = Math.round(oW * scaleX); + const dH = Math.round(oH * scaleY); + let newData; + if (this.resizeType === 'sliceHack') { + newData = this.sliceByTwo(options, oW, oH, dW, dH); + } else if (this.resizeType === 'hermite') { + newData = this.hermiteFastResize(options, oW, oH, dW, dH); + } else if (this.resizeType === 'bilinear') { + newData = this.bilinearFiltering(options, oW, oH, dW, dH); + } else if (this.resizeType === 'lanczos') { + newData = this.lanczosResize(options, oW, oH, dW, dH); + } else { + // this should never trigger, is here just for safety net. + newData = new ImageData(dW, dH); + } + options.imageData = newData; + } + + /** + * Filter sliceByTwo + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + sliceByTwo(options, oW, oH, dW, dH) { + const imageData = options.imageData; + const mult = 0.5; + let doneW = false; + let doneH = false; + let stepW = oW * mult; + let stepH = oH * mult; + const resources = options.filterBackend.resources; + let sX = 0; + let sY = 0; + const dX = oW; + let dY = 0; + if (!resources.sliceByTwo) { + resources.sliceByTwo = createCanvasElement(); + } + const tmpCanvas = resources.sliceByTwo; + if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) { + tmpCanvas.width = oW * 1.5; + tmpCanvas.height = oH; + } + const ctx = tmpCanvas.getContext('2d'); + ctx.clearRect(0, 0, oW * 1.5, oH); + ctx.putImageData(imageData, 0, 0); + dW = Math.floor(dW); + dH = Math.floor(dH); + while (!doneW || !doneH) { + oW = stepW; + oH = stepH; + if (dW < Math.floor(stepW * mult)) { + stepW = Math.floor(stepW * mult); + } else { + stepW = dW; + doneW = true; + } + if (dH < Math.floor(stepH * mult)) { + stepH = Math.floor(stepH * mult); + } else { + stepH = dH; + doneH = true; + } + ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH); + sX = dX; + sY = dY; + dY += stepH; + } + return ctx.getImageData(sX, sY, dW, dH); + } + + /** + * Filter lanczosResize + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + lanczosResize(options, oW, oH, dW, dH) { + function process(u) { + let v, i, weight, idx, a, red, green, blue, alpha, fX, fY; + center.x = (u + 0.5) * ratioX; + icenter.x = Math.floor(center.x); + for (v = 0; v < dH; v++) { + center.y = (v + 0.5) * ratioY; + icenter.y = Math.floor(center.y); + a = 0; + red = 0; + green = 0; + blue = 0; + alpha = 0; + for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { + if (i < 0 || i >= oW) { + continue; + } + fX = Math.floor(1000 * Math.abs(i - center.x)); + if (!cacheLanc[fX]) { + cacheLanc[fX] = {}; + } + for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { + if (j < 0 || j >= oH) { + continue; + } + fY = Math.floor(1000 * Math.abs(j - center.y)); + if (!cacheLanc[fX][fY]) { + cacheLanc[fX][fY] = lanczos(Math.sqrt(Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2)) / 1000); + } + weight = cacheLanc[fX][fY]; + if (weight > 0) { + idx = (j * oW + i) * 4; + a += weight; + red += weight * srcData[idx]; + green += weight * srcData[idx + 1]; + blue += weight * srcData[idx + 2]; + alpha += weight * srcData[idx + 3]; + } + } + } + idx = (v * dW + u) * 4; + destData[idx] = red / a; + destData[idx + 1] = green / a; + destData[idx + 2] = blue / a; + destData[idx + 3] = alpha / a; + } + if (++u < dW) { + return process(u); + } else { + return destImg; + } + } + const srcData = options.imageData.data, + destImg = options.ctx.createImageData(dW, dH), + destData = destImg.data, + lanczos = this.lanczosCreate(this.lanczosLobes), + ratioX = this.rcpScaleX, + ratioY = this.rcpScaleY, + rcpRatioX = 2 / this.rcpScaleX, + rcpRatioY = 2 / this.rcpScaleY, + range2X = Math.ceil(ratioX * this.lanczosLobes / 2), + range2Y = Math.ceil(ratioY * this.lanczosLobes / 2), + cacheLanc = {}, + center = { + x: 0, + y: 0 + }, + icenter = { + x: 0, + y: 0 + }; + return process(0); + } + + /** + * bilinearFiltering + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + bilinearFiltering(options, oW, oH, dW, dH) { + let a; + let b; + let c; + let d; + let x; + let y; + let i; + let j; + let xDiff; + let yDiff; + let chnl; + let color; + let offset = 0; + let origPix; + const ratioX = this.rcpScaleX; + const ratioY = this.rcpScaleY; + const w4 = 4 * (oW - 1); + const img = options.imageData; + const pixels = img.data; + const destImage = options.ctx.createImageData(dW, dH); + const destPixels = destImage.data; + for (i = 0; i < dH; i++) { + for (j = 0; j < dW; j++) { + x = Math.floor(ratioX * j); + y = Math.floor(ratioY * i); + xDiff = ratioX * j - x; + yDiff = ratioY * i - y; + origPix = 4 * (y * oW + x); + for (chnl = 0; chnl < 4; chnl++) { + a = pixels[origPix + chnl]; + b = pixels[origPix + 4 + chnl]; + c = pixels[origPix + w4 + chnl]; + d = pixels[origPix + w4 + 4 + chnl]; + color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff; + destPixels[offset++] = color; + } + } + } + return destImage; + } + + /** + * hermiteFastResize + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + hermiteFastResize(options, oW, oH, dW, dH) { + const ratioW = this.rcpScaleX, + ratioH = this.rcpScaleY, + ratioWHalf = Math.ceil(ratioW / 2), + ratioHHalf = Math.ceil(ratioH / 2), + img = options.imageData, + data = img.data, + img2 = options.ctx.createImageData(dW, dH), + data2 = img2.data; + for (let j = 0; j < dH; j++) { + for (let i = 0; i < dW; i++) { + const x2 = (i + j * dW) * 4; + let weight = 0; + let weights = 0; + let weightsAlpha = 0; + let gxR = 0; + let gxG = 0; + let gxB = 0; + let gxA = 0; + const centerY = (j + 0.5) * ratioH; + for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { + const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf, + centerX = (i + 0.5) * ratioW, + w0 = dy * dy; + for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { + let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf; + const w = Math.sqrt(w0 + dx * dx); + /* eslint-disable max-depth */ + if (w > 1 && w < -1) { + continue; + } + //hermite filter + weight = 2 * w * w * w - 3 * w * w + 1; + if (weight > 0) { + dx = 4 * (xx + yy * oW); + //alpha + gxA += weight * data[dx + 3]; + weightsAlpha += weight; + //colors + if (data[dx + 3] < 255) { + weight = weight * data[dx + 3] / 250; + } + gxR += weight * data[dx]; + gxG += weight * data[dx + 1]; + gxB += weight * data[dx + 2]; + weights += weight; + } + /* eslint-enable max-depth */ + } + } + data2[x2] = gxR / weights; + data2[x2 + 1] = gxG / weights; + data2[x2 + 2] = gxB / weights; + data2[x2 + 3] = gxA / weightsAlpha; + } + } + return img2; + } +} +/** + * Resize type + * for webgl resizeType is just lanczos, for canvas2d can be: + * bilinear, hermite, sliceHack, lanczos. + * @default + */ +/** + * Scale factor for resizing, x axis + * @param {Number} scaleX + * @default + */ +/** + * Scale factor for resizing, y axis + * @param {Number} scaleY + * @default + */ +/** + * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos + * @param {Number} lanczosLobes + * @default + */ +_defineProperty(Resize, "type", 'Resize'); +_defineProperty(Resize, "defaults", resizeDefaultValues); +_defineProperty(Resize, "uniformLocations", ['uDelta', 'uTaps']); +classRegistry.setClass(Resize); + +const fragmentSource$1 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n"; + +const saturationDefaultValues = { + saturation: 0 +}; + +/** + * Saturate filter class + * @example + * const filter = new Saturation({ + * saturation: 1 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Saturation extends BaseFilter { + getFragmentSource() { + return fragmentSource$1; + } + + /** + * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const adjust = -this.saturation; + for (let i = 0; i < data.length; i += 4) { + const max = Math.max(data[i], data[i + 1], data[i + 2]); + data[i] += max !== data[i] ? (max - data[i]) * adjust : 0; + data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0; + data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uSaturation, -this.saturation); + } + isNeutralState() { + return this.saturation === 0; + } +} +/** + * Saturation value, from -1 to 1. + * Increases/decreases the color saturation. + * A value of 0 has no effect. + * + * @param {Number} saturation + * @default + */ +_defineProperty(Saturation, "type", 'Saturation'); +_defineProperty(Saturation, "defaults", saturationDefaultValues); +_defineProperty(Saturation, "uniformLocations", ['uSaturation']); +classRegistry.setClass(Saturation); + +const fragmentSource = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n"; + +const vibranceDefaultValues = { + vibrance: 0 +}; + +/** + * Vibrance filter class + * @example + * const filter = new Vibrance({ + * vibrance: 1 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Vibrance extends BaseFilter { + getFragmentSource() { + return fragmentSource; + } + + /** + * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const adjust = -this.vibrance; + for (let i = 0; i < data.length; i += 4) { + const max = Math.max(data[i], data[i + 1], data[i + 2]); + const avg = (data[i] + data[i + 1] + data[i + 2]) / 3; + const amt = Math.abs(max - avg) * 2 / 255 * adjust; + data[i] += max !== data[i] ? (max - data[i]) * amt : 0; + data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0; + data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uVibrance, -this.vibrance); + } + isNeutralState() { + return this.vibrance === 0; + } +} +/** + * Vibrance value, from -1 to 1. + * Increases/decreases the saturation of more muted colors with less effect on saturated colors. + * A value of 0 has no effect. + * + * @param {Number} vibrance + * @default + */ +_defineProperty(Vibrance, "type", 'Vibrance'); +_defineProperty(Vibrance, "defaults", vibranceDefaultValues); +_defineProperty(Vibrance, "uniformLocations", ['uVibrance']); +classRegistry.setClass(Vibrance); + +var filters = /*#__PURE__*/Object.freeze({ + __proto__: null, + BaseFilter: BaseFilter, + BlackWhite: BlackWhite, + BlendColor: BlendColor, + BlendImage: BlendImage, + Blur: Blur, + Brightness: Brightness, + Brownie: Brownie, + ColorMatrix: ColorMatrix, + Composed: Composed, + Contrast: Contrast, + Convolute: Convolute, + Gamma: Gamma, + Grayscale: Grayscale, + HueRotation: HueRotation, + Invert: Invert, + Kodachrome: Kodachrome, + Noise: Noise, + Pixelate: Pixelate, + Polaroid: Polaroid, + RemoveColor: RemoveColor, + Resize: Resize, + Saturation: Saturation, + Sepia: Sepia, + Technicolor: Technicolor, + Vibrance: Vibrance, + Vintage: Vintage +}); + +export { ActiveSelection, BaseBrush, FabricObject$1 as BaseFabricObject, Canvas, Canvas2dFilterBackend, CanvasDOMManager, Circle, CircleBrush, ClipPathLayout, Color, Control, Ellipse, FabricImage, FabricObject, FabricText, FitContentLayout, FixedLayout, Gradient, Group, IText, FabricImage as Image, InteractiveFabricObject, Intersection, LayoutManager, LayoutStrategy, Line, FabricObject as Object, Observable, Path, Pattern, PatternBrush, PencilBrush, Point, Polygon, Polyline, Rect, Shadow, SprayBrush, StaticCanvas, StaticCanvasDOMManager, FabricText as Text, Textbox, Triangle, WebGLFilterBackend, cache, classRegistry, config, index as controlsUtils, createCollectionMixin, filters, getCSSRules, getEnv, getFabricDocument, getFabricWindow, getFilterBackend, iMatrix, initFilterBackend, isPutImageFaster, isWebGLPipelineState, loadSVGFromString, loadSVGFromURL, parseAttributes, parseFontDeclaration, parsePointsAttribute, parseSVGDocument, parseStyleAttribute, parseTransformAttribute, runningAnimations, setEnv, setFilterBackend, index$1 as util, VERSION as version }; +//# sourceMappingURL=index.mjs.map diff --git a/dist/index.mjs.map b/dist/index.mjs.map new file mode 100644 index 00000000000..e1ec42ca5b2 --- /dev/null +++ b/dist/index.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"index.mjs","sources":["../src/config.ts","../src/util/internals/console.ts","../src/filters/GLProbes/GLProbe.ts","../src/filters/GLProbes/WebGLProbe.ts","../src/env/browser.ts","../src/env/index.ts","../src/cache.ts","../src/constants.ts","../src/ClassRegistry.ts","../src/util/animation/AnimationRegistry.ts","../src/Observable.ts","../src/util/internals/removeFromArray.ts","../src/util/misc/cos.ts","../src/util/misc/sin.ts","../src/Point.ts","../src/Collection.ts","../src/CommonMethods.ts","../src/util/animation/AnimationFrameProvider.ts","../src/util/internals/uid.ts","../src/util/misc/dom.ts","../src/util/misc/radiansDegreesConversion.ts","../src/util/misc/matrix.ts","../src/util/misc/objectEnlive.ts","../src/util/misc/pick.ts","../src/color/color_map.ts","../src/color/constants.ts","../src/color/util.ts","../src/color/Color.ts","../src/util/misc/toFixed.ts","../src/util/misc/svgParsing.ts","../src/util/typeAssertions.ts","../src/util/dom_misc.ts","../src/canvas/DOMManagers/util.ts","../src/canvas/DOMManagers/StaticCanvasDOMManager.ts","../src/canvas/StaticCanvasOptions.ts","../src/canvas/StaticCanvas.ts","../src/util/dom_event.ts","../src/util/misc/boundingBoxFromPoints.ts","../src/util/misc/objectTransforms.ts","../src/util/misc/planeChange.ts","../src/controls/fireEvent.ts","../src/util/misc/resolveOrigin.ts","../src/controls/util.ts","../src/controls/drag.ts","../src/shapes/Object/FabricObjectSVGExportMixin.ts","../src/parser/getSvgRegex.ts","../src/parser/constants.ts","../src/util/misc/vectors.ts","../src/Shadow.ts","../src/util/misc/capValue.ts","../src/shapes/Object/defaultValues.ts","../src/util/animation/easing.ts","../src/util/animation/AnimationBase.ts","../src/util/animation/ValueAnimation.ts","../src/util/animation/ArrayAnimation.ts","../src/util/animation/ColorAnimation.ts","../src/util/animation/animate.ts","../src/Intersection.ts","../src/shapes/Object/ObjectGeometry.ts","../src/shapes/Object/Object.ts","../src/controls/wrapWithFireEvent.ts","../src/controls/wrapWithFixedAnchor.ts","../src/controls/changeWidth.ts","../src/controls/controlRendering.ts","../src/controls/Control.ts","../src/controls/rotate.ts","../src/controls/scale.ts","../src/controls/skew.ts","../src/controls/scaleSkew.ts","../src/controls/commonControls.ts","../src/shapes/Object/InteractiveObject.ts","../src/util/applyMixins.ts","../src/shapes/Object/FabricObject.ts","../src/util/misc/isTransparent.ts","../src/util/misc/rotatePoint.ts","../src/util/internals/findRight.ts","../src/util/misc/projectStroke/StrokeProjectionsBase.ts","../src/util/misc/projectStroke/StrokeLineJoinProjections.ts","../src/util/misc/projectStroke/StrokeLineCapProjections.ts","../src/util/misc/projectStroke/index.ts","../src/util/internals/cloneStyles.ts","../src/util/lang_string.ts","../src/util/misc/textStyles.ts","../src/parser/attributes.ts","../src/parser/selectorMatches.ts","../src/parser/doesSomeParentMatch.ts","../src/parser/elementMatchesRule.ts","../src/parser/getGlobalStylesForElement.ts","../src/parser/normalizeAttr.ts","../src/util/internals/cleanupSvgAttribute.ts","../src/parser/parseTransformAttribute.ts","../src/parser/normalizeValue.ts","../src/parser/parseFontDeclaration.ts","../src/parser/parseStyleObject.ts","../src/parser/parseStyleString.ts","../src/parser/parseStyleAttribute.ts","../src/parser/setStrokeFillOpacity.ts","../src/parser/parseAttributes.ts","../src/shapes/Rect.ts","../src/LayoutManager/constants.ts","../src/LayoutManager/LayoutStrategies/utils.ts","../src/LayoutManager/LayoutStrategies/LayoutStrategy.ts","../src/LayoutManager/LayoutStrategies/FitContentLayout.ts","../src/LayoutManager/LayoutManager.ts","../src/shapes/Group.ts","../src/util/misc/groupSVGElements.ts","../src/util/misc/findScaleTo.ts","../src/util/path/regex.ts","../src/util/path/index.ts","../src/util/dom_style.ts","../src/util/misc/mergeClipPaths.ts","../src/util/internals/getRandomInt.ts","../src/util/internals/dom_request.ts","../src/util/transform_matrix_removal.ts","../src/canvas/DOMManagers/CanvasDOMManager.ts","../src/canvas/CanvasOptions.ts","../src/canvas/SelectableCanvas.ts","../src/canvas/TextEditingManager.ts","../src/canvas/Canvas.ts","../src/gradient/constants.ts","../src/util/internals/ifNaN.ts","../src/parser/percent.ts","../src/gradient/parser/parseColorStops.ts","../src/gradient/parser/misc.ts","../src/gradient/parser/parseCoords.ts","../src/gradient/Gradient.ts","../src/Pattern/Pattern.ts","../src/brushes/BaseBrush.ts","../src/shapes/Path.ts","../src/brushes/PencilBrush.ts","../src/shapes/Circle.ts","../src/brushes/CircleBrush.ts","../src/brushes/SprayBrush.ts","../src/brushes/PatternBrush.ts","../src/shapes/Line.ts","../src/shapes/Triangle.ts","../src/shapes/Ellipse.ts","../src/parser/parsePointsAttribute.ts","../src/shapes/Polyline.ts","../src/shapes/Polygon.ts","../src/shapes/Text/constants.ts","../src/shapes/Text/StyledText.ts","../src/shapes/Text/TextSVGExportMixin.ts","../src/shapes/Text/Text.ts","../src/shapes/IText/DraggableTextDelegate.ts","../src/shapes/IText/ITextBehavior.ts","../src/shapes/IText/ITextKeyBehavior.ts","../src/shapes/IText/ITextClickBehavior.ts","../src/shapes/IText/constants.ts","../src/shapes/IText/IText.ts","../src/shapes/Textbox.ts","../src/LayoutManager/LayoutStrategies/ClipPathLayout.ts","../src/LayoutManager/LayoutStrategies/FixedLayout.ts","../src/LayoutManager/ActiveSelectionLayoutManager.ts","../src/shapes/ActiveSelection.ts","../src/filters/Canvas2dFilterBackend.ts","../src/filters/WebGLFilterBackend.ts","../src/filters/FilterBackend.ts","../src/shapes/Image.ts","../src/parser/applyViewboxTransform.ts","../src/parser/getTagName.ts","../src/parser/hasInvalidAncestor.ts","../src/parser/getMultipleNodes.ts","../src/parser/parseUseDirectives.ts","../src/parser/recursivelyParseGradientsXlink.ts","../src/parser/getGradientDefs.ts","../src/parser/getCSSRules.ts","../src/parser/elements_parser.ts","../src/parser/parseSVGDocument.ts","../src/parser/loadSVGFromString.ts","../src/parser/loadSVGFromURL.ts","../src/controls/polyControl.ts","../src/controls/pathControl.ts","../src/filters/utils.ts","../src/filters/shaders/baseFilter.ts","../src/filters/BaseFilter.ts","../src/filters/shaders/blendColor.ts","../src/filters/BlendColor.ts","../src/filters/shaders/blendImage.ts","../src/filters/BlendImage.ts","../src/filters/shaders/blur.ts","../src/filters/Blur.ts","../src/filters/shaders/brightness.ts","../src/filters/Brightness.ts","../src/filters/shaders/colorMatrix.ts","../src/filters/ColorMatrix.ts","../src/filters/ColorMatrixFilters.ts","../src/filters/Composed.ts","../src/filters/shaders/constrast.ts","../src/filters/Contrast.ts","../src/filters/shaders/convolute.ts","../src/filters/Convolute.ts","../src/filters/shaders/gamma.ts","../src/filters/Gamma.ts","../src/filters/shaders/grayscale.ts","../src/filters/Grayscale.ts","../src/filters/HueRotation.ts","../src/filters/shaders/invert.ts","../src/filters/Invert.ts","../src/filters/shaders/noise.ts","../src/filters/Noise.ts","../src/filters/shaders/pixelate.ts","../src/filters/Pixelate.ts","../src/filters/shaders/removeColor.ts","../src/filters/RemoveColor.ts","../src/filters/Resize.ts","../src/filters/shaders/saturation.ts","../src/filters/Saturation.ts","../src/filters/shaders/vibrance.ts","../src/filters/Vibrance.ts"],"sourcesContent":["export type TConfiguration = Partial;\n\nclass BaseConfiguration {\n /**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\n browserShadowBlurConstant = 1;\n\n /**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\n DPI = 96;\n\n /**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n devicePixelRatio =\n typeof window !== 'undefined' ? window.devicePixelRatio : 1; // eslint-disable-line no-restricted-globals\n\n /**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n perfLimitSizeTotal = 2097152;\n\n /**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\n maxCacheSideLimit = 4096;\n\n /**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n minCacheSideLimit = 256;\n\n /**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n * @deprecated\n */\n disableStyleCopyPaste = false;\n\n /**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\n enableGLFiltering = true;\n\n /**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n *\n * In order to support old hardware set to `2048` to avoid OOM\n *\n * @since 2.0.0\n * @type Number\n * @default\n */\n textureSize = 4096;\n\n /**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\n forceGLPutImageData = false;\n\n /**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from\n * the curve is very hard to hit any cache.\n * Enable only if you know why it could be useful.\n * Candidate for removal/simplification\n * @default false\n */\n cachesBoundsOfCurve = false;\n\n /**\n * Map of font files\n * Map of font files\n */\n fontPaths: Record = {};\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * Used in exporting methods (`toObject`, `toJSON`, `toSVG`)\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n */\n NUM_FRACTION_DIGITS = 4;\n}\n\nexport class Configuration extends BaseConfiguration {\n constructor(config?: TConfiguration) {\n super();\n this.configure(config);\n }\n\n configure(config: TConfiguration = {}) {\n Object.assign(this, config);\n }\n\n /**\n * Map of font files\n */\n addFonts(\n paths: Record = {},\n ) {\n this.fontPaths = {\n ...this.fontPaths,\n ...paths,\n };\n }\n\n removeFonts(fontFamilys: string[] = []) {\n fontFamilys.forEach((fontFamily) => {\n delete this.fontPaths[fontFamily];\n });\n }\n\n clearFonts() {\n this.fontPaths = {};\n }\n\n restoreDefaults(keys?: (keyof T)[]) {\n const defaults = new BaseConfiguration() as T;\n const config =\n keys?.reduce((acc, key) => {\n acc[key] = defaults[key];\n return acc;\n }, {} as T) || defaults;\n this.configure(config);\n }\n}\n\nexport const config = new Configuration();\n","export const log = (\n severity: 'log' | 'warn' | 'error',\n ...optionalParams: any[]\n) =>\n // eslint-disable-next-line no-restricted-syntax\n console[severity]('fabric', ...optionalParams);\n\nexport class FabricError extends Error {\n constructor(message?: string, options?: ErrorOptions) {\n super(`fabric: ${message}`, options);\n }\n}\n\nexport class SignalAbortedError extends FabricError {\n constructor(context: string) {\n super(`${context} 'options.signal' is in 'aborted' state`);\n }\n}\n","export type GLPrecision = 'lowp' | 'mediump' | 'highp';\n\nexport abstract class GLProbe {\n declare GLPrecision: GLPrecision | undefined;\n abstract queryWebGL(canvas: HTMLCanvasElement): void;\n abstract isSupported(textureSize: number): boolean;\n}\n","import { log } from '../../util/internals/console';\nimport { GLProbe } from './GLProbe';\nimport type { GLPrecision } from './GLProbe';\n\n/**\n * Lazy initialize WebGL constants\n */\nexport class WebGLProbe extends GLProbe {\n declare maxTextureSize?: number;\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {GLPrecision} Precision to test can be any of following\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n private testPrecision(\n gl: WebGLRenderingContext,\n precision: GLPrecision,\n ): boolean {\n const fragmentSource = `precision ${precision} float;\\nvoid main(){}`;\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n if (!fragmentShader) {\n return false;\n }\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);\n }\n\n /**\n * query browser for WebGL\n */\n queryWebGL(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext('webgl');\n if (gl) {\n this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this.GLPrecision = (['highp', 'mediump', 'lowp'] as const).find(\n (precision) => this.testPrecision(gl, precision),\n );\n gl.getExtension('WEBGL_lose_context')!.loseContext();\n log('log', `WebGL: max texture size ${this.maxTextureSize}`);\n }\n }\n\n isSupported(textureSize: number) {\n return !!this.maxTextureSize && this.maxTextureSize >= textureSize;\n }\n}\n","/* eslint-disable no-restricted-globals */\nimport { WebGLProbe } from '../filters/GLProbes/WebGLProbe';\nimport type { TCopyPasteData, TFabricEnv } from './types';\n\nconst copyPasteData: TCopyPasteData = {};\n\nexport const getEnv = (): TFabricEnv => {\n return {\n document,\n window,\n isTouchSupported:\n 'ontouchstart' in window ||\n 'ontouchstart' in document ||\n (window && window.navigator && window.navigator.maxTouchPoints > 0),\n WebGLProbe: new WebGLProbe(),\n dispose() {\n // noop\n },\n copyPasteData,\n };\n};\n","/**\n * This file is consumed by fabric.\n * The `./node` and `./browser` files define the env variable that is used by this module.\n * The `./browser` module is defined to be the default env and doesn't set the env at all.\n * This is done in order to support isomorphic usage for browser and node applications\n * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env.\n */\n\nimport { config } from '../config';\nimport { getEnv as getBrowserEnv } from './browser';\nimport type { TFabricEnv } from './types';\nimport type { DOMWindow } from 'jsdom';\n\nlet env: TFabricEnv;\n\n/**\n * Sets the environment variables used by fabric.\\\n * This is exposed for special cases, such as configuring a test environment, and should be used with care.\n *\n * **CAUTION**: Must be called before using the package.\n *\n * @example\n * Passing `window` and `document` objects to fabric (in case they are mocked or something)\n * import { getEnv, setEnv } from 'fabric';\n * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in.\n * setEnv({ ...getEnv(), window, document });\n * // done with setup, using fabric is now safe\n */\nexport const setEnv = (value: TFabricEnv) => {\n env = value;\n};\n\n/**\n * In order to support SSR we **MUST** access the browser env only after the window has loaded\n */\nexport const getEnv = () => env || (env = getBrowserEnv());\n\nexport const getFabricDocument = (): Document => getEnv().document;\n\nexport const getFabricWindow = (): (Window & typeof globalThis) | DOMWindow =>\n getEnv().window;\n\n/**\n * @returns the config value if defined, fallbacks to the environment value\n */\nexport const getDevicePixelRatio = () =>\n Math.max(config.devicePixelRatio ?? getFabricWindow().devicePixelRatio, 1);\n","import { config } from './config';\nimport type { TRectBounds } from './typedefs';\n\nexport class Cache {\n /**\n * Cache of widths of chars in text rendering.\n */\n charWidthsCache: Record<\n /** fontFamily */ string,\n Record<\n /** fontStyleCacheKey */ string,\n Record\n >\n > = {};\n\n /**\n * @return {Object} reference to cache\n */\n getFontCache({\n fontFamily,\n fontStyle,\n fontWeight,\n }: {\n fontFamily: string;\n fontStyle: string;\n fontWeight: string | number;\n }) {\n fontFamily = fontFamily.toLowerCase();\n if (!this.charWidthsCache[fontFamily]) {\n this.charWidthsCache[fontFamily] = {};\n }\n const fontCache = this.charWidthsCache[fontFamily];\n const cacheKey = `${fontStyle.toLowerCase()}_${(\n fontWeight + ''\n ).toLowerCase()}`;\n if (!fontCache[cacheKey]) {\n fontCache[cacheKey] = {};\n }\n return fontCache[cacheKey];\n }\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @param {String} [fontFamily] font family to clear\n */\n clearFontCache(fontFamily?: string) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n this.charWidthsCache = {};\n } else if (this.charWidthsCache[fontFamily]) {\n delete this.charWidthsCache[fontFamily];\n }\n }\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @param {number} ar aspect ratio\n * @return {number[]} Limited dimensions X and Y\n */\n limitDimsByArea(ar: number) {\n const { perfLimitSizeTotal } = config;\n const roughWidth = Math.sqrt(perfLimitSizeTotal * ar);\n // we are not returning a point on purpose, to avoid circular dependencies\n // this is an internal utility\n return [\n Math.floor(roughWidth),\n Math.floor(perfLimitSizeTotal / roughWidth),\n ];\n }\n\n /**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\n boundsOfCurveCache: Record = {};\n}\n\nexport const cache = new Cache();\n","import type { TMat2D } from './typedefs';\n// use this syntax so babel plugin see this import here\nimport { version } from '../package.json';\n\nexport const VERSION = version;\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport const halfPI = Math.PI / 2;\nexport const twoMathPi = Math.PI * 2;\nexport const PiBy180 = Math.PI / 180;\n\nexport const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]) as TMat2D;\nexport const DEFAULT_SVG_FONT_SIZE = 16;\nexport const ALIASING_LIMIT = 2;\n\n/* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\nexport const kRect = 1 - 0.5522847498;\n\nexport const CENTER = 'center';\nexport const LEFT = 'left';\nexport const TOP = 'top';\nexport const BOTTOM = 'bottom';\nexport const RIGHT = 'right';\nexport const NONE = 'none';\n\nexport const reNewline = /\\r?\\n/;\n\nexport const MOVING = 'moving';\nexport const SCALING = 'scaling';\nexport const ROTATING = 'rotating';\nexport const ROTATE = 'rotate';\nexport const SKEWING = 'skewing';\nexport const RESIZING = 'resizing';\nexport const MODIFY_POLY = 'modifyPoly';\nexport const MODIFY_PATH = 'modifyPath';\nexport const CHANGED = 'changed';\nexport const SCALE = 'scale';\nexport const SCALE_X = 'scaleX';\nexport const SCALE_Y = 'scaleY';\nexport const SKEW_X = 'skewX';\nexport const SKEW_Y = 'skewY';\nexport const FILL = 'fill';\nexport const STROKE = 'stroke';\nexport const MODIFIED = 'modified';\n","import { FabricError } from './util/internals/console';\n\n/*\n * This Map connects the objects type value with their\n * class implementation. It used from any object to understand which are\n * the classes to enlive when requesting a object.type = 'path' for example.\n * Objects uses it for clipPath, Canvas uses it for everything.\n * This is necessary for generic code to run and enlive instances from serialized representation.\n * You can customize which classes get enlived from SVG parsing using this classRegistry.\n * The Registry start empty and gets filled in depending which files you import.\n * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from\n * different sources you will need to import all fabric because you may need all classes.\n */\n\nexport const JSON = 'json';\nexport const SVG = 'svg';\n\nexport class ClassRegistry {\n declare [JSON]: Map;\n declare [SVG]: Map;\n\n constructor() {\n this[JSON] = new Map();\n this[SVG] = new Map();\n }\n\n has(classType: string): boolean {\n return this[JSON].has(classType);\n }\n\n getClass(classType: string): T {\n const constructor = this[JSON].get(classType);\n if (!constructor) {\n throw new FabricError(`No class registered for ${classType}`);\n }\n return constructor;\n }\n\n setClass(classConstructor: any, classType?: string) {\n if (classType) {\n this[JSON].set(classType, classConstructor);\n } else {\n this[JSON].set(classConstructor.type, classConstructor);\n // legacy\n // @TODO: needs to be removed in fabric 7 or 8\n this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);\n }\n }\n\n getSVGClass(SVGTagName: string): any {\n return this[SVG].get(SVGTagName);\n }\n\n setSVGClass(classConstructor: any, SVGTagName?: string) {\n this[SVG].set(\n SVGTagName ?? classConstructor.type.toLowerCase(),\n classConstructor,\n );\n }\n}\n\nexport const classRegistry = new ClassRegistry();\n","import type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type { AnimationBase } from './AnimationBase';\n\n/**\n * Array holding all running animations\n */\nclass AnimationRegistry extends Array {\n /**\n * Remove a single animation using an animation context\n * @param {AnimationBase} context\n */\n remove(context: AnimationBase) {\n const index = this.indexOf(context);\n index > -1 && this.splice(index, 1);\n }\n\n /**\n * Cancel all running animations on the next frame\n */\n cancelAll() {\n const animations = this.splice(0);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations attached to a canvas on the next frame\n * @param {StaticCanvas} canvas\n */\n cancelByCanvas(canvas: StaticCanvas) {\n if (!canvas) {\n return [];\n }\n const animations = this.filter(\n (animation) =>\n animation.target === canvas ||\n (typeof animation.target === 'object' &&\n (animation.target as FabricObject)?.canvas === canvas),\n );\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations for target on the next frame\n * @param target\n */\n cancelByTarget(target: AnimationBase['target']) {\n if (!target) {\n return [];\n }\n const animations = this.filter((animation) => animation.target === target);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n}\n\nexport const runningAnimations = new AnimationRegistry();\n","export type TEventCallback = (options: T) => any;\n\ntype EventRegistryObject = {\n [K in keyof E]?: TEventCallback;\n};\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\nexport class Observable {\n private __eventListeners: Record =\n {} as Record;\n\n /**\n * Observes specified event\n * @alias on\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n on(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n on(handlers: EventRegistryObject): VoidFunction;\n on(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (!this.__eventListeners) {\n this.__eventListeners = {} as Record;\n }\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this.on(eventName as K, handler as TEventCallback);\n });\n return () => this.off(arg0);\n } else if (handler) {\n const eventName = arg0;\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n return () => this.off(eventName, handler);\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * Observes specified event **once**\n * @alias once\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n once(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n once(handlers: EventRegistryObject): VoidFunction;\n once(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n const disposers: VoidFunction[] = [];\n Object.entries(arg0).forEach(([eventName, handler]) => {\n disposers.push(this.once(eventName as K, handler as TEventCallback));\n });\n return () => disposers.forEach((d) => d());\n } else if (handler) {\n const disposer = this.on(\n arg0,\n function onceHandler(this: Observable, ...args) {\n handler.call(this, ...args);\n disposer();\n },\n );\n return disposer;\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * @private\n * @param {string} eventName\n * @param {Function} [handler]\n */\n private _removeEventListener(\n eventName: K,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n\n if (handler) {\n const eventListener = this.__eventListeners[eventName];\n const index = eventListener.indexOf(handler);\n index > -1 && eventListener.splice(index, 1);\n } else {\n this.__eventListeners[eventName] = [];\n }\n }\n\n /**\n * Unsubscribe all event listeners for eventname.\n * Do not use this pattern. You could kill internal fabricJS events.\n * We know we should have protected events for internal flows, but we don't have yet\n * @deprecated\n * @param {string} eventName event name (eg. 'after:render')\n */\n off(eventName: K): void;\n /**\n * unsubscribe an event listener\n * @param {string} eventName event name (eg. 'after:render')\n * @param {TEventCallback} handler event listener to unsubscribe\n */\n off(eventName: K, handler: TEventCallback): void;\n /**\n * unsubscribe event listeners\n * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n */\n off(handlers: EventRegistryObject): void;\n /**\n * unsubscribe all event listeners\n */\n off(): void;\n off(\n arg0?: K | EventRegistryObject,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners) {\n return;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (typeof arg0 === 'undefined') {\n for (const eventName in this.__eventListeners) {\n this._removeEventListener(eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (typeof arg0 === 'object') {\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this._removeEventListener(eventName as K, handler as TEventCallback);\n });\n } else {\n this._removeEventListener(arg0, handler);\n }\n }\n\n /**\n * Fires event with an optional options object\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n */\n fire(eventName: K, options?: EventSpec[K]) {\n if (!this.__eventListeners) {\n return;\n }\n\n const listenersForEvent = this.__eventListeners[eventName]?.concat();\n if (listenersForEvent) {\n for (let i = 0; i < listenersForEvent.length; i++) {\n listenersForEvent[i].call(this, options || {});\n }\n }\n }\n}\n","/**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\nexport const removeFromArray = (array: T[], value: T): T[] => {\n const idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the cosin value for angle.\n */\nexport const cos = (angle: TRadian): number => {\n if (angle === 0) {\n return 1;\n }\n const angleSlice = Math.abs(angle) / halfPI;\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n case 2:\n return -1;\n }\n return Math.cos(angle);\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the sin value for angle.\n */\nexport const sin = (angle: TRadian): number => {\n if (angle === 0) {\n return 0;\n }\n const angleSlice = angle / halfPI;\n const value = Math.sign(angle);\n switch (angleSlice) {\n case 1:\n return value;\n case 2:\n return 0;\n case 3:\n return -value;\n }\n return Math.sin(angle);\n};\n","import type { TMat2D, TRadian } from './typedefs';\nimport { cos } from './util/misc/cos';\nimport { sin } from './util/misc/sin';\n\nexport interface XY {\n x: number;\n y: number;\n}\n\n/**\n * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com)\n */\nexport class Point implements XY {\n declare x: number;\n\n declare y: number;\n\n constructor();\n constructor(x: number, y: number);\n constructor(point?: XY);\n constructor(arg0: number | XY = 0, y = 0) {\n if (typeof arg0 === 'object') {\n this.x = arg0.x;\n this.y = arg0.y;\n } else {\n this.x = arg0;\n this.y = y;\n }\n }\n\n /**\n * Adds another point to this one and returns another one\n * @param {XY} that\n * @return {Point} new Point instance with added values\n */\n add(that: XY): Point {\n return new Point(this.x + that.x, this.y + that.y);\n }\n\n /**\n * Adds another point to this one\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n addEquals(that: XY): Point {\n this.x += that.x;\n this.y += that.y;\n return this;\n }\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {Point} new Point with added value\n */\n scalarAdd(scalar: number): Point {\n return new Point(this.x + scalar, this.y + scalar);\n }\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarAddEquals(scalar: number): Point {\n this.x += scalar;\n this.y += scalar;\n return this;\n }\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {XY} that\n * @return {Point} new Point object with subtracted values\n */\n subtract(that: XY): Point {\n return new Point(this.x - that.x, this.y - that.y);\n }\n\n /**\n * Subtracts another point from this point\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n subtractEquals(that: XY): Point {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n }\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarSubtract(scalar: number): Point {\n return new Point(this.x - scalar, this.y - scalar);\n }\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarSubtractEquals(scalar: number): Point {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n }\n\n /**\n * Multiplies this point by another value and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n multiply(that: XY): Point {\n return new Point(this.x * that.x, this.y * that.y);\n }\n\n /**\n * Multiplies this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarMultiply(scalar: number): Point {\n return new Point(this.x * scalar, this.y * scalar);\n }\n\n /**\n * Multiplies this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarMultiplyEquals(scalar: number): Point {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n }\n\n /**\n * Divides this point by another and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n divide(that: XY): Point {\n return new Point(this.x / that.x, this.y / that.y);\n }\n\n /**\n * Divides this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarDivide(scalar: number): Point {\n return new Point(this.x / scalar, this.y / scalar);\n }\n\n /**\n * Divides this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarDivideEquals(scalar: number): Point {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n }\n\n /**\n * Returns true if this point is equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n eq(that: XY): boolean {\n return this.x === that.x && this.y === that.y;\n }\n\n /**\n * Returns true if this point is less than another one\n * @param {XY} that\n * @return {Boolean}\n */\n lt(that: XY): boolean {\n return this.x < that.x && this.y < that.y;\n }\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n lte(that: XY): boolean {\n return this.x <= that.x && this.y <= that.y;\n }\n\n /**\n\n * Returns true if this point is greater another one\n * @param {XY} that\n * @return {Boolean}\n */\n gt(that: XY): boolean {\n return this.x > that.x && this.y > that.y;\n }\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n gte(that: XY): boolean {\n return this.x >= that.x && this.y >= that.y;\n }\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {XY} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {Point}\n */\n lerp(that: XY, t = 0.5): Point {\n t = Math.max(Math.min(1, t), 0);\n return new Point(\n this.x + (that.x - this.x) * t,\n this.y + (that.y - this.y) * t,\n );\n }\n\n /**\n * Returns distance from this point and another one\n * @param {XY} that\n * @return {Number}\n */\n distanceFrom(that: XY): number {\n const dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /**\n * Returns the point between this point and another one\n * @param {XY} that\n * @return {Point}\n */\n midPointFrom(that: XY): Point {\n return this.lerp(that);\n }\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {XY} that\n * @return {Point}\n */\n min(that: XY): Point {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n }\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {XY} that\n * @return {Point}\n */\n max(that: XY): Point {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n }\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY(x: number, y: number) {\n this.x = x;\n this.y = y;\n return this;\n }\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX(x: number) {\n this.x = x;\n return this;\n }\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY(y: number) {\n this.y = y;\n return this;\n }\n\n /**\n * Sets x/y of this point from another point\n * @param {XY} that\n * @chainable\n */\n setFromPoint(that: XY) {\n this.x = that.x;\n this.y = that.y;\n return this;\n }\n\n /**\n * Swaps x/y of this point and another point\n * @param {XY} that\n */\n swap(that: XY) {\n const x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n }\n\n /**\n * return a cloned instance of the point\n * @return {Point}\n */\n clone(): Point {\n return new Point(this.x, this.y);\n }\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {XY} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\n rotate(radians: TRadian, origin: XY = ZERO): Point {\n // TODO benchmark and verify the add and subtract how much cost\n // and then in case early return if no origin is passed\n const sinus = sin(radians),\n cosinus = cos(radians);\n const p = this.subtract(origin);\n const rotated = new Point(\n p.x * cosinus - p.y * sinus,\n p.x * sinus + p.y * cosinus,\n );\n return rotated.add(origin);\n }\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {TMat2D} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\n transform(t: TMat2D, ignoreOffset = false): Point {\n return new Point(\n t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]),\n t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5]),\n );\n }\n}\n\nexport const ZERO = new Point(0, 0);\n","import type { Constructor, TBBox } from './typedefs';\nimport { removeFromArray } from './util/internals/removeFromArray';\nimport { Point } from './Point';\nimport type { ActiveSelection } from './shapes/ActiveSelection';\nimport type { Group } from './shapes/Group';\nimport type { InteractiveFabricObject } from './shapes/Object/InteractiveObject';\nimport type { FabricObject } from './shapes/Object/FabricObject';\n\nexport const isCollection = (\n fabricObject?: FabricObject,\n): fabricObject is Group | ActiveSelection => {\n return !!fabricObject && Array.isArray((fabricObject as Group)._objects);\n};\n\nexport function createCollectionMixin(Base: TBase) {\n class Collection extends Base {\n /**\n * @type {FabricObject[]}\n * @TODO needs to end up in the constructor too\n */\n _objects: FabricObject[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectAdded(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectRemoved(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onStackOrderChanged(object: FabricObject) {\n // subclasses should override this method\n }\n\n /**\n * Adds objects to collection\n * Objects should be instances of (or inherit from) FabricObject\n * @param {...FabricObject[]} objects to add\n * @returns {number} new array length\n */\n add(...objects: FabricObject[]): number {\n const size = this._objects.push(...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {number} index Index to insert object at\n * @param {...FabricObject[]} objects Object(s) to insert\n * @returns {number} new array length\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n this._objects.splice(index, 0, ...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return this._objects.length;\n }\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @private\n * @param {...FabricObject[]} objects objects to remove\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const array = this._objects,\n removed: FabricObject[] = [];\n objects.forEach((object) => {\n const index = array.indexOf(object);\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n array.splice(index, 1);\n removed.push(object);\n this._onObjectRemoved(object);\n }\n });\n return removed;\n }\n\n /**\n * Executes given function for each object in this group\n * A simple shortcut for getObjects().forEach, before es6 was more complicated,\n * now is just a shortcut.\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n */\n forEachObject(\n callback: (\n object: FabricObject,\n index: number,\n array: FabricObject[],\n ) => any,\n ) {\n this.getObjects().forEach((object, index, objects) =>\n callback(object, index, objects),\n );\n }\n\n /**\n * Returns an array of children objects of this instance\n * @param {...String} [types] When specified, only objects of these types are returned\n * @return {Array}\n */\n getObjects(...types: string[]) {\n if (types.length === 0) {\n return [...this._objects];\n }\n return this._objects.filter((o) => o.isType(...types));\n }\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Object} object at index\n */\n item(index: number) {\n return this._objects[index];\n }\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty() {\n return this._objects.length === 0;\n }\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size() {\n return this._objects.length;\n }\n\n /**\n * Returns true if collection contains an object.\\\n * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons**\n * instead of `a.contains(b)` use `b.isDescendantOf(a)`\n * @param {Object} object Object to check against\n * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`\n * @return {Boolean} `true` if collection contains an object\n */\n contains(object: FabricObject, deep?: boolean): boolean {\n if (this._objects.includes(object)) {\n return true;\n } else if (deep) {\n return this._objects.some(\n (obj) =>\n obj instanceof Collection &&\n (obj as unknown as Collection).contains(object, true),\n );\n }\n return false;\n }\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity() {\n return this._objects.reduce((memo, current) => {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @returns {boolean} true if change occurred\n */\n sendObjectToBack(object: FabricObject) {\n if (!object || object === this._objects[0]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @returns {boolean} true if change occurred\n */\n bringObjectToFront(object: FabricObject) {\n if (!object || object === this._objects[this._objects.length - 1]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.push(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional parameter, `intersecting` allows to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @returns {boolean} true if change occurred\n */\n sendObjectBackwards(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n const newIdx = this.findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional parameter, intersecting allows to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @returns {boolean} true if change occurred\n */\n bringObjectForward(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n const newIdx = this.findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {number} index Position to move to\n * @returns {boolean} true if change occurred\n */\n moveObjectTo(object: FabricObject, index: number) {\n if (object === this._objects[index]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n findNewLowerIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse down the stack looking for the nearest intersecting object\n for (let i = idx - 1; i >= 0; --i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n }\n\n findNewUpperIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse up the stack looking for the nearest intersecting object\n for (let i = idx + 1; i < this._objects.length; ++i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n }\n\n /**\n * Given a bounding box, return all the objects of the collection that are contained in the bounding box.\n * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well.\n * This is meant to work with selection. Is not a generic method.\n * @param {TBBox} bbox a bounding box in scene coordinates\n * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting\n * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise\n */\n collectObjects(\n { left, top, width, height }: TBBox,\n { includeIntersecting = true }: { includeIntersecting?: boolean } = {},\n ) {\n const objects: InteractiveFabricObject[] = [],\n tl = new Point(left, top),\n br = tl.add(new Point(width, height));\n\n // we iterate reverse order to collect top first in case of click.\n for (let i = this._objects.length - 1; i >= 0; i--) {\n const object = this._objects[i] as unknown as InteractiveFabricObject;\n if (\n object.selectable &&\n object.visible &&\n ((includeIntersecting && object.intersectsWithRect(tl, br)) ||\n object.isContainedWithinRect(tl, br) ||\n (includeIntersecting && object.containsPoint(tl)) ||\n (includeIntersecting && object.containsPoint(br)))\n ) {\n objects.push(object);\n }\n }\n\n return objects;\n }\n }\n\n // https://github.com/microsoft/TypeScript/issues/32080\n return Collection as typeof Collection & TBase;\n}\n","import { Observable } from './Observable';\n\nexport class CommonMethods extends Observable {\n /**\n * Sets object's properties from options, for initialization only\n * @protected\n * @param {Object} [options] Options object\n */\n protected _setOptions(options: any = {}) {\n for (const prop in options) {\n this.set(prop, options[prop]);\n }\n }\n\n /**\n * @private\n */\n _setObject(obj: Record) {\n for (const prop in obj) {\n this._set(prop, obj[prop]);\n }\n }\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n */\n set(key: string | Record, value?: any) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n return this;\n }\n\n _set(key: string, value: any) {\n this[key as keyof this] = value;\n }\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n */\n toggle(property: string) {\n const value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n }\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get(property: string): any {\n return this[property as keyof this];\n }\n}\n","import { getFabricWindow } from '../../env';\n\nexport function requestAnimFrame(callback: FrameRequestCallback): number {\n return getFabricWindow().requestAnimationFrame(callback);\n}\n\nexport function cancelAnimFrame(handle: number): void {\n return getFabricWindow().cancelAnimationFrame(handle);\n}\n","let id = 0;\n\nexport const uid = () => id++;\n","import { getFabricDocument } from '../../env';\nimport type { ImageFormat } from '../../typedefs';\nimport { FabricError } from '../internals/console';\n/**\n * Creates canvas element\n * @return {CanvasElement} initialized canvas element\n */\nexport const createCanvasElement = (): HTMLCanvasElement => {\n const element = getFabricDocument().createElement('canvas');\n if (!element || typeof element.getContext === 'undefined') {\n throw new FabricError('Failed to create `canvas` element');\n }\n return element;\n};\n\n/**\n * Creates image element (works on client and node)\n * @return {HTMLImageElement} HTML image element\n */\nexport const createImage = (): HTMLImageElement =>\n getFabricDocument().createElement('img');\n\n/**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @return {CanvasElement} initialized canvas element\n */\nexport const copyCanvasElement = (\n canvas: HTMLCanvasElement,\n): HTMLCanvasElement => {\n const newCanvas = createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d')?.drawImage(canvas, 0, 0);\n return newCanvas;\n};\n\n/**\n * since 2.6.0 moved from canvas instance to utility.\n * possibly useless\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @return {String} data url\n */\nexport const toDataURL = (\n canvasEl: HTMLCanvasElement,\n format: ImageFormat,\n quality: number,\n) => canvasEl.toDataURL(`image/${format}`, quality);\n\nexport const isHTMLCanvas = (\n canvas?: HTMLCanvasElement | string,\n): canvas is HTMLCanvasElement => {\n return !!canvas && (canvas as HTMLCanvasElement).getContext !== undefined;\n};\n","import type { TRadian, TDegree } from '../../typedefs';\nimport { PiBy180 } from '../../constants';\n\n/**\n * Transforms degrees to radians.\n * @param {TDegree} degrees value in degrees\n * @return {TRadian} value in radians\n */\nexport const degreesToRadians = (degrees: TDegree): TRadian =>\n (degrees * PiBy180) as TRadian;\n\n/**\n * Transforms radians to degrees.\n * @param {TRadian} radians value in radians\n * @return {TDegree} value in degrees\n */\nexport const radiansToDegrees = (radians: TRadian): TDegree =>\n (radians / PiBy180) as TDegree;\n","import { iMatrix } from '../../constants';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TDegree, TRadian, TMat2D } from '../../typedefs';\nimport { cos } from './cos';\nimport { degreesToRadians, radiansToDegrees } from './radiansDegreesConversion';\nimport { sin } from './sin';\n\nexport type TRotateMatrixArgs = {\n angle?: TDegree;\n};\n\nexport type TTranslateMatrixArgs = {\n translateX?: number;\n translateY?: number;\n};\n\nexport type TScaleMatrixArgs = {\n scaleX?: number;\n scaleY?: number;\n flipX?: boolean;\n flipY?: boolean;\n skewX?: TDegree;\n skewY?: TDegree;\n};\n\nexport type TComposeMatrixArgs = TTranslateMatrixArgs &\n TRotateMatrixArgs &\n TScaleMatrixArgs;\n\nexport type TQrDecomposeOut = Required<\n Omit\n>;\n\nexport const isIdentityMatrix = (mat: TMat2D) =>\n mat.every((value, index) => value === iMatrix[index]);\n\n/**\n * Apply transform t to point p\n * @deprecated use {@link Point#transform}\n * @param {Point | XY} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\nexport const transformPoint = (\n p: XY,\n t: TMat2D,\n ignoreOffset?: boolean,\n): Point => new Point(p).transform(t, ignoreOffset);\n\n/**\n * Invert transformation t\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\nexport const invertTransform = (t: TMat2D): TMat2D => {\n const a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0] as TMat2D,\n { x, y } = new Point(t[4], t[5]).transform(r, true);\n r[4] = -x;\n r[5] = -y;\n return r;\n};\n\n/**\n * Multiply matrix A by matrix B to nest transformations\n * @param {TMat2D} a First transformMatrix\n * @param {TMat2D} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {TMat2D} The product of the two transform matrices\n */\nexport const multiplyTransformMatrices = (\n a: TMat2D,\n b: TMat2D,\n is2x2?: boolean,\n): TMat2D =>\n [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5],\n ] as TMat2D;\n\n/**\n * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it\n *\n * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))`\n *\n * @param matrices an array of matrices\n * @param [is2x2] flag to multiply matrices as 2x2 matrices\n * @returns the multiplication product\n */\nexport const multiplyTransformMatrixArray = (\n matrices: (TMat2D | undefined | null | false)[],\n is2x2?: boolean,\n) =>\n matrices.reduceRight(\n (product: TMat2D, curr) =>\n curr && product\n ? multiplyTransformMatrices(curr, product, is2x2)\n : curr || product,\n undefined as unknown as TMat2D,\n ) || iMatrix.concat();\n\nexport const calcPlaneRotation = ([a, b]: TMat2D) =>\n Math.atan2(b, a) as TRadian;\n\n/**\n * Decomposes standard 2x3 matrix into transform components\n * @param {TMat2D} a transformMatrix\n * @return {Object} Components of transform\n */\nexport const qrDecompose = (a: TMat2D): TQrDecomposeOut => {\n const angle = calcPlaneRotation(a),\n denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),\n scaleX = Math.sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);\n return {\n angle: radiansToDegrees(angle),\n scaleX,\n scaleY,\n skewX: radiansToDegrees(skewX),\n skewY: 0 as TDegree,\n translateX: a[4] || 0,\n translateY: a[5] || 0,\n };\n};\n\n/**\n * Generate a translation matrix\n *\n * A translation matrix in the form of\n * [ 1 0 x ]\n * [ 0 1 y ]\n * [ 0 0 1 ]\n *\n * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details\n *\n * @param {number} x translation on X axis\n * @param {number} [y] translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createTranslateMatrix = (x: number, y = 0): TMat2D => [\n 1,\n 0,\n 0,\n 1,\n x,\n y,\n];\n\n/**\n * Generate a rotation matrix around around a point (x,y), defaulting to (0,0)\n *\n * A matrix in the form of\n * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x]\n * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y]\n * [0 0 1 ]\n *\n *\n * @param {TDegree} angle rotation in degrees\n * @param {XY} [pivotPoint] pivot point to rotate around\n * @returns {TMat2D} matrix\n */\nexport function createRotateMatrix(\n { angle = 0 }: TRotateMatrixArgs = {},\n { x = 0, y = 0 }: Partial = {},\n): TMat2D {\n const angleRadiant = degreesToRadians(angle),\n cosValue = cos(angleRadiant),\n sinValue = sin(angleRadiant);\n return [\n cosValue,\n sinValue,\n -sinValue,\n cosValue,\n x ? x - (cosValue * x - sinValue * y) : 0,\n y ? y - (sinValue * x + cosValue * y) : 0,\n ];\n}\n\n/**\n * Generate a scale matrix around the point (0,0)\n *\n * A matrix in the form of\n * [x 0 0]\n * [0 y 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale\n *\n * @param {number} x scale on X axis\n * @param {number} [y] scale on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createScaleMatrix = (x: number, y: number = x): TMat2D => [\n x,\n 0,\n 0,\n y,\n 0,\n 0,\n];\n\nexport const angleToSkew = (angle: TDegree) =>\n Math.tan(degreesToRadians(angle));\n\nexport const skewToAngle = (value: TRadian) =>\n radiansToDegrees(Math.atan(value));\n\n/**\n * Generate a skew matrix for the X axis\n *\n * A matrix in the form of\n * [1 x 0]\n * [0 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx\n *\n * @param {TDegree} skewValue translation on X axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewXMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n 0,\n angleToSkew(skewValue),\n 1,\n 0,\n 0,\n];\n\n/**\n * Generate a skew matrix for the Y axis\n *\n * A matrix in the form of\n * [1 0 0]\n * [y 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy\n *\n * @param {TDegree} skewValue translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewYMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n angleToSkew(skewValue),\n 0,\n 1,\n 0,\n 0,\n];\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @return {Number[]} transform matrix\n */\nexport const calcDimensionsMatrix = ({\n scaleX = 1,\n scaleY = 1,\n flipX = false,\n flipY = false,\n skewX = 0 as TDegree,\n skewY = 0 as TDegree,\n}: TScaleMatrixArgs) => {\n let matrix = createScaleMatrix(\n flipX ? -scaleX : scaleX,\n flipY ? -scaleY : scaleY,\n );\n if (skewX) {\n matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true);\n }\n if (skewY) {\n matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true);\n }\n return matrix;\n};\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\nexport const composeMatrix = (options: TComposeMatrixArgs): TMat2D => {\n const { translateX = 0, translateY = 0, angle = 0 as TDegree } = options;\n let matrix = createTranslateMatrix(translateX, translateY);\n if (angle) {\n matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ angle }));\n }\n const scaleMatrix = calcDimensionsMatrix(options);\n if (!isIdentityMatrix(scaleMatrix)) {\n matrix = multiplyTransformMatrices(matrix, scaleMatrix);\n }\n return matrix;\n};\n","import { noop } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {},\n) =>\n new Promise(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n >(\n serializedObj: Record,\n instance: T,\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor & {\n fromObject(options: any, context: Abortable): Promise;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n }),\n ),\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record,\n>(\n serializedObject: any,\n { signal }: Abortable = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n /**\n * clipPath or shadow or gradient or text on a path or a pattern,\n * or the backgroundImage or overlayImage of canvas\n * If we have a type and there is a classe registered for it, we enlive it.\n * If there is no class registered for it we return the value as is\n * */\n if (value.type && classRegistry.has(value.type)) {\n return enlivenObjects([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n","/**\n * Populates an object with properties of another object\n * @param {Object} source Source object\n * @param {string[]} properties Properties names to include\n * @returns object populated with the picked keys\n */\nexport const pick = >(\n source: T,\n keys: (keyof T)[] = [],\n) => {\n return keys.reduce((o, key) => {\n if (key in source) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n\nexport const pickBy = >(\n source: T,\n predicate: (value: T[K], key: K, collection: T) => boolean,\n) => {\n return (Object.keys(source) as (keyof T)[]).reduce((o, key) => {\n if (predicate(source[key], key, source)) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n","/**\n * Map of the 148 color names with HEX code\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\nexport const ColorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#0FF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000',\n blanchedalmond: '#FFEBCD',\n blue: '#00F',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#0FF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#F0F',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#789',\n lightslategrey: '#789',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#0F0',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#F0F',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#639',\n red: '#F00',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FF0',\n yellowgreen: '#9ACD32',\n};\n","/**\n * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`)\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb\n * Formal syntax at the time of writing:\n * =\n * rgb( [ | none ]{3} [ / [ | none ] ]? ) |\n * rgb( [ | none ]{3} [ / [ | none ] ]? )\n * = | \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an rgba or rgb CSS color value\n *\n * /^ # Beginning of the string\n * rgba? # \"rgb\" or \"rgba\"\n * \\(\\s* # Opening parenthesis and optional whitespace\n * (\\d{0,3} # 0 to three digits R channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the first color component\n * %? # Optional percent sign after the first color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits G channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the second color component\n * %? # Optional percent sign after the second color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits B channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the third color component\n * %? # Optional percent sign after the third color component\n * \\s* # Optional whitespace\n * (?: # Beginning of non-capturing group for alpha value\n * \\s* # Optional whitespace\n * [,/] # Comma or slash separator for alpha value\n * \\s* # Optional whitespace\n * (\\d{0,3} # Zero to three digits\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for alpha value\n * %? # Optional percent sign after alpha value\n * \\s* # Optional whitespace\n * )? # End of non-capturing group for alpha value (optional)\n * \\) # Closing parenthesis\n * $ # End of the string\n *\n * The alpha channel can be in the format 0.4 .7 or 1 or 73%\n *\n * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color.\n * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us\n */\nexport const reRGBa = () =>\n /^rgba?\\(\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl\n * Formal syntax at the time of writing:\n * =\n * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? )\n *\n * =\n * |\n * \n *\n * =\n * |\n * \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an hsla or hsl CSS color value\n *\n * /^hsla?\\( // Matches the beginning of the string and the opening parenthesis of \"hsl\" or \"hsla\"\n * \\s* // Matches any whitespace characters (space, tab, etc.) zero or more times\n * (\\d{0,3} // Hue: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Hue: Optional (non capture group) decimal with one or more digits.\n * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad\n * ) // Hue: End capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Saturation: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group\n * %?) // Saturation: match optional % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Lightness: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group\n * %?) // Lightness: match % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * (?: // Alpha: Begins a non-capturing group for the alpha value\n * \\s* // Matches any whitespace characters zero or more times\n * [,/] // Matches a comma or forward slash\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d*(?:\\.\\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group\n * \\s* // Matches any whitespace characters zero or more times\n * )? // Makes the alpha value group optional\n * \\) // Matches the closing parenthesis\n * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode\n *\n * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color.\n * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us.\n */\nexport const reHSLa = () =>\n /^hsla?\\(\\s*([+-]?\\d{0,3}(?:\\.\\d+)?(?:deg|turn|rad)?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d*(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n */\nexport const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i;\n","import type { TRGBAColorSource } from './typedefs';\n\n/**\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\nexport const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n};\n\n/**\n * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson}\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @param {Number} a Alpha color value pass through\n * @return {TRGBColorSource} Hsl color\n */\nexport const rgb2Hsl = (\n r: number,\n g: number,\n b: number,\n a: number,\n): TRGBAColorSource => {\n r /= 255;\n g /= 255;\n b /= 255;\n const maxValue = Math.max(r, g, b),\n minValue = Math.min(r, g, b);\n\n let h!: number, s: number;\n const l = (maxValue + minValue) / 2;\n\n if (maxValue === minValue) {\n h = s = 0; // achromatic\n } else {\n const d = maxValue - minValue;\n s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue);\n switch (maxValue) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a];\n};\n\nexport const fromAlphaToFloat = (value = '1') =>\n parseFloat(value) / (value.endsWith('%') ? 100 : 1);\n\n/**\n * Convert a value in the inclusive range [0, 255] to hex\n */\nexport const hexify = (value: number) =>\n Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0');\n\n/**\n * Calculate the grey average value for rgb and pass through alpha\n */\nexport const greyAverage = ([\n r,\n g,\n b,\n a = 1,\n]: TRGBAColorSource): TRGBAColorSource => {\n const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11);\n return [avg, avg, avg, a];\n};\n","import { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { ColorNameMap } from './color_map';\nimport { reHSLa, reHex, reRGBa } from './constants';\nimport type { TRGBAColorSource, TColorArg } from './typedefs';\nimport {\n hue2rgb,\n hexify,\n rgb2Hsl,\n fromAlphaToFloat,\n greyAverage,\n} from './util';\n\n/**\n * @class Color common color operations\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors}\n */\nexport class Color {\n private declare _source: TRGBAColorSource;\n isUnrecognised = false;\n\n /**\n *\n * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list\n */\n constructor(color?: TColorArg) {\n if (!color) {\n // we default to black as canvas does\n this.setSource([0, 0, 0, 1]);\n } else if (color instanceof Color) {\n this.setSource([...color._source]);\n } else if (Array.isArray(color)) {\n const [r, g, b, a = 1] = color;\n this.setSource([r, g, b, a]);\n } else {\n this.setSource(this._tryParsingColor(color));\n }\n }\n\n /**\n * @private\n * @param {string} [color] Color value to parse\n * @returns {TRGBAColorSource}\n */\n protected _tryParsingColor(color: string) {\n if (color in ColorNameMap) {\n color = ColorNameMap[color as keyof typeof ColorNameMap];\n }\n return color === 'transparent'\n ? ([255, 255, 255, 0] as TRGBAColorSource)\n : Color.sourceFromHex(color) ||\n Color.sourceFromRgb(color) ||\n Color.sourceFromHsl(color) ||\n // color is not recognized\n // we default to black as canvas does\n // eslint-disable-next-line no-constant-binary-expression\n ((this.isUnrecognised = true) && ([0, 0, 0, 1] as TRGBAColorSource));\n }\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {TRGBAColorSource}\n */\n getSource() {\n return this._source;\n }\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {TRGBAColorSource} source\n */\n setSource(source: TRGBAColorSource) {\n this._source = source;\n }\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb() {\n const [r, g, b] = this.getSource();\n return `rgb(${r},${g},${b})`;\n }\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba() {\n return `rgba(${this.getSource().join(',')})`;\n }\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl() {\n const [h, s, l] = rgb2Hsl(...this.getSource());\n return `hsl(${h},${s}%,${l}%)`;\n }\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla() {\n const [h, s, l, a] = rgb2Hsl(...this.getSource());\n return `hsla(${h},${s}%,${l}%,${a})`;\n }\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex() {\n const fullHex = this.toHexa();\n return fullHex.slice(0, 6);\n }\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa() {\n const [r, g, b, a] = this.getSource();\n return `${hexify(r)}${hexify(g)}${hexify(b)}${hexify(Math.round(a * 255))}`;\n }\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha() {\n return this.getSource()[3];\n }\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {Color} thisArg\n */\n setAlpha(alpha: number) {\n this._source[3] = alpha;\n return this;\n }\n\n /**\n * Transforms color to its grayscale representation\n * @return {Color} thisArg\n */\n toGrayscale() {\n this.setSource(greyAverage(this.getSource()));\n return this;\n }\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {Color} thisArg\n */\n toBlackWhite(threshold: number) {\n const [average, , , a] = greyAverage(this.getSource()),\n bOrW = average < (threshold || 127) ? 0 : 255;\n this.setSource([bOrW, bOrW, bOrW, a]);\n return this;\n }\n\n /**\n * Overlays color with another color\n * @param {String|Color} otherColor\n * @return {Color} thisArg\n */\n overlayWith(otherColor: string | Color) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n const source = this.getSource(),\n otherAlpha = 0.5,\n otherSource = otherColor.getSource(),\n [R, G, B] = source.map((value, index) =>\n Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha),\n );\n\n this.setSource([R, G, B, source[3]]);\n return this;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {Color}\n */\n static fromRgb(color: string): Color {\n return Color.fromRgba(color);\n }\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromRgba(color: string): Color {\n return new Color(Color.sourceFromRgb(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromRgb(color: string): TRGBAColorSource | undefined {\n const match = color.match(reRGBa());\n if (match) {\n const [r, g, b] = match.slice(1, 4).map((value) => {\n const parsedValue = parseFloat(value);\n return value.endsWith('%')\n ? Math.round(parsedValue * 2.55)\n : parsedValue;\n });\n return [r, g, b, fromAlphaToFloat(match[4])];\n }\n }\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf Color\n * @return {Color}\n */\n static fromHsl(color: string): Color {\n return Color.fromHsla(color);\n }\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromHsla(color: string): Color {\n return new Color(Color.sourceFromHsl(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {TRGBAColorSource | undefined} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n static sourceFromHsl(color: string): TRGBAColorSource | undefined {\n const match = color.match(reHSLa());\n if (!match) {\n return;\n }\n const match1degrees = Color.parseAngletoDegrees(match[1]);\n\n const h = (((match1degrees % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / 100,\n l = parseFloat(match[3]) / 100;\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n fromAlphaToFloat(match[4]),\n ];\n }\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf Color\n * @param {String} color Color value ex: FF5555\n * @return {Color}\n */\n static fromHex(color: string): Color {\n return new Color(Color.sourceFromHex(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromHex(color: string): TRGBAColorSource | undefined {\n if (color.match(reHex())) {\n const value = color.slice(color.indexOf('#') + 1),\n isShortNotation = value.length <= 4;\n let expandedValue: string[];\n if (isShortNotation) {\n expandedValue = value.split('').map((hex) => hex + hex);\n } else {\n expandedValue = value.match(/.{2}/g)!;\n }\n const [r, g, b, a = 255] = expandedValue.map((hexCouple) =>\n parseInt(hexCouple, 16),\n );\n return [r, g, b, a / 255];\n }\n }\n\n /**\n * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad)\n * into degrees without the 'deg' suffix\n * @static\n * @memberOf Color\n * @param {String} value ex: 0deg, 0.5turn, 2rad\n * @return {Number} number in degrees or NaN if inputs are invalid\n */\n static parseAngletoDegrees(value: string): number {\n const lowercase = value.toLowerCase();\n const numeric = parseFloat(lowercase);\n\n if (lowercase.includes('rad')) {\n return radiansToDegrees(numeric);\n }\n\n if (lowercase.includes('turn')) {\n return numeric * 360;\n }\n\n // Value is probably just a number already in degrees eg '50'\n return numeric;\n }\n}\n","/**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @param {number|string} number number to operate on\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {number}\n */\nexport const toFixed = (number: number | string, fractionDigits: number) =>\n parseFloat(Number(number).toFixed(fractionDigits));\n","import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return ``;\n};\n","import type { FabricObject } from '../shapes/Object/Object';\nimport type { TFiller } from '../typedefs';\nimport type { FabricText } from '../shapes/Text/Text';\nimport type { Pattern } from '../Pattern';\nimport type { Path } from '../shapes/Path';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\n\nexport const isFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && (filler as TFiller).toLive !== undefined;\n};\n\nexport const isSerializableFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && typeof (filler as TFiller).toObject === 'function';\n};\n\nexport const isPattern = (filler: TFiller): filler is Pattern => {\n return (\n !!filler && (filler as Pattern).offsetX !== undefined && 'source' in filler\n );\n};\n\nexport const isTextObject = (\n fabricObject?: FabricObject,\n): fabricObject is FabricText => {\n return (\n !!fabricObject &&\n typeof (fabricObject as FabricText)._renderText === 'function'\n );\n};\n\nexport const isPath = (fabricObject?: FabricObject): fabricObject is Path => {\n // we could use instanceof but that would mean pulling in Text code for a simple check\n // @todo discuss what to do and how to do\n return (\n !!fabricObject &&\n typeof (fabricObject as Path)._renderPathCommands === 'function'\n );\n};\n\nexport const isActiveSelection = (\n fabricObject?: FabricObject,\n): fabricObject is ActiveSelection =>\n !!fabricObject && 'multiSelectionStacking' in fabricObject;\n","/**\n * Returns element scroll offsets\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\nexport function getScrollLeftTop(element: HTMLElement | null) {\n const doc = element && getDocumentFromElement(element);\n let left = 0,\n top = 0;\n if (!element || !doc) {\n return { left, top };\n }\n let elementLoop: HTMLElement | Document | ShadowRoot = element;\n const docElement = doc.documentElement,\n body = doc.body || {\n scrollLeft: 0,\n scrollTop: 0,\n };\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (\n elementLoop &&\n (elementLoop.parentNode || (elementLoop as unknown as ShadowRoot).host)\n ) {\n elementLoop = (elementLoop.parentNode ||\n (elementLoop as unknown as ShadowRoot).host) as\n | HTMLElement\n | Document\n | ShadowRoot;\n if (elementLoop === doc) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n } else {\n left += (elementLoop as HTMLElement).scrollLeft || 0;\n top += (elementLoop as HTMLElement).scrollTop || 0;\n }\n\n if (\n elementLoop.nodeType === 1 &&\n (elementLoop as HTMLElement).style.position === 'fixed'\n ) {\n break;\n }\n }\n\n return { left, top };\n}\n\nexport const getDocumentFromElement = (el: HTMLElement) =>\n el.ownerDocument || null;\n\nexport const getWindowFromElement = (el: HTMLElement) =>\n el.ownerDocument?.defaultView || null;\n","import { NONE } from '../../constants';\nimport type { TSize } from '../../typedefs';\nimport {\n getDocumentFromElement,\n getWindowFromElement,\n getScrollLeftTop,\n} from '../../util/dom_misc';\n\nexport const setCanvasDimensions = (\n el: HTMLCanvasElement,\n ctx: CanvasRenderingContext2D,\n { width, height }: TSize,\n retinaScaling = 1,\n) => {\n el.width = width;\n el.height = height;\n if (retinaScaling > 1) {\n el.setAttribute('width', (width * retinaScaling).toString());\n el.setAttribute('height', (height * retinaScaling).toString());\n ctx.scale(retinaScaling, retinaScaling);\n }\n};\n\nexport type CSSDimensions = {\n width: number | string;\n height: number | string;\n};\n\nexport const setCSSDimensions = (\n el: HTMLElement,\n { width, height }: Partial,\n) => {\n width && (el.style.width = typeof width === 'number' ? `${width}px` : width);\n height &&\n (el.style.height = typeof height === 'number' ? `${height}px` : height);\n};\n\n/**\n * Returns offset for a given element\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\nexport function getElementOffset(element: HTMLElement) {\n const doc = element && getDocumentFromElement(element),\n offset = { left: 0, top: 0 };\n\n if (!doc) {\n return offset;\n }\n const elemStyle: CSSStyleDeclaration =\n getWindowFromElement(element)?.getComputedStyle(element, null) ||\n ({} as CSSStyleDeclaration);\n offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;\n offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;\n offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;\n offset.top += parseInt(elemStyle.paddingTop, 10) || 0;\n\n let box = { left: 0, top: 0 };\n\n const docElem = doc.documentElement;\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n const scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left:\n box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top,\n };\n}\n\n/**\n * Makes element unselectable\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\nexport function makeElementUnselectable(element: HTMLElement) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = () => false;\n }\n element.style.userSelect = NONE;\n return element;\n}\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport type { CSSDimensions } from './util';\nimport { setCSSDimensions, getElementOffset } from './util';\nimport { createCanvasElement, isHTMLCanvas } from '../../util/misc/dom';\nimport { setCanvasDimensions } from './util';\nimport { FabricError } from '../../util/internals/console';\n\nexport type CanvasItem = {\n el: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n};\n\nexport class StaticCanvasDOMManager {\n /**\n * Keeps a copy of the canvas style before setting retina scaling and other potions\n * in order to return it to original state on dispose\n * @type string\n */\n private _originalCanvasStyle?: string;\n\n lower: CanvasItem;\n\n constructor(arg0?: string | HTMLCanvasElement) {\n const el = this.createLowerCanvas(arg0);\n this.lower = { el, ctx: el.getContext('2d')! };\n }\n\n protected createLowerCanvas(arg0?: HTMLCanvasElement | string) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n const el = isHTMLCanvas(arg0)\n ? arg0\n : (arg0 &&\n (getFabricDocument().getElementById(arg0) as HTMLCanvasElement)) ||\n createCanvasElement();\n if (el.hasAttribute('data-fabric')) {\n throw new FabricError(\n 'Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?',\n );\n }\n this._originalCanvasStyle = el.style.cssText;\n el.setAttribute('data-fabric', 'main');\n el.classList.add('lower-canvas');\n return el;\n }\n\n cleanupDOM({ width, height }: TSize) {\n const { el } = this.lower;\n // restore canvas style and attributes\n el.classList.remove('lower-canvas');\n el.removeAttribute('data-fabric');\n // restore canvas size to original size in case retina scaling was applied\n el.setAttribute('width', `${width}`);\n el.setAttribute('height', `${height}`);\n el.style.cssText = this._originalCanvasStyle || '';\n this._originalCanvasStyle = undefined;\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n const { el, ctx } = this.lower;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial) {\n setCSSDimensions(this.lower.el, size);\n }\n\n /**\n * Calculates canvas element offset relative to the document\n */\n calcOffset() {\n return getElementOffset(this.lower.el);\n }\n\n dispose() {\n getEnv().dispose(this.lower.el);\n // @ts-expect-error disposing\n delete this.lower;\n }\n}\n","import { iMatrix } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TFiller, TMat2D, TOptions } from '../typedefs';\n\ninterface CanvasDrawableOptions {\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n backgroundVpt: boolean;\n\n /**\n * Background color of canvas instance.\n * @type {(String|TFiller)}\n * @default\n */\n backgroundColor: TFiller | string;\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n backgroundImage?: FabricObject;\n\n /**\n * if set to false overlay image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n overlayVpt: boolean;\n\n /**\n * Overlay color of canvas instance.\n * @since 1.3.9\n * @type {(String|TFiller)}\n * @default\n */\n overlayColor: TFiller | string;\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n overlayImage?: FabricObject;\n}\n\ninterface CanvasRenderingOptions {\n /**\n * Indicates whether {@link StaticCanvas#add}, {@link StaticCanvas#insertAt} and {@link StaticCanvas#remove},\n * {@link StaticCanvas#moveTo}, {@link StaticCanvas#clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are queued and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: boolean;\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @type Boolean\n * @default true\n */\n skipOffscreen: boolean;\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: boolean;\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: boolean;\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type FabricObject\n */\n clipPath?: FabricObject;\n}\n\nexport interface CanvasExportOptions {\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: boolean;\n\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: boolean;\n}\n\nexport interface StaticCanvasOptions\n extends CanvasDrawableOptions,\n CanvasRenderingOptions,\n CanvasExportOptions {\n /**\n * Width in virtual/logical pixels of the canvas.\n * The canvas can be larger than width if retina scaling is active\n * @type number\n */\n width: number;\n\n /**\n * Height in virtual/logical pixels of the canvas.\n * The canvas can be taller than width if retina scaling is active\n * @type height\n */\n height: number;\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n controlsAboveOverlay: boolean;\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n allowTouchScrolling: boolean;\n\n /**\n * The transformation (a Canvas 2D API transform matrix) which focuses the viewport\n * @type Array\n * @example Default transform\n * canvas.viewportTransform = [1, 0, 0, 1, 0, 0];\n * @example Scale by 70% and translate toward bottom-right by 50, without skewing\n * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];\n * @default\n */\n viewportTransform: TMat2D;\n}\n\nexport const staticCanvasDefaults: TOptions = {\n backgroundVpt: true,\n backgroundColor: '',\n overlayVpt: true,\n overlayColor: '',\n\n includeDefaultValues: true,\n svgViewportTransformation: true,\n\n renderOnAddRemove: true,\n skipOffscreen: true,\n enableRetinaScaling: true,\n imageSmoothingEnabled: true,\n\n /**\n * @todo move to Canvas\n */\n controlsAboveOverlay: false,\n /**\n * @todo move to Canvas\n */\n allowTouchScrolling: false,\n\n viewportTransform: [...iMatrix],\n};\n","import { config } from '../config';\nimport { CENTER, VERSION } from '../constants';\nimport type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs';\nimport type { Gradient } from '../gradient/Gradient';\nimport { createCollectionMixin, isCollection } from '../Collection';\nimport { CommonMethods } from '../CommonMethods';\nimport type { Pattern } from '../Pattern';\nimport { Point } from '../Point';\nimport type { TCachedFabricObject } from '../shapes/Object/Object';\nimport type {\n Abortable,\n Constructor,\n TCornerPoint,\n TDataUrlOptions,\n TFiller,\n TMat2D,\n TSize,\n TSVGReviver,\n TToCanvasElementOptions,\n TValidToObjectMethod,\n TOptions,\n} from '../typedefs';\nimport {\n cancelAnimFrame,\n requestAnimFrame,\n} from '../util/animation/AnimationFrameProvider';\nimport { runningAnimations } from '../util/animation/AnimationRegistry';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement, toDataURL } from '../util/misc/dom';\nimport { invertTransform, transformPoint } from '../util/misc/matrix';\nimport type { EnlivenObjectOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { toFixed } from '../util/misc/toFixed';\nimport { isFiller, isPattern, isTextObject } from '../util/typeAssertions';\nimport { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager';\nimport type { CSSDimensions } from './DOMManagers/util';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\nimport { staticCanvasDefaults } from './StaticCanvasOptions';\nimport { log, FabricError } from '../util/internals/console';\nimport { getDevicePixelRatio } from '../env';\n\n/**\n * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset\n * Better try to restrict with types to avoid confusion.\n */\nexport type TCanvasSizeOptions =\n | {\n backstoreOnly?: true;\n cssOnly?: false;\n }\n | {\n backstoreOnly?: false;\n cssOnly?: true;\n };\n\nexport type TSVGExportOptions = {\n suppressPreamble?: boolean;\n viewBox?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n encoding?: 'UTF-8'; // test Encoding type and see what happens\n width?: string;\n height?: string;\n reviver?: TSVGReviver;\n};\n\n/**\n * Static canvas class\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260\nexport class StaticCanvas<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends StaticCanvasEvents = StaticCanvasEvents,\n >\n extends createCollectionMixin(CommonMethods)\n implements StaticCanvasOptions\n{\n declare width: number;\n declare height: number;\n\n // background\n declare backgroundVpt: boolean;\n declare backgroundColor: TFiller | string;\n declare backgroundImage?: FabricObject;\n // overlay\n declare overlayVpt: boolean;\n declare overlayColor: TFiller | string;\n declare overlayImage?: FabricObject;\n\n declare clipPath?: FabricObject;\n\n declare includeDefaultValues: boolean;\n\n // rendering config\n declare renderOnAddRemove: boolean;\n declare skipOffscreen: boolean;\n declare enableRetinaScaling: boolean;\n declare imageSmoothingEnabled: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare controlsAboveOverlay: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare allowTouchScrolling: boolean;\n\n declare viewportTransform: TMat2D;\n\n /**\n * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries}\n */\n declare vptCoords: TCornerPoint;\n\n /**\n * A reference to the canvas actual HTMLCanvasElement.\n * Can be use to read the raw pixels, but never write or manipulate\n * @type HTMLCanvasElement\n */\n get lowerCanvasEl() {\n return this.elements.lower?.el;\n }\n\n get contextContainer() {\n return this.elements.lower?.ctx;\n }\n\n /**\n * If true the Canvas is in the process or has been disposed/destroyed.\n * No more rendering operation will be executed on this canvas.\n * @type boolean\n */\n declare destroyed?: boolean;\n\n /**\n * Started the process of disposing but not done yet.\n * WIll likely complete the render cycle already scheduled but stopping adding more.\n * @type boolean\n */\n declare disposed?: boolean;\n\n declare _offset: { left: number; top: number };\n protected declare hasLostContext: boolean;\n protected declare nextRenderHandle: number;\n\n declare elements: StaticCanvasDOMManager;\n\n /**\n * When true control drawing is skipped.\n * This boolean is used to avoid toDataURL to export controls.\n * Usage of this boolean to build up other flows and features is not supported\n * @type Boolean\n * @default false\n */\n protected declare skipControlsDrawing: boolean;\n\n static ownDefaults = staticCanvasDefaults;\n\n // reference to\n protected declare __cleanupTask?: {\n (): void;\n kill: (reason?: any) => void;\n };\n\n static getDefaults(): Record {\n return StaticCanvas.ownDefaults;\n }\n\n constructor(\n el?: string | HTMLCanvasElement,\n options: TOptions = {},\n ) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof StaticCanvas).getDefaults(),\n );\n this.set(options);\n this.initElements(el);\n this._setDimensionsImpl({\n width: this.width || this.elements.lower.el.width || 0,\n height: this.height || this.elements.lower.el.height || 0,\n });\n this.skipControlsDrawing = false;\n this.viewportTransform = [...this.viewportTransform];\n this.calcViewportBoundaries();\n }\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new StaticCanvasDOMManager(el);\n }\n\n add(...objects: FabricObject[]) {\n const size = super.add(...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n insertAt(index: number, ...objects: FabricObject[]) {\n const size = super.insertAt(index, ...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return removed;\n }\n\n _onObjectAdded(obj: FabricObject) {\n if (obj.canvas && (obj.canvas as StaticCanvas) !== this) {\n log(\n 'warn',\n 'Canvas is trying to add an object that belongs to a different canvas.\\n' +\n 'Resulting to default behavior: removing object from previous canvas and adding to new canvas',\n );\n obj.canvas.remove(obj);\n }\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added', { target: this });\n }\n\n _onObjectRemoved(obj: FabricObject) {\n obj._set('canvas', undefined);\n this.fire('object:removed', { target: obj });\n obj.fire('removed', { target: this });\n }\n\n _onStackOrderChanged() {\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * @private\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling() {\n return this.enableRetinaScaling ? getDevicePixelRatio() : 1;\n }\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n */\n calcOffset() {\n return (this._offset = this.elements.calcOffset());\n }\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth(): number {\n return this.width;\n }\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight(): number {\n return this.height;\n }\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setWidth(\n value: TSize['width'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setWidth(\n value: CSSDimensions['width'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setWidth(value: number, options?: never) {\n return this.setDimensions({ width: value }, options);\n }\n\n /**s\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setHeight(\n value: TSize['height'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setHeight(\n value: CSSDimensions['height'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setHeight(value: CSSDimensions['height'], options?: never) {\n return this.setDimensions({ height: value }, options);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: Partial,\n { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {},\n ) {\n if (!cssOnly) {\n const size = {\n width: this.width,\n height: this.height,\n ...(dimensions as Partial),\n };\n this.elements.setDimensions(size, this.getRetinaScaling());\n this.hasLostContext = true;\n this.width = size.width;\n this.height = size.height;\n }\n if (!backstoreOnly) {\n this.elements.setCSSDimensions(dimensions);\n }\n\n this.calcOffset();\n }\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n */\n setDimensions(\n dimensions: Partial,\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setDimensions(\n dimensions: Partial,\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setDimensions(dimensions: Partial, options?: never): void;\n setDimensions(\n dimensions: Partial,\n options?: TCanvasSizeOptions,\n ) {\n this._setDimensionsImpl(dimensions, options);\n if (!options || !options.cssOnly) {\n this.requestRenderAll();\n }\n }\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom() {\n return this.viewportTransform[0];\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n this.viewportTransform = vpt;\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Sets zoom level of this canvas instance, the zoom centered around point\n * meaning that following zoom to point with the same point will have the visual\n * effect of the zoom originating from that point. The point won't move.\n * It has nothing to do with canvas center or visual center of the viewport.\n * @param {Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n zoomToPoint(point: Point, value: number) {\n // TODO: just change the scale, preserve other transformations\n const before = point,\n vpt: TMat2D = [...this.viewportTransform];\n const newPoint = transformPoint(point, invertTransform(vpt));\n vpt[0] = value;\n vpt[3] = value;\n const after = transformPoint(newPoint, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n this.setViewportTransform(vpt);\n }\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n setZoom(value: number) {\n this.zoomToPoint(new Point(0, 0), value);\n }\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {Point} point to move to\n */\n absolutePan(point: Point) {\n const vpt: TMat2D = [...this.viewportTransform];\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n }\n\n /**\n * Pans viewpoint relatively\n * @param {Point} point (position vector) to move by\n */\n relativePan(point: Point) {\n return this.absolutePan(\n new Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5],\n ),\n );\n }\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement(): HTMLCanvasElement {\n return this.elements.lower.el;\n }\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n */\n clearContext(ctx: CanvasRenderingContext2D) {\n ctx.clearRect(0, 0, this.width, this.height);\n }\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext(): CanvasRenderingContext2D {\n return this.elements.lower.ctx;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n this.remove(...this.getObjects());\n this.backgroundImage = undefined;\n this.overlayImage = undefined;\n this.backgroundColor = '';\n this.overlayColor = '';\n this.clearContext(this.getContext());\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Renders the canvas\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n this.renderCanvas(this.getContext(), this._objects);\n }\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n */\n renderAndReset() {\n this.nextRenderHandle = 0;\n this.renderAll();\n }\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n */\n requestRenderAll() {\n if (!this.nextRenderHandle && !this.disposed && !this.destroyed) {\n this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset());\n }\n }\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport\n */\n calcViewportBoundaries(): TCornerPoint {\n const width = this.width,\n height = this.height,\n iVpt = invertTransform(this.viewportTransform),\n a = transformPoint({ x: 0, y: 0 }, iVpt),\n b = transformPoint({ x: width, y: height }, iVpt),\n // we don't support vpt flipping\n // but the code is robust enough to mostly work with flipping\n min = a.min(b),\n max = a.max(b);\n return (this.vptCoords = {\n tl: min,\n tr: new Point(max.x, min.y),\n bl: new Point(min.x, max.y),\n br: max,\n });\n }\n\n cancelRequestedRender() {\n if (this.nextRenderHandle) {\n cancelAnimFrame(this.nextRenderHandle);\n this.nextRenderHandle = 0;\n }\n }\n\n drawControls(_ctx: CanvasRenderingContext2D) {\n // Static canvas has no controls\n }\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n */\n renderCanvas(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n if (this.destroyed) {\n return;\n }\n\n const v = this.viewportTransform,\n path = this.clipPath;\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n // @ts-expect-error node-canvas stuff\n ctx.patternQuality = 'best';\n this.fire('before:render', { ctx });\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n if (path) {\n path._set('canvas', this);\n // needed to setup a couple of variables\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCanvas(ctx, path as TCachedFabricObject);\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n this.fire('after:render', { ctx });\n\n if (this.__cleanupTask) {\n this.__cleanupTask();\n this.__cleanupTask = undefined;\n }\n }\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n const v = this.viewportTransform;\n ctx.save();\n ctx.transform(...v);\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n ctx.globalCompositeOperation = 'destination-in';\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n for (let i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay(\n ctx: CanvasRenderingContext2D,\n property: 'background' | 'overlay',\n ) {\n const fill = this[`${property}Color`],\n object = this[`${property}Image`],\n v = this.viewportTransform,\n needsVpt = this[`${property}Vpt`];\n if (!fill && !object) {\n return;\n }\n const isAFiller = isFiller(fill);\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */)! : fill;\n if (needsVpt) {\n ctx.transform(...v);\n }\n if (isAFiller) {\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n const m = ((fill as Gradient<'linear'>).gradientTransform ||\n (fill as Pattern).patternTransform) as TMat2D;\n m && ctx.transform(...m);\n }\n ctx.fill();\n ctx.restore();\n }\n if (object) {\n ctx.save();\n const { skipOffscreen } = this;\n // if the object doesn't move with the viewport,\n // the offscreen concept does not apply;\n this.skipOffscreen = needsVpt;\n if (needsVpt) {\n ctx.transform(...v);\n }\n object.render(ctx);\n this.skipOffscreen = skipOffscreen;\n ctx.restore();\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n * @deprecated migrate to `getCenterPoint`\n */\n getCenter() {\n return {\n top: this.height / 2,\n left: this.width / 2,\n };\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * @return {Point}\n */\n getCenterPoint() {\n return new Point(this.width / 2, this.height / 2);\n }\n\n /**\n * Centers object horizontally in the canvas\n */\n centerObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getCenterPoint().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically in the canvas\n * @param {FabricObject} object Object to center vertically\n */\n centerObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n centerObject(object: FabricObject) {\n return this._centerObject(object, this.getCenterPoint());\n }\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObject(object: FabricObject) {\n return this._centerObject(object, this.getVpCenter());\n }\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getVpCenter().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getVpCenter().y),\n );\n }\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {Point} vpCenter, viewport center\n */\n getVpCenter(): Point {\n return transformPoint(\n this.getCenterPoint(),\n invertTransform(this.viewportTransform),\n );\n }\n\n /**\n * @private\n * @param {FabricObject} object Object to center\n * @param {Point} center Center point\n */\n _centerObject(object: FabricObject, center: Point) {\n object.setXY(center, CENTER, CENTER);\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Returns dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON(propertiesToInclude?: string[]) {\n return this.toDatalessObject(propertiesToInclude);\n }\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n }\n\n /**\n * Returns Object representation of canvas\n * this alias is provided because if you call JSON.stringify on an instance,\n * the toJSON object will be invoked if it exists.\n * Having a toJSON method means you can do JSON.stringify(myCanvas)\n * @return {Object} JSON compatible object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example JSON without default values\n * var json = canvas.toJSON();\n */\n toJSON() {\n return this.toObject();\n }\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n }\n\n /**\n * @private\n */\n _toObjectMethod(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const clipPath = this.clipPath;\n const clipPathData =\n clipPath && !clipPath.excludeFromExport\n ? this._toObject(clipPath, methodName, propertiesToInclude)\n : null;\n return {\n version: VERSION,\n ...pick(this, propertiesToInclude as (keyof this)[]),\n objects: this._objects\n .filter((object) => !object.excludeFromExport)\n .map((instance) =>\n this._toObject(instance, methodName, propertiesToInclude),\n ),\n ...this.__serializeBgOverlay(methodName, propertiesToInclude),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n let originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n const object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = !!originalValue;\n }\n return object;\n }\n\n /**\n * @private\n */\n __serializeBgOverlay(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const data: any = {},\n bgImage = this.backgroundImage,\n overlayImage = this.overlayImage,\n bgColor = this.backgroundColor,\n overlayColor = this.overlayColor;\n\n if (isFiller(bgColor)) {\n if (!bgColor.excludeFromExport) {\n data.background = bgColor.toObject(propertiesToInclude);\n }\n } else if (bgColor) {\n data.background = bgColor;\n }\n\n if (isFiller(overlayColor)) {\n if (!overlayColor.excludeFromExport) {\n data.overlay = overlayColor.toObject(propertiesToInclude);\n }\n } else if (overlayColor) {\n data.overlay = overlayColor;\n }\n\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(\n bgImage,\n methodName,\n propertiesToInclude,\n );\n }\n if (overlayImage && !overlayImage.excludeFromExport) {\n data.overlayImage = this._toObject(\n overlayImage,\n methodName,\n propertiesToInclude,\n );\n }\n\n return data;\n }\n\n /* _TO_SVG_START_ */\n\n declare svgViewportTransformation: boolean;\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-coordinate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG(options: TSVGExportOptions = {}, reviver?: TSVGReviver) {\n options.reviver = reviver;\n const markup: string[] = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n if (this.clipPath) {\n markup.push(`\\n`);\n }\n this._setSVGBgOverlayColor(markup, 'background');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n this._setSVGObjects(markup, reviver);\n if (this.clipPath) {\n markup.push('\\n');\n }\n this._setSVGBgOverlayColor(markup, 'overlay');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n }\n\n /**\n * @private\n */\n _setSVGPreamble(markup: string[], options: TSVGExportOptions): void {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n',\n );\n }\n\n /**\n * @private\n */\n _setSVGHeader(markup: string[], options: TSVGExportOptions): void {\n const width = options.width || `${this.width}`,\n height = options.height || `${this.height}`,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,\n optViewBox = options.viewBox;\n let viewBox: string;\n if (optViewBox) {\n viewBox = `viewBox=\"${optViewBox.x} ${optViewBox.y} ${optViewBox.width} ${optViewBox.height}\" `;\n } else if (this.svgViewportTransformation) {\n const vpt = this.viewportTransform;\n viewBox = `viewBox=\"${toFixed(\n -vpt[4] / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS)} ${toFixed(\n this.width / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS)}\" `;\n } else {\n viewBox = `viewBox=\"0 0 ${this.width} ${this.height}\" `;\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ',\n VERSION,\n '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n this.createSVGClipPathMarkup(options),\n '\\n',\n );\n }\n\n createSVGClipPathMarkup(options: TSVGExportOptions): string {\n const clipPath = this.clipPath;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n return `\\n${clipPath.toClipPathSVG(\n options.reviver,\n )}\\n`;\n }\n return '';\n }\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup(): string {\n return (['background', 'overlay'] as const)\n .map((prop) => {\n const fill = this[`${prop}Color`];\n if (isFiller(fill)) {\n const shouldTransform = this[`${prop}Vpt`],\n vpt = this.viewportTransform,\n object = {\n // otherwise circular dependency\n isType: () => false,\n width: this.width / (shouldTransform ? vpt[0] : 1),\n height: this.height / (shouldTransform ? vpt[3] : 1),\n };\n return fill.toSVG(object as FabricObject, {\n additionalTransform: shouldTransform ? matrixToSVG(vpt) : '',\n });\n }\n })\n .join('');\n }\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup(): string {\n const objects: FabricObject[] = [],\n fontList: Record = {},\n fontPaths = config.fontPaths;\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n if (isCollection(object)) {\n object._objects.forEach(add);\n }\n });\n\n objects.forEach((obj) => {\n if (!isTextObject(obj)) {\n return;\n }\n const { styles, fontFamily } = obj;\n if (fontList[fontFamily] || !fontPaths[fontFamily]) {\n return;\n }\n fontList[fontFamily] = true;\n if (!styles) {\n return;\n }\n Object.values(styles).forEach((styleRow) => {\n Object.values(styleRow).forEach(({ fontFamily = '' }) => {\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n });\n });\n });\n\n const fontListMarkup = Object.keys(fontList)\n .map(\n (fontFamily) =>\n `\\t\\t@font-face {\\n\\t\\t\\tfont-family: '${fontFamily}';\\n\\t\\t\\tsrc: url('${fontPaths[fontFamily]}');\\n\\t\\t}\\n`,\n )\n .join('');\n\n if (fontListMarkup) {\n return `\\t\\n`;\n }\n return '';\n }\n\n /**\n * @private\n */\n _setSVGObjects(markup: string[], reviver?: TSVGReviver) {\n this.forEachObject((fabricObject) => {\n if (fabricObject.excludeFromExport) {\n return;\n }\n this._setSVGObject(markup, fabricObject, reviver);\n });\n }\n\n /**\n * This is its own function because the Canvas ( non static ) requires extra code here\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n markup.push(instance.toSVG(reviver));\n }\n\n /**\n * @private\n */\n _setSVGBgOverlayImage(\n markup: string[],\n property: 'overlayImage' | 'backgroundImage',\n reviver?: TSVGReviver,\n ) {\n const bgOrOverlay = this[property];\n if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) {\n markup.push(bgOrOverlay.toSVG(reviver));\n }\n }\n\n /**\n * @TODO this seems to handle patterns but fail at gradients.\n * @private\n */\n _setSVGBgOverlayColor(markup: string[], property: 'background' | 'overlay') {\n const filler = this[`${property}Color`];\n if (!filler) {\n return;\n }\n if (isFiller(filler)) {\n const repeat = (filler as Pattern).repeat || '',\n finalWidth = this.width,\n finalHeight = this.height,\n shouldInvert = this[`${property}Vpt`],\n additionalTransform = shouldInvert\n ? matrixToSVG(invertTransform(this.viewportTransform))\n : '';\n markup.push(\n `\\n`,\n );\n } else {\n markup.push(\n '\\n',\n );\n }\n }\n /* _TO_SVG_END_ */\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n *\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n *\n * @param {String|Object} json JSON string or object\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @param {Object} [options] options\n * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {Promise} instance\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll());\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * }).then((canvas) => {\n * ... canvas is restored, add your code.\n * });\n *\n */\n loadFromJSON(\n json: string | Record,\n reviver?: EnlivenObjectOptions['reviver'],\n { signal }: Abortable = {},\n ): Promise {\n if (!json) {\n return Promise.reject(new FabricError('`json` is undefined'));\n }\n\n // parse json if it wasn't already\n const serialized = typeof json === 'string' ? JSON.parse(json) : json;\n const {\n objects = [],\n backgroundImage,\n background,\n overlayImage,\n overlay,\n clipPath,\n } = serialized;\n const renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n return Promise.all([\n enlivenObjects(objects, {\n reviver,\n signal,\n }),\n enlivenObjectEnlivables(\n {\n backgroundImage,\n backgroundColor: background,\n overlayImage,\n overlayColor: overlay,\n clipPath,\n },\n { signal },\n ),\n ]).then(([enlived, enlivedMap]) => {\n this.clear();\n this.add(...enlived);\n this.set(serialized);\n this.set(enlivedMap);\n this.renderOnAddRemove = renderOnAddRemove;\n return this;\n });\n }\n\n /**\n * Clones canvas instance\n * @param {string[]} [properties] Array of properties to include in the cloned canvas and children\n */\n clone(properties: string[]) {\n const data = this.toObject(properties);\n const canvas = this.cloneWithoutData();\n return canvas.loadFromJSON(data);\n }\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size.\n */\n cloneWithoutData() {\n const el = createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n return new (this.constructor as Constructor)(el);\n }\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link https://jsfiddle.net/xsjua1rd/ demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n * @example Generate dataURL with objects that overlap a specified object\n * var myObject;\n * var dataURL = canvas.toDataURL({\n * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject)\n * });\n */\n toDataURL(options = {} as TDataUrlOptions): string {\n const {\n format = 'png',\n quality = 1,\n multiplier = 1,\n enableRetinaScaling = false,\n } = options;\n const finalMultiplier =\n multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1);\n\n return toDataURL(\n this.toCanvasElement(finalMultiplier, options),\n format,\n quality,\n );\n }\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [options] Cropping informations\n * @param {Number} [options.left] Cropping left offset.\n * @param {Number} [options.top] Cropping top offset.\n * @param {Number} [options.width] Cropping width.\n * @param {Number} [options.height] Cropping height.\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n */\n toCanvasElement(\n multiplier = 1,\n { width, height, left, top, filter } = {} as TToCanvasElementOptions,\n ): HTMLCanvasElement {\n const scaledWidth = (width || this.width) * multiplier,\n scaledHeight = (height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n originalSkipControlsDrawing = this.skipControlsDrawing,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (left || 0)) * multiplier,\n translateY = (vp[5] - (top || 0)) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY] as TMat2D,\n originalRetina = this.enableRetinaScaling,\n canvasEl = createCanvasElement(),\n objectsToRender = filter\n ? this._objects.filter((obj) => filter(obj))\n : this._objects;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.enableRetinaScaling = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.skipControlsDrawing = true;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d')!, objectsToRender);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.enableRetinaScaling = originalRetina;\n this.skipControlsDrawing = originalSkipControlsDrawing;\n return canvasEl;\n }\n\n /**\n * Waits until rendering has settled to destroy the canvas\n * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed\n * @throws if aborted by a consequent call\n */\n dispose() {\n !this.disposed &&\n this.elements.cleanupDOM({ width: this.width, height: this.height });\n runningAnimations.cancelByCanvas(this);\n this.disposed = true;\n return new Promise((resolve, reject) => {\n const task = () => {\n this.destroy();\n resolve(true);\n };\n task.kill = reject;\n if (this.__cleanupTask) {\n this.__cleanupTask.kill('aborted');\n }\n\n if (this.destroyed) {\n resolve(false);\n } else if (this.nextRenderHandle) {\n this.__cleanupTask = task;\n } else {\n task();\n }\n });\n }\n\n /**\n * Clears the canvas element, disposes objects and frees resources.\n *\n * Invoked as part of the **async** operation of {@link dispose}.\n *\n * **CAUTION**:\n *\n * This method is **UNSAFE**.\n * You may encounter a race condition using it if there's a requested render.\n * Call this method only if you are sure rendering has settled.\n * Consider using {@link dispose} as it is **SAFE**\n *\n * @private\n */\n destroy() {\n this.destroyed = true;\n this.cancelRequestedRender();\n this.forEachObject((object) => object.dispose());\n this._objects = [];\n if (this.backgroundImage) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = undefined;\n if (this.overlayImage) {\n this.overlayImage.dispose();\n }\n this.overlayImage = undefined;\n this.elements.dispose();\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString() {\n return `#`;\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport { getScrollLeftTop } from './dom_misc';\n\nconst touchEvents = ['touchstart', 'touchmove', 'touchend'];\n\nfunction getTouchInfo(event: TouchEvent | MouseEvent): MouseEvent | Touch {\n const touchProp = (event as TouchEvent).changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event as MouseEvent;\n}\n\nexport const getPointer = (event: TPointerEvent): Point => {\n const element = event.target as HTMLElement,\n scroll = getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top);\n};\n\nexport const isTouchEvent = (event: TPointerEvent) =>\n touchEvents.includes(event.type) ||\n (event as PointerEvent).pointerType === 'touch';\n\nexport const stopEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n};\n","import type { XY } from '../../Point';\nimport type { TBBox } from '../../typedefs';\n\n/**\n * Calculates bounding box (left, top, width, height) from given `points`\n * @param {XY[]} points\n * @return {Object} Object with left, top, width, height properties\n */\nexport const makeBoundingBoxFromPoints = (points: XY[]): TBBox => {\n let left = 0,\n top = 0,\n width = 0,\n height = 0;\n\n for (let i = 0, len = points.length; i < len; i++) {\n const { x, y } = points[i];\n if (x > width || !i) width = x;\n if (x < left || !i) left = x;\n if (y > height || !i) height = y;\n if (y < top || !i) top = y;\n }\n\n return {\n left,\n top,\n width: width - left,\n height: height - top,\n };\n};\n","import { Point } from '../../Point';\nimport { CENTER } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from './matrix';\n\n/**\n * given an object and a transform, apply the inverse transform to the object,\n * this is equivalent to remove from that object that transformation, so that\n * added in a space with the removed transform, the object will be the same as before.\n * Removing from an object a transform that scale by 2 is like scaling it by 1/2.\n * Removing from an object a transform that rotate by 30deg is like rotating by 30deg\n * in the opposite direction.\n * This util is used to add objects inside transformed groups or nested groups.\n * @param {FabricObject} object the object you want to transform\n * @param {TMat2D} transform the destination transform\n */\nexport const removeTransformFromObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const inverted = invertTransform(transform),\n finalTransform = multiplyTransformMatrices(\n inverted,\n object.calcOwnMatrix(),\n );\n applyTransformToObject(object, finalTransform);\n};\n\n/**\n * given an object and a transform, apply the transform to the object.\n * this is equivalent to change the space where the object is drawn.\n * Adding to an object a transform that scale by 2 is like scaling it by 2.\n * This is used when removing an object from an active selection for example.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const addTransformToObject = (object: FabricObject, transform: TMat2D) =>\n applyTransformToObject(\n object,\n multiplyTransformMatrices(transform, object.calcOwnMatrix()),\n );\n\n/**\n * discard an object transform state and apply the one from the matrix.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const applyTransformToObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const { translateX, translateY, scaleX, scaleY, ...otherOptions } =\n qrDecompose(transform),\n center = new Point(translateX, translateY);\n object.flipX = false;\n object.flipY = false;\n Object.assign(object, otherOptions);\n object.set({ scaleX, scaleY });\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n/**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @param {FabricObject} target object to transform\n */\nexport const resetObjectTransform = (target: FabricObject) => {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n};\n\n/**\n * Extract Object transform values\n * @param {FabricObject} target object to read from\n * @return {Object} Components of transform\n */\nexport const saveObjectTransform = (target: FabricObject) => ({\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top,\n});\n\n/**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform.\n * Use to calculate the boxes around objects for controls.\n * @param {Number} width\n * @param {Number} height\n * @param {TMat2D} t\n * @returns {Point} size\n */\nexport const sizeAfterTransform = (\n width: number,\n height: number,\n t: TMat2D,\n) => {\n const dimX = width / 2,\n dimY = height / 2,\n points = [\n new Point(-dimX, -dimY),\n new Point(dimX, -dimY),\n new Point(-dimX, dimY),\n new Point(dimX, dimY),\n ].map((p) => p.transform(t)),\n bbox = makeBoundingBoxFromPoints(points);\n return new Point(bbox.width, bbox.height);\n};\n","import { iMatrix } from '../../constants';\nimport type { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { invertTransform, multiplyTransformMatrices } from './matrix';\nimport { applyTransformToObject } from './objectTransforms';\n\n/**\n * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\\\n * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`)\n * @param [from]\n * @param [to]\n * @returns\n */\nexport const calcPlaneChangeMatrix = (\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n) => multiplyTransformMatrices(invertTransform(to), from);\n\n/**\n * Sends a point from the source coordinate plane to the destination coordinate plane.\\\n * From the canvas/viewer's perspective the point remains unchanged.\n *\n * @example Send point from canvas plane to group plane\n * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 });\n * var group = new Group([obj], { strokeWidth: 0 });\n * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix());\n * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix());\n * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group\n *\n * @param {Point} point\n * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane.\n * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane.\n * @returns {Point} transformed point\n */\nexport const sendPointToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to));\n\n/**\n * See {@link sendPointToPlane}\n */\nexport const sendVectorToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to), true);\n\n/**\n *\n * A util that abstracts applying transform to objects.\\\n * Sends `object` to the destination coordinate plane by applying the relevant transformations.\\\n * Changes the space/plane where `object` is drawn.\\\n * From the canvas/viewer's perspective `object` remains unchanged.\n *\n * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer\n * let obj, obj2;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * // render\n * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix());\n * obj.clipPath = undefined;\n * obj2.clipPath = clipPath;\n * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer\n *\n * @example Clip an object's clip path with an existing object\n * let obj, existingObj;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix());\n * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo);\n * clipPath.clipPath = existingObj;\n *\n * @param {FabricObject} object\n * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas.\n * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane.\n * @returns {Matrix} the transform matrix that was applied to `object`\n */\nexport const sendObjectToPlane = (\n object: FabricObject,\n from?: TMat2D,\n to?: TMat2D,\n): TMat2D => {\n const t = calcPlaneChangeMatrix(from, to);\n applyTransformToObject(\n object,\n multiplyTransformMatrices(t, object.calcOwnMatrix()),\n );\n return t;\n};\n","import type {\n ObjectModificationEvents,\n TModificationEvents,\n} from '../EventTypeDefs';\n\nexport const fireEvent = (\n eventName: TModificationEvents,\n options: ObjectModificationEvents[typeof eventName],\n) => {\n const {\n transform: { target },\n } = options;\n target.canvas?.fire(`object:${eventName}`, {\n ...options,\n target,\n });\n target.fire(eventName, options);\n};\n","import type { TOriginX, TOriginY } from '../../typedefs';\n\nconst originOffset = {\n left: -0.5,\n top: -0.5,\n center: 0,\n bottom: 0.5,\n right: 0.5,\n};\n/**\n * Resolves origin value relative to center\n * @private\n * @param {TOriginX | TOriginY} originValue originX / originY\n * @returns number\n */\n\nexport const resolveOrigin = (\n originValue: TOriginX | TOriginY | number,\n): number =>\n typeof originValue === 'string'\n ? originOffset[originValue]\n : originValue - 0.5;\n","import type {\n TPointerEvent,\n Transform,\n TransformAction,\n BasicTransformEvent,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TOriginX, TOriginY } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\nimport { CENTER } from '../constants';\n\nexport const NOT_ALLOWED_CURSOR = 'not-allowed';\n\n/**\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {FabricObject} [target] inserted back to help overriding. Unused\n */\nexport const getActionFromCorner = (\n alreadySelected: boolean,\n corner: string | undefined,\n e: TPointerEvent,\n target: FabricObject,\n) => {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n const control = target.controls[corner];\n return control.getActionName(e, control, target);\n};\n\n/**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\nexport function isTransformCentered(transform: Transform) {\n return (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) &&\n resolveOrigin(transform.originY) === resolveOrigin(CENTER)\n );\n}\n\nexport function invertOrigin(origin: TOriginX | TOriginY) {\n return -resolveOrigin(origin) + 0.5;\n}\n\nexport const isLocked = (\n target: FabricObject,\n lockingKey:\n | 'lockMovementX'\n | 'lockMovementY'\n | 'lockRotation'\n | 'lockScalingX'\n | 'lockScalingY'\n | 'lockSkewingX'\n | 'lockSkewingY'\n | 'lockScalingFlip',\n) => target[lockingKey];\n\nexport const commonEventInfo: TransformAction<\n Transform,\n BasicTransformEvent\n> = (eventData, transform, x, y) => {\n return {\n e: eventData,\n transform,\n pointer: new Point(x, y),\n };\n};\n\n/**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n * @param {Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\nexport function findCornerQuadrant(\n fabricObject: FabricObject,\n control: Control,\n): number {\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle(),\n cornerAngle =\n angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round((cornerAngle % 360) / 45);\n}\n\n/**\n * @returns the normalized point (rotated relative to center) in local coordinates\n */\nfunction normalizePoint(\n target: FabricObject,\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n): Point {\n const center = target.getRelativeCenterPoint(),\n p =\n typeof originX !== 'undefined' && typeof originY !== 'undefined'\n ? target.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n )\n : new Point(target.left, target.top),\n p2 = target.angle\n ? point.rotate(-degreesToRadians(target.angle), center)\n : point;\n return p2.subtract(p);\n}\n\n/**\n * Transforms a point to the offset from the given origin\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\nexport function getLocalPoint(\n { target, corner }: Transform,\n originX: TOriginX,\n originY: TOriginY,\n x: number,\n y: number,\n) {\n const control = target.controls[corner],\n zoom = target.canvas?.getZoom() || 1,\n padding = target.padding / zoom,\n localPoint = normalizePoint(target, new Point(x, y), originX, originY);\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { LEFT, TOP, MOVING } from '../constants';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo, isLocked } from './util';\n\n/**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\nexport const dragHandler: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target, offsetX, offsetY } = transform,\n newLeft = x - offsetX,\n newTop = y - offsetY,\n moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,\n moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;\n moveX && target.set(LEFT, newLeft);\n moveY && target.set(TOP, newTop);\n if (moveX || moveY) {\n fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));\n }\n return moveX || moveY;\n};\n","import type { TSVGReviver } from '../../typedefs';\nimport { uid } from '../../util/internals/uid';\nimport { colorPropToSVG, matrixToSVG } from '../../util/misc/svgParsing';\nimport { FILL, NONE, STROKE } from '../../constants';\nimport type { FabricObject } from './FabricObject';\nimport { isFiller } from '../../util/typeAssertions';\n\nexport class FabricObjectSVGExportMixin {\n /**\n * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed.\n * This reference is a UID in the fabric namespace and is temporary stored here.\n * @type {String}\n */\n declare clipPathId?: string;\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(\n this: FabricObjectSVGExportMixin & FabricObject,\n skipShadow?: boolean,\n ) {\n const fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray\n ? this.strokeDashArray.join(' ')\n : NONE,\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = colorPropToSVG(FILL, this.fill),\n stroke = colorPropToSVG(STROKE, this.stroke);\n\n return [\n stroke,\n 'stroke-width: ',\n strokeWidth,\n '; ',\n 'stroke-dasharray: ',\n strokeDashArray,\n '; ',\n 'stroke-linecap: ',\n strokeLineCap,\n '; ',\n 'stroke-dashoffset: ',\n strokeDashOffset,\n '; ',\n 'stroke-linejoin: ',\n strokeLineJoin,\n '; ',\n 'stroke-miterlimit: ',\n strokeMiterLimit,\n '; ',\n fill,\n 'fill-rule: ',\n fillRule,\n '; ',\n 'opacity: ',\n opacity,\n ';',\n filter,\n visibility,\n ].join('');\n }\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';\n }\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons(\n this: FabricObjectSVGExportMixin & FabricObject & { id?: string },\n ) {\n return [\n this.id ? `id=\"${this.id}\" ` : '',\n this.clipPath\n ? `clip-path=\"url(#${\n (this.clipPath as FabricObjectSVGExportMixin & FabricObject)\n .clipPathId\n })\" `\n : '',\n ].join('');\n }\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform(\n this: FabricObjectSVGExportMixin & FabricObject,\n full?: boolean,\n additionalTransform = '',\n ) {\n const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = `transform=\"${matrixToSVG(transform)}`;\n return `${svgTransform}${additionalTransform}\" `;\n }\n\n /**\n * Returns svg representation of an instance\n * This function is implemented in each subclass\n * This is just because typescript otherwise cryies all the time\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(_reviver?: TSVGReviver): string[] {\n return [''];\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver,\n });\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver,\n })\n );\n }\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n reviver,\n additionalTransform = '',\n }: { reviver?: TSVGReviver; additionalTransform?: string } = {},\n ) {\n const commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n }\n\n /**\n * @private\n */\n _createBaseSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n noStyle,\n reviver,\n withShadow,\n additionalTransform,\n }: {\n noStyle?: boolean;\n reviver?: TSVGReviver;\n withShadow?: boolean;\n additionalTransform?: string;\n } = {},\n ): string {\n const styleInfo = noStyle ? '' : `style=\"${this.getSvgStyles()}\" `,\n shadowInfo = withShadow ? `style=\"${this.getSvgFilter()}\" ` : '',\n clipPath = this.clipPath as FabricObjectSVGExportMixin & FabricObject,\n vectorEffect = this.strokeUniform\n ? 'vector-effect=\"non-scaling-stroke\" '\n : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke,\n fill = this.fill,\n shadow = this.shadow,\n markup = [],\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n let clipPathMarkup;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n clipPathMarkup = `\\n${clipPath.toClipPathSVG(reviver)}\\n`;\n }\n if (absoluteClipPath) {\n markup.push('\\n');\n }\n markup.push(\n '\\n',\n );\n const commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(),\n ' ',\n additionalTransform ? `transform=\"${additionalTransform}\" ` : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (isFiller(fill)) {\n markup.push(fill.toSVG(this));\n }\n if (isFiller(stroke)) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n }\n\n addPaintOrder(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.paintFirst !== FILL ? ` paint-order=\"${this.paintFirst}\" ` : '';\n }\n}\n","export function getSvgRegex(arr: string[]) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n}\n","import { getSvgRegex } from './getSvgRegex';\nimport { LEFT, TOP } from '../constants';\n\nexport const reNum = String.raw`(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)`;\n\nexport const svgNS = 'http://www.w3.org/2000/svg';\n\nexport const reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' +\n reNum +\n '))?\\\\s+(.*)',\n);\n\nexport const svgValidTagNames = [\n 'path',\n 'circle',\n 'polygon',\n 'polyline',\n 'ellipse',\n 'rect',\n 'line',\n 'image',\n 'text',\n ],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = [\n 'pattern',\n 'defs',\n 'symbol',\n 'metadata',\n 'clipPath',\n 'mask',\n 'desc',\n ],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n attributesMap = {\n cx: LEFT,\n x: LEFT,\n r: 'radius',\n cy: TOP,\n y: TOP,\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing',\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n\nexport const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n\nexport const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n\nexport const svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n// matches, e.g.: +14.56e-12, etc.\nexport const reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*' +\n '$',\n);\n","import type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n\nconst unitVectorX = new Point(1, 0);\nconst zero = new Point();\n\n/**\n * Rotates `vector` with `radians`\n * @param {Point} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotateVector = (vector: Point, radians: TRadian) =>\n vector.rotate(radians);\n\n/**\n * Creates a vector from points represented as a point\n *\n * @param {Point} from\n * @param {Point} to\n * @returns {Point} vector\n */\nexport const createVector = (from: XY, to: XY): Point =>\n new Point(to).subtract(from);\n\n/**\n * return the magnitude of a vector\n * @return {number}\n */\nexport const magnitude = (point: Point) => point.distanceFrom(zero);\n\n/**\n * Calculates the angle between 2 vectors\n * @param {Point} a\n * @param {Point} b\n * @returns the angle in radians from `a` to `b`\n */\nexport const calcAngleBetweenVectors = (a: Point, b: Point): TRadian =>\n Math.atan2(crossProduct(a, b), dotProduct(a, b)) as TRadian;\n\n/**\n * Calculates the angle between the x axis and the vector\n * @param {Point} v\n * @returns the angle in radians of `v`\n */\nexport const calcVectorRotation = (v: Point) =>\n calcAngleBetweenVectors(unitVectorX, v);\n\n/**\n * @param {Point} v\n * @returns {Point} vector representing the unit vector pointing to the direction of `v`\n */\nexport const getUnitVector = (v: Point): Point =>\n v.eq(zero) ? v : v.scalarDivide(magnitude(v));\n\n/**\n * @param {Point} v\n * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true`\n * @returns {Point} the unit orthogonal vector\n */\nexport const getOrthonormalVector = (\n v: Point,\n counterClockwise = true,\n): Point =>\n getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1));\n\n/**\n * Cross product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number} the magnitude of Z vector\n */\nexport const crossProduct = (a: Point, b: Point): number =>\n a.x * b.y - a.y * b.x;\n\n/**\n * Dot product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number}\n */\nexport const dotProduct = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\n\n/**\n * Checks if the vector is between two others. It is considered\n * to be inside when the vector to be tested is between the\n * initial vector and the final vector (included) in a counterclockwise direction.\n * @param {Point} t vector to be tested\n * @param {Point} a initial vector\n * @param {Point} b final vector\n * @returns {boolean} true if the vector is among the others\n */\nexport const isBetweenVectors = (t: Point, a: Point, b: Point): boolean => {\n if (t.eq(a) || t.eq(b)) return true;\n const AxB = crossProduct(a, b),\n AxT = crossProduct(a, t),\n BxT = crossProduct(b, t);\n return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0);\n};\n","import { classRegistry } from './ClassRegistry';\nimport { Color } from './color/Color';\nimport { config } from './config';\nimport { reNum } from './parser/constants';\nimport { Point } from './Point';\nimport type { FabricObject } from './shapes/Object/FabricObject';\nimport type { TClassProperties } from './typedefs';\nimport { uid } from './util/internals/uid';\nimport { pickBy } from './util/misc/pick';\nimport { degreesToRadians } from './util/misc/radiansDegreesConversion';\nimport { toFixed } from './util/misc/toFixed';\nimport { rotateVector } from './util/misc/vectors';\n\n/**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * - (?:\\s|^): This part captures either a whitespace character (\\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down:\n * - (-?\\d+): Captures an optional minus sign followed by one or more digits (integer part of the number).\n * - (?:\\.\\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number).\n * - (?:px)?: Optionally captures the \"px\" unit.\n * - (?:\\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: Similar to the previous step, this captures the vertical offset.\n\n(\\d+(?:\\.\\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign.\n\n(?:\\s+(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and \"px\" unit.\n\n(?:$|\\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.\n */\n// eslint-disable-next-line max-len\n\nconst shadowOffsetRegex = '(-?\\\\d+(?:\\\\.\\\\d*)?(?:px)?(?:\\\\s?|$))?';\n\nconst reOffsetsAndBlur = new RegExp(\n '(?:\\\\s|^)' +\n shadowOffsetRegex +\n shadowOffsetRegex +\n '(' +\n reNum +\n '?(?:px)?)?(?:\\\\s?|$)(?:$|\\\\s)',\n);\n\nexport const shadowDefaultValues: Partial> = {\n color: 'rgb(0,0,0)',\n blur: 0,\n offsetX: 0,\n offsetY: 0,\n affectStroke: false,\n includeDefaultValues: true,\n nonScaling: false,\n};\n\nexport type SerializedShadowOptions = {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n affectStroke: boolean;\n nonScaling: boolean;\n type: string;\n};\n\nexport class Shadow {\n /**\n * Shadow color\n * @type String\n * @default\n */\n declare color: string;\n\n /**\n * Shadow blur\n * @type Number\n */\n declare blur: number;\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n declare offsetX: number;\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n declare offsetY: number;\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n declare affectStroke: boolean;\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n declare includeDefaultValues: boolean;\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n declare nonScaling: boolean;\n\n declare id: number;\n\n static ownDefaults = shadowDefaultValues;\n\n static type = 'shadow';\n\n /**\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n */\n constructor(options: Partial>);\n constructor(svgAttribute: string);\n constructor(arg0: string | Partial>) {\n const options: Partial> =\n typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;\n Object.assign(this, Shadow.ownDefaults, options);\n this.id = uid();\n }\n\n /**\n * @param {String} value Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n static parseShadow(value: string) {\n const shadowStr = value.trim(),\n [, offsetX = 0, offsetY = 0, blur = 0] = (\n reOffsetsAndBlur.exec(shadowStr) || []\n ).map((value) => parseFloat(value) || 0),\n color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim();\n\n return {\n color,\n offsetX,\n offsetY,\n blur,\n };\n }\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n }\n\n /**\n * Returns SVG representation of a shadow\n * @param {FabricObject} object\n * @return {String} SVG representation of a shadow\n */\n toSVG(object: FabricObject) {\n const offset = rotateVector(\n new Point(this.offsetX, this.offsetY),\n degreesToRadians(-object.angle),\n ),\n BLUR_BOX = 20,\n color = new Color(this.color);\n let fBoxX = 40,\n fBoxY = 40;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX =\n toFixed(\n (Math.abs(offset.x) + this.blur) / object.width,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n fBoxY =\n toFixed(\n (Math.abs(offset.y) + this.blur) / object.height,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return `\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\n\\t\\n\\n`;\n }\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject() {\n const data: SerializedShadowOptions = {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling,\n type: (this.constructor as typeof Shadow).type,\n };\n const defaults = Shadow.ownDefaults as SerializedShadowOptions;\n return !this.includeDefaultValues\n ? pickBy(data, (value, key) => value !== defaults[key])\n : data;\n }\n\n static async fromObject(options: Partial>) {\n return new this(options);\n }\n}\n\nclassRegistry.setClass(Shadow, 'shadow');\n","export const capValue = (min: number, value: number, max: number) =>\n Math.max(min, Math.min(value, max));\n","import {\n TOP,\n LEFT,\n SCALE_Y,\n SCALE_X,\n SKEW_X,\n SKEW_Y,\n FILL,\n STROKE,\n} from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { InteractiveFabricObject } from './InteractiveObject';\nimport type { FabricObject } from './Object';\n\nexport const stateProperties = [\n TOP,\n LEFT,\n SCALE_X,\n SCALE_Y,\n 'flipX',\n 'flipY',\n 'originX',\n 'originY',\n 'angle',\n 'opacity',\n 'globalCompositeOperation',\n 'shadow',\n 'visible',\n SKEW_X,\n SKEW_Y,\n];\n\nexport const cacheProperties = [\n FILL,\n STROKE,\n 'strokeWidth',\n 'strokeDashArray',\n 'width',\n 'height',\n 'paintFirst',\n 'strokeUniform',\n 'strokeLineCap',\n 'strokeDashOffset',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'backgroundColor',\n 'clipPath',\n];\n\nexport const fabricObjectDefaultValues: Partial<\n TClassProperties\n> = {\n // see composeMatrix() to see order of transforms. First defaults listed based on this\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n angle: 0,\n flipX: false,\n flipY: false,\n scaleX: 1,\n scaleY: 1,\n minScaleLimit: 0,\n skewX: 0,\n skewY: 0,\n originX: LEFT,\n originY: TOP,\n strokeWidth: 1,\n strokeUniform: false,\n padding: 0,\n opacity: 1,\n paintFirst: FILL,\n fill: 'rgb(0,0,0)',\n fillRule: 'nonzero',\n stroke: null,\n strokeDashArray: null,\n strokeDashOffset: 0,\n strokeLineCap: 'butt',\n strokeLineJoin: 'miter',\n strokeMiterLimit: 4,\n globalCompositeOperation: 'source-over',\n backgroundColor: '',\n shadow: null,\n visible: true,\n includeDefaultValues: true,\n excludeFromExport: false,\n objectCaching: true,\n clipPath: undefined,\n inverted: false,\n absolutePositioned: false,\n centeredRotation: true,\n centeredScaling: false,\n dirty: true,\n} as const;\n\nexport const interactiveObjectDefaultValues: Partial<\n TClassProperties\n> = {\n noScaleCache: true,\n lockMovementX: false,\n lockMovementY: false,\n lockRotation: false,\n lockScalingX: false,\n lockScalingY: false,\n lockSkewingX: false,\n lockSkewingY: false,\n lockScalingFlip: false,\n cornerSize: 13,\n touchCornerSize: 24,\n transparentCorners: true,\n cornerColor: 'rgb(178,204,255)',\n cornerStrokeColor: '',\n cornerStyle: 'rect',\n cornerDashArray: null,\n hasControls: true,\n borderColor: 'rgb(178,204,255)',\n borderDashArray: null,\n borderOpacityWhenMoving: 0.4,\n borderScaleFactor: 1,\n hasBorders: true,\n selectionBackgroundColor: '',\n selectable: true,\n evented: true,\n perPixelTargetFind: false,\n activeOn: 'down',\n hoverCursor: null,\n moveCursor: null,\n};\n","/**\n * Easing functions\n * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner}\n */\n\nimport { twoMathPi, halfPI } from '../../constants';\nimport type { TEasingFunction } from './types';\n\nconst normalize = (a: number, c: number, p: number, s: number) => {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = (p / twoMathPi) * Math.asin(1);\n } else {\n s = (p / twoMathPi) * Math.asin(c / a);\n }\n }\n return { a, c, p, s };\n};\n\nconst elastic = (\n a: number,\n s: number,\n p: number,\n t: number,\n d: number,\n): number =>\n a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * twoMathPi) / p);\n\n/**\n * Default sinusoidal easing\n */\nexport const defaultEasing: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Cubic easing in\n */\nexport const easeInCubic: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 3 + b;\n\n/**\n * Cubic easing out\n */\nexport const easeOutCubic: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 3 + 1) + b;\n\n/**\n * Cubic easing in and out\n */\nexport const easeInOutCubic: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 3 + b;\n }\n return (c / 2) * ((t - 2) ** 3 + 2) + b;\n};\n\n/**\n * Quartic easing in\n */\nexport const easeInQuart: TEasingFunction = (t, b, c, d) =>\n c * (t /= d) * t ** 3 + b;\n\n/**\n * Quartic easing out\n */\nexport const easeOutQuart: TEasingFunction = (t, b, c, d) =>\n -c * ((t = t / d - 1) * t ** 3 - 1) + b;\n\n/**\n * Quartic easing in and out\n */\nexport const easeInOutQuart: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 4 + b;\n }\n return (-c / 2) * ((t -= 2) * t ** 3 - 2) + b;\n};\n\n/**\n * Quintic easing in\n */\nexport const easeInQuint: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 5 + b;\n\n/**\n * Quintic easing out\n */\nexport const easeOutQuint: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 5 + 1) + b;\n\n/**\n * Quintic easing in and out\n */\nexport const easeInOutQuint: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 5 + b;\n }\n return (c / 2) * ((t - 2) ** 5 + 2) + b;\n};\n\n/**\n * Sinusoidal easing in\n */\nexport const easeInSine: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Sinusoidal easing out\n */\nexport const easeOutSine: TEasingFunction = (t, b, c, d) =>\n c * Math.sin((t / d) * halfPI) + b;\n\n/**\n * Sinusoidal easing in and out\n */\nexport const easeInOutSine: TEasingFunction = (t, b, c, d) =>\n (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b;\n\n/**\n * Exponential easing in\n */\nexport const easeInExpo: TEasingFunction = (t, b, c, d) =>\n t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b;\n\n/**\n * Exponential easing out\n */\nexport const easeOutExpo: TEasingFunction = (t, b, c, d) =>\n t === d ? b + c : c * -(2 ** ((-10 * t) / d) + 1) + b;\n\n/**\n * Exponential easing in and out\n */\nexport const easeInOutExpo: TEasingFunction = (t, b, c, d) => {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * 2 ** (10 * (t - 1)) + b;\n }\n return (c / 2) * -(2 ** (-10 * --t) + 2) + b;\n};\n\n/**\n * Circular easing in\n */\nexport const easeInCirc: TEasingFunction = (t, b, c, d) =>\n -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n\n/**\n * Circular easing out\n */\nexport const easeOutCirc: TEasingFunction = (t, b, c, d) =>\n c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n\n/**\n * Circular easing in and out\n */\nexport const easeInOutCirc: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (-c / 2) * (Math.sqrt(1 - t ** 2) - 1) + b;\n }\n return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n};\n\n/**\n * Elastic easing in\n */\nexport const easeInElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP } = normalize(a, c, p, s);\n return -elastic(normA, normS, normP, t, d) + b;\n};\n\n/**\n * Elastic easing out\n */\nexport const easeOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n return (\n normA * 2 ** (-10 * t) * Math.sin(((t * d - normS) * twoMathPi) / normP) +\n normC +\n b\n );\n};\n\n/**\n * Elastic easing in and out\n */\nexport const easeInOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(normA, normS, normP, t, d) + b;\n }\n return (\n normA *\n Math.pow(2, -10 * (t -= 1)) *\n Math.sin(((t * d - normS) * twoMathPi) / normP) *\n 0.5 +\n normC +\n b\n );\n};\n\n/**\n * Backwards easing in\n */\nexport const easeInBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * (t /= d) * t * ((s + 1) * t - s) + b;\n\n/**\n * Backwards easing out\n */\nexport const easeOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n\n/**\n * Backwards easing in and out\n */\nexport const easeInOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n return (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n};\n\n/**\n * Bouncing easing out\n */\nexport const easeOutBounce: TEasingFunction = (t, b, c, d) => {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n};\n\n/**\n * Bouncing easing in\n */\nexport const easeInBounce: TEasingFunction = (t, b, c, d) =>\n c - easeOutBounce(d - t, 0, c, d) + b;\n\n/**\n * Bouncing easing in and out\n */\nexport const easeInOutBounce: TEasingFunction = (t, b, c, d) =>\n t < d / 2\n ? easeInBounce(t * 2, 0, c, d) * 0.5 + b\n : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n\n/**\n * Quadratic easing in\n */\nexport const easeInQuad: TEasingFunction = (t, b, c, d) => c * (t /= d) * t + b;\n\n/**\n * Quadratic easing out\n */\nexport const easeOutQuad: TEasingFunction = (t, b, c, d) =>\n -c * (t /= d) * (t - 2) + b;\n\n/**\n * Quadratic easing in and out\n */\nexport const easeInOutQuad: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 2 + b;\n }\n return (-c / 2) * (--t * (t - 2) - 1) + b;\n};\n","import { noop } from '../../constants';\nimport { requestAnimFrame } from './AnimationFrameProvider';\nimport { runningAnimations } from './AnimationRegistry';\nimport { defaultEasing } from './easing';\nimport type {\n AnimationState,\n TAbortCallback,\n TBaseAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultAbort = () => false;\n\nexport abstract class AnimationBase<\n T extends number | number[] = number | number[],\n> {\n declare readonly startValue: T;\n declare readonly endValue: T;\n declare readonly duration: number;\n declare readonly delay: number;\n\n protected declare readonly byValue: T;\n protected declare readonly easing: TEasingFunction;\n\n private declare readonly _onStart: VoidFunction;\n private declare readonly _onChange: TOnAnimationChangeCallback;\n private declare readonly _onComplete: TOnAnimationChangeCallback;\n private declare readonly _abort: TAbortCallback;\n\n /**\n * Used to register the animation to a target object\n * so that it can be cancelled within the object context\n */\n declare readonly target?: unknown;\n\n private _state: AnimationState = 'pending';\n /**\n * Time %, or the ratio of `timeElapsed / duration`\n * @see tick\n */\n durationProgress = 0;\n /**\n * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)`\n */\n valueProgress = 0;\n /**\n * Current value\n */\n declare value: T;\n /**\n * Animation start time ms\n */\n private declare startTime: number;\n\n constructor({\n startValue,\n byValue,\n duration = 500,\n delay = 0,\n easing = defaultEasing,\n onStart = noop,\n onChange = noop,\n onComplete = noop,\n abort = defaultAbort,\n target,\n }: TBaseAnimationOptions) {\n this.tick = this.tick.bind(this);\n\n this.duration = duration;\n this.delay = delay;\n this.easing = easing;\n this._onStart = onStart;\n this._onChange = onChange;\n this._onComplete = onComplete;\n this._abort = abort;\n this.target = target;\n\n this.startValue = startValue;\n this.byValue = byValue;\n this.value = this.startValue;\n this.endValue = Object.freeze(this.calculate(this.duration).value);\n }\n\n get state() {\n return this._state;\n }\n\n isDone() {\n return this._state === 'aborted' || this._state === 'completed';\n }\n\n /**\n * Calculate the current value based on the easing parameters\n * @param timeElapsed in ms\n * @protected\n */\n protected abstract calculate(timeElapsed: number): {\n value: T;\n valueProgress: number;\n };\n\n start() {\n const firstTick: FrameRequestCallback = (timestamp) => {\n if (this._state !== 'pending') return;\n this.startTime = timestamp || +new Date();\n this._state = 'running';\n this._onStart();\n this.tick(this.startTime);\n };\n\n this.register();\n\n // setTimeout(cb, 0) will run cb on the next frame, causing a delay\n // we don't want that\n if (this.delay > 0) {\n setTimeout(() => requestAnimFrame(firstTick), this.delay);\n } else {\n requestAnimFrame(firstTick);\n }\n }\n\n private tick(t: number) {\n const durationMs = (t || +new Date()) - this.startTime;\n const boundDurationMs = Math.min(durationMs, this.duration);\n this.durationProgress = boundDurationMs / this.duration;\n const { value, valueProgress } = this.calculate(boundDurationMs);\n this.value = Object.freeze(value);\n this.valueProgress = valueProgress;\n\n if (this._state === 'aborted') {\n return;\n } else if (\n this._abort(this.value, this.valueProgress, this.durationProgress)\n ) {\n this._state = 'aborted';\n this.unregister();\n } else if (durationMs >= this.duration) {\n this.durationProgress = this.valueProgress = 1;\n this._onChange(this.endValue, this.valueProgress, this.durationProgress);\n this._state = 'completed';\n this._onComplete(\n this.endValue,\n this.valueProgress,\n this.durationProgress,\n );\n this.unregister();\n } else {\n this._onChange(this.value, this.valueProgress, this.durationProgress);\n requestAnimFrame(this.tick);\n }\n }\n\n private register() {\n runningAnimations.push(this as unknown as AnimationBase);\n }\n\n private unregister() {\n runningAnimations.remove(this as unknown as AnimationBase);\n }\n\n abort() {\n this._state = 'aborted';\n this.unregister();\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ValueAnimationOptions } from './types';\n\nexport class ValueAnimation extends AnimationBase {\n constructor({\n startValue = 0,\n endValue = 100,\n ...otherOptions\n }: ValueAnimationOptions) {\n super({\n ...otherOptions,\n startValue,\n byValue: endValue - startValue,\n });\n }\n\n protected calculate(timeElapsed: number) {\n const value = this.easing(\n timeElapsed,\n this.startValue,\n this.byValue,\n this.duration,\n );\n return {\n value,\n valueProgress: Math.abs((value - this.startValue) / this.byValue),\n };\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ArrayAnimationOptions } from './types';\n\nexport class ArrayAnimation extends AnimationBase {\n constructor({\n startValue = [0],\n endValue = [100],\n ...options\n }: ArrayAnimationOptions) {\n super({\n ...options,\n startValue,\n byValue: endValue.map((value, i) => value - startValue[i]),\n });\n }\n protected calculate(timeElapsed: number) {\n const values = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n );\n return {\n value: values,\n valueProgress: Math.abs(\n (values[0] - this.startValue[0]) / this.byValue[0],\n ),\n };\n }\n}\n","import { Color } from '../../color/Color';\nimport type { TRGBAColorSource } from '../../color/typedefs';\nimport { halfPI } from '../../constants';\nimport { capValue } from '../misc/capValue';\nimport { AnimationBase } from './AnimationBase';\nimport type {\n ColorAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultColorEasing: TEasingFunction = (\n timeElapsed,\n startValue,\n byValue,\n duration,\n) => {\n const durationProgress = 1 - Math.cos((timeElapsed / duration) * halfPI);\n return startValue + byValue * durationProgress;\n};\n\nconst wrapColorCallback = (\n callback?: TOnAnimationChangeCallback,\n) =>\n callback &&\n ((rgba: TRGBAColorSource, valueProgress: number, durationProgress: number) =>\n callback(new Color(rgba).toRgba(), valueProgress, durationProgress));\n\nexport class ColorAnimation extends AnimationBase {\n constructor({\n startValue,\n endValue,\n easing = defaultColorEasing,\n onChange,\n onComplete,\n abort,\n ...options\n }: ColorAnimationOptions) {\n const startColor = new Color(startValue).getSource();\n const endColor = new Color(endValue).getSource();\n super({\n ...options,\n startValue: startColor,\n byValue: endColor.map(\n (value, i) => value - startColor[i],\n ) as TRGBAColorSource,\n easing,\n onChange: wrapColorCallback(onChange),\n onComplete: wrapColorCallback(onComplete),\n abort: wrapColorCallback(abort),\n });\n }\n protected calculate(timeElapsed: number) {\n const [r, g, b, a] = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n ) as TRGBAColorSource;\n const value = [\n ...[r, g, b].map(Math.round),\n capValue(0, a, 1),\n ] as TRGBAColorSource;\n return {\n value,\n valueProgress:\n // to correctly calculate the change ratio we must find a changed value\n value\n .map((p, i) =>\n this.byValue[i] !== 0\n ? Math.abs((p - this.startValue[i]) / this.byValue[i])\n : 0,\n )\n .find((p) => p !== 0) || 0,\n };\n }\n}\n","import { ValueAnimation } from './ValueAnimation';\nimport { ArrayAnimation } from './ArrayAnimation';\nimport { ColorAnimation } from './ColorAnimation';\nimport type {\n ValueAnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n} from './types';\nimport type { TColorArg } from '../../color/typedefs';\n\nexport type TAnimation =\n T extends TColorArg\n ? ColorAnimation\n : T extends number[]\n ? ArrayAnimation\n : ValueAnimation;\n\nconst isArrayAnimation = (\n options: ArrayAnimationOptions | ValueAnimationOptions,\n): options is ArrayAnimationOptions => {\n return Array.isArray(options.startValue) || Array.isArray(options.endValue);\n};\n\n/**\n * Changes value(s) from startValue to endValue within a certain period of time,\n * invoking callbacks as the value(s) change.\n *\n * @example\n * animate({\n * startValue: 1,\n * endValue: 0,\n * onChange: (v) => {\n * obj.set('opacity', v);\n * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll`\n * canvas.renderAll();\n * }\n * });\n *\n * @example Using lists:\n * animate({\n * startValue: [1, 2, 3],\n * endValue: [2, 4, 6],\n * onChange: ([x, y, zoom]) => {\n * canvas.zoomToPoint(new Point(x, y), zoom);\n * canvas.renderAll();\n * }\n * });\n *\n */\nexport function animate(options: ArrayAnimationOptions): ArrayAnimation;\nexport function animate(options: ValueAnimationOptions): ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n>(\n options: T,\n): T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n R extends T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation,\n>(options: T): R {\n const animation = (\n isArrayAnimation(options)\n ? new ArrayAnimation(options)\n : new ValueAnimation(options)\n ) as R;\n animation.start();\n return animation;\n}\n\nexport function animateColor(options: ColorAnimationOptions) {\n const animation = new ColorAnimation(options);\n animation.start();\n return animation;\n}\n","import { Point } from './Point';\nimport { createVector } from './util/misc/vectors';\n\n/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\nexport type IntersectionType = 'Intersection' | 'Coincident' | 'Parallel';\n\nexport class Intersection {\n declare points: Point[];\n\n declare status?: IntersectionType;\n\n constructor(status?: IntersectionType) {\n this.status = status;\n this.points = [];\n }\n\n /**\n * Used to verify if a point is alredy in the collection\n * @param {Point} point\n * @returns {boolean}\n */\n private includes(point: Point): boolean {\n return this.points.some((p) => p.eq(point));\n }\n\n /**\n * Appends points of intersection\n * @param {...Point[]} points\n * @return {Intersection} thisArg\n * @chainable\n */\n private append(...points: Point[]): Intersection {\n this.points = this.points.concat(\n points.filter((point) => {\n return !this.includes(point);\n }),\n );\n return this;\n }\n\n /**\n * check if point T is on the segment or line defined between A and B\n *\n * @param {Point} T the point we are checking for\n * @param {Point} A one extremity of the segment\n * @param {Point} B the other extremity of the segment\n * @param [infinite] if true checks if `T` is on the line defined by `A` and `B`\n * @returns true if `T` is contained\n */\n static isPointContained(T: Point, A: Point, B: Point, infinite = false) {\n if (A.eq(B)) {\n // Edge case: the segment is a point, we check for coincidence,\n // infinite param has no meaning because there are infinite lines to consider\n return T.eq(A);\n } else if (A.x === B.x) {\n // Edge case: horizontal line.\n // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y\n return (\n T.x === A.x &&\n (infinite || (T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)))\n );\n } else if (A.y === B.y) {\n // Edge case: vertical line.\n // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x\n return (\n T.y === A.y &&\n (infinite || (T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)))\n );\n } else {\n // Generic case: sloped line.\n // we check that AT has the same slope as AB\n // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size\n // for the infinite case we check the absolute value of the slope, since direction is meaningless\n const AB = createVector(A, B);\n const AT = createVector(A, T);\n const s = AT.divide(AB);\n return infinite\n ? Math.abs(s.x) === Math.abs(s.y)\n : s.x === s.y && s.x >= 0 && s.x <= 1;\n }\n }\n\n /**\n * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points}\n * @see https://en.wikipedia.org/wiki/Point_in_polygon\n * @param point\n * @param points polygon points\n * @returns\n */\n static isPointInPolygon(point: Point, points: Point[]) {\n const other = new Point(point).setX(\n Math.min(point.x - 1, ...points.map((p) => p.x)),\n );\n let hits = 0;\n for (let index = 0; index < points.length; index++) {\n const inter = this.intersectSegmentSegment(\n // polygon side\n points[index],\n points[(index + 1) % points.length],\n // ray\n point,\n other,\n );\n if (inter.includes(point)) {\n // point is on the polygon side\n return true;\n }\n hits += Number(inter.status === 'Intersection');\n }\n return hits % 2 === 1;\n }\n\n /**\n * Checks if a line intersects another\n * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection}\n * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule}\n * @static\n * @param {Point} a1\n * @param {Point} a2\n * @param {Point} b1\n * @param {Point} b2\n * @param {boolean} [aInfinite=true] check segment intersection by passing `false`\n * @param {boolean} [bInfinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLineLine(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n aInfinite = true,\n bInfinite = true,\n ): Intersection {\n const a2xa1x = a2.x - a1.x,\n a2ya1y = a2.y - a1.y,\n b2xb1x = b2.x - b1.x,\n b2yb1y = b2.y - b1.y,\n a1xb1x = a1.x - b1.x,\n a1yb1y = a1.y - b1.y,\n uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x,\n ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x,\n uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y;\n if (uB !== 0) {\n const ua = uaT / uB,\n ub = ubT / uB;\n if (\n (aInfinite || (0 <= ua && ua <= 1)) &&\n (bInfinite || (0 <= ub && ub <= 1))\n ) {\n return new Intersection('Intersection').append(\n new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y),\n );\n } else {\n return new Intersection();\n }\n } else {\n if (uaT === 0 || ubT === 0) {\n const segmentsCoincide =\n aInfinite ||\n bInfinite ||\n Intersection.isPointContained(a1, b1, b2) ||\n Intersection.isPointContained(a2, b1, b2) ||\n Intersection.isPointContained(b1, a1, a2) ||\n Intersection.isPointContained(b2, a1, a2);\n return new Intersection(segmentsCoincide ? 'Coincident' : undefined);\n } else {\n return new Intersection('Parallel');\n }\n }\n }\n\n /**\n * Checks if a segment intersects a line\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} s1 boundary point of segment\n * @param {Point} s2 other boundary point of segment\n * @param {Point} l1 point on line\n * @param {Point} l2 other point on line\n * @return {Intersection}\n */\n static intersectSegmentLine(\n s1: Point,\n s2: Point,\n l1: Point,\n l2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(s1, s2, l1, l2, false, true);\n }\n\n /**\n * Checks if a segment intersects another\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point} b1 boundary point of segment\n * @param {Point} b2 other boundary point of segment\n * @return {Intersection}\n */\n static intersectSegmentSegment(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(a1, a2, b1, b2, false, false);\n }\n\n /**\n * Checks if line intersects polygon\n *\n * @todo account for stroke\n *\n * @static\n * @see {@link intersectSegmentPolygon} for segment intersection\n * @param {Point} a1 point on line\n * @param {Point} a2 other point on line\n * @param {Point[]} points polygon points\n * @param {boolean} [infinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLinePolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n infinite = true,\n ): Intersection {\n const result = new Intersection();\n const length = points.length;\n\n for (let i = 0, b1, b2, inter; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false);\n if (inter.status === 'Coincident') {\n return inter;\n }\n result.append(...inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if segment intersects polygon\n * @static\n * @see {@link intersectLinePolygon} for line intersection\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point[]} points polygon points\n * @return {Intersection}\n */\n static intersectSegmentPolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n ): Intersection {\n return Intersection.intersectLinePolygon(a1, a2, points, false);\n }\n\n /**\n * Checks if polygon intersects another polygon\n *\n * @todo account for stroke\n *\n * @static\n * @param {Point[]} points1\n * @param {Point[]} points2\n * @return {Intersection}\n */\n static intersectPolygonPolygon(\n points1: Point[],\n points2: Point[],\n ): Intersection {\n const result = new Intersection(),\n length = points1.length;\n const coincidences: Intersection[] = [];\n\n for (let i = 0; i < length; i++) {\n const a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectSegmentPolygon(a1, a2, points2);\n if (inter.status === 'Coincident') {\n coincidences.push(inter);\n result.append(a1, a2);\n } else {\n result.append(...inter.points);\n }\n }\n\n if (coincidences.length > 0 && coincidences.length === points1.length) {\n return new Intersection('Coincident');\n } else if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @see {@link intersectPolygonPolygon} for polygon intersection\n * @param {Point[]} points polygon points\n * @param {Point} r1 top left point of rect\n * @param {Point} r2 bottom right point of rect\n * @return {Intersection}\n */\n static intersectPolygonRectangle(\n points: Point[],\n r1: Point,\n r2: Point,\n ): Intersection {\n const min = r1.min(r2),\n max = r1.max(r2),\n topRight = new Point(max.x, min.y),\n bottomLeft = new Point(min.x, max.y);\n\n return Intersection.intersectPolygonPolygon(points, [\n min,\n topRight,\n max,\n bottomLeft,\n ]);\n }\n}\n","import type {\n TBBox,\n TCornerPoint,\n TDegree,\n TMat2D,\n TOriginX,\n TOriginY,\n} from '../../typedefs';\nimport { SCALE_X, SCALE_Y, iMatrix } from '../../constants';\nimport { Intersection } from '../../Intersection';\nimport { Point } from '../../Point';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n createRotateMatrix,\n createTranslateMatrix,\n composeMatrix,\n invertTransform,\n multiplyTransformMatrices,\n transformPoint,\n calcPlaneRotation,\n} from '../../util/misc/matrix';\nimport { radiansToDegrees } from '../../util/misc/radiansDegreesConversion';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type { ControlProps } from './types/ControlProps';\nimport { resolveOrigin } from '../../util/misc/resolveOrigin';\nimport type { Group } from '../Group';\nimport { calcDimensionsMatrix } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport { CommonMethods } from '../../CommonMethods';\nimport type { BaseProps } from './types/BaseProps';\nimport type { FillStrokeProps } from './types/FillStrokeProps';\nimport { CENTER, LEFT, TOP } from '../../constants';\n\ntype TMatrixCache = {\n key: number[];\n value: TMat2D;\n};\n\ntype TACoords = TCornerPoint;\n\nexport class ObjectGeometry\n extends CommonMethods\n implements\n Pick,\n BaseProps,\n Pick\n{\n // #region Geometry\n\n declare padding: number;\n\n /**\n * Describe object's corner position in scene coordinates.\n * The coordinates are derived from the following:\n * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth.\n * The coordinates do not depend on viewport changes.\n * The coordinates get updated with {@link setCoords}.\n * You can calculate them without updating with {@link calcACoords()}\n */\n declare aCoords: TACoords;\n\n /**\n * storage cache for object transform matrix\n */\n declare ownMatrixCache?: TMatrixCache;\n\n /**\n * storage cache for object full transform matrix\n */\n declare matrixCache?: TMatrixCache;\n\n /**\n * A Reference of the Canvas where the object is actually added\n * @type StaticCanvas | Canvas;\n * @default undefined\n * @private\n */\n declare canvas?: StaticCanvas | Canvas;\n\n /**\n * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane\n */\n getX(): number {\n return this.getXY().x;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane\n */\n setX(value: number) {\n this.setXY(this.getXY().setX(value));\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane\n */\n getY(): number {\n return this.getXY().y;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane\n */\n setY(value: number) {\n this.setXY(this.getXY().setY(value));\n }\n\n /**\n * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getX}\n */\n getRelativeX(): number {\n return this.left;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this method is identical to {@link setX}\n */\n setRelativeX(value: number) {\n this.left = value;\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getY}\n */\n getRelativeY(): number {\n return this.top;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link setY}\n */\n setRelativeY(value: number) {\n this.top = value;\n }\n\n /**\n * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane\n */\n getXY(): Point {\n const relativePosition = this.getRelativeXY();\n return this.group\n ? transformPoint(relativePosition, this.group.calcTransformMatrix())\n : relativePosition;\n }\n\n /**\n * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate.\n * You can specify {@link originX} and {@link originY} values,\n * that otherwise are the object's current values.\n * @example Set object's bottom left corner to point (5,5) on canvas\n * object.setXY(new Point(5, 5), 'left', 'bottom').\n * @param {Point} point position in scene coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setXY(point: Point, originX?: TOriginX, originY?: TOriginY) {\n if (this.group) {\n point = transformPoint(\n point,\n invertTransform(this.group.calcTransformMatrix()),\n );\n }\n this.setRelativeXY(point, originX, originY);\n }\n\n /**\n * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n */\n getRelativeXY(): Point {\n return new Point(this.left, this.top);\n }\n\n /**\n * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas)\n * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setRelativeXY(\n point: Point,\n originX: TOriginX = this.originX,\n originY: TOriginY = this.originY,\n ) {\n this.setPositionByOrigin(point, originX, originY);\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return false;\n }\n\n /**\n * @return {Point[]} [tl, tr, br, bl] in the scene plane\n */\n getCoords(): Point[] {\n const { tl, tr, br, bl } =\n this.aCoords || (this.aCoords = this.calcACoords());\n const coords = [tl, tr, br, bl];\n if (this.group) {\n const t = this.group.calcTransformMatrix();\n return coords.map((p) => transformPoint(p, t));\n }\n return coords;\n }\n\n /**\n * Checks if object intersects with the scene rect formed by {@link tl} and {@link br}\n */\n intersectsWithRect(tl: Point, br: Point): boolean {\n const intersection = Intersection.intersectPolygonRectangle(\n this.getCoords(),\n tl,\n br,\n );\n return intersection.status === 'Intersection';\n }\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject(other: ObjectGeometry): boolean {\n const intersection = Intersection.intersectPolygonPolygon(\n this.getCoords(),\n other.getCoords(),\n );\n\n return (\n intersection.status === 'Intersection' ||\n intersection.status === 'Coincident' ||\n other.isContainedWithinObject(this) ||\n this.isContainedWithinObject(other)\n );\n }\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject(other: ObjectGeometry): boolean {\n const points = this.getCoords();\n return points.every((point) => other.containsPoint(point));\n }\n\n /**\n * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br}\n */\n isContainedWithinRect(tl: Point, br: Point): boolean {\n const { left, top, width, height } = this.getBoundingRect();\n return (\n left >= tl.x &&\n left + width <= br.x &&\n top >= tl.y &&\n top + height <= br.y\n );\n }\n\n isOverlapping(other: T): boolean {\n return (\n this.intersectsWithObject(other) ||\n this.isContainedWithinObject(other) ||\n other.isContainedWithinObject(this)\n );\n }\n\n /**\n * Checks if point is inside the object\n * @param {Point} point Point to check against\n * @return {Boolean} true if point is inside the object\n */\n containsPoint(point: Point): boolean {\n return Intersection.isPointInPolygon(point, this.getCoords());\n }\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n const points = this.getCoords();\n // if some point is on screen, the object is on screen.\n if (\n points.some(\n (point) =>\n point.x <= br.x &&\n point.x >= tl.x &&\n point.y <= br.y &&\n point.y >= tl.y,\n )\n ) {\n return true;\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n // check if the object is so big that it contains the entire viewport\n return this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n const allPointsAreOutside = this.getCoords().every(\n (point) =>\n (point.x >= br.x || point.x <= tl.x) &&\n (point.y >= br.y || point.y <= tl.y),\n );\n // check if the object is so big that it contains the entire viewport\n return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect(): TBBox {\n return makeBoundingBoxFromPoints(this.getCoords());\n }\n\n /**\n * Returns width of an object's bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} width value\n */\n getScaledWidth(): number {\n return this._getTransformedDimensions().x;\n }\n\n /**\n * Returns height of an object bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} height value\n */\n getScaledHeight(): number {\n return this._getTransformedDimensions().y;\n }\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {void}\n */\n scale(value: number): void {\n this._set(SCALE_X, value);\n this._set(SCALE_Y, value);\n this.setCoords();\n }\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {void}\n */\n scaleToWidth(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n }\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {void}\n */\n scaleToHeight(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n }\n\n getCanvasRetinaScaling() {\n return this.canvas?.getRetinaScaling() || 1;\n }\n\n /**\n * Returns the object angle relative to canvas counting also the group property\n * @returns {TDegree}\n */\n getTotalAngle(): TDegree {\n return this.group\n ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix()))\n : this.angle;\n }\n\n /**\n * Retrieves viewportTransform from Object's canvas if available\n * @return {TMat2D}\n */\n getViewportTransform(): TMat2D {\n return this.canvas?.viewportTransform || (iMatrix.concat() as TMat2D);\n }\n\n /**\n * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates.\n * those never change with zoom or viewport changes.\n * @return {TCornerPoint}\n */\n calcACoords(): TCornerPoint {\n const rotateMatrix = createRotateMatrix({ angle: this.angle }),\n { x, y } = this.getRelativeCenterPoint(),\n tMatrix = createTranslateMatrix(x, y),\n finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n return {\n // corners\n tl: transformPoint({ x: -w, y: -h }, finalMatrix),\n tr: transformPoint({ x: w, y: -h }, finalMatrix),\n bl: transformPoint({ x: -w, y: h }, finalMatrix),\n br: transformPoint({ x: w, y: h }, finalMatrix),\n };\n }\n\n /**\n * Sets corner and controls position coordinates based on current angle, width and height, left and top.\n * aCoords are used to quickly find an object on the canvas.\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n */\n setCoords(): void {\n this.aCoords = this.calcACoords();\n }\n\n transformMatrixKey(skipGroup = false): number[] {\n let prefix: number[] = [];\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup);\n }\n prefix.push(\n this.top,\n this.left,\n this.width,\n this.height,\n this.scaleX,\n this.scaleY,\n this.angle,\n this.strokeWidth,\n this.skewX,\n this.skewY,\n +this.flipX,\n +this.flipY,\n resolveOrigin(this.originX),\n resolveOrigin(this.originY),\n );\n\n return prefix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {TMat2D} transform matrix for the object\n */\n calcTransformMatrix(skipGroup = false): TMat2D {\n let matrix = this.calcOwnMatrix();\n if (skipGroup || !this.group) {\n return matrix;\n }\n const key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache;\n if (cache && cache.key.every((x, i) => x === key[i])) {\n return cache.value;\n }\n if (this.group) {\n matrix = multiplyTransformMatrices(\n this.group.calcTransformMatrix(false),\n matrix,\n );\n }\n this.matrixCache = {\n key,\n value: matrix,\n };\n return matrix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {TMat2D} transform matrix for the object\n */\n calcOwnMatrix(): TMat2D {\n const key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache;\n if (cache && cache.key === key) {\n return cache.value;\n }\n const center = this.getRelativeCenterPoint(),\n options = {\n angle: this.angle,\n translateX: center.x,\n translateY: center.y,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY,\n },\n value = composeMatrix(options);\n this.ownMatrixCache = {\n key,\n value,\n };\n return value;\n }\n\n /**\n * Calculate object dimensions from its properties\n * @private\n * @returns {Point} dimensions\n */\n _getNonTransformedDimensions(): Point {\n return new Point(this.width, this.height).scalarAdd(this.strokeWidth);\n }\n\n /**\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * @private\n * @param {object} [options] transform options\n * @returns {Point} dimensions\n */\n _calculateCurrentDimensions(options?: any): Point {\n return this._getTransformedDimensions(options)\n .transform(this.getViewportTransform(), true)\n .scalarAdd(2 * this.padding);\n }\n\n // #region Origin\n\n declare top: number;\n declare left: number;\n declare width: number;\n declare height: number;\n declare flipX: boolean;\n declare flipY: boolean;\n declare scaleX: number;\n declare scaleY: number;\n declare skewX: number;\n declare skewY: number;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originX: TOriginX;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originY: TOriginY;\n declare angle: TDegree;\n declare strokeWidth: number;\n declare strokeUniform: boolean;\n\n /**\n * Object containing this object.\n * can influence its size and position\n */\n declare group?: Group;\n\n /**\n * Calculate object bounding box dimensions from its properties scale, skew.\n * This bounding box is aligned with object angle and not with canvas axis or screen.\n * @param {Object} [options]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @private\n * @returns {Point} dimensions\n */\n _getTransformedDimensions(options: any = {}): Point {\n const dimOptions = {\n // if scaleX or scaleY are negative numbers,\n // this will return dimensions that are negative.\n // and this will break assumptions around the codebase\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n width: this.width,\n height: this.height,\n strokeWidth: this.strokeWidth,\n ...options,\n };\n // stroke is applied before/after transformations are applied according to `strokeUniform`\n const strokeWidth = dimOptions.strokeWidth;\n let preScalingStrokeValue = strokeWidth,\n postScalingStrokeValue = 0;\n\n if (this.strokeUniform) {\n preScalingStrokeValue = 0;\n postScalingStrokeValue = strokeWidth;\n }\n const dimX = dimOptions.width + preScalingStrokeValue,\n dimY = dimOptions.height + preScalingStrokeValue,\n noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0;\n let finalDimensions;\n if (noSkew) {\n finalDimensions = new Point(\n dimX * dimOptions.scaleX,\n dimY * dimOptions.scaleY,\n );\n } else {\n finalDimensions = sizeAfterTransform(\n dimX,\n dimY,\n calcDimensionsMatrix(dimOptions),\n );\n }\n\n return finalDimensions.scalarAdd(postScalingStrokeValue);\n }\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToGivenOrigin(\n point: Point,\n fromOriginX: TOriginX,\n fromOriginY: TOriginY,\n toOriginX: TOriginX,\n toOriginY: TOriginY,\n ): Point {\n let x = point.x,\n y = point.y;\n const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX),\n offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY);\n\n if (offsetX || offsetY) {\n const dim = this._getTransformedDimensions();\n x += offsetX * dim.x;\n y += offsetY * dim.y;\n }\n\n return new Point(x, y);\n }\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToCenterPoint(\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n if (originX === CENTER && originY === CENTER) {\n return point;\n }\n const p = this.translateToGivenOrigin(\n point,\n originX,\n originY,\n CENTER,\n CENTER,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), point);\n }\n return p;\n }\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {Point} center The point which corresponds to center of the object\n * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToOriginPoint(\n center: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n const p = this.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), center);\n }\n return p;\n }\n\n /**\n * Returns the center coordinates of the object relative to canvas\n * @return {Point}\n */\n getCenterPoint(): Point {\n const relCenter = this.getRelativeCenterPoint();\n return this.group\n ? transformPoint(relCenter, this.group.calcTransformMatrix())\n : relCenter;\n }\n\n /**\n * Returns the center coordinates of the object relative to it's parent\n * @return {Point}\n */\n getRelativeCenterPoint(): Point {\n return this.translateToCenterPoint(\n new Point(this.left, this.top),\n this.originX,\n this.originY,\n );\n }\n\n /**\n * Returns the position of the object as if it has a different origin.\n * Take an object that has left, top set to 100, 100 with origin 'left', 'top'.\n * Return the values of left top ( wrapped in a point ) that you would need to keep\n * the same position if origin where different.\n * Alternatively you can use this to also find which point in the parent plane is a specific origin\n * ( where is the bottom right corner of my object? )\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n getPointByOrigin(originX: TOriginX, originY: TOriginY): Point {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n }\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {Point} pos The new position of the object\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin(pos: Point, originX: TOriginX, originY: TOriginY) {\n const center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(\n center,\n this.originX,\n this.originY,\n );\n this.set({ left: position.x, top: position.y });\n }\n\n /**\n * @private\n */\n _getLeftTopCoords() {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n LEFT,\n TOP,\n );\n }\n}\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport {\n ALIASING_LIMIT,\n CENTER,\n iMatrix,\n LEFT,\n SCALE_X,\n SCALE_Y,\n STROKE,\n FILL,\n TOP,\n VERSION,\n} from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport { Shadow } from '../../Shadow';\nimport type {\n TDegree,\n TFiller,\n TSize,\n TCacheCanvasDimensions,\n Abortable,\n TOptions,\n ImageFormat,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { runningAnimations } from '../../util/animation/AnimationRegistry';\nimport { capValue } from '../../util/misc/capValue';\nimport { createCanvasElement, toDataURL } from '../../util/misc/dom';\nimport { invertTransform, qrDecompose } from '../../util/misc/matrix';\nimport { enlivenObjectEnlivables } from '../../util/misc/objectEnlive';\nimport {\n resetObjectTransform,\n saveObjectTransform,\n} from '../../util/misc/objectTransforms';\nimport { sendObjectToPlane } from '../../util/misc/planeChange';\nimport { pick, pickBy } from '../../util/misc/pick';\nimport { toFixed } from '../../util/misc/toFixed';\nimport type { Group } from '../Group';\nimport { StaticCanvas } from '../../canvas/StaticCanvas';\nimport {\n isFiller,\n isSerializableFiller,\n isTextObject,\n} from '../../util/typeAssertions';\nimport type { FabricImage } from '../Image';\nimport {\n cacheProperties,\n fabricObjectDefaultValues,\n stateProperties,\n} from './defaultValues';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { SerializedObjectProps } from './types/SerializedObjectProps';\nimport type { ObjectProps } from './types/ObjectProps';\nimport { getDevicePixelRatio, getEnv } from '../../env';\nimport { log } from '../../util/internals/console';\nimport type { TColorArg } from '../../color/typedefs';\nimport type { TAnimation } from '../../util/animation/animate';\nimport { animate, animateColor } from '../../util/animation/animate';\nimport type {\n AnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n ValueAnimationOptions,\n} from '../../util/animation/types';\nimport { ObjectGeometry } from './ObjectGeometry';\n\ntype TAncestor = FabricObject;\ntype TCollection = Group;\n\nexport type Ancestors =\n | [FabricObject | Group]\n | [FabricObject | Group, ...Group[]]\n | Group[];\n\nexport type AncestryComparison = {\n /**\n * common ancestors of `this` and`other`(may include`this` | `other`)\n */\n common: Ancestors;\n /**\n * ancestors that are of `this` only\n */\n fork: Ancestors;\n /**\n * ancestors that are of `other` only\n */\n otherFork: Ancestors;\n};\n\nexport type TCachedFabricObject = T &\n Required<\n Pick<\n T,\n | 'zoomX'\n | 'zoomY'\n | '_cacheCanvas'\n | '_cacheContext'\n | 'cacheTranslationX'\n | 'cacheTranslationY'\n >\n > & {\n _cacheContext: CanvasRenderingContext2D;\n };\n\nexport type ObjectToCanvasElementOptions = {\n format?: ImageFormat;\n /** Multiplier to scale by */\n multiplier?: number;\n /** Cropping left offset. Introduced in v1.2.14 */\n left?: number;\n /** Cropping top offset. Introduced in v1.2.14 */\n top?: number;\n /** Cropping width. Introduced in v1.2.14 */\n width?: number;\n /** Cropping height. Introduced in v1.2.14 */\n height?: number;\n /** Enable retina scaling for clone image. Introduce in 1.6.4 */\n enableRetinaScaling?: boolean;\n /** Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 */\n withoutTransform?: boolean;\n /** Remove current object shadow. Introduced in 2.4.2 */\n withoutShadow?: boolean;\n /** Account for canvas viewport transform */\n viewportTransform?: boolean;\n /** Function to create the output canvas to export onto */\n canvasProvider?: (el?: HTMLCanvasElement) => T;\n};\n\ntype toDataURLOptions = ObjectToCanvasElementOptions & {\n quality?: number;\n};\n\n/**\n * Root object class from which all 2d shape classes inherit from\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n * @fires modified\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\nexport class FabricObject<\n Props extends TOptions = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends ObjectGeometry\n implements ObjectProps\n{\n declare minScaleLimit: number;\n\n declare opacity: number;\n\n declare paintFirst: 'fill' | 'stroke';\n declare fill: string | TFiller | null;\n declare fillRule: CanvasFillRule;\n declare stroke: string | TFiller | null;\n declare strokeDashArray: number[] | null;\n declare strokeDashOffset: number;\n declare strokeLineCap: CanvasLineCap;\n declare strokeLineJoin: CanvasLineJoin;\n declare strokeMiterLimit: number;\n\n declare globalCompositeOperation: GlobalCompositeOperation;\n declare backgroundColor: string;\n\n declare shadow: Shadow | null;\n\n declare visible: boolean;\n\n declare includeDefaultValues: boolean;\n declare excludeFromExport: boolean;\n\n declare objectCaching: boolean;\n\n declare clipPath?: FabricObject;\n declare inverted: boolean;\n declare absolutePositioned: boolean;\n declare centeredRotation: boolean;\n declare centeredScaling: boolean;\n\n /**\n * This list of properties is used to check if the state of an object is changed.\n * This state change now is only used for children of groups to understand if a group\n * needs its cache regenerated during a .set call\n * @type Array\n */\n static stateProperties: string[] = stateProperties;\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n static cacheProperties: string[] = cacheProperties;\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n declare dirty: boolean;\n\n /**\n * Quick access for the _cacheCanvas rendering context\n * This is part of the objectCaching feature\n * since 1.7.0\n * @type boolean\n * @default undefined\n * @private\n */\n _cacheContext: CanvasRenderingContext2D | null = null;\n\n /**\n * A reference to the HTMLCanvasElement that is used to contain the cache of the object\n * this canvas element is resized and cleared as needed\n * Is marked private, you can read it, don't use it since it is handled by fabric\n * since 1.7.0\n * @type HTMLCanvasElement\n * @default undefined\n * @private\n */\n declare _cacheCanvas?: HTMLCanvasElement;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, X axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomX?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomY?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationX?: number;\n\n /**\n * translation of the cacheCanvas away from the center, for subpixel accuracy and crispness\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationY?: number;\n\n /**\n * A reference to the parent of the object, usually a Group\n * @type number\n * @default undefined\n * @private\n */\n declare group?: Group;\n\n /**\n * Indicate if the object is sitting on a cache dedicated to it\n * or is part of a larger cache for many object ( a group for example)\n * @type number\n * @default undefined\n * @private\n */\n declare ownCaching?: boolean;\n\n /**\n * Private. indicates if the object inside a group is on a transformed context or not\n * or is part of a larger cache for many object ( a group for example)\n * @type boolean\n * @default undefined\n * @private\n */\n declare _transformDone?: boolean;\n\n static ownDefaults = fabricObjectDefaultValues;\n\n static getDefaults(): Record {\n return FabricObject.ownDefaults;\n }\n\n /**\n * The class type.\n * This is used for serialization and deserialization purposes and internally it can be used\n * to identify classes.\n * When we transform a class in a plain JS object we need a way to recognize which class it was,\n * and the type is the way we do that. It has no other purposes and you should not give one.\n * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type).\n * To idenfity a class use instanceof class ( instanceof Rect ).\n * We do not do that in fabricJS code because we want to try to have code splitting possible.\n */\n static type = 'FabricObject';\n\n /**\n * Legacy identifier of the class. Prefer using utils like isType or instanceOf\n * Will be removed in fabric 7 or 8.\n * The setter exists to avoid type errors in old code and possibly current deserialization code.\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n const name = (this.constructor as typeof FabricObject).type;\n if (name === 'FabricObject') {\n return 'object';\n }\n return name.toLowerCase();\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, FabricObject.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas() {\n this._cacheCanvas = createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n }\n\n /**\n * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize(\n dims: TSize & { zoomX: number; zoomY: number; capped: boolean } & any,\n ) {\n const width = dims.width,\n height = dims.height,\n max = config.maxCacheSideLimit,\n min = config.minCacheSideLimit;\n if (\n width <= max &&\n height <= max &&\n width * height <= config.perfLimitSizeTotal\n ) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n const ar = width / height,\n [limX, limY] = cache.limitDimsByArea(ar),\n x = capValue(min, limX, max),\n y = capValue(min, limY, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const objectScale = this.getTotalObjectScaling(),\n // calculate dimensions without skewing\n dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),\n neededX = (dim.x * objectScale.x) / this.scaleX,\n neededY = (dim.y * objectScale.y) / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.x,\n zoomY: objectScale.y,\n x: neededX,\n y: neededY,\n };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const canvas = this._cacheCanvas!,\n context = this._cacheContext,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = config.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n zoomX = dims.zoomX,\n zoomY = dims.zoomY,\n dimensionsChanged = width !== canvas.width || height !== canvas.height,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY;\n\n if (!canvas || !context) {\n return false;\n }\n\n let drawingWidth,\n drawingHeight,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\n if (dimensionsChanged) {\n const canvasWidth = (this._cacheCanvas as HTMLCanvasElement).width,\n canvasHeight = (this._cacheCanvas as HTMLCanvasElement).height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking =\n (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize &&\n canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (\n sizeGrowing &&\n !dims.capped &&\n (width > minCacheSize || height > minCacheSize)\n ) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (isTextObject(this) && this.path) {\n shouldRedraw = true;\n shouldResizeCanvas = true;\n // IMHO in those lines we are using zoomX and zoomY not the this version.\n additionalWidth += this.getHeightOfLine(0) * this.zoomX!;\n additionalHeight += this.getHeightOfLine(0) * this.zoomY!;\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX =\n Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY =\n Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n context.translate(this.cacheTranslationX, this.cacheTranslationY);\n context.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n }\n\n /**\n * Sets object's properties from options, for class constructor only.\n * Needs to be overridden for different defaults.\n * @protected\n * @param {Object} [options] Options object\n */\n protected setOptions(options: Record = {}) {\n this._setOptions(options);\n }\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform(ctx: CanvasRenderingContext2D) {\n const needFullTransform =\n (this.group && !this.group._transformDone) ||\n (this.group && this.canvas && ctx === (this.canvas as Canvas).contextTop);\n const m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Point}\n */\n getObjectScaling() {\n // if the object is a top level one, on the canvas, we go for simple aritmetic\n // otherwise the complex method with angles will return approximations and decimals\n // and will likely kill the cache when not needed\n // https://github.com/fabricjs/fabric.js/issues/7157\n if (!this.group) {\n return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY));\n }\n // if we are inside a group total zoom calculation is complex, we defer to generic matrices\n const options = qrDecompose(this.calcTransformMatrix());\n return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY));\n }\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling() {\n const scale = this.getObjectScaling();\n if (this.canvas) {\n const zoom = this.canvas.getZoom();\n const retina = this.getCanvasRetinaScaling();\n return scale.scalarMultiply(zoom * retina);\n }\n return scale;\n }\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity() {\n let opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n }\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @todo: this is a control action issue, not a geometry one\n * @private\n * @param {Number} value, unconstrained\n * @return {Number} constrained value;\n */\n _constrainScale(value: number): number {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\n return value;\n }\n\n /**\n * Handles setting values on the instance and handling internal side effects\n * @protected\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (key === SCALE_X || key === SCALE_Y) {\n value = this._constrainScale(value);\n }\n if (key === SCALE_X && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n // i don't like this automatic initialization here\n } else if (key === 'shadow' && value && !(value instanceof Shadow)) {\n value = new Shadow(value);\n }\n\n const isChanged = this[key as keyof this] !== value;\n this[key as keyof this] = value;\n\n // invalidate caches\n if (\n isChanged &&\n (this.constructor as typeof FabricObject).cacheProperties.includes(key)\n ) {\n this.dirty = true;\n }\n // a dirty child makes the parent dirty.\n // but a non dirty child does not make the parent not dirty.\n // the parent could be dirty for some other reason.\n this.parent &&\n (this.dirty ||\n (isChanged &&\n (this.constructor as typeof FabricObject).stateProperties.includes(\n key,\n ))) &&\n this.parent._set('dirty', true);\n\n return this;\n }\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf FabricObject.prototype\n * @return {Boolean}\n */\n isNotVisible() {\n return (\n this.opacity === 0 ||\n (!this.width && !this.height && this.strokeWidth === 0) ||\n !this.visible\n );\n }\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.shouldCache()) {\n this.renderCache();\n (this as TCachedFabricObject).drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n this.drawObject(ctx);\n this.dirty = false;\n }\n ctx.restore();\n }\n\n drawSelectionBackground(_ctx: CanvasRenderingContext2D) {\n /* no op */\n }\n\n renderCache(options?: any) {\n options = options || {};\n if (!this._cacheCanvas || !this._cacheContext) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty() && this._cacheContext) {\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n }\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas() {\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke() {\n return (\n this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0\n );\n }\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill() {\n return this.fill && this.fill !== 'transparent';\n }\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache() {\n if (\n this.paintFirst === STROKE &&\n this.hasFill() &&\n this.hasStroke() &&\n !!this.shadow\n ) {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache() {\n this.ownCaching =\n this.needsItsOwnCache() ||\n (this.objectCaching && (!this.parent || !this.parent.isOnACache()));\n return this.ownCaching;\n }\n\n /**\n * Check if this object will cast a shadow with an offset.\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n * @deprecated\n */\n willDrawShadow() {\n return (\n !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0)\n );\n }\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {FabricObject} clipPath\n */\n drawClipPathOnCache(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (clipPath.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (clipPath.absolutePositioned) {\n const m = invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {boolean} forClipping apply clipping styles\n */\n drawObject(ctx: CanvasRenderingContext2D, forClipping?: boolean) {\n const originalFill = this.fill,\n originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n }\n this._render(ctx);\n this._drawClipPath(ctx, this.clipPath);\n this.fill = originalFill;\n this.stroke = originalStroke;\n }\n\n /**\n * Prepare clipPath state and cache and draw it on instance's cache\n * @param {CanvasRenderingContext2D} ctx\n * @param {FabricObject} clipPath\n */\n _drawClipPath(ctx: CanvasRenderingContext2D, clipPath?: FabricObject) {\n if (!clipPath) {\n return;\n }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n clipPath._set('canvas', this.canvas);\n clipPath.shouldCache();\n clipPath._transformDone = true;\n clipPath.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx, clipPath as TCachedFabricObject);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(this: TCachedFabricObject, ctx: CanvasRenderingContext2D) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(\n this._cacheCanvas,\n -this.cacheTranslationX,\n -this.cacheTranslationY,\n );\n }\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty(skipCanvas = false) {\n if (this.isNotVisible()) {\n return false;\n }\n const canvas = this._cacheCanvas;\n const ctx = this._cacheContext;\n if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned)) {\n if (canvas && ctx && !skipCanvas) {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n }\n return true;\n }\n }\n return false;\n }\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n if (!this.backgroundColor) {\n return;\n }\n const dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y);\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity(ctx: CanvasRenderingContext2D) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n }\n\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n decl: Pick<\n this,\n | 'stroke'\n | 'strokeWidth'\n | 'strokeLineCap'\n | 'strokeDashOffset'\n | 'strokeLineJoin'\n | 'strokeMiterLimit'\n >,\n ) {\n const stroke = decl.stroke;\n if (stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n if (isFiller(stroke)) {\n if (\n (stroke as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (stroke as Gradient<'linear'>).gradientTransform ||\n (stroke as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, stroke);\n } else {\n // is a simple gradient or pattern\n ctx.strokeStyle = stroke.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, stroke);\n }\n } else {\n // is a color\n ctx.strokeStyle = decl.stroke as string;\n }\n }\n }\n\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n if (fill) {\n if (isFiller(fill)) {\n ctx.fillStyle = fill.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, fill);\n } else {\n ctx.fillStyle = fill;\n }\n }\n }\n\n _setClippingProperties(ctx: CanvasRenderingContext2D) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n }\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n */\n _setLineDash(ctx: CanvasRenderingContext2D, dashArray?: number[] | null) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies of the dash array when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push(...dashArray);\n }\n ctx.setLineDash(dashArray);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n const shadow = this.shadow,\n canvas = this.canvas,\n retinaScaling = this.getCanvasRetinaScaling(),\n [sx, , , sy] = canvas?.viewportTransform || iMatrix,\n multX = sx * retinaScaling,\n multY = sy * retinaScaling,\n scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling();\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur =\n (shadow.blur *\n config.browserShadowBlurConstant *\n (multX + multY) *\n (scaling.x + scaling.y)) /\n 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TFiller} filler {@link Pattern} or {@link Gradient}\n */\n _applyPatternGradientTransform(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n if (!isFiller(filler)) {\n return { offsetX: 0, offsetY: 0 };\n }\n const t =\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform;\n const offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if ((filler as Gradient<'linear'>).gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n }\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} _ctx Context to render on\n */\n _render(_ctx: CanvasRenderingContext2D) {\n // placeholder to be overridden\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._setFillStyles(ctx, this);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform) {\n const scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.x, 1 / scaling.y);\n }\n this._setLineDash(ctx, this.strokeDashArray);\n this._setStrokeStyles(ctx, this);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Gradient} filler\n */\n _applyPatternForTransformedGradient(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n const dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = createCanvasElement(),\n retinaScaling = this.getCanvasRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n // in case width and height are less than 1px, we have to round up.\n // since the pattern is no-repeat, this is fine\n pCanvas.width = Math.ceil(width);\n pCanvas.height = Math.ceil(height);\n const pCtx = pCanvas.getContext('2d');\n if (!pCtx) {\n return;\n }\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling,\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx)!;\n pCtx.fill();\n ctx.translate(\n -this.width / 2 - this.strokeWidth / 2,\n -this.height / 2 - this.strokeWidth / 2,\n );\n ctx.scale(\n (retinaScaling * this.scaleX) / dims.zoomX,\n (retinaScaling * this.scaleY) / dims.zoomY,\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat') ?? '';\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement() {\n return new Point(this.left + this.width / 2, this.top + this.height / 2);\n }\n\n /**\n * Clones an instance.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {Promise}\n */\n clone(propertiesToInclude?: string[]): Promise {\n const objectForm = this.toObject(propertiesToInclude);\n return (this.constructor as typeof FabricObject).fromObject(\n objectForm,\n ) as unknown as Promise;\n }\n\n /**\n * Creates an instance of Image out of an object\n * makes use of toCanvasElement.\n * Once this method was based on toDataUrl and loadImage, so it also had a quality\n * and format option. toCanvasElement is faster and produce no loss of quality.\n * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.\n * toCanvasElement and then toBlob from the obtained canvas is also a good option.\n * @todo fix the export type, it could not be Image but the type that getClass return for 'image'.\n * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {FabricImage} Object cloned as image.\n */\n cloneAsImage(options: ObjectToCanvasElementOptions): FabricImage {\n const canvasEl = this.toCanvasElement(options);\n // TODO: how to import Image w/o an import cycle?\n const ImageClass = classRegistry.getClass('image');\n return new ImageClass(canvasEl);\n }\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {ObjectToCanvasElementOptions} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform\n * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas\n * @return {HTMLCanvasElement} Returns DOM element with the FabricObject\n */\n toCanvasElement(options: ObjectToCanvasElementOptions = {}) {\n const origParams = saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1,\n multiplier = (options.multiplier || 1) * retinaScaling,\n canvasProvider: (el: HTMLCanvasElement) => StaticCanvas =\n options.canvasProvider ||\n ((el: HTMLCanvasElement) =>\n new StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n }));\n delete this.group;\n if (options.withoutTransform) {\n resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n if (options.viewportTransform) {\n sendObjectToPlane(this, this.getViewportTransform());\n }\n\n this.setCoords();\n const el = createCanvasElement(),\n boundingRect = this.getBoundingRect(),\n shadow = this.shadow,\n shadowOffset = new Point();\n\n if (shadow) {\n const shadowBlur = shadow.blur;\n const scaling = shadow.nonScaling\n ? new Point(1, 1)\n : this.getObjectScaling();\n // consider non scaling shadow.\n shadowOffset.x =\n 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x);\n shadowOffset.y =\n 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y);\n }\n const width = boundingRect.width + shadowOffset.x,\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n const canvas = canvasProvider(el);\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(\n new Point(canvas.width / 2, canvas.height / 2),\n CENTER,\n CENTER,\n );\n const originalCanvas = this.canvas;\n // static canvas and canvas have both an array of InteractiveObjects\n // @ts-expect-error this needs to be fixed somehow, or ignored globally\n canvas._objects = [this];\n this.set('canvas', canvas);\n this.setCoords();\n const canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.set('canvas', originalCanvas);\n this.shadow = originalShadow;\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams);\n this.setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n // since render has settled it is safe to destroy canvas\n canvas.destroy();\n return canvasEl;\n }\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL(options: toDataURLOptions = {}) {\n return toDataURL(\n this.toCanvasElement(options),\n options.format || 'png',\n options.quality || 1,\n );\n }\n\n /**\n * Returns true if any of the specified types is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType(...types: string[]) {\n return (\n types.includes((this.constructor as typeof FabricObject).type) ||\n types.includes(this.type)\n );\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity() {\n return 1;\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {TDegree} angle Angle value (in degrees)\n */\n rotate(angle: TDegree) {\n const { centeredRotation, originX, originY } = this;\n\n if (centeredRotation) {\n const { x, y } = this.getRelativeCenterPoint();\n this.originX = CENTER;\n this.originY = CENTER;\n this.left = x;\n this.top = y;\n }\n\n this.set('angle', angle);\n\n if (centeredRotation) {\n const { x, y } = this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n this.left = x;\n this.top = y;\n this.originX = originX;\n this.originY = originY;\n }\n }\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup() {\n // implemented by sub-classes, as needed.\n }\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation(ctx: CanvasRenderingContext2D) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n\n /**\n * cancel instance's running animations\n * override if necessary to dispose artifacts such as `clipPath`\n */\n dispose() {\n runningAnimations.cancelByTarget(this);\n this.off();\n this._set('canvas', undefined);\n // clear caches\n this._cacheCanvas && getEnv().dispose(this._cacheCanvas);\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n // #region Animation methods\n /**\n * List of properties to consider for animating colors.\n * @type String[]\n */\n static colorProperties: string[] = [FILL, STROKE, 'backgroundColor'];\n\n /**\n * Animates object's properties\n * @param {Record} animatable map of keys and end values\n * @param {Partial>} options\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @return {Record>} map of animation contexts\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n */\n animate(\n animatable: Record,\n options?: Partial>,\n ): Record> {\n return Object.entries(animatable).reduce(\n (acc, [key, endValue]) => {\n acc[key] = this._animate(key, endValue, options);\n return acc;\n },\n {} as Record>,\n );\n }\n\n /**\n * @private\n * @param {String} key Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n */\n _animate(\n key: string,\n endValue: T,\n options: Partial> = {},\n ): TAnimation {\n const path = key.split('.');\n const propIsColor = (\n this.constructor as typeof FabricObject\n ).colorProperties.includes(path[path.length - 1]);\n const { abort, startValue, onChange, onComplete } = options;\n const animationOptions = {\n ...options,\n target: this,\n // path.reduce... is the current value in case start value isn't provided\n startValue:\n startValue ?? path.reduce((deep: any, key) => deep[key], this),\n endValue,\n abort: abort?.bind(this),\n onChange: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n path.reduce((deep: Record, key, index) => {\n if (index === path.length - 1) {\n deep[key] = value;\n }\n return deep[key];\n }, this);\n onChange &&\n // @ts-expect-error generic callback arg0 is wrong\n onChange(value, valueProgress, durationProgress);\n },\n onComplete: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n this.setCoords();\n onComplete &&\n // @ts-expect-error generic callback arg0 is wrong\n onComplete(value, valueProgress, durationProgress);\n },\n } as AnimationOptions;\n\n return (\n propIsColor\n ? animateColor(animationOptions as ColorAnimationOptions)\n : animate(\n animationOptions as ValueAnimationOptions | ArrayAnimationOptions,\n )\n ) as TAnimation;\n }\n\n // #region Object stacking methods\n\n /**\n * A reference to the parent of the object\n * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref\n */\n declare parent?: Group;\n\n /**\n * Checks if object is descendant of target\n * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons\n * @param {TAncestor} target\n * @returns {boolean}\n */\n isDescendantOf(target: TAncestor): boolean {\n const { parent, group } = this;\n return (\n parent === target ||\n group === target ||\n // walk up\n (!!parent && parent.isDescendantOf(target)) ||\n (!!group && group !== parent && group.isDescendantOf(target))\n );\n }\n\n /**\n * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top\n */\n getAncestors(): Ancestors {\n const ancestors: TAncestor[] = [];\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let parent: TAncestor | undefined = this;\n do {\n parent = parent.parent;\n parent && ancestors.push(parent);\n } while (parent);\n return ancestors as Ancestors;\n }\n\n /**\n * Compare ancestors\n *\n * @param {StackedObject} other\n * @returns {AncestryComparison} an object that represent the ancestry situation.\n */\n findCommonAncestors(other: T): AncestryComparison {\n if (this === other) {\n return {\n fork: [],\n otherFork: [],\n common: [this, ...this.getAncestors()],\n } as AncestryComparison;\n }\n const ancestors = this.getAncestors();\n const otherAncestors = other.getAncestors();\n // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case\n if (\n ancestors.length === 0 &&\n otherAncestors.length > 0 &&\n this === otherAncestors[otherAncestors.length - 1]\n ) {\n return {\n fork: [],\n otherFork: [\n other,\n ...otherAncestors.slice(0, otherAncestors.length - 1),\n ],\n common: [this],\n } as AncestryComparison;\n }\n // compare ancestors\n for (let i = 0, ancestor; i < ancestors.length; i++) {\n ancestor = ancestors[i];\n if (ancestor === other) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n for (let j = 0; j < otherAncestors.length; j++) {\n if (this === otherAncestors[j]) {\n return {\n fork: [],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: [this, ...ancestors],\n } as AncestryComparison;\n }\n if (ancestor === otherAncestors[j]) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n }\n }\n // nothing shared\n return {\n fork: [this, ...ancestors],\n otherFork: [other, ...otherAncestors],\n common: [],\n } as AncestryComparison;\n }\n\n /**\n *\n * @param {StackedObject} other\n * @returns {boolean}\n */\n hasCommonAncestors(other: T): boolean {\n const commonAncestors = this.findCommonAncestors(other);\n return commonAncestors && !!commonAncestors.common.length;\n }\n\n /**\n *\n * @param {FabricObject} other object to compare against\n * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined`\n */\n isInFrontOf(other: T): boolean | undefined {\n if (this === other) {\n return undefined;\n }\n const ancestorData = this.findCommonAncestors(other);\n\n if (ancestorData.fork.includes(other as any)) {\n return true;\n }\n if (ancestorData.otherFork.includes(this as any)) {\n return false;\n }\n // if there isn't a common ancestor, we take the canvas.\n // if there is no canvas, there is nothing to compare\n const firstCommonAncestor = ancestorData.common[0] || this.canvas;\n if (!firstCommonAncestor) {\n return undefined;\n }\n const headOfFork = ancestorData.fork.pop(),\n headOfOtherFork = ancestorData.otherFork.pop(),\n thisIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfFork as any,\n ),\n otherIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfOtherFork as any,\n );\n return thisIndex > -1 && thisIndex > otherIndex;\n }\n\n // #region Serialization\n /**\n * Define a list of custom properties that will be serialized when\n * instance.toObject() gets called\n */\n static customProperties: string[] = [];\n\n /**\n * Returns an object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject(propertiesToInclude: any[] = []): any {\n const propertiesToSerialize = propertiesToInclude.concat(\n FabricObject.customProperties,\n (this.constructor as typeof FabricObject).customProperties || [],\n );\n let clipPathData: Partial | undefined;\n const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n const {\n clipPath,\n fill,\n stroke,\n shadow,\n strokeDashArray,\n left,\n top,\n originX,\n originY,\n width,\n height,\n strokeWidth,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit,\n scaleX,\n scaleY,\n angle,\n flipX,\n flipY,\n opacity,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX,\n skewY,\n } = this;\n if (clipPath && !clipPath.excludeFromExport) {\n clipPathData = clipPath.toObject(\n propertiesToSerialize.concat('inverted', 'absolutePositioned'),\n );\n }\n const toFixedBound = (val: number) => toFixed(val, NUM_FRACTION_DIGITS);\n const object = {\n ...pick(this, propertiesToSerialize as (keyof this)[]),\n type: (this.constructor as typeof FabricObject).type,\n version: VERSION,\n originX,\n originY,\n left: toFixedBound(left),\n top: toFixedBound(top),\n width: toFixedBound(width),\n height: toFixedBound(height),\n fill: isSerializableFiller(fill) ? fill.toObject() : fill,\n stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke,\n strokeWidth: toFixedBound(strokeWidth),\n strokeDashArray: strokeDashArray\n ? strokeDashArray.concat()\n : strokeDashArray,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit: toFixedBound(strokeMiterLimit),\n scaleX: toFixedBound(scaleX),\n scaleY: toFixedBound(scaleY),\n angle: toFixedBound(angle),\n flipX,\n flipY,\n opacity: toFixedBound(opacity),\n shadow: shadow ? shadow.toObject() : shadow,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX: toFixedBound(skewX),\n skewY: toFixedBound(skewY),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n\n return !this.includeDefaultValues\n ? this._removeDefaultValues(object)\n : object;\n }\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: any[]): any {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n }\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues(object: T): Partial {\n // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance\n // ownDefault vs prototype is swappable only if you change all the fabric objects consistently.\n const defaults = (this.constructor as typeof FabricObject).getDefaults();\n const hasStaticDefaultValues = Object.keys(defaults).length > 0;\n const baseValues = hasStaticDefaultValues\n ? defaults\n : Object.getPrototypeOf(this);\n\n return pickBy(object, (value, key) => {\n if (key === LEFT || key === TOP || key === 'type') {\n return true;\n }\n const baseValue = baseValues[key];\n return (\n value !== baseValue &&\n // basically a check for [] === []\n !(\n Array.isArray(value) &&\n Array.isArray(baseValue) &&\n value.length === 0 &&\n baseValue.length === 0\n )\n );\n });\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString() {\n return `#<${(this.constructor as typeof FabricObject).type}>`;\n }\n\n /**\n *\n * @param {Function} klass\n * @param {object} object\n * @param {object} [options]\n * @param {string} [options.extraParam] property to pass as first argument to the constructor\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static _fromObject(\n { type, ...serializedObjectOptions }: Record,\n { extraParam, ...options }: Abortable & { extraParam?: string } = {},\n ): Promise {\n return enlivenObjectEnlivables(serializedObjectOptions, options).then(\n (enlivedObjectOptions) => {\n // from the resulting enlived options, extract options.extraParam to arg0\n // to avoid accidental overrides later\n if (extraParam) {\n delete enlivedObjectOptions[extraParam];\n return new this(\n serializedObjectOptions[extraParam],\n // @ts-expect-error different signature\n enlivedObjectOptions,\n );\n } else {\n return new this(enlivedObjectOptions);\n }\n },\n ) as Promise;\n }\n\n /**\n *\n * @param {object} object\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n object: T,\n options?: Abortable,\n ) {\n return this._fromObject(object, options);\n }\n}\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n","import type {\n TModificationEvents,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\n/**\n * Wrap an action handler with firing an event if the action is performed\n * @param {TModificationEvents} eventName the event we want to fire\n * @param {TransformActionHandler} actionHandler the function to wrap\n * @param {object} extraEventInfo extra information to pas to the event handler\n * @return {TransformActionHandler} a function with an action handler signature\n */\nexport const wrapWithFireEvent = <\n T extends Transform,\n P extends object = Record,\n>(\n eventName: TModificationEvents,\n actionHandler: TransformActionHandler,\n extraEventInfo?: P,\n) => {\n return ((eventData, transform, x, y) => {\n const actionPerformed = actionHandler(eventData, transform, x, y);\n if (actionPerformed) {\n fireEvent(eventName, {\n ...commonEventInfo(eventData, transform, x, y),\n ...extraEventInfo,\n });\n }\n return actionPerformed;\n }) as TransformActionHandler;\n};\n","import type { Transform, TransformActionHandler } from '../EventTypeDefs';\n\n/**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\nexport function wrapWithFixedAnchor(\n actionHandler: TransformActionHandler,\n) {\n return ((eventData, transform, x, y) => {\n const { target, originX, originY } = transform,\n centerPoint = target.getRelativeCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, originX, originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n // flipping requires to change the transform origin, so we read from the mutated transform\n // instead of leveraging the one destructured before\n target.setPositionByOrigin(\n constraint,\n transform.originX,\n transform.originY,\n );\n return actionPerformed;\n }) as TransformActionHandler;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { CENTER, LEFT, RESIZING, RIGHT } from '../constants';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { getLocalPoint, isTransformCentered } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Action handler to change object's width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const changeObjectWidth: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const localPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // make sure the control changes width ONLY from it's side of target\n if (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) ||\n (resolveOrigin(transform.originX) === resolveOrigin(RIGHT) &&\n localPoint.x < 0) ||\n (resolveOrigin(transform.originX) === resolveOrigin(LEFT) &&\n localPoint.x > 0)\n ) {\n const { target } = transform,\n strokePadding =\n target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width,\n newWidth = Math.ceil(\n Math.abs((localPoint.x * multiplier) / target.scaleX) - strokePadding,\n );\n target.set('width', Math.max(newWidth, 0));\n // check against actual target width in case `newWidth` was rejected\n return oldWidth !== target.width;\n }\n return false;\n};\n\nexport const changeWidth = wrapWithFireEvent(\n RESIZING,\n wrapWithFixedAnchor(changeObjectWidth),\n);\n","import { FILL, STROKE, twoMathPi } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\n\nexport type ControlRenderingStyleOverride = Partial<\n Pick<\n InteractiveFabricObject,\n | 'cornerStyle'\n | 'cornerSize'\n | 'cornerColor'\n | 'cornerStrokeColor'\n | 'cornerDashArray'\n | 'transparentCorners'\n >\n>;\n\nexport type ControlRenderer<\n O extends InteractiveFabricObject = InteractiveFabricObject,\n> = (\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: O,\n) => void;\n\n/**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCircleControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n let myLeft = left,\n myTop = top,\n size;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // TODO: use proper ellipse code.\n if (xSize > ySize) {\n size = xSize;\n ctx.scale(1.0, ySize / xSize);\n myTop = (top * xSize) / ySize;\n } else if (ySize > xSize) {\n size = ySize;\n ctx.scale(xSize / ySize, 1.0);\n myLeft = (left * ySize) / xSize;\n } else {\n size = xSize;\n }\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n}\n\n/**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderSquareControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle();\n ctx.rotate(degreesToRadians(angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n ctx[`${methodName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);\n if (stroke) {\n ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n }\n ctx.restore();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type {\n ControlActionHandler,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { Intersection } from '../Intersection';\nimport { Point } from '../Point';\nimport { SCALE } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport type { TCornerPoint, TDegree, TMat2D } from '../typedefs';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { renderCircleControl, renderSquareControl } from './controlRendering';\n\nexport class Control {\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the control set.\n * @type {Boolean}\n * @default true\n */\n visible = true;\n\n /**\n * Name of the action that the control will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName = SCALE;\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle = 0;\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x = 0;\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y = 0;\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX = 0;\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY = 0;\n\n /**\n * Sets the length of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeX = 0;\n\n /**\n * Sets the height of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeY = 0;\n\n /**\n * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeX = 0;\n\n /**\n * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeY = 0;\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle = 'crosshair';\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection = false;\n\n constructor(options?: Partial) {\n Object.assign(this, options);\n }\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare actionHandler: TransformActionHandler;\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseDownHandler?: ControlActionHandler;\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseUpHandler?: ControlActionHandler;\n\n shouldActivate(\n controlKey: string,\n fabricObject: InteractiveFabricObject,\n pointer: Point,\n { tl, tr, br, bl }: TCornerPoint,\n ) {\n // TODO: locking logic can be handled here instead of in the control handler logic\n return (\n fabricObject.canvas?.getActiveObject() === fabricObject &&\n fabricObject.isControlVisible(controlKey) &&\n Intersection.isPointInPolygon(pointer, [tl, tr, br, bl])\n );\n }\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getActionHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): TransformActionHandler | undefined {\n return this.actionHandler;\n }\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseDownHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseDownHandler;\n }\n\n /**\n * Returns control mouseUp handler.\n * During actions the fabricObject or the control can be of different obj\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseUpHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseUpHandler;\n }\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.cursorStyle;\n }\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n getActionName(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.actionName;\n }\n\n /**\n * Returns controls visibility\n * @param {FabricObject} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility(fabricObject: InteractiveFabricObject, controlKey: string) {\n return fabricObject._controlsVisibility?.[controlKey] ?? this.visible;\n }\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility(\n visibility: boolean,\n name: string,\n fabricObject: InteractiveFabricObject,\n ) {\n this.visible = visibility;\n }\n\n positionHandler(\n dim: Point,\n finalMatrix: TMat2D,\n fabricObject: InteractiveFabricObject,\n currentControl: Control,\n ) {\n return new Point(\n this.x * dim.x + this.offsetX,\n this.y * dim.y + this.offsetY,\n ).transform(finalMatrix);\n }\n\n /**\n * Returns the coords for this control based on object values.\n * @param {Number} objectAngle angle from the fabric object holding the control\n * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if\n * isTouch is true)\n * @param {Number} centerX x coordinate where the control center should be\n * @param {Number} centerY y coordinate where the control center should be\n * @param {boolean} isTouch true if touch corner, false if normal corner\n */\n calcCornerCoords(\n angle: TDegree,\n objectCornerSize: number,\n centerX: number,\n centerY: number,\n isTouch: boolean,\n fabricObject: InteractiveFabricObject,\n ) {\n const t = multiplyTransformMatrixArray([\n createTranslateMatrix(centerX, centerY),\n createRotateMatrix({ angle }),\n createScaleMatrix(\n (isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize,\n (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize,\n ),\n ]);\n return {\n tl: new Point(-0.5, -0.5).transform(t),\n tr: new Point(0.5, -0.5).transform(t),\n br: new Point(0.5, 0.5).transform(t),\n bl: new Point(-0.5, 0.5).transform(t),\n };\n }\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {FabricObject} fabricObject the object where the control is about to be rendered\n */\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: InteractiveFabricObject,\n ) {\n styleOverride = styleOverride || {};\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n renderCircleControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n break;\n default:\n renderSquareControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n }\n }\n}\n","import type {\n ControlCursorCallback,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { ROTATING } from '../constants';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { isLocked, NOT_ALLOWED_CURSOR } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const rotationStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (fabricObject.lockRotation) {\n return NOT_ALLOWED_CURSOR;\n }\n return control.cursorStyle;\n};\n\n/**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\nconst rotateObjectWithSnapping: TransformActionHandler = (\n eventData,\n { target, ex, ey, theta, originX, originY },\n x,\n y,\n) => {\n const pivotPoint = target.translateToOriginPoint(\n target.getRelativeCenterPoint(),\n originX,\n originY,\n );\n\n if (isLocked(target, 'lockRotation')) {\n return false;\n }\n\n const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x);\n let angle = radiansToDegrees(curAngle - lastAngle + theta);\n\n if (target.snapAngle && target.snapAngle > 0) {\n const snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n const hasRotated = target.angle !== angle;\n // TODO: why aren't we using set?\n target.angle = angle;\n return hasRotated;\n};\n\nexport const rotationWithSnapping = wrapWithFireEvent(\n ROTATING,\n wrapWithFixedAnchor(rotateObjectWithSnapping),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxis } from '../typedefs';\nimport type { Canvas } from '../canvas/Canvas';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n invertOrigin,\n isLocked,\n isTransformCentered,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport { SCALE_X, SCALE_Y, SCALING } from '../constants';\n\ntype ScaleTransform = Transform & {\n gestureScale?: number;\n signX?: number;\n signY?: number;\n};\n\ntype ScaleBy = TAxis | 'equally' | '' | undefined;\n\n/**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\nexport function scaleIsProportional(\n eventData: TPointerEvent,\n fabricObject: FabricObject,\n): boolean {\n const canvas = fabricObject.canvas as Canvas,\n uniformIsToggled = eventData[canvas.uniScaleKey!];\n return (\n (canvas.uniformScaling && !uniformIsToggled) ||\n (!canvas.uniformScaling && uniformIsToggled)\n );\n}\n\n/**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\nexport function scalingIsForbidden(\n fabricObject: FabricObject,\n by: ScaleBy,\n scaleProportionally: boolean,\n) {\n const lockX = isLocked(fabricObject, 'lockScalingX'),\n lockY = isLocked(fabricObject, 'lockScalingY');\n if (lockX && lockY) {\n return true;\n }\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n if (lockX && by === 'x') {\n return true;\n }\n if (lockY && by === 'y') {\n return true;\n }\n // code crashes because of a division by 0 if a 0 sized object is scaled\n // forbid to prevent scaling to happen. ISSUE-9475\n const { width, height, strokeWidth } = fabricObject;\n if (width === 0 && strokeWidth === 0 && by !== 'y') {\n return true;\n }\n if (height === 0 && strokeWidth === 0 && by !== 'x') {\n return true;\n }\n return false;\n}\n\nconst scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];\n\n/**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n const scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by =\n control.x !== 0 && control.y === 0\n ? 'x'\n : control.x === 0 && control.y !== 0\n ? 'y'\n : '';\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control);\n return `${scaleMap[n]}-resize`;\n};\n\n/**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\nfunction scaleObject(\n eventData: TPointerEvent,\n transform: ScaleTransform,\n x: number,\n y: number,\n options: { by?: ScaleBy } = {},\n) {\n const target = transform.target,\n by = options.by,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally);\n let newPoint, scaleX, scaleY, dim, signX, signY;\n\n if (forbidScaling) {\n return false;\n }\n if (transform.gestureScale) {\n scaleX = transform.scaleX * transform.gestureScale;\n scaleY = transform.scaleY * transform.gestureScale;\n } else {\n newPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1;\n signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1;\n if (!transform.signX) {\n transform.signX = signX;\n }\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (\n isLocked(target, 'lockScalingFlip') &&\n (transform.signX !== signX || transform.signY !== signY)\n ) {\n return false;\n }\n\n dim = target._getTransformedDimensions();\n // missing detection of flip and logic to switch the origin\n if (scaleProportionally && !by) {\n // uniform scaling\n const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n { original } = transform,\n originalDistance =\n Math.abs((dim.x * original.scaleX) / target.scaleX) +\n Math.abs((dim.y * original.scaleY) / target.scaleY),\n scale = distance / originalDistance;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n } else {\n scaleX = Math.abs((newPoint.x * target.scaleX) / dim.x);\n scaleY = Math.abs((newPoint.y * target.scaleY) / dim.y);\n }\n // if we are scaling by center, we need to double the scale\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = invertOrigin(transform.originX);\n scaleX *= -1;\n transform.signX = signX;\n }\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = invertOrigin(transform.originY);\n scaleY *= -1;\n transform.signY = signY;\n }\n }\n // minScale is taken care of in the setter.\n const oldScaleX = target.scaleX,\n oldScaleY = target.scaleY;\n if (!by) {\n !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX);\n !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY);\n } else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set(SCALE_X, scaleX);\n by === 'y' && target.set(SCALE_Y, scaleY);\n }\n return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n}\n\n/**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scaleObjectFromCorner: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y);\n};\n\n/**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'x' });\n};\n\n/**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'y' });\n};\n\nexport const scalingEqually = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectFromCorner),\n);\n\nexport const scalingX = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectX),\n);\n\nexport const scalingY = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectY),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { TAxis, TAxisKey } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n isLocked,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport {\n CENTER,\n SCALE_X,\n SCALE_Y,\n SKEWING,\n SKEW_X,\n SKEW_Y,\n} from '../constants';\n\nexport type SkewTransform = Transform & { skewingSide: -1 | 1 };\n\nconst AXIS_KEYS: Record<\n TAxis,\n {\n counterAxis: TAxis;\n scale: TAxisKey<'scale'>;\n skew: TAxisKey<'skew'>;\n lockSkewing: TAxisKey<'lockSkewing'>;\n origin: TAxisKey<'origin'>;\n flip: TAxisKey<'flip'>;\n }\n> = {\n x: {\n counterAxis: 'y',\n scale: SCALE_X,\n skew: SKEW_X,\n lockSkewing: 'lockSkewingX',\n origin: 'originX',\n flip: 'flipX',\n },\n y: {\n counterAxis: 'x',\n scale: SCALE_Y,\n skew: SKEW_Y,\n lockSkewing: 'lockSkewingY',\n origin: 'originY',\n flip: 'flipY',\n },\n};\n\nconst skewMap = ['ns', 'nesw', 'ew', 'nwse'];\n\n/**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const skewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) {\n return NOT_ALLOWED_CURSOR;\n }\n if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control) % 4;\n return `${skewMap[n]}-resize`;\n};\n\n/**\n * Since skewing is applied before scaling, calculations are done in a scaleless plane\n * @see https://github.com/fabricjs/fabric.js/pull/8380\n */\nfunction skewObject(\n axis: TAxis,\n { target, ex, ey, skewingSide, ...transform }: SkewTransform,\n pointer: Point,\n) {\n const { skew: skewKey } = AXIS_KEYS[axis],\n offset = pointer\n .subtract(new Point(ex, ey))\n .divide(new Point(target.scaleX, target.scaleY))[axis],\n skewingBefore = target[skewKey],\n skewingStart = transform[skewKey],\n shearingStart = Math.tan(degreesToRadians(skewingStart)),\n // let a, b be the size of target\n // let a' be the value of a after applying skewing\n // then:\n // a' = a + b * skewA => skewA = (a' - a) / b\n // the value b is tricky since skewY is applied before skewX\n b =\n axis === 'y'\n ? target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n // since skewY is applied before skewX, b (=width) is not affected by skewX\n skewX: 0,\n }).x\n : target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n }).y;\n\n const shearing =\n (2 * offset * skewingSide) /\n // we max out fractions to safeguard from asymptotic behavior\n Math.max(b, 1) +\n // add starting state\n shearingStart;\n\n const skewing = radiansToDegrees(Math.atan(shearing));\n\n target.set(skewKey, skewing);\n const changed = skewingBefore !== target[skewKey];\n\n if (changed && axis === 'y') {\n // we don't want skewing to affect scaleX\n // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer\n const { skewX, scaleX } = target,\n dimBefore = target._getTransformedDimensions({ skewY: skewingBefore }),\n dimAfter = target._getTransformedDimensions(),\n compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1;\n compensationFactor !== 1 &&\n target.set(SCALE_X, compensationFactor * scaleX);\n }\n\n return changed;\n}\n\n/**\n * Wrapped Action handler for skewing on a given axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nfunction skewHandler(\n axis: TAxis,\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n) {\n const { target } = transform,\n {\n counterAxis,\n origin: originKey,\n lockSkewing: lockSkewingKey,\n skew: skewKey,\n flip: flipKey,\n } = AXIS_KEYS[axis];\n if (isLocked(target, lockSkewingKey)) {\n return false;\n }\n\n const { origin: counterOriginKey, flip: counterFlipKey } =\n AXIS_KEYS[counterAxis],\n counterOriginFactor =\n resolveOrigin(transform[counterOriginKey]) *\n (target[counterFlipKey] ? -1 : 1),\n // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively.\n // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively.\n // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer,\n // so we factor skewing direction by this value.\n skewingSide = (-Math.sign(counterOriginFactor) *\n (target[flipKey] ? -1 : 1)) as 1 | -1,\n skewingDirection =\n ((target[skewKey] === 0 &&\n // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing\n getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0) ||\n // in case target has skewing we use that as the direction\n target[skewKey] > 0\n ? 1\n : -1) * skewingSide,\n // anchor to the opposite side of the skewing direction\n // normalize value from [-1, 1] to origin value [0, 1]\n origin = -skewingDirection * 0.5 + 0.5;\n\n const finalHandler = wrapWithFireEvent(\n SKEWING,\n wrapWithFixedAnchor((eventData, transform, x, y) =>\n skewObject(axis, transform, new Point(x, y)),\n ),\n );\n\n return finalHandler(\n eventData,\n {\n ...transform,\n [originKey]: origin,\n skewingSide,\n },\n x,\n y,\n );\n}\n\n/**\n * Wrapped Action handler for skewing on the X axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('x', eventData, transform, x, y);\n};\n\n/**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('y', eventData, transform, x, y);\n};\n","import type {\n ControlCallback,\n ControlCursorCallback,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { SCALE_X, SCALE_Y, SKEW_X, SKEW_Y } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxisKey } from '../typedefs';\nimport { scaleCursorStyleHandler, scalingX, scalingY } from './scale';\nimport { skewCursorStyleHandler, skewHandlerX, skewHandlerY } from './skew';\n\nfunction isAltAction(eventData: TPointerEvent, target: FabricObject) {\n return eventData[target.canvas!.altActionKey!];\n}\n\n/**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\nexport const scaleOrSkewActionName: ControlCallback<\n TAxisKey<'skew' | 'scale'> | ''\n> = (eventData, control, fabricObject) => {\n const isAlternative = isAltAction(eventData, fabricObject);\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_X : SCALE_Y;\n }\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_Y : SCALE_X;\n }\n return '';\n};\n\n/**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleSkewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n return isAltAction(eventData, fabricObject)\n ? skewCursorStyleHandler(eventData, control, fabricObject)\n : scaleCursorStyleHandler(eventData, control, fabricObject);\n};\n/**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingXOrSkewingY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerY(eventData, transform, x, y)\n : scalingX(eventData, transform, x, y);\n};\n\n/**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingYOrSkewingX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerX(eventData, transform, x, y)\n : scalingY(eventData, transform, x, y);\n};\n","import { RESIZING, ROTATE } from '../constants';\nimport { changeWidth } from './changeWidth';\nimport { Control } from './Control';\nimport { rotationStyleHandler, rotationWithSnapping } from './rotate';\nimport { scaleCursorStyleHandler, scalingEqually } from './scale';\nimport {\n scaleOrSkewActionName,\n scaleSkewCursorStyleHandler,\n scalingXOrSkewingY,\n scalingYOrSkewingX,\n} from './scaleSkew';\n\n// use this function if you want to generate new controls for every instance\nexport const createObjectDefaultControls = () => ({\n ml: new Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mr: new Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mb: new Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n mt: new Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n tl: new Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n tr: new Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n bl: new Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n br: new Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n mtr: new Control({\n x: 0,\n y: -0.5,\n actionHandler: rotationWithSnapping,\n cursorStyleHandler: rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: ROTATE,\n }),\n});\n\nexport const createResizeControls = () => ({\n mr: new Control({\n x: 0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n ml: new Control({\n x: -0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n});\n\nexport const createTextboxDefaultControls = () => ({\n ...createObjectDefaultControls(),\n ...createResizeControls(),\n});\n","import { Point, ZERO } from '../../Point';\nimport type { TCornerPoint, TDegree } from '../../typedefs';\nimport { FabricObject } from './Object';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport type { TQrDecomposeOut } from '../../util/misc/matrix';\nimport {\n calcDimensionsMatrix,\n createRotateMatrix,\n createTranslateMatrix,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../../util/misc/matrix';\nimport type { Control } from '../../controls/Control';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { ControlRenderingStyleOverride } from '../../controls/controlRendering';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { createObjectDefaultControls } from '../../controls/commonControls';\nimport { interactiveObjectDefaultValues } from './defaultValues';\nimport { SCALE } from '../../constants';\n\nexport type TOCoord = Point & {\n corner: TCornerPoint;\n touchCorner: TCornerPoint;\n};\n\nexport type TControlSet = Record;\n\nexport type TBorderRenderingStyleOverride = Partial<\n Pick\n>;\n\nexport type TStyleOverride = ControlRenderingStyleOverride &\n TBorderRenderingStyleOverride &\n Partial<\n Pick & {\n forActiveSelection: boolean;\n }\n >;\n\nexport class InteractiveFabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n declare noScaleCache: boolean;\n\n declare snapAngle?: TDegree;\n declare snapThreshold?: TDegree;\n\n declare lockMovementX: boolean;\n declare lockMovementY: boolean;\n declare lockRotation: boolean;\n declare lockScalingX: boolean;\n declare lockScalingY: boolean;\n declare lockSkewingX: boolean;\n declare lockSkewingY: boolean;\n declare lockScalingFlip: boolean;\n\n declare cornerSize: number;\n declare touchCornerSize: number;\n declare transparentCorners: boolean;\n declare cornerColor: string;\n declare cornerStrokeColor: string;\n declare cornerStyle: 'rect' | 'circle';\n declare cornerDashArray: number[] | null;\n declare hasControls: boolean;\n\n declare borderColor: string;\n declare borderDashArray: number[] | null;\n declare borderOpacityWhenMoving: number;\n declare borderScaleFactor: number;\n declare hasBorders: boolean;\n declare selectionBackgroundColor: string;\n\n declare selectable: boolean;\n declare evented: boolean;\n declare perPixelTargetFind: boolean;\n declare activeOn: 'down' | 'up';\n\n declare hoverCursor: CSSStyleDeclaration['cursor'] | null;\n declare moveCursor: CSSStyleDeclaration['cursor'] | null;\n\n /**\n * The object's controls' position in viewport coordinates\n * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}.\n * `corner/touchCorner` describe the 4 points forming the interactive area of the corner.\n * Used to draw and locate controls.\n */\n declare oCoords: Record;\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * this isn't cleaned automatically. Non selected objects may have wrong values\n * @type [string]\n */\n declare __corner?: string;\n\n /**\n * a map of control visibility for this object.\n * this was left when controls were introduced to not break the api too much\n * this takes priority over the generic control visibility\n */\n declare _controlsVisibility: Record;\n\n /**\n * holds the controls for the object.\n * controls are added by default_controls.js\n */\n declare controls: TControlSet;\n\n /**\n * internal boolean to signal the code that the object is\n * part of the move action.\n */\n declare isMoving?: boolean;\n\n /**\n * A boolean used from the gesture module to keep tracking of a scaling\n * action when there is no scaling transform in place.\n * This is an edge case and is used twice in all codebase.\n * Probably added to keep track of some performance issues\n * @TODO use git blame to investigate why it was added\n * DON'T USE IT. WE WILL TRY TO REMOVE IT\n */\n declare _scaling?: boolean;\n\n declare canvas?: Canvas;\n\n static ownDefaults = interactiveObjectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...InteractiveFabricObject.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof InteractiveFabricObject).createControls(),\n InteractiveFabricObject.ownDefaults,\n );\n this.setOptions(options);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults\n * @param {Object} [options] Options object\n */\n static createControls(): { controls: Record } {\n return { controls: createObjectDefaultControls() };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n const transform = targetCanvas._currentTransform,\n target = transform.target,\n action = transform.action;\n if (\n this === (target as unknown as this) &&\n action &&\n action.startsWith(SCALE)\n ) {\n return false;\n }\n }\n return super._updateCacheCanvas();\n }\n\n getActiveControl() {\n const key = this.__corner;\n return key\n ? {\n key,\n control: this.controls[key],\n coord: this.oCoords[key],\n }\n : undefined;\n }\n\n /**\n * Determines which corner is under the mouse cursor, represented by `pointer`.\n * This function is return a corner only if the object is the active one.\n * This is done to avoid selecting corner of non active object and activating transformations\n * rather than drag action. The default behavior of fabricJS is that if you want to transform\n * an object, first you select it to show the control set\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found.\n */\n findControl(\n pointer: Point,\n forTouch = false,\n ): { key: string; control: Control; coord: TOCoord } | undefined {\n if (!this.hasControls || !this.canvas) {\n return undefined;\n }\n\n this.__corner = undefined;\n const cornerEntries = Object.entries(this.oCoords);\n for (let i = cornerEntries.length - 1; i >= 0; i--) {\n const [key, corner] = cornerEntries[i];\n const control = this.controls[key];\n\n if (\n control.shouldActivate(\n key,\n this,\n pointer,\n forTouch ? corner.touchCorner : corner.corner,\n )\n ) {\n // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2);\n this.__corner = key;\n\n return { key, control, coord: this.oCoords[key] };\n }\n }\n\n return undefined;\n }\n\n /**\n * Calculates the coordinates of the center of each control plus the corners of the control itself\n * This basically just delegates to each control positionHandler\n * WARNING: changing what is passed to positionHandler is a breaking change, since position handler\n * is a public api and should be done just if extremely necessary\n * @return {Record}\n */\n calcOCoords(): Record {\n const vpt = this.getViewportTransform(),\n center = this.getCenterPoint(),\n tMatrix = createTranslateMatrix(center.x, center.y),\n rMatrix = createRotateMatrix({\n angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0),\n }),\n positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix),\n startMatrix = multiplyTransformMatrices(vpt, positionMatrix),\n finalMatrix = multiplyTransformMatrices(startMatrix, [\n 1 / vpt[0],\n 0,\n 0,\n 1 / vpt[3],\n 0,\n 0,\n ]),\n transformOptions = this.group\n ? qrDecompose(this.calcTransformMatrix())\n : undefined;\n // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it\n if (transformOptions) {\n transformOptions.scaleX = Math.abs(transformOptions.scaleX);\n transformOptions.scaleY = Math.abs(transformOptions.scaleY);\n }\n const dim = this._calculateCurrentDimensions(transformOptions),\n coords: Record = {};\n\n this.forEachControl((control, key) => {\n const position = control.positionHandler(dim, finalMatrix, this, control);\n // coords[key] are sometimes used as points. Those are points to which we add\n // the property corner and touchCorner from `_calcCornerCoords`.\n // don't remove this assign for an object spread.\n coords[key] = Object.assign(\n position,\n this._calcCornerCoords(control, position),\n );\n });\n\n // debug code\n /*\n const canvas = this.canvas;\n setTimeout(function () {\n if (!canvas) return;\n canvas.contextTop.clearRect(0, 0, 700, 700);\n canvas.contextTop.fillStyle = 'green';\n Object.keys(coords).forEach(function(key) {\n const control = coords[key];\n canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n });\n } 50);\n */\n return coords;\n }\n\n /**\n * Sets the coordinates that determine the interaction area of each control\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @todo evaluate simplification of code switching to circle interaction area at runtime\n * @private\n */\n private _calcCornerCoords(control: Control, position: Point) {\n const angle = this.getTotalAngle();\n const corner = control.calcCornerCoords(\n angle,\n this.cornerSize,\n position.x,\n position.y,\n false,\n this,\n );\n const touchCorner = control.calcCornerCoords(\n angle,\n this.touchCornerSize,\n position.x,\n position.y,\n true,\n this,\n );\n return { corner, touchCorner };\n }\n\n /**\n * @override set controls' coordinates as well\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n * @return {void}\n */\n setCoords(): void {\n super.setCoords();\n this.canvas && (this.oCoords = this.calcOCoords());\n }\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the control's key and the object that is calling the iterator\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl(\n fn: (\n control: Control,\n key: string,\n fabricObject: InteractiveFabricObject,\n ) => any,\n ) {\n for (const i in this.controls) {\n fn(this.controls[i], i, this);\n }\n }\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @todo evaluate if make this disappear in favor of a pre-render hook for objects\n * this was added by Andrea Bogazzi to make possible some feature for work reasons\n * it seemed a good option, now is an edge case\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n */\n drawSelectionBackground(ctx: CanvasRenderingContext2D): void {\n if (\n !this.selectionBackgroundColor ||\n (this.canvas && (this.canvas._activeObject as unknown as this) !== this)\n ) {\n return;\n }\n ctx.save();\n const center = this.getRelativeCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.getViewportTransform();\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n }\n\n /**\n * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style.\n * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center\n * @param {Point} size the control box size used\n */\n strokeBorders(ctx: CanvasRenderingContext2D, size: Point): void {\n ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size\n * @param {TStyleOverride} styleOverride object to override the object style\n */\n _drawBorders(\n ctx: CanvasRenderingContext2D,\n size: Point,\n styleOverride: TStyleOverride = {},\n ): void {\n const options = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n borderDashArray: this.borderDashArray,\n ...styleOverride,\n };\n ctx.save();\n ctx.strokeStyle = options.borderColor;\n this._setLineDash(ctx, options.borderDashArray);\n this.strokeBorders(ctx, size);\n options.hasControls && this.drawControlsConnectingLines(ctx, size);\n ctx.restore();\n }\n\n /**\n * Renders controls and borders for the object\n * the context here is not transformed\n * @todo move to interactivity\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TStyleOverride} [styleOverride] properties to override the object style\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: TStyleOverride = {},\n ) {\n const { hasBorders, hasControls } = this;\n const styleOptions = {\n hasBorders,\n hasControls,\n ...styleOverride,\n };\n const vpt = this.getViewportTransform(),\n shouldDrawBorders = styleOptions.hasBorders,\n shouldDrawControls = styleOptions.hasControls;\n const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix());\n const options = qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n // since interactive groups have been introduced, an object could be inside a group and needing controls\n // the following equality check `this.group === this.parent` covers:\n // object without a group ( undefined === undefined )\n // object inside a group\n // excludes object inside a group but multi selected since group and parent will differ in value\n if (this.group === this.parent) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.flipX) {\n options.angle -= 180;\n }\n ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle));\n shouldDrawBorders && this.drawBorders(ctx, options, styleOverride);\n shouldDrawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {TStyleOverride} [styleOverride] object to override the object style\n */\n drawBorders(\n ctx: CanvasRenderingContext2D,\n options: TQrDecomposeOut,\n styleOverride: TStyleOverride,\n ): void {\n let size;\n if ((styleOverride && styleOverride.forActiveSelection) || this.group) {\n const bbox = sizeAfterTransform(\n this.width,\n this.height,\n calcDimensionsMatrix(options),\n ),\n stroke = !this.isStrokeAccountedForInDimensions()\n ? (this.strokeUniform\n ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1)\n : // this is extremely confusing. options comes from the upper function\n // and is the qrDecompose of a matrix that takes in account zoom too\n new Point(options.scaleX, options.scaleY)\n ).scalarMultiply(this.strokeWidth)\n : ZERO;\n size = bbox\n .add(stroke)\n .scalarAdd(this.borderScaleFactor)\n .scalarAdd(this.padding * 2);\n } else {\n size = this._calculateCurrentDimensions().scalarAdd(\n this.borderScaleFactor,\n );\n }\n this._drawBorders(ctx, size, styleOverride);\n }\n\n /**\n * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size object size x = width, y = height\n */\n drawControlsConnectingLines(\n ctx: CanvasRenderingContext2D,\n size: Point,\n ): void {\n let shouldStroke = false;\n\n ctx.beginPath();\n this.forEachControl((control, key) => {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(this, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * size.x, control.y * size.y);\n ctx.lineTo(\n control.x * size.x + control.offsetX,\n control.y * size.y + control.offsetY,\n );\n }\n });\n shouldStroke && ctx.stroke();\n }\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * Be aware that since fabric 6.0 this function does not call setCoords anymore.\n * setCoords needs to be called manually if the object of which we are rendering controls\n * is outside the standard selection and transform process.\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {ControlRenderingStyleOverride} styleOverride object to override the object style\n */\n drawControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: ControlRenderingStyleOverride = {},\n ) {\n ctx.save();\n const retinaScaling = this.getCanvasRetinaScaling();\n const { cornerStrokeColor, cornerDashArray, cornerColor } = this;\n const options = {\n cornerStrokeColor,\n cornerDashArray,\n cornerColor,\n ...styleOverride,\n };\n ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);\n ctx.strokeStyle = ctx.fillStyle = options.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = options.cornerStrokeColor;\n }\n this._setLineDash(ctx, options.cornerDashArray);\n this.forEachControl((control, key) => {\n if (control.getVisibility(this, key)) {\n const p = this.oCoords[key];\n control.render(ctx, p.x, p.y, options, this);\n }\n });\n ctx.restore();\n }\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr',\n * but since the control api allow for any control name, can be any string.\n * @returns {boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible(controlKey: string): boolean {\n return (\n this.controls[controlKey] &&\n this.controls[controlKey].getVisibility(this, controlKey)\n );\n }\n\n /**\n * Sets the visibility of the specified control.\n * please do not use.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * but since the control api allow for any control name, can be any string.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details\n */\n setControlVisible(controlKey: string, visible: boolean) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n this._controlsVisibility[controlKey] = visible;\n }\n\n /**\n * Sets the visibility state of object controls, this is just a bulk option for setControlVisible;\n * @param {Record} [options] with an optional key per control\n * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n */\n setControlsVisibility(options: Record = {}) {\n Object.entries(options).forEach(([controlKey, visibility]) =>\n this.setControlVisible(controlKey, visibility),\n );\n }\n\n /**\n * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box\n * that is in the canvas.contextContainer.\n * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object.\n * Example: blinking cursor text selection, drag effects.\n * @todo discuss swapping restoreManually with a renderCallback, but think of async issues\n * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else.\n * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed\n * with the object transformMatrix, or restored to neutral transform\n */\n clearContextTop(\n restoreManually?: boolean,\n ): CanvasRenderingContext2D | undefined {\n if (!this.canvas) {\n return;\n }\n const ctx = this.canvas.contextTop;\n if (!ctx) {\n return;\n }\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n // we add 4 pixel, to be sure to do not leave any pixel out\n const width = this.width + 4,\n height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n\n restoreManually || ctx.restore();\n return ctx;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {TPointerEvent} [options.e] event if the process is generated by an event\n * @param {FabricObject} [options.object] next object we are setting as active, and reason why\n * this is being deselected\n */\n onDeselect(_options?: {\n e?: TPointerEvent;\n object?: InteractiveFabricObject;\n }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {Event} [_options.e] event if the process is generated by an event\n */\n onSelect(_options?: { e?: TPointerEvent }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * Override to customize Drag behavior\n * Fired from {@link Canvas#_onMouseMove}\n * @returns true in order for the window to start a drag session\n */\n shouldStartDragging(_e: TPointerEvent) {\n return false;\n }\n\n /**\n * Override to customize Drag behavior\\\n * Fired once a drag session has started\n * @returns true to handle the drag event\n */\n onDragStart(_e: DragEvent) {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * @public\n * @param {DragEvent} _e\n * @returns {boolean} true if the object currently dragged can be dropped on the target\n */\n canDrop(_e: DragEvent): boolean {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the source of a drag event\n * example: render the selection status for the part of text that is being dragged from a text object\n * @public\n * @param {DragEvent} _e\n */\n renderDragSourceEffect(_e: DragEvent) {\n // for subclasses\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the target of a drag event\n * used to show that the underly object can receive a drop, or to show how the\n * object will change when dropping. example: show the cursor where the text is about to be dropped\n * @public\n * @param {DragEvent} _e\n */\n renderDropTargetEffect(_e: DragEvent) {\n // for subclasses\n }\n}\n","import type { Constructor } from '../typedefs';\n\n/***\n * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern\n */\nexport function applyMixins(\n derivedCtor: T,\n constructors: S[],\n) {\n constructors.forEach((baseCtor) => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\n name !== 'constructor' &&\n Object.defineProperty(\n derivedCtor.prototype,\n name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||\n Object.create(null),\n );\n });\n });\n return derivedCtor as T & { prototype: InstanceType };\n}\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport { FabricObjectSVGExportMixin } from './FabricObjectSVGExportMixin';\nimport { InteractiveFabricObject } from './InteractiveObject';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { classRegistry } from '../../ClassRegistry';\n\n// TODO somehow we have to make a tree-shakeable import\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FabricObject<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Props extends TFabricObjectProps = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObjectSVGExportMixin {}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class FabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends InteractiveFabricObject {}\n\napplyMixins(FabricObject, [FabricObjectSVGExportMixin]);\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n\nexport { cacheProperties } from './defaultValues';\n","/**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer\n * @return {boolean} true if transparent\n */\nexport const isTransparent = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n tolerance: number,\n): boolean => {\n tolerance = Math.round(tolerance);\n const size = tolerance * 2 + 1;\n const { data } = ctx.getImageData(x - tolerance, y - tolerance, size, size);\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (let i = 3; i < data.length; i += 4) {\n const alphaChannel = data[i];\n if (alphaChannel > 0) {\n return false;\n }\n }\n return true;\n};\n","import type { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n/**\n * Rotates `point` around `origin` with `radians`\n * @deprecated use the Point.rotate\n * @param {Point} origin The origin of the rotation\n * @param {Point} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotatePoint = (\n point: Point,\n origin: Point,\n radians: TRadian,\n): Point => point.rotate(radians, origin);\n","export const findIndexRight = (\n array: T[],\n predicate: (value: T, index: number, array: T[]) => boolean,\n) => {\n for (let index = array.length - 1; index >= 0; index--) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport { createVector } from '../vectors';\nimport type { TProjectStrokeOnPointsOptions, TProjection } from './types';\n\n/**\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n * @todo consider removing skewing from points before calculating stroke projection,\n * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537\n */\nexport abstract class StrokeProjectionsBase {\n declare options: TProjectStrokeOnPointsOptions;\n declare scale: Point;\n declare strokeUniformScalar: Point;\n declare strokeProjectionMagnitude: number;\n\n constructor(options: TProjectStrokeOnPointsOptions) {\n this.options = options;\n this.strokeProjectionMagnitude = this.options.strokeWidth / 2;\n this.scale = new Point(this.options.scaleX, this.options.scaleY);\n this.strokeUniformScalar = this.options.strokeUniform\n ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY)\n : new Point(1, 1);\n }\n\n /**\n * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account.\n */\n protected createSideVector(from: XY, to: XY) {\n const v = createVector(from, to);\n return this.options.strokeUniform ? v.multiply(this.scale) : v;\n }\n\n protected abstract calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude?: number,\n ): Point;\n\n protected projectOrthogonally(from: Point, to: Point, magnitude?: number) {\n return this.applySkew(\n from.add(this.calcOrthogonalProjection(from, to, magnitude)),\n );\n }\n\n protected isSkewed() {\n return this.options.skewX !== 0 || this.options.skewY !== 0;\n }\n\n protected applySkew(point: Point) {\n const p = new Point(point);\n // skewY must be applied before skewX as this distortion affects skewX calculation\n p.y += p.x * Math.tan(degreesToRadians(this.options.skewY));\n p.x += p.y * Math.tan(degreesToRadians(this.options.skewX));\n return p;\n }\n\n protected scaleUnitVector(unitVector: Point, scalar: number) {\n return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar);\n }\n\n protected abstract projectPoints(): Point[];\n\n public abstract project(): TProjection[];\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { halfPI, twoMathPi } from '../../../constants';\nimport type { TRadian } from '../../../typedefs';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport {\n calcAngleBetweenVectors,\n calcVectorRotation,\n crossProduct,\n getOrthonormalVector,\n getUnitVector,\n isBetweenVectors,\n magnitude,\n rotateVector,\n} from '../vectors';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nconst zeroVector = new Point();\n\n/**\n * class in charge of finding projections for each type of line join\n * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)}\n *\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin\n * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n *\n */\nexport class StrokeLineJoinProjections extends StrokeProjectionsBase {\n /**\n * The point being projected (the angle ∠BAC)\n */\n declare A: Point;\n /**\n * The point before A\n */\n declare B: Point;\n /**\n * The point after A\n */\n declare C: Point;\n /**\n * The AB vector\n */\n AB: Point;\n /**\n * The AC vector\n */\n AC: Point;\n /**\n * The angle of A (∠BAC)\n */\n alpha: TRadian;\n /**\n * The bisector of A (∠BAC)\n */\n bisector: Point;\n\n static getOrthogonalRotationFactor(vector1: Point, vector2?: Point) {\n const angle = vector2\n ? calcAngleBetweenVectors(vector1, vector2)\n : calcVectorRotation(vector1);\n return Math.abs(angle) < halfPI ? -1 : 1;\n }\n\n constructor(A: XY, B: XY, C: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.B = new Point(B);\n this.C = new Point(C);\n this.AB = this.createSideVector(this.A, this.B);\n this.AC = this.createSideVector(this.A, this.C);\n this.alpha = calcAngleBetweenVectors(this.AB, this.AC);\n this.bisector = getUnitVector(\n // if AC is also the zero vector nothing will be projected\n // in that case the next point will handle the projection\n rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2),\n );\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n const orthogonalProjection = getOrthonormalVector(vector);\n const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(\n orthogonalProjection,\n this.bisector,\n );\n return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide);\n }\n\n /**\n * BEVEL\n * Calculation: the projection points are formed by the vector orthogonal to the vertex.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel\n */\n projectBevel() {\n const projections: Point[] = [];\n // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C`\n (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(\n (to) => {\n projections.push(this.projectOrthogonally(this.A, to));\n projections.push(\n this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude),\n );\n },\n );\n return projections;\n }\n\n /**\n * MITER\n * Calculation: the corner is formed by extending the outer edges of the stroke\n * at the tangents of the path segments until they intersect.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter\n */\n projectMiter() {\n const projections: Point[] = [],\n alpha = Math.abs(this.alpha),\n hypotUnitScalar = 1 / Math.sin(alpha / 2),\n miterVector = this.scaleUnitVector(\n this.bisector,\n -this.strokeProjectionMagnitude * hypotUnitScalar,\n );\n\n // When two line segments meet at a sharp angle, it is possible for the join to extend,\n // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes\n // a limit on the extent of the line join.\n // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit\n // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit\n const strokeMiterLimit = this.options.strokeUniform\n ? magnitude(\n this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit),\n )\n : this.options.strokeMiterLimit;\n\n if (\n magnitude(miterVector) / this.strokeProjectionMagnitude <=\n strokeMiterLimit\n ) {\n projections.push(this.applySkew(this.A.add(miterVector)));\n }\n /* when the miter-limit is reached, the stroke line join becomes of type bevel.\n We always need two orthogonal projections which are basically bevel-type projections,\n so regardless of whether the miter-limit was reached or not, we include these projections.\n */\n projections.push(...this.projectBevel());\n\n return projections;\n }\n\n /**\n * ROUND (without skew)\n * Calculation: the projections are the two vectors parallel to X and Y axes\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew\n */\n private projectRoundNoSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [],\n // correctSide is used to only consider projecting for the outer side\n correctSide = new Point(\n StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector),\n StrokeLineJoinProjections.getOrthogonalRotationFactor(\n new Point(this.bisector.y, this.bisector.x),\n ),\n ),\n radiusOnAxisX = new Point(1, 0)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide),\n radiusOnAxisY = new Point(0, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide);\n\n [radiusOnAxisX, radiusOnAxisY].forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.A.add(vector));\n }\n });\n return projections;\n }\n\n /**\n * ROUND (with skew)\n * Calculation: the projections are the points furthest from the vertex in\n * the direction of the X and Y axes after distortion.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew\n */\n private projectRoundWithSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [];\n\n const { skewX, skewY, scaleX, scaleY, strokeUniform } = this.options,\n shearing = new Point(\n Math.tan(degreesToRadians(skewX)),\n Math.tan(degreesToRadians(skewY)),\n );\n // The points furthest from the vertex in the direction of the X and Y axes after distortion\n const circleRadius = this.strokeProjectionMagnitude,\n newY = strokeUniform\n ? circleRadius /\n scaleY /\n Math.sqrt(1 / scaleY ** 2 + (1 / scaleX ** 2) * shearing.y ** 2)\n : circleRadius / Math.sqrt(1 + shearing.y ** 2),\n furthestY = new Point(\n // Safe guard due to floating point precision. In some situations the square root\n // was returning NaN because of a negative number close to zero.\n Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)),\n newY,\n ),\n newX = strokeUniform\n ? circleRadius /\n Math.sqrt(\n 1 +\n (shearing.x ** 2 * (1 / scaleY) ** 2) /\n (1 / scaleX + (1 / scaleX) * shearing.x * shearing.y) ** 2,\n )\n : circleRadius /\n Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2),\n furthestX = new Point(\n newX,\n Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0)),\n );\n\n [\n furthestX,\n furthestX.scalarMultiply(-1),\n furthestY,\n furthestY.scalarMultiply(-1),\n ]\n // We need to skew the vector here as this information is used to check if\n // it is between the start and end of the circle segment\n .map((vector) =>\n this.applySkew(\n strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector,\n ),\n )\n .forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.applySkew(this.A).add(vector));\n }\n });\n\n return projections;\n }\n\n projectRound() {\n const projections: Point[] = [];\n /* Include the start and end points of the circle segment, so that only\n the projections contained within it are included */\n // add the orthogonal projections (start and end points of circle segment)\n projections.push(...this.projectBevel());\n // let's determines which one of the orthogonal projection is the beginning and end of the circle segment.\n // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different.\n const isStraightLine = this.alpha % twoMathPi === 0,\n // change the origin of the projections to point A\n // so that the cross product calculation is correct\n newOrigin = this.applySkew(this.A),\n proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin),\n proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin),\n // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector.\n comparisonVector = isStraightLine\n ? this.applySkew(this.AB.scalarMultiply(-1))\n : this.applySkew(\n this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1),\n ),\n // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0)\n isProj0Start = crossProduct(proj0, comparisonVector) > 0,\n startCircle = isProj0Start ? proj0 : proj1,\n endCircle = isProj0Start ? proj1 : proj0;\n if (!this.isSkewed()) {\n projections.push(...this.projectRoundNoSkew(startCircle, endCircle));\n } else {\n projections.push(...this.projectRoundWithSkew(startCircle, endCircle));\n }\n return projections;\n }\n\n /**\n * Project stroke width on points returning projections for each point as follows:\n * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel)\n * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke.\n * - `round`: same as `bevel` when it has no skew, with skew are 4 points.\n */\n protected projectPoints() {\n switch (this.options.strokeLineJoin) {\n case 'miter':\n return this.projectMiter();\n case 'round':\n return this.projectRound();\n default:\n return this.projectBevel();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n angle: this.alpha,\n bisector: this.bisector,\n }));\n }\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { getOrthonormalVector, getUnitVector } from '../vectors';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\n/**\n * class in charge of finding projections for each type of line cap for start/end of an open path\n * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)}\n *\n * Reference:\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap\n * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n */\nexport class StrokeLineCapProjections extends StrokeProjectionsBase {\n /**\n * edge point\n */\n declare A: Point;\n /**\n * point next to edge point\n */\n declare T: Point;\n\n constructor(A: XY, T: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.T = new Point(T);\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n return this.scaleUnitVector(getOrthonormalVector(vector), magnitude);\n }\n\n /**\n * OPEN PATH START/END - Line cap: Butt\n * Calculation: to find the projections, just find the points orthogonal to the stroke\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt\n */\n projectButt() {\n return [\n this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude),\n this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude),\n ];\n }\n\n /**\n * OPEN PATH START/END - Line cap: Round\n * Calculation: same as stroke line join `round`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round\n */\n projectRound() {\n const projections: Point[] = [];\n\n if (!this.isSkewed() && this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(\n this.applySkew(this.A.add(projection)),\n this.applySkew(this.A.subtract(projection)),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(\n this.A,\n this.T,\n this.T,\n this.options,\n ).projectRound(),\n );\n }\n\n return projections;\n }\n\n /**\n * OPEN PATH START/END - Line cap: Square\n * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square\n */\n projectSquare() {\n const projections: Point[] = [];\n\n if (this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(this.A.add(projection), this.A.subtract(projection));\n } else {\n const orthogonalProjection = this.calcOrthogonalProjection(\n this.A,\n this.T,\n this.strokeProjectionMagnitude,\n );\n const strokePointingOut = this.scaleUnitVector(\n getUnitVector(this.createSideVector(this.A, this.T)),\n -this.strokeProjectionMagnitude,\n );\n const projectedA = this.A.add(strokePointingOut);\n projections.push(\n projectedA.add(orthogonalProjection),\n projectedA.subtract(orthogonalProjection),\n );\n }\n\n return projections.map((p) => this.applySkew(p));\n }\n\n protected projectPoints() {\n switch (this.options.strokeLineCap) {\n case 'round':\n return this.projectRound();\n case 'square':\n return this.projectSquare();\n default:\n return this.projectButt();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n }));\n }\n}\n","import { Point, type XY } from '../../../Point';\nimport { findIndexRight } from '../../internals/findRight';\nimport { StrokeLineCapProjections } from './StrokeLineCapProjections';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nexport * from './types';\n\n/**\n *\n * Used to calculate object's bounding box\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n *\n */\nexport const projectStrokeOnPoints = (\n points: XY[],\n options: TProjectStrokeOnPointsOptions,\n openPath = false,\n): TProjection[] => {\n const projections: TProjection[] = [];\n\n if (points.length === 0) {\n return projections;\n }\n\n // first we remove duplicate neighboring points\n const reduced = points.reduce(\n (reduced, point) => {\n if (!reduced[reduced.length - 1].eq(point)) {\n reduced.push(new Point(point));\n }\n return reduced;\n },\n [new Point(points[0])],\n );\n\n if (reduced.length === 1) {\n openPath = true;\n } else if (!openPath) {\n // remove points from end in case they equal the first point\n // in order to correctly project the first point\n const start = reduced[0];\n const index = findIndexRight(reduced, (point) => !point.eq(start));\n reduced.splice(index + 1);\n }\n\n reduced.forEach((A, index, points) => {\n let B: XY, C: XY;\n if (index === 0) {\n C = points[1];\n B = openPath ? A : points[points.length - 1];\n } else if (index === points.length - 1) {\n B = points[index - 1];\n C = openPath ? A : points[0];\n } else {\n B = points[index - 1];\n C = points[index + 1];\n }\n\n if (openPath && points.length === 1) {\n projections.push(\n ...new StrokeLineCapProjections(A, A, options).project(),\n );\n } else if (openPath && (index === 0 || index === points.length - 1)) {\n projections.push(\n ...new StrokeLineCapProjections(\n A,\n index === 0 ? C : B,\n options,\n ).project(),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(A, B, C, options).project(),\n );\n }\n });\n\n return projections;\n};\n","import type { TextStyle } from '../../shapes/Text/StyledText';\n\nexport const cloneStyles = (style: TextStyle): TextStyle => {\n const newObj: TextStyle = {};\n Object.keys(style).forEach((key) => {\n newObj[key] = {};\n Object.keys(style[key]).forEach((keyInner) => {\n newObj[key][keyInner] = { ...style[key][keyInner] };\n });\n });\n return newObj;\n};\n","/**\n * Capitalizes a string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\nexport const capitalize = (string: string, firstLetterOnly = false): string =>\n `${string.charAt(0).toUpperCase()}${\n firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()\n }`;\n\n/**\n * Escapes XML in a string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\nexport const escapeXml = (string: string): string =>\n string\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n\n/**\n * Divide a string in the user perceived single units\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\nexport const graphemeSplit = (textstring: string): string[] => {\n const graphemes = [];\n for (let i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr as string);\n }\n return graphemes;\n};\n\n// taken from mdn in the charAt doc page.\nconst getWholeChar = (str: string, i: number): string | boolean => {\n const code = str.charCodeAt(i);\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xd800 || code > 0xdfff) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 <= code && code <= 0xdbff) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n const next = str.charCodeAt(i + 1);\n if (0xdc00 > next || next > 0xdfff) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n const prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 > prev || prev > 0xdbff) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n};\n","import { reNewline } from '../../constants';\nimport type {\n TextStyle,\n TextStyleDeclaration,\n} from '../../shapes/Text/StyledText';\nimport { cloneStyles } from '../internals/cloneStyles';\nimport { graphemeSplit } from '../lang_string';\n\nexport type TextStyleArray = {\n start: number;\n end: number;\n style: TextStyleDeclaration;\n}[];\n\n/**\n * @param {Object} prevStyle first style to compare\n * @param {Object} thisStyle second style to compare\n * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties\n * @return {boolean} true if the style changed\n */\nexport const hasStyleChanged = (\n prevStyle: TextStyleDeclaration,\n thisStyle: TextStyleDeclaration,\n forTextSpans = false,\n) =>\n prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.deltaY !== thisStyle.deltaY ||\n (forTextSpans &&\n (prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough));\n\n/**\n * Returns the array form of a text object's inline styles property with styles grouped in ranges\n * rather than per character. This format is less verbose, and is better suited for storage\n * so it is used in serialization (not during runtime).\n * @param {object} styles per character styles for a text object\n * @param {String} text the text string that the styles are applied to\n * @return {{start: number, end: number, style: object}[]}\n */\nexport const stylesToArray = (\n styles: TextStyle,\n text: string,\n): TextStyleArray => {\n const textLines = text.split('\\n'),\n stylesArray = [];\n let charIndex = -1,\n prevStyle = {};\n // clone style structure to prevent mutation\n styles = cloneStyles(styles);\n\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n if (!styles[i]) {\n //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle\n charIndex += chars.length;\n prevStyle = {};\n continue;\n }\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n const thisStyle = styles[i][c];\n //check if style exists for this character\n if (thisStyle && Object.keys(thisStyle).length > 0) {\n if (hasStyleChanged(prevStyle, thisStyle, true)) {\n stylesArray.push({\n start: charIndex,\n end: charIndex + 1,\n style: thisStyle,\n });\n } else {\n //if style is the same as previous character, increase end index\n stylesArray[stylesArray.length - 1].end++;\n }\n }\n prevStyle = thisStyle || {};\n }\n }\n return stylesArray;\n};\n\n/**\n * Returns the object form of the styles property with styles that are assigned per\n * character rather than grouped by range. This format is more verbose, and is\n * only used during runtime (not for serialization/storage)\n * @param {Array} styles the serialized form of a text object's styles\n * @param {String} text the text string that the styles are applied to\n * @return {Object}\n */\nexport const stylesFromArray = (\n styles: TextStyleArray | TextStyle,\n text: string,\n): TextStyle => {\n if (!Array.isArray(styles)) {\n // clone to prevent mutation\n return cloneStyles(styles);\n }\n const textLines = text.split(reNewline),\n stylesObject: TextStyle = {};\n let charIndex = -1,\n styleIndex = 0;\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n //check if there's a style collection that includes the current character\n if (\n styles[styleIndex] &&\n styles[styleIndex].start <= charIndex &&\n charIndex < styles[styleIndex].end\n ) {\n //create object for line index if it doesn't exist\n stylesObject[i] = stylesObject[i] || {};\n //assign a style at this character's index\n stylesObject[i][c] = { ...styles[styleIndex].style };\n //if character is at the end of the current style collection, move to the next\n if (charIndex === styles[styleIndex].end - 1) {\n styleIndex++;\n }\n }\n }\n }\n return stylesObject;\n};\n","import { FILL, STROKE } from '../constants';\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nexport const SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n FILL,\n 'fill-opacity',\n 'fill-rule',\n 'opacity',\n STROKE,\n 'stroke-dasharray',\n 'stroke-linecap',\n 'stroke-dashoffset',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke-width',\n 'id',\n 'paint-order',\n 'vector-effect',\n 'instantiated_by_use',\n 'clip-path',\n];\n","export function selectorMatches(element: HTMLElement, selector: string) {\n const nodeName = element.nodeName;\n const classNames = element.getAttribute('class');\n const id = element.getAttribute('id');\n const azAz = '(?![a-zA-Z\\\\-]+)';\n let matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n const splitClassNames = classNames.split(' ');\n for (let i = splitClassNames.length; i--; ) {\n matcher = new RegExp('\\\\.' + splitClassNames[i] + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\n\nexport function doesSomeParentMatch(element: HTMLElement, selectors: string[]) {\n let selector: string,\n parentMatching = true;\n while (\n element.parentElement &&\n element.parentElement.nodeType === 1 &&\n selectors.length\n ) {\n if (parentMatching) {\n selector = selectors.pop()!;\n }\n element = element.parentElement;\n parentMatching = selectorMatches(element, selector!);\n }\n return selectors.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\nimport { doesSomeParentMatch } from './doesSomeParentMatch';\n\n/**\n * @private\n */\n\nexport function elementMatchesRule(element: HTMLElement, selectors: string[]) {\n let parentMatching = true;\n // start from rightmost selector.\n const firstMatching = selectorMatches(element, selectors.pop()!);\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && selectors.length === 0;\n}\n","import { elementMatchesRule } from './elementMatchesRule';\nimport type { CSSRules } from './typedefs';\n\n/**\n * @private\n */\n\nexport function getGlobalStylesForElement(\n element: HTMLElement,\n cssRules: CSSRules = {},\n) {\n let styles: Record = {};\n for (const rule in cssRules) {\n if (elementMatchesRule(element, rule.split(' '))) {\n styles = {\n ...styles,\n ...cssRules[rule],\n };\n }\n }\n return styles;\n}\n","import { attributesMap } from './constants';\n\nexport const normalizeAttr = (\n attr: keyof typeof attributesMap | string,\n): string => attributesMap[attr as keyof typeof attributesMap] ?? attr;\n","import { reNum } from '../../parser/constants';\n\nconst regex = new RegExp(`(${reNum})`, 'gi');\n\nexport const cleanupSvgAttribute = (attributeValue: string) =>\n attributeValue\n .replace(regex, ' $1 ')\n // replace annoying commas and arbitrary whitespace with single spaces\n .replace(/,/gi, ' ')\n .replace(/\\s+/gi, ' ');\n","import { ROTATE, SCALE, SKEW_X, SKEW_Y, iMatrix } from '../constants';\nimport { reNum } from './constants';\nimport type { TMat2D } from '../typedefs';\nimport { cleanupSvgAttribute } from '../util/internals/cleanupSvgAttribute';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createSkewXMatrix,\n createSkewYMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\n\n// == begin transform regexp\nconst p = `(${reNum})`;\nconst skewX = String.raw`(skewX)\\(${p}\\)`;\nconst skewY = String.raw`(skewY)\\(${p}\\)`;\nconst rotate = String.raw`(rotate)\\(${p}(?: ${p} ${p})?\\)`;\nconst scale = String.raw`(scale)\\(${p}(?: ${p})?\\)`;\nconst translate = String.raw`(translate)\\(${p}(?: ${p})?\\)`;\nconst matrix = String.raw`(matrix)\\(${p} ${p} ${p} ${p} ${p} ${p}\\)`;\nconst transform = `(?:${matrix}|${translate}|${rotate}|${scale}|${skewX}|${skewY})`;\nconst transforms = `(?:${transform}*)`;\nconst transformList = String.raw`^\\s*(?:${transforms}?)\\s*$`;\n// http://www.w3.org/TR/SVG/coords.html#TransformAttribute\nconst reTransformList = new RegExp(transformList);\nconst reTransform = new RegExp(transform);\nconst reTransformAll = new RegExp(transform, 'g');\n// == end transform regexp\n\n/**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {TTransformMatrix} Array of 6 elements representing transformation matrix\n */\nexport function parseTransformAttribute(attributeValue: string): TMat2D {\n // first we clean the string\n attributeValue = cleanupSvgAttribute(attributeValue)\n // remove spaces around front parentheses\n .replace(/\\s*([()])\\s*/gi, '$1');\n\n // start with identity matrix\n const matrices: TMat2D[] = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (\n !attributeValue ||\n (attributeValue && !reTransformList.test(attributeValue))\n ) {\n return [...iMatrix];\n }\n\n for (const match of attributeValue.matchAll(reTransformAll)) {\n const transformMatch = reTransform.exec(match[0]);\n if (!transformMatch) {\n continue;\n }\n let matrix: TMat2D = iMatrix;\n const matchedParams = transformMatch.filter((m) => !!m);\n const [, operation, ...rawArgs] = matchedParams;\n const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map((arg) =>\n parseFloat(arg),\n );\n\n switch (operation) {\n case 'translate':\n matrix = createTranslateMatrix(arg0, arg1);\n break;\n case ROTATE:\n matrix = createRotateMatrix({ angle: arg0 }, { x: arg1, y: arg2 });\n break;\n case SCALE:\n matrix = createScaleMatrix(arg0, arg1);\n break;\n case SKEW_X:\n matrix = createSkewXMatrix(arg0);\n break;\n case SKEW_Y:\n matrix = createSkewYMatrix(arg0);\n break;\n case 'matrix':\n matrix = [arg0, arg1, arg2, arg3, arg4, arg5];\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix);\n }\n\n return multiplyTransformMatrixArray(matrices);\n}\n","import { multiplyTransformMatrices } from '../util/misc/matrix';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { parseTransformAttribute } from './parseTransformAttribute';\nimport { CENTER, LEFT, RIGHT, NONE, FILL, STROKE } from '../constants';\n\nexport function normalizeValue(\n attr: string,\n value: any,\n parentAttributes: Record,\n fontSize: number,\n): string | null | boolean | number[] | number {\n const isArray = Array.isArray(value);\n let parsed: number | number[];\n let ouputValue: string | null | boolean | number[] | number = value;\n if ((attr === FILL || attr === STROKE) && value === NONE) {\n ouputValue = '';\n } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === NONE) {\n ouputValue = null;\n } else {\n ouputValue = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n ouputValue = multiplyTransformMatrices(\n parentAttributes.transformMatrix,\n parseTransformAttribute(value),\n );\n } else {\n ouputValue = parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n ouputValue = value !== NONE && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n ouputValue = false;\n }\n } else if (attr === 'opacity') {\n ouputValue = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n ouputValue *= parentAttributes.opacity as number;\n }\n } else if (attr === 'textAnchor' /* text-anchor */) {\n ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER;\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = (parseUnit(value, fontSize) / fontSize) * 1000;\n } else if (attr === 'paintFirst') {\n const fillIndex = value.indexOf(FILL);\n const strokeIndex = value.indexOf(STROKE);\n ouputValue = FILL;\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n ouputValue = STROKE;\n } else if (fillIndex === -1 && strokeIndex > -1) {\n ouputValue = STROKE;\n }\n } else if (\n attr === 'href' ||\n attr === 'xlink:href' ||\n attr === 'font' ||\n attr === 'id'\n ) {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality';\n } else {\n parsed = isArray\n ? (value as string[]).map(parseUnit)\n : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed! as number) ? ouputValue : parsed!;\n}\n","import { parseUnit } from '../util/misc/svgParsing';\nimport { reFontDeclaration } from './constants';\n\n/**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\nexport function parseFontDeclaration(\n value: string,\n oStyle: Record,\n): void {\n const match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n const fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight))\n ? fontWeight\n : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n}\n","/**\n * Takes a style object and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleObject(\n style: Record,\n oStyle: Record,\n): void {\n Object.entries(style).forEach(([prop, value]) => {\n if (value === undefined) {\n return;\n }\n oStyle[prop.toLowerCase()] = value;\n });\n}\n","/**\n * Takes a style string and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleString(\n style: string,\n oStyle: Record,\n): void {\n style\n .replace(/;\\s*$/, '')\n .split(';')\n .forEach((chunk) => {\n if (!chunk) return;\n const [attr, value] = chunk.split(':');\n oStyle[attr.trim().toLowerCase()] = value.trim();\n });\n}\n","import { parseStyleObject } from './parseStyleObject';\nimport { parseStyleString } from './parseStyleString';\n\n/**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\nexport function parseStyleAttribute(element: HTMLElement): Record {\n const oStyle: Record = {},\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n } else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n}\n","import { Color } from '../color/Color';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject } from '../shapes/Object/FabricObject';\n\nconst colorAttributesMap = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity',\n};\n\n/**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\nexport function setStrokeFillOpacity(\n attributes: Record,\n): Record {\n const defaults = FabricObject.getDefaults();\n Object.entries(colorAttributesMap).forEach(([attr, colorAttr]) => {\n if (\n typeof attributes[colorAttr] === 'undefined' ||\n attributes[attr] === ''\n ) {\n return;\n }\n if (typeof attributes[attr] === 'undefined') {\n if (!defaults[attr]) {\n return;\n }\n attributes[attr] = defaults[attr];\n }\n if (attributes[attr].indexOf('url(') === 0) {\n return;\n }\n const color = new Color(attributes[attr]);\n attributes[attr] = color\n .setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2))\n .toRgba();\n });\n return attributes;\n}\n","import { DEFAULT_SVG_FONT_SIZE } from '../constants';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { cPath, fSize, svgValidParentsRegEx } from './constants';\nimport { getGlobalStylesForElement } from './getGlobalStylesForElement';\nimport { normalizeAttr } from './normalizeAttr';\nimport { normalizeValue } from './normalizeValue';\nimport { parseFontDeclaration } from './parseFontDeclaration';\nimport { parseStyleAttribute } from './parseStyleAttribute';\nimport { setStrokeFillOpacity } from './setStrokeFillOpacity';\nimport type { CSSRules } from './typedefs';\n\n/**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @param {SVGElement | HTMLElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\nexport function parseAttributes(\n element: HTMLElement | null,\n attributes: string[],\n cssRules?: CSSRules,\n): Record {\n if (!element) {\n return {};\n }\n\n let parentAttributes: Record = {},\n fontSize: number,\n parentFontSize = DEFAULT_SVG_FONT_SIZE;\n\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (\n element.parentNode &&\n svgValidParentsRegEx.test(element.parentNode.nodeName)\n ) {\n parentAttributes = parseAttributes(\n element.parentElement,\n attributes,\n cssRules,\n );\n if (parentAttributes.fontSize) {\n fontSize = parentFontSize = parseUnit(parentAttributes.fontSize);\n }\n }\n\n const ownAttributes: Record = {\n ...attributes.reduce>((memo, attr) => {\n const value = element.getAttribute(attr);\n if (value) {\n memo[attr] = value;\n }\n return memo;\n }, {}),\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ...getGlobalStylesForElement(element, cssRules),\n ...parseStyleAttribute(element),\n };\n\n if (ownAttributes[cPath]) {\n element.setAttribute(cPath, ownAttributes[cPath]);\n }\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n ownAttributes[fSize] = `${fontSize}`;\n }\n\n // this should have its own complex type\n const normalizedStyle: Record<\n string,\n string | boolean | number | number[] | null\n > = {};\n for (const attr in ownAttributes) {\n const normalizedAttr = normalizeAttr(attr);\n const normalizedValue = normalizeValue(\n normalizedAttr,\n ownAttributes[attr],\n parentAttributes,\n fontSize!,\n );\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n parseFontDeclaration(normalizedStyle.font as string, normalizedStyle);\n }\n const mergedAttrs = { ...parentAttributes, ...normalizedStyle };\n return svgValidParentsRegEx.test(element.nodeName)\n ? mergedAttrs\n : setStrokeFillOpacity(mergedAttrs);\n}\n","import { kRect } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const rectDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueRectProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedRectProps\n extends SerializedObjectProps,\n UniqueRectProps {}\n\nexport interface RectProps extends FabricObjectProps, UniqueRectProps {}\n\nconst RECT_PROPS = ['rx', 'ry'] as const;\n\nexport class Rect<\n Props extends TOptions = Partial,\n SProps extends SerializedRectProps = SerializedRectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements RectProps\n{\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Rect';\n\n static cacheProperties = [...cacheProperties, ...RECT_PROPS];\n\n static ownDefaults = rectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Rect.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Rect.ownDefaults);\n this.setOptions(options);\n this._initRxRy();\n }\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy() {\n const { rx, ry } = this;\n if (rx && !ry) {\n this.ry = rx;\n } else if (ry && !rx) {\n this.rx = ry;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const { width: w, height: h } = this;\n const x = -w / 2;\n const y = -h / 2;\n const rx = this.rx ? Math.min(this.rx, w / 2) : 0;\n const ry = this.ry ? Math.min(this.ry, h / 2) : 0;\n const isRounded = rx !== 0 || ry !== 0;\n\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded &&\n ctx.bezierCurveTo(\n x + w - kRect * rx,\n y,\n x + w,\n y + kRect * ry,\n x + w,\n y + ry,\n );\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded &&\n ctx.bezierCurveTo(\n x + w,\n y + h - kRect * ry,\n x + w - kRect * rx,\n y + h,\n x + w - rx,\n y + h,\n );\n\n ctx.lineTo(x + rx, y + h);\n isRounded &&\n ctx.bezierCurveTo(\n x + kRect * rx,\n y + h,\n x,\n y + h - kRect * ry,\n x,\n y + h - ry,\n );\n\n ctx.lineTo(x, y + ry);\n isRounded &&\n ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...RECT_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { width, height, rx, ry } = this;\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`)\n * @static\n * @memberOf Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'rx',\n 'ry',\n 'width',\n 'height',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns {@link Rect} instance from an SVG element\n * @static\n * @memberOf Rect\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n left = 0,\n top = 0,\n width = 0,\n height = 0,\n visible = true,\n ...restOfparsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n\n return new this({\n ...options,\n ...restOfparsedAttributes,\n left,\n top,\n width,\n height,\n visible: Boolean(visible && width && height),\n });\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Rect);\nclassRegistry.setSVGClass(Rect);\n","export const LAYOUT_TYPE_INITIALIZATION = 'initialization';\nexport const LAYOUT_TYPE_ADDED = 'added';\nexport const LAYOUT_TYPE_REMOVED = 'removed';\nexport const LAYOUT_TYPE_IMPERATIVE = 'imperative';\nexport const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified';\nexport const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying';\n","import { Point, ZERO } from '../../Point';\nimport type { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { multiplyTransformMatrixArray } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport {\n calcPlaneChangeMatrix,\n sendVectorToPlane,\n} from '../../util/misc/planeChange';\n\n/**\n * @returns 2 points, the tl and br corners of the non rotated bounding box of an object\n * in the {@link group} plane, taking into account objects that {@link group} is their parent\n * but also belong to the active selection.\n */\nexport const getObjectBounds = (\n destinationGroup: Group,\n object: FabricObject,\n): Point[] => {\n const {\n strokeUniform,\n strokeWidth,\n width,\n height,\n group: currentGroup,\n } = object;\n const t =\n currentGroup && currentGroup !== destinationGroup\n ? calcPlaneChangeMatrix(\n currentGroup.calcTransformMatrix(),\n destinationGroup.calcTransformMatrix(),\n )\n : null;\n const objectCenter = t\n ? object.getRelativeCenterPoint().transform(t)\n : object.getRelativeCenterPoint();\n const accountForStroke = !object['isStrokeAccountedForInDimensions']();\n const strokeUniformVector =\n strokeUniform && accountForStroke\n ? sendVectorToPlane(\n new Point(strokeWidth, strokeWidth),\n undefined,\n destinationGroup.calcTransformMatrix(),\n )\n : ZERO;\n const scalingStrokeWidth =\n !strokeUniform && accountForStroke ? strokeWidth : 0;\n const sizeVector = sizeAfterTransform(\n width + scalingStrokeWidth,\n height + scalingStrokeWidth,\n multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true),\n )\n .add(strokeUniformVector)\n .scalarDivide(2);\n return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)];\n};\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_IMPERATIVE,\n} from '../constants';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { getObjectBounds } from './utils';\n\n/**\n * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout.\n * Returning `undefined` signals the `LayoutManager` to skip the layout.\n *\n * In charge of calculating the bounding box of the passed objects.\n */\nexport abstract class LayoutStrategy {\n /**\n * override by subclass for persistence (TS does not support `static abstract`)\n */\n static type = 'strategy';\n\n /**\n * Used by the `LayoutManager` to perform layout\n * @TODO/fix: if this method is calcResult, should calc unconditionally.\n * the condition to not calc should be evaluated by the layoutManager.\n * @returns layout result **OR** `undefined` to skip layout\n */\n public calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n if (this.shouldPerformLayout(context)) {\n return this.calcBoundingBox(objects, context);\n }\n }\n\n shouldPerformLayout({ type, prevStrategy, strategy }: StrictLayoutContext) {\n return (\n type === LAYOUT_TYPE_INITIALIZATION ||\n type === LAYOUT_TYPE_IMPERATIVE ||\n (!!prevStrategy && strategy !== prevStrategy)\n );\n }\n\n shouldLayoutClipPath({ type, target: { clipPath } }: StrictLayoutContext) {\n return (\n type !== LAYOUT_TYPE_INITIALIZATION &&\n clipPath &&\n !clipPath.absolutePositioned\n );\n }\n\n getInitialSize(\n context: StrictLayoutContext & InitializationLayoutContext,\n result: Pick,\n ) {\n return result.size;\n }\n\n /**\n * Override this method to customize layout.\n */\n calcBoundingBox(\n objects: FabricObject[],\n context: StrictLayoutContext,\n ): LayoutStrategyResult | undefined {\n const { type, target } = context;\n if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) {\n return context.overrides;\n }\n if (objects.length === 0) {\n return;\n }\n const { left, top, width, height } = makeBoundingBoxFromPoints(\n objects\n .map((object) => getObjectBounds(target, object))\n .reduce((coords, curr) => coords.concat(curr), []),\n );\n const bboxSize = new Point(width, height);\n const bboxLeftTop = new Point(left, top);\n const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2));\n\n if (type === LAYOUT_TYPE_INITIALIZATION) {\n const actualSize = this.getInitialSize(context, {\n size: bboxSize,\n center: bboxCenter,\n });\n return {\n // in `initialization` we do not account for target's transformation matrix\n center: bboxCenter,\n // TODO: investigate if this is still necessary\n relativeCorrection: new Point(0, 0),\n size: actualSize,\n };\n } else {\n // we send `relativeCenter` up to group's containing plane\n const center = bboxCenter.transform(target.calcOwnMatrix());\n return {\n center,\n size: bboxSize,\n };\n }\n }\n}\n","import type { StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to fit target's objects.\n */\nexport class FitContentLayout extends LayoutStrategy {\n static readonly type = 'fit-content';\n\n /**\n * @override layout on all triggers\n * Override at will\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldPerformLayout(context: StrictLayoutContext) {\n return true;\n }\n}\n\nclassRegistry.setClass(FitContentLayout);\n","import { Point } from '../Point';\nimport {\n CENTER,\n CHANGED,\n MODIFIED,\n MODIFY_PATH,\n MODIFY_POLY,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n iMatrix,\n} from '../constants';\nimport type { Group } from '../shapes/Group';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { invertTransform } from '../util/misc/matrix';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { FitContentLayout } from './LayoutStrategies/FitContentLayout';\nimport type { LayoutStrategy } from './LayoutStrategies/LayoutStrategy';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_OBJECT_MODIFIED,\n LAYOUT_TYPE_OBJECT_MODIFYING,\n} from './constants';\nimport type {\n LayoutContext,\n LayoutResult,\n RegistrationContext,\n StrictLayoutContext,\n} from './types';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TModificationEvents } from '../EventTypeDefs';\n\nconst LAYOUT_MANAGER = 'layoutManager';\n\nexport type SerializedLayoutManager = {\n type: string;\n strategy: string;\n};\n\nexport class LayoutManager {\n private declare _prevLayoutStrategy?: LayoutStrategy;\n protected declare _subscriptions: Map;\n\n strategy: LayoutStrategy;\n\n constructor(strategy: LayoutStrategy = new FitContentLayout()) {\n this.strategy = strategy;\n this._subscriptions = new Map();\n }\n\n public performLayout(context: LayoutContext) {\n const strictContext: StrictLayoutContext = {\n bubbles: true,\n strategy: this.strategy,\n ...context,\n prevStrategy: this._prevLayoutStrategy,\n stopPropagation() {\n this.bubbles = false;\n },\n };\n\n this.onBeforeLayout(strictContext);\n\n const layoutResult = this.getLayoutResult(strictContext);\n if (layoutResult) {\n this.commitLayout(strictContext, layoutResult);\n }\n\n this.onAfterLayout(strictContext, layoutResult);\n this._prevLayoutStrategy = strictContext.strategy;\n }\n\n /**\n * Attach handlers for events that we know will invalidate the layout when\n * performed on child objects ( general transforms ).\n * Returns the disposers for later unsubscribing and cleanup\n * @param {FabricObject} object\n * @param {RegistrationContext & Partial} context\n * @returns {VoidFunction[]} disposers remove the handlers\n */\n protected attachHandlers(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ): VoidFunction[] {\n const { target } = context;\n return (\n [\n MODIFIED,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n CHANGED,\n MODIFY_POLY,\n MODIFY_PATH,\n ] as (TModificationEvents & 'modified')[]\n ).map((key) =>\n object.on(key, (e) =>\n this.performLayout(\n key === MODIFIED\n ? {\n type: LAYOUT_TYPE_OBJECT_MODIFIED,\n trigger: key,\n e,\n target,\n }\n : {\n type: LAYOUT_TYPE_OBJECT_MODIFYING,\n trigger: key,\n e,\n target,\n },\n ),\n ),\n );\n }\n\n /**\n * Subscribe an object to transform events that will trigger a layout change on the parent\n * This is important only for interactive groups.\n * @param object\n * @param context\n */\n protected subscribe(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ) {\n this.unsubscribe(object, context);\n const disposers = this.attachHandlers(object, context);\n this._subscriptions.set(object, disposers);\n }\n\n /**\n * unsubscribe object layout triggers\n */\n protected unsubscribe(\n object: FabricObject,\n _context?: RegistrationContext & Partial,\n ) {\n (this._subscriptions.get(object) || []).forEach((d) => d());\n this._subscriptions.delete(object);\n }\n\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.unsubscribe(object, context));\n }\n\n subscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.subscribe(object, context));\n }\n\n protected onBeforeLayout(context: StrictLayoutContext) {\n const { target, type } = context;\n const { canvas } = target;\n // handle layout triggers subscription\n // @TODO: gate the registration when the group is interactive\n if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) {\n this.subscribeTargets(context);\n } else if (type === LAYOUT_TYPE_REMOVED) {\n this.unsubscribeTargets(context);\n }\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:before', {\n context,\n });\n canvas &&\n canvas.fire('object:layout:before', {\n target,\n context,\n });\n\n if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) {\n const { strategy: _, ...tricklingContext } = context;\n // traverse the tree\n target.forEachObject(\n (object) =>\n (object as Group).layoutManager &&\n (object as Group).layoutManager.performLayout({\n ...tricklingContext,\n bubbles: false,\n target: object as Group,\n }),\n );\n }\n }\n\n protected getLayoutResult(\n context: StrictLayoutContext,\n ): Required | undefined {\n const { target, strategy, type } = context;\n\n const result = strategy.calcLayoutResult(context, target.getObjects());\n\n if (!result) {\n return;\n }\n\n const prevCenter =\n type === LAYOUT_TYPE_INITIALIZATION\n ? new Point()\n : target.getRelativeCenterPoint();\n\n const {\n center: nextCenter,\n correction = new Point(),\n relativeCorrection = new Point(),\n } = result;\n const offset = prevCenter\n .subtract(nextCenter)\n .add(correction)\n .transform(\n // in `initialization` we do not account for target's transformation matrix\n type === LAYOUT_TYPE_INITIALIZATION\n ? iMatrix\n : invertTransform(target.calcOwnMatrix()),\n true,\n )\n .add(relativeCorrection);\n\n return {\n result,\n prevCenter,\n nextCenter,\n offset,\n };\n }\n\n protected commitLayout(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n const {\n result: { size },\n nextCenter,\n } = layoutResult;\n // set dimensions\n target.set({ width: size.x, height: size.y });\n // layout descendants\n this.layoutObjects(context, layoutResult);\n // set position\n // in `initialization` we do not account for target's transformation matrix\n if (context.type === LAYOUT_TYPE_INITIALIZATION) {\n // TODO: what about strokeWidth?\n target.set({\n left:\n context.x ?? nextCenter.x + size.x * resolveOrigin(target.originX),\n top: context.y ?? nextCenter.y + size.y * resolveOrigin(target.originY),\n });\n } else {\n target.setPositionByOrigin(nextCenter, CENTER, CENTER);\n // invalidate\n target.setCoords();\n target.set('dirty', true);\n }\n }\n\n protected layoutObjects(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n // adjust objects to account for new center\n target.forEachObject((object) => {\n object.group === target &&\n this.layoutObject(context, layoutResult, object);\n });\n // adjust clip path to account for new center\n context.strategy.shouldLayoutClipPath(context) &&\n this.layoutObject(context, layoutResult, target.clipPath as FabricObject);\n }\n\n /**\n * @param {FabricObject} object\n * @param {Point} offset\n */\n protected layoutObject(\n context: StrictLayoutContext,\n { offset }: Required,\n object: FabricObject,\n ) {\n // TODO: this is here for cache invalidation.\n // verify if this is necessary since we have explicit\n // cache invalidation at the end of commitLayout\n object.set({\n left: object.left + offset.x,\n top: object.top + offset.y,\n });\n }\n\n protected onAfterLayout(\n context: StrictLayoutContext,\n layoutResult?: LayoutResult,\n ) {\n const {\n target,\n strategy,\n bubbles,\n prevStrategy: _,\n ...bubblingContext\n } = context;\n const { canvas } = target;\n\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:after', {\n context,\n result: layoutResult,\n });\n canvas &&\n canvas.fire('object:layout:after', {\n context,\n result: layoutResult,\n target,\n });\n\n // bubble\n const parent = target.parent;\n if (bubbles && parent?.layoutManager) {\n // add target to context#path\n (bubblingContext.path || (bubblingContext.path = [])).push(target);\n // all parents should invalidate their layout\n parent.layoutManager.performLayout({\n ...bubblingContext,\n target: parent,\n });\n }\n target.set('dirty', true);\n }\n\n dispose() {\n const { _subscriptions } = this;\n _subscriptions.forEach((disposers) => disposers.forEach((d) => d()));\n _subscriptions.clear();\n }\n\n toObject() {\n return {\n type: LAYOUT_MANAGER,\n strategy: (this.strategy.constructor as typeof LayoutStrategy).type,\n };\n }\n\n toJSON() {\n return this.toObject();\n }\n}\n\nclassRegistry.setClass(LayoutManager, LAYOUT_MANAGER);\n","import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';\nimport { createCollectionMixin } from '../Collection';\nimport type {\n TClassProperties,\n TSVGReviver,\n TOptions,\n Abortable,\n} from '../typedefs';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n} from '../util/misc/matrix';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { applyTransformToObject } from '../util/misc/objectTransforms';\nimport { FabricObject } from './Object/FabricObject';\nimport { Rect } from './Rect';\nimport { classRegistry } from '../ClassRegistry';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport { log } from '../util/internals/console';\nimport type {\n ImperativeLayoutOptions,\n LayoutBeforeEvent,\n LayoutAfterEvent,\n} from '../LayoutManager/types';\nimport { LayoutManager } from '../LayoutManager/LayoutManager';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { SerializedLayoutManager } from '../LayoutManager/LayoutManager';\nimport type { FitContentLayout } from '../LayoutManager';\n\n/**\n * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case.\n * We could have used a boolean in the constructor, as we did previously, but we think the boolean\n * would stay in the group's constructor interface and create confusion, therefore it was removed.\n * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called.\n */\nclass NoopLayoutManager extends LayoutManager {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n performLayout() {}\n}\n\nexport interface GroupEvents extends ObjectEvents, CollectionEvents {\n 'layout:before': LayoutBeforeEvent;\n 'layout:after': LayoutAfterEvent;\n}\n\nexport interface GroupOwnProps {\n subTargetCheck: boolean;\n interactive: boolean;\n}\n\nexport interface SerializedGroupProps\n extends SerializedObjectProps,\n GroupOwnProps {\n objects: SerializedObjectProps[];\n layoutManager: SerializedLayoutManager;\n}\n\nexport interface GroupProps extends FabricObjectProps, GroupOwnProps {\n layoutManager: LayoutManager;\n}\n\nexport const groupDefaultValues: Partial> = {\n strokeWidth: 0,\n subTargetCheck: false,\n interactive: false,\n};\n\n/**\n * @fires object:added\n * @fires object:removed\n * @fires layout:before\n * @fires layout:after\n */\nexport class Group\n extends createCollectionMixin(\n FabricObject,\n )\n implements GroupProps\n{\n /**\n * Used to optimize performance\n * set to `false` if you don't need contained objects to be targets of events\n * @default\n * @type boolean\n */\n declare subTargetCheck: boolean;\n\n /**\n * Used to allow targeting of object inside groups.\n * set to true if you want to select an object inside a group.\\\n * **REQUIRES** `subTargetCheck` set to true\n * This will be not removed but slowly replaced with a method setInteractive\n * that will take care of enabling subTargetCheck and necessary object events.\n * There is too much attached to group interactivity to just be evaluated by a\n * boolean in the code\n * @default\n * @deprecated\n * @type boolean\n */\n declare interactive: boolean;\n\n declare layoutManager: LayoutManager;\n\n /**\n * Used internally to optimize performance\n * Once an object is selected, instance is rendered without the selected object.\n * This way instance is cached only once for the entire interaction with the selected object.\n * @private\n */\n protected _activeObjects: FabricObject[] = [];\n\n static type = 'Group';\n\n static ownDefaults: Record = groupDefaultValues;\n private __objectSelectionTracker: (ev: ObjectEvents['selected']) => void;\n private __objectSelectionDisposer: (ev: ObjectEvents['deselected']) => void;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Group.ownDefaults,\n };\n }\n\n /**\n * Constructor\n *\n * @param {FabricObject[]} [objects] instance objects\n * @param {Object} [options] Options object\n */\n constructor(objects: FabricObject[] = [], options: Partial = {}) {\n super();\n Object.assign(this, Group.ownDefaults);\n this.setOptions(options);\n this.groupInit(objects, options);\n }\n\n /**\n * Shared code between group and active selection\n * Meant to be used by the constructor.\n */\n protected groupInit(\n objects: FabricObject[],\n options: {\n layoutManager?: LayoutManager;\n top?: number;\n left?: number;\n },\n ) {\n this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller\n\n this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(\n this,\n true,\n );\n this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(\n this,\n false,\n );\n\n this.forEachObject((object) => {\n this.enterGroup(object, false);\n });\n\n // perform initial layout\n this.layoutManager = options.layoutManager ?? new LayoutManager();\n this.layoutManager.performLayout({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: this,\n targets: [...objects],\n // @TODO remove this concept from the layout manager.\n // Layout manager will calculate the correct position,\n // group options can override it later.\n x: options.left,\n y: options.top,\n });\n }\n\n /**\n * Checks if object can enter group and logs relevant warnings\n * @private\n * @param {FabricObject} object\n * @returns\n */\n canEnterGroup(object: FabricObject) {\n if (object === this || this.isDescendantOf(object)) {\n // prevent circular object tree\n log(\n 'error',\n 'Group: circular object trees are not supported, this call has no effect',\n );\n return false;\n } else if (this._objects.indexOf(object) !== -1) {\n // is already in the objects array\n log(\n 'error',\n 'Group: duplicate objects are not supported inside group, this call has no effect',\n );\n return false;\n }\n return true;\n }\n\n /**\n * Override this method to enhance performance (for groups with a lot of objects).\n * If Overriding, be sure not pass illegal objects to group - it will break your app.\n * @private\n */\n protected _filterObjectsBeforeEnteringGroup(objects: FabricObject[]) {\n return objects.filter((object, index, array) => {\n // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates)\n return this.canEnterGroup(object) && array.indexOf(object) === index;\n });\n }\n\n /**\n * Add objects\n * @param {...FabricObject[]} objects\n */\n add(...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.add(...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {FabricObject[]} objects Object to insert\n * @param {Number} index Index to insert object at\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.insertAt(index, ...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Remove objects\n * @param {...FabricObject[]} objects\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed);\n return removed;\n }\n\n _onObjectAdded(object: FabricObject) {\n this.enterGroup(object, true);\n this.fire('object:added', { target: object });\n object.fire('added', { target: this });\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _onObjectRemoved(object: FabricObject, removeParentTransform?: boolean) {\n this.exitGroup(object, removeParentTransform);\n this.fire('object:removed', { target: object });\n object.fire('removed', { target: this });\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n this.layoutManager.performLayout({\n type,\n targets,\n target: this,\n });\n }\n\n _onStackOrderChanged() {\n this._set('dirty', true);\n }\n\n /**\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n const prev = this[key as keyof this];\n super._set(key, value);\n if (key === 'canvas' && prev !== value) {\n (this._objects || []).forEach((object) => {\n object._set(key, value);\n });\n }\n return this;\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return this.subTargetCheck;\n }\n\n /**\n * Remove all objects\n * @returns {FabricObject[]} removed objects\n */\n removeAll() {\n this._activeObjects = [];\n return this.remove(...this._objects);\n }\n\n /**\n * keeps track of the selected objects\n * @private\n */\n __objectSelectionMonitor(\n selected: T,\n {\n target: object,\n }: ObjectEvents[T extends true ? 'selected' : 'deselected'],\n ) {\n const activeObjects = this._activeObjects;\n if (selected) {\n activeObjects.push(object);\n this._set('dirty', true);\n } else if (activeObjects.length > 0) {\n const index = activeObjects.indexOf(object);\n if (index > -1) {\n activeObjects.splice(index, 1);\n this._set('dirty', true);\n }\n }\n }\n\n /**\n * @private\n * @param {boolean} watch\n * @param {FabricObject} object\n */\n _watchObject(watch: boolean, object: FabricObject) {\n // make sure we listen only once\n watch && this._watchObject(false, object);\n if (watch) {\n object.on('selected', this.__objectSelectionTracker);\n object.on('deselected', this.__objectSelectionDisposer);\n } else {\n object.off('selected', this.__objectSelectionTracker);\n object.off('deselected', this.__objectSelectionDisposer);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n object.group && object.group.remove(object);\n object._set('parent', this);\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n _enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n if (removeParentTransform) {\n // can this be converted to utils (sendObjectToPlane)?\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n invertTransform(this.calcTransformMatrix()),\n object.calcTransformMatrix(),\n ),\n );\n }\n this._shouldSetNestedCoords() && object.setCoords();\n object._set('group', this);\n object._set('canvas', this.canvas);\n this._watchObject(true, object);\n const activeObject =\n this.canvas &&\n this.canvas.getActiveObject &&\n this.canvas.getActiveObject();\n // if we are adding the activeObject in a group\n if (\n activeObject &&\n (activeObject === object || object.isDescendantOf(activeObject))\n ) {\n this._activeObjects.push(object);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n object._set('parent', undefined);\n object._set('canvas', undefined);\n }\n\n /**\n * Executes the inner fabric logic of exiting a group.\n * - Stop watching the object\n * - Remove the object from the optimization map this._activeObjects\n * - unset the group property of the object\n * @protected\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n object._set('group', undefined);\n if (!removeParentTransform) {\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n this.calcTransformMatrix(),\n object.calcTransformMatrix(),\n ),\n );\n object.setCoords();\n }\n this._watchObject(false, object);\n const index =\n this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1;\n if (index > -1) {\n this._activeObjects.splice(index, 1);\n }\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache() {\n const ownCache = FabricObject.prototype.shouldCache.call(this);\n if (ownCache) {\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n }\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow() {\n if (super.willDrawShadow()) {\n return true;\n }\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if instance or its group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache(): boolean {\n return this.ownCaching || (!!this.parent && this.parent.isOnACache());\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject(ctx: CanvasRenderingContext2D) {\n this._renderBackground(ctx);\n for (let i = 0; i < this._objects.length; i++) {\n // TODO: handle rendering edge case somehow\n if (\n this.canvas?.preserveObjectStacking &&\n this._objects[i].group !== this\n ) {\n ctx.save();\n ctx.transform(...invertTransform(this.calcTransformMatrix()));\n this._objects[i].render(ctx);\n ctx.restore();\n } else if (this._objects[i].group === this) {\n this._objects[i].render(ctx);\n }\n }\n this._drawClipPath(ctx, this.clipPath);\n }\n\n /**\n * @override\n * @return {Boolean}\n */\n setCoords() {\n super.setCoords();\n this._shouldSetNestedCoords() &&\n this.forEachObject((object) => object.setCoords());\n }\n\n triggerLayout(options: ImperativeLayoutOptions = {}) {\n this.layoutManager.performLayout({\n target: this,\n type: LAYOUT_TYPE_IMPERATIVE,\n ...options,\n });\n }\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render(ctx: CanvasRenderingContext2D) {\n this._transformDone = true;\n super.render(ctx);\n this._transformDone = false;\n }\n\n /**\n *\n * @private\n * @param {'toObject'|'toDatalessObject'} [method]\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {FabricObject[]} serialized objects\n */\n __serializeObjects(\n method: 'toObject' | 'toDatalessObject',\n propertiesToInclude?: string[],\n ) {\n const _includeDefaultValues = this.includeDefaultValues;\n return this._objects\n .filter(function (obj) {\n return !obj.excludeFromExport;\n })\n .map(function (obj) {\n const originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n const data = obj[method || 'toObject'](propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n // delete data.version;\n return data;\n });\n }\n\n /**\n * Returns object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit<\n GroupProps & TClassProperties,\n keyof SerializedGroupProps\n >,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SerializedGroupProps {\n const layoutManager = this.layoutManager.toObject();\n\n return {\n ...super.toObject([\n 'subTargetCheck',\n 'interactive',\n ...propertiesToInclude,\n ]),\n ...(layoutManager.strategy !== 'fit-content' || this.includeDefaultValues\n ? { layoutManager }\n : {}),\n objects: this.__serializeObjects(\n 'toObject',\n propertiesToInclude as string[],\n ),\n };\n }\n\n toString() {\n return `#`;\n }\n\n dispose() {\n this.layoutManager.unsubscribeTargets({\n targets: this.getObjects(),\n target: this,\n });\n this._activeObjects = [];\n this.forEachObject((object) => {\n this._watchObject(false, object);\n object.dispose();\n });\n super.dispose();\n }\n\n /**\n * @private\n */\n _createSVGBgRect(reviver?: TSVGReviver) {\n if (!this.backgroundColor) {\n return '';\n }\n const fillStroke = Rect.prototype._toSVG.call(this);\n const commons = fillStroke.indexOf('COMMON_PARTS');\n fillStroke[commons] = 'for=\"group\" ';\n const markup = fillStroke.join('');\n return reviver ? reviver(markup) : markup;\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG(reviver?: TSVGReviver) {\n const svgString = ['\\n'];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('\\n');\n return svgString;\n }\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles(): string {\n const opacity =\n typeof this.opacity !== 'undefined' && this.opacity !== 1\n ? `opacity: ${this.opacity};`\n : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].join('');\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const svgString = [];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n return this._createBaseClipPathSVGMarkup(svgString, {\n reviver,\n });\n }\n\n /**\n * @todo support loading from svg\n * @private\n * @static\n * @memberOf Group\n * @param {Object} object Object to create a group from\n * @returns {Promise}\n */\n static fromObject>(\n { type, objects = [], layoutManager, ...options }: T,\n abortable?: Abortable,\n ) {\n return Promise.all([\n enlivenObjects(objects, abortable),\n enlivenObjectEnlivables(options, abortable),\n ]).then(([objects, hydratedOptions]) => {\n const group = new this(objects, {\n ...options,\n ...hydratedOptions,\n layoutManager: new NoopLayoutManager(),\n });\n if (layoutManager) {\n const layoutClass = classRegistry.getClass(\n layoutManager.type,\n );\n const strategyClass = classRegistry.getClass(\n layoutManager.strategy,\n );\n group.layoutManager = new layoutClass(new strategyClass());\n } else {\n group.layoutManager = new LayoutManager();\n }\n group.layoutManager.subscribeTargets({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: group,\n targets: group.getObjects(),\n });\n group.setCoords();\n return group;\n });\n }\n}\n\nclassRegistry.setClass(Group);\n","import type { GroupProps } from '../../shapes/Group';\nimport { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\n\n/**\n * TODO experiment with different layout manager and svg results ( fixed fit content )\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group\n * @return {FabricObject | Group}\n */\nexport const groupSVGElements = (\n elements: FabricObject[],\n options?: Partial,\n) => {\n if (elements && elements.length === 1) {\n return elements[0];\n }\n return new Group(elements, options);\n};\n","import type { TSize } from '../../typedefs';\n\n/**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\nexport const findScaleToFit = (source: TSize, destination: TSize) =>\n Math.min(\n destination.width / source.width,\n destination.height / source.height,\n );\n\n/**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\nexport const findScaleToCover = (source: TSize, destination: TSize) =>\n Math.max(\n destination.width / source.width,\n destination.height / source.height,\n );\n","import { reNum } from '../../parser/constants';\n\nconst commaWsp = `\\\\s*,?\\\\s*`;\n\n/**\n * p for param\n * using \"bad naming\" here because it makes the regex much easier to read\n * p is a number that is preceded by an arbitary number of spaces, maybe 0,\n * a comma or not, and then possibly more spaces or not.\n */\nconst p = `${commaWsp}(${reNum})`;\n\n// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;\n\n// const reLineCommand = `(L) ?(?:${p}${p} ?)+`;\n\n// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;\n\n// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;\n\n// const reClosePathCommand = String.raw`(Z)\\s*`;\n\n// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;\n\n// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;\n\nexport const reArcCommandPoints = `${p}${p}${p}${commaWsp}([01])${commaWsp}([01])${p}${p}`;\n// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;\n\n// export const rePathCommandGroups =\n// `(?:(?:${reMoveToCommand})` +\n// `|(?:${reLineCommand})` +\n// `|(?:${reHorizontalLineCommand})` +\n// `|(?:${reVerticalLineCommand})` +\n// `|(?:${reClosePathCommand})` +\n// `|(?:${reCubicCurveCommand})` +\n// `|(?:${reCubicCurveShortcutCommand})` +\n// `|(?:${reQuadraticCurveCommand})` +\n// `|(?:${reQuadraticCurveShortcutCommand})` +\n// `|(?:${reArcCommand}))`;\n\nexport const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = >basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = >basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example Usage\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n for (let out = null; (out = regExpArcCommandPoints.exec(matchStr)); ) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n","// TODO this file needs to go away, cross browser style support is not fabricjs domain.\n\n/**\n * wrapper for setting element's style\n * @param {HTMLElement} element\n * @param {Object | string} styles\n */\nexport function setStyle(\n element: HTMLElement,\n styles: string | Record,\n) {\n const elementStyle = element.style;\n if (!elementStyle || !styles) {\n return;\n } else if (typeof styles === 'string') {\n elementStyle.cssText += ';' + styles;\n } else {\n Object.entries(styles).forEach(([property, value]) =>\n elementStyle.setProperty(property, value),\n );\n }\n}\n","import type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { sendObjectToPlane } from './planeChange';\nimport { Group } from '../../shapes/Group';\n/**\n * Merges 2 clip paths into one visually equal clip path\n *\n * **IMPORTANT**:\\\n * Does **NOT** clone the arguments, clone them proir if necessary.\n *\n * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap.\n * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible.\n *\n * In order to handle the `inverted` property we follow logic described in the following cases:\\\n * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\\\n * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\\\n * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged.\n *\n * @memberOf fabric.util\n * @param {fabric.Object} c1\n * @param {fabric.Object} c2\n * @returns {fabric.Object} merged clip path\n */\nexport const mergeClipPaths = (c1: FabricObject, c2: FabricObject) => {\n let a = c1,\n b = c2;\n if (a.inverted && !b.inverted) {\n // case (2)\n a = c2;\n b = c1;\n }\n // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane\n sendObjectToPlane(b, b.group?.calcTransformMatrix(), a.calcTransformMatrix());\n // assign the `inverted` prop to the wrapping group\n const inverted = a.inverted && b.inverted;\n if (inverted) {\n // case (1)\n a.inverted = b.inverted = false;\n }\n return new Group([a], { clipPath: b, inverted });\n};\n","/**\n * Returns random number between 2 specified ones.\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\nexport const getRandomInt = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n","import { getFabricWindow } from '../../env';\nimport { noop } from '../../constants';\nimport type { Abortable } from '../../typedefs';\nimport { SignalAbortedError } from './console';\n\ntype requestOptions = Abortable & {\n onComplete?: (xhr: XMLHttpRequest) => void;\n};\n\n/**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @deprecated this has to go away, we can use a modern browser method to do the same.\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n\nexport function request(url: string, options: requestOptions = {}) {\n const onComplete = options.onComplete || noop,\n xhr = new (getFabricWindow().XMLHttpRequest)(),\n signal = options.signal,\n abort = function () {\n xhr.abort();\n },\n removeListener = function () {\n signal && signal.removeEventListener('abort', abort);\n xhr.onerror = xhr.ontimeout = noop;\n };\n\n if (signal && signal.aborted) {\n throw new SignalAbortedError('request');\n } else if (signal) {\n signal.addEventListener('abort', abort, { once: true });\n }\n\n /** @ignore */\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4) {\n removeListener();\n onComplete(xhr);\n xhr.onreadystatechange = noop;\n }\n };\n\n xhr.onerror = xhr.ontimeout = removeListener;\n\n xhr.open('get', url, true);\n\n xhr.send();\n return xhr;\n}\n","import { CENTER, SCALE_X, SCALE_Y } from '../constants';\nimport type { FabricImage } from '../shapes/Image';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { qrDecompose } from './misc/matrix';\n\ntype FabricObjectWithTransformMatrix = FabricObject & {\n transformMatrix?: TMat2D;\n};\n\n/**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n */\nconst _assignTransformMatrixProps = (\n object: FabricObjectWithTransformMatrix,\n) => {\n if (object.transformMatrix) {\n const { scaleX, scaleY, angle, skewX } = qrDecompose(\n object.transformMatrix,\n );\n object.flipX = false;\n object.flipY = false;\n object.set(SCALE_X, scaleX);\n object.set(SCALE_Y, scaleY);\n object.angle = angle;\n object.skewX = skewX;\n object.skewY = 0;\n }\n};\n\n/**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n */\nexport const removeTransformMatrixForSvgParsing = (\n object: FabricObjectWithTransformMatrix,\n preserveAspectRatioOptions?: any,\n) => {\n let center = object._findCenterFromElement();\n if (object.transformMatrix) {\n _assignTransformMatrixProps(object);\n center = center.transform(object.transformMatrix);\n }\n delete object.transformMatrix;\n if (preserveAspectRatioOptions) {\n object.scaleX *= preserveAspectRatioOptions.scaleX;\n object.scaleY *= preserveAspectRatioOptions.scaleY;\n (object as FabricImage).cropX = preserveAspectRatioOptions.cropX;\n (object as FabricImage).cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n object.width = preserveAspectRatioOptions.width;\n object.height = preserveAspectRatioOptions.height;\n }\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport { createCanvasElement, setStyle } from '../../util';\nimport type { CSSDimensions } from './util';\nimport { makeElementUnselectable, setCSSDimensions } from './util';\nimport type { CanvasItem } from './StaticCanvasDOMManager';\nimport { StaticCanvasDOMManager } from './StaticCanvasDOMManager';\nimport { setCanvasDimensions } from './util';\nimport { NONE } from '../../constants';\n\nexport class CanvasDOMManager extends StaticCanvasDOMManager {\n upper: CanvasItem;\n container: HTMLDivElement;\n\n constructor(\n arg0?: string | HTMLCanvasElement,\n {\n allowTouchScrolling = false,\n containerClass = '',\n }: {\n allowTouchScrolling?: boolean;\n /**\n * @deprecated here only for backward compatibility\n */\n containerClass?: string;\n } = {},\n ) {\n super(arg0);\n const { el: lowerCanvasEl } = this.lower;\n const upperCanvasEl = this.createUpperCanvas();\n this.upper = { el: upperCanvasEl, ctx: upperCanvasEl.getContext('2d')! };\n this.applyCanvasStyle(lowerCanvasEl, {\n allowTouchScrolling,\n });\n this.applyCanvasStyle(upperCanvasEl, {\n allowTouchScrolling,\n styles: {\n position: 'absolute',\n left: '0',\n top: '0',\n },\n });\n const container = this.createContainerElement();\n container.classList.add(containerClass);\n if (lowerCanvasEl.parentNode) {\n lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl);\n }\n container.append(lowerCanvasEl, upperCanvasEl);\n this.container = container;\n }\n\n protected createUpperCanvas() {\n const { el: lowerCanvasEl } = this.lower;\n const el = createCanvasElement();\n // we assign the same classname of the lowerCanvas\n el.className = lowerCanvasEl.className;\n // but then we remove the lower-canvas specific className\n el.classList.remove('lower-canvas');\n // we add the specific upper-canvas class\n el.classList.add('upper-canvas');\n el.setAttribute('data-fabric', 'top');\n el.style.cssText = lowerCanvasEl.style.cssText;\n el.setAttribute('draggable', 'true');\n return el;\n }\n\n protected createContainerElement() {\n const container = getFabricDocument().createElement('div');\n container.setAttribute('data-fabric', 'wrapper');\n setStyle(container, {\n position: 'relative',\n });\n makeElementUnselectable(container);\n return container;\n }\n\n /**\n * @private\n * @param {HTMLCanvasElement} element canvas element to apply styles on\n */\n protected applyCanvasStyle(\n element: HTMLCanvasElement,\n options: {\n allowTouchScrolling?: boolean;\n styles?: Record;\n },\n ) {\n const { styles, allowTouchScrolling } = options;\n setStyle(element, {\n ...styles,\n 'touch-action': allowTouchScrolling ? 'manipulation' : NONE,\n });\n makeElementUnselectable(element);\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n super.setDimensions(size, retinaScaling);\n const { el, ctx } = this.upper;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial): void {\n super.setCSSDimensions(size);\n setCSSDimensions(this.upper.el, size);\n setCSSDimensions(this.container, size);\n }\n\n cleanupDOM(size: TSize) {\n const container = this.container,\n { el: lowerCanvasEl } = this.lower,\n { el: upperCanvasEl } = this.upper;\n super.cleanupDOM(size);\n container.removeChild(upperCanvasEl);\n container.removeChild(lowerCanvasEl);\n if (container.parentNode) {\n container.parentNode.replaceChild(lowerCanvasEl, container);\n }\n }\n\n dispose() {\n super.dispose();\n getEnv().dispose(this.upper.el);\n // @ts-expect-error disposing\n delete this.upper;\n // @ts-expect-error disposing\n delete this.container;\n }\n}\n","import type { ModifierKey, TOptionalModifierKey } from '../EventTypeDefs';\nimport type { TOptions } from '../typedefs';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\n\nexport interface CanvasTransformOptions {\n /**\n * When true, objects can be transformed by one side (unproportionately)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: boolean;\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n uniScaleKey: TOptionalModifierKey;\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: boolean;\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: boolean;\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n centeredKey: TOptionalModifierKey;\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n altActionKey: TOptionalModifierKey;\n}\n\nexport interface CanvasSelectionOptions {\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: boolean;\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type ModifierKey|ModifierKey[]\n * @default\n */\n selectionKey: TOptionalModifierKey | ModifierKey[];\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|ModifierKey\n * @default\n */\n altSelectionKey: TOptionalModifierKey;\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: string;\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: number[];\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: string;\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: number;\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: boolean;\n}\n\nexport interface CanvasCursorOptions {\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n hoverCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n moveCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default default\n */\n defaultCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default crosshair\n */\n freeDrawingCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default not-allowed\n */\n notAllowedCursor: CSSStyleDeclaration['cursor'];\n}\n\nexport interface TargetFindOptions {\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: boolean;\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: number;\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: boolean;\n}\n\nexport interface CanvasEventsOptions {\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: boolean;\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: boolean;\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: boolean;\n\n /**\n * When the option is enabled, PointerEvent is used instead of TPointerEvent.\n * @type Boolean\n * @default\n */\n enablePointerEvents: boolean;\n}\n\nexport interface CanvasOptions\n extends StaticCanvasOptions,\n CanvasTransformOptions,\n CanvasSelectionOptions,\n CanvasCursorOptions,\n TargetFindOptions,\n CanvasEventsOptions {\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n * @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly\n */\n containerClass: string;\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: boolean;\n}\n\nexport type TCanvasOptions = TOptions;\n\nexport const canvasDefaults: TOptions = {\n uniformScaling: true,\n uniScaleKey: 'shiftKey',\n centeredScaling: false,\n centeredRotation: false,\n centeredKey: 'altKey',\n altActionKey: 'shiftKey',\n\n selection: true,\n selectionKey: 'shiftKey',\n selectionColor: 'rgba(100, 100, 255, 0.3)',\n selectionDashArray: [],\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n selectionLineWidth: 1,\n selectionFullyContained: false,\n\n hoverCursor: 'move',\n moveCursor: 'move',\n defaultCursor: 'default',\n freeDrawingCursor: 'crosshair',\n notAllowedCursor: 'not-allowed',\n\n perPixelTargetFind: false,\n targetFindTolerance: 0,\n skipTargetFind: false,\n\n stopContextMenu: false,\n fireRightClick: false,\n fireMiddleClick: false,\n enablePointerEvents: false,\n\n containerClass: 'canvas-container',\n\n preserveObjectStacking: false,\n};\n","import { dragHandler } from '../controls/drag';\nimport { getActionFromCorner } from '../controls/util';\nimport { Point } from '../Point';\nimport { FabricObject } from '../shapes/Object/FabricObject';\nimport type {\n CanvasEvents,\n ModifierKey,\n TOptionalModifierKey,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport {\n addTransformToObject,\n saveObjectTransform,\n} from '../util/misc/objectTransforms';\nimport type { TCanvasSizeOptions } from './StaticCanvas';\nimport { StaticCanvas } from './StaticCanvas';\nimport { isCollection } from '../Collection';\nimport { isTransparent } from '../util/misc/isTransparent';\nimport type {\n TMat2D,\n TOriginX,\n TOriginY,\n TSize,\n TSVGReviver,\n} from '../typedefs';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { getPointer, isTouchEvent } from '../util/dom_event';\nimport type { IText } from '../shapes/IText/IText';\nimport type { BaseBrush } from '../brushes/BaseBrush';\nimport { pick } from '../util/misc/pick';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { cos, createCanvasElement, sin } from '../util';\nimport { CanvasDOMManager } from './DOMManagers/CanvasDOMManager';\nimport {\n BOTTOM,\n CENTER,\n LEFT,\n MODIFIED,\n RESIZING,\n RIGHT,\n ROTATE,\n SCALE,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CanvasOptions } from './CanvasOptions';\nimport { canvasDefaults } from './CanvasOptions';\nimport { Intersection } from '../Intersection';\nimport { isActiveSelection } from '../util/typeAssertions';\n\n/**\n * Canvas class\n * @class Canvas\n * @extends StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n *\n * @fires object:modified at the end of a transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drag:enter object drag enter\n * @fires drag:leave object drag leave\n * @fires drop:before before drop event. Prepare for the drop event (same native event).\n * @fires drop\n * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event).\n * @example\n * let a: fabric.Object, b: fabric.Object;\n * let flag = false;\n * canvas.add(a, b);\n * a.on('drop:before', opt => {\n * // we want a to accept the drop even though it's below b in the stack\n * flag = this.canDrop(opt.e);\n * });\n * b.canDrop = function(e) {\n * !flag && this.draggableTextDelegate.canDrop(e);\n * }\n * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black'));\n * a.on('drop', opt => {\n * opt.e.defaultPrevented // drop occurred\n * opt.didDrop // drop occurred on canvas\n * opt.target // drop target\n * opt.target !== a && a.set('text', 'I lost');\n * });\n * canvas.on('drop:after', opt => {\n * // inform user who won\n * if(!opt.e.defaultPrevented) {\n * // no winners\n * }\n * else if(!opt.didDrop) {\n * // my objects didn't win, some other lucky object\n * }\n * else {\n * // we have a winner it's opt.target!!\n * }\n * })\n *\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * @fires contextmenu:before\n * @fires contextmenu\n * @example\n * let handler;\n * targets.forEach(target => {\n * target.on('contextmenu:before', opt => {\n * // decide which target should handle the event before canvas hijacks it\n * if (someCaseHappens && opt.targets.includes(target)) {\n * handler = target;\n * }\n * });\n * target.on('contextmenu', opt => {\n * // do something fantastic\n * });\n * });\n * canvas.on('contextmenu', opt => {\n * if (!handler) {\n * // no one takes responsibility, it's always left to me\n * // let's show them how it's done!\n * }\n * });\n *\n */\nexport class SelectableCanvas\n extends StaticCanvas\n implements Omit\n{\n declare _objects: FabricObject[];\n\n // transform config\n declare uniformScaling: boolean;\n declare uniScaleKey: TOptionalModifierKey;\n declare centeredScaling: boolean;\n declare centeredRotation: boolean;\n declare centeredKey: TOptionalModifierKey;\n declare altActionKey: TOptionalModifierKey;\n\n // selection config\n declare selection: boolean;\n declare selectionKey: TOptionalModifierKey | ModifierKey[];\n declare altSelectionKey: TOptionalModifierKey;\n declare selectionColor: string;\n declare selectionDashArray: number[];\n declare selectionBorderColor: string;\n declare selectionLineWidth: number;\n declare selectionFullyContained: boolean;\n\n // cursors\n declare hoverCursor: CSSStyleDeclaration['cursor'];\n declare moveCursor: CSSStyleDeclaration['cursor'];\n declare defaultCursor: CSSStyleDeclaration['cursor'];\n declare freeDrawingCursor: CSSStyleDeclaration['cursor'];\n declare notAllowedCursor: CSSStyleDeclaration['cursor'];\n\n declare containerClass: string;\n\n // target find config\n declare perPixelTargetFind: boolean;\n declare targetFindTolerance: number;\n declare skipTargetFind: boolean;\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n declare isDrawingMode: boolean;\n\n declare preserveObjectStacking: boolean;\n\n // event config\n declare stopContextMenu: boolean;\n declare fireRightClick: boolean;\n declare fireMiddleClick: boolean;\n\n /**\n * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget\n * @type FabricObject[]\n */\n targets: FabricObject[] = [];\n\n /**\n * Keep track of the hovered target\n * @type FabricObject | null\n * @private\n */\n declare _hoveredTarget?: FabricObject;\n\n /**\n * hold the list of nested targets hovered\n * @type FabricObject[]\n * @private\n */\n _hoveredTargets: FabricObject[] = [];\n\n /**\n * hold the list of objects to render\n * @type FabricObject[]\n * @private\n */\n _objectsToRender?: FabricObject[];\n\n /**\n * hold a reference to a data structure that contains information\n * on the current on going transform\n * @type\n * @private\n */\n _currentTransform: Transform | null = null;\n\n /**\n * hold a reference to a data structure used to track the selection\n * box on canvas drag\n * on the current on going transform\n * x, y, deltaX and deltaY are in scene plane\n * @type\n * @private\n */\n protected _groupSelector: {\n x: number;\n y: number;\n deltaX: number;\n deltaY: number;\n } | null = null;\n\n /**\n * internal flag used to understand if the context top requires a cleanup\n * in case this is true, the contextTop will be cleared at the next render\n * @type boolean\n * @private\n */\n contextTopDirty = false;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _absolutePointer holds a reference to the pointer in fabricCanvas/design coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _absolutePointer?: Point;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _pointer holds a reference to the pointer in html coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _pointer?: Point;\n\n /**\n * During a mouse event we may need the target multiple times in multiple functions.\n * _target holds a reference to the target that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * @type {FabricObject}\n */\n protected declare _target?: FabricObject;\n\n static ownDefaults = canvasDefaults;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...SelectableCanvas.ownDefaults };\n }\n\n declare elements: CanvasDOMManager;\n get upperCanvasEl() {\n return this.elements.upper?.el;\n }\n get contextTop() {\n return this.elements.upper?.ctx;\n }\n get wrapperEl() {\n return this.elements.container;\n }\n private declare pixelFindCanvasEl: HTMLCanvasElement;\n private declare pixelFindContext: CanvasRenderingContext2D;\n\n protected declare _isCurrentlyDrawing: boolean;\n declare freeDrawingBrush?: BaseBrush;\n declare _activeObject?: FabricObject;\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new CanvasDOMManager(el, {\n allowTouchScrolling: this.allowTouchScrolling,\n containerClass: this.containerClass,\n });\n this._createCacheCanvas();\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was added\n */\n _onObjectAdded(obj: FabricObject) {\n this._objectsToRender = undefined;\n super._onObjectAdded(obj);\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was removed\n */\n _onObjectRemoved(obj: FabricObject) {\n this._objectsToRender = undefined;\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { deselected: [obj] });\n this._discardActiveObject();\n this.fire('selection:cleared', { deselected: [obj] });\n obj.fire('deselected', {\n target: obj,\n });\n }\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n super._onObjectRemoved(obj);\n }\n\n _onStackOrderChanged() {\n this._objectsToRender = undefined;\n super._onStackOrderChanged();\n }\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender(): FabricObject[] {\n const activeObject = this._activeObject;\n return !this.preserveObjectStacking && activeObject\n ? this._objects\n .filter((object) => !object.group && object !== activeObject)\n .concat(activeObject)\n : this._objects;\n }\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n this.hasLostContext = false;\n }\n !this._objectsToRender &&\n (this._objectsToRender = this._chooseObjectsToRender());\n this.renderCanvas(this.getContext(), this._objectsToRender);\n }\n\n /**\n * text selection is rendered by the active text instance during the rendering cycle\n */\n renderTopLayer(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n }\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * Does not render text selection.\n */\n renderTop() {\n const ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n // todo: how do i know if the after:render is for the top or normal contex?\n this.fire('after:render', { ctx });\n }\n\n /**\n * Set the canvas tolerance value for pixel taret find.\n * Use only integer numbers.\n * @private\n */\n setTargetFindTolerance(value: number) {\n value = Math.round(value);\n this.targetFindTolerance = value;\n const retina = this.getRetinaScaling();\n const size = Math.ceil((value * 2 + 1) * retina);\n this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size;\n this.pixelFindContext.scale(retina, retina);\n }\n\n /**\n * Returns true if object is transparent at a certain location\n * Clarification: this is `is target transparent at location X or are controls there`\n * @TODO this seems dumb that we treat controls with transparency. we can find controls\n * programmatically without painting them, the cache canvas optimization is always valid\n * @param {FabricObject} target Object to check\n * @param {Number} x Left coordinate in viewport space\n * @param {Number} y Top coordinate in viewport space\n * @return {Boolean}\n */\n isTargetTransparent(target: FabricObject, x: number, y: number): boolean {\n const tolerance = this.targetFindTolerance;\n const ctx = this.pixelFindContext;\n this.clearContext(ctx);\n ctx.save();\n ctx.translate(-x + tolerance, -y + tolerance);\n ctx.transform(...this.viewportTransform);\n const selectionBgc = target.selectionBackgroundColor;\n target.selectionBackgroundColor = '';\n target.render(ctx);\n target.selectionBackgroundColor = selectionBgc;\n ctx.restore();\n // our canvas is square, and made around tolerance.\n // so tolerance in this case also represent the center of the canvas.\n const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling());\n return isTransparent(\n ctx,\n enhancedTolerance,\n enhancedTolerance,\n enhancedTolerance,\n );\n }\n\n /**\n * takes an event and determines if selection key has been pressed\n * @private\n * @param {TPointerEvent} e Event object\n */\n _isSelectionKeyPressed(e: TPointerEvent): boolean {\n const sKey = this.selectionKey;\n if (!sKey) {\n return false;\n }\n if (Array.isArray(sKey)) {\n return !!sKey.find((key) => !!key && e[key] === true);\n } else {\n return e[sKey];\n }\n }\n\n /**\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target\n */\n _shouldClearSelection(\n e: TPointerEvent,\n target?: FabricObject,\n ): target is undefined {\n const activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return !!(\n !target ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e)) ||\n (target && !target.evented) ||\n (target && !target.selectable && activeObject && activeObject !== target)\n );\n }\n\n /**\n * This method will take in consideration a modifier key pressed and the control we are\n * about to drag, and try to guess the anchor point ( origin ) of the transormation.\n * This should be really in the realm of controls, and we should remove specific code for legacy\n * embedded actions.\n * @TODO this probably deserve discussion/rediscovery and change/refactor\n * @private\n * @deprecated\n * @param {FabricObject} target\n * @param {string} action\n * @param {boolean} altKey\n * @returns {boolean} true if the transformation should be centered\n */\n private _shouldCenterTransform(\n target: FabricObject,\n action: string,\n modifierKeyPressed: boolean,\n ) {\n if (!target) {\n return;\n }\n\n let centerTransform;\n\n if (\n action === SCALE ||\n action === SCALE_X ||\n action === SCALE_Y ||\n action === RESIZING\n ) {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === ROTATE) {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !modifierKeyPressed : modifierKeyPressed;\n }\n\n /**\n * Given the control clicked, determine the origin of the transform.\n * This is bad because controls can totally have custom names\n * should disappear before release 4.0\n * @private\n * @deprecated\n */\n _getOriginFromCorner(\n target: FabricObject,\n controlName: string,\n ): { x: TOriginX; y: TOriginY } {\n const origin = {\n x: target.originX,\n y: target.originY,\n };\n\n if (!controlName) {\n return origin;\n }\n\n // is a left control ?\n if (['ml', 'tl', 'bl'].includes(controlName)) {\n origin.x = RIGHT;\n // is a right control ?\n } else if (['mr', 'tr', 'br'].includes(controlName)) {\n origin.x = LEFT;\n }\n // is a top control ?\n if (['tl', 'mt', 'tr'].includes(controlName)) {\n origin.y = BOTTOM;\n // is a bottom control ?\n } else if (['bl', 'mb', 'br'].includes(controlName)) {\n origin.y = TOP;\n }\n return origin;\n }\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {FabricObject} target\n * @param {boolean} [alreadySelected] pass true to setup the active control\n */\n _setupCurrentTransform(\n e: TPointerEvent,\n target: FabricObject,\n alreadySelected: boolean,\n ): void {\n const pointer = target.group\n ? // transform pointer to target's containing coordinate plane\n sendPointToPlane(\n this.getScenePoint(e),\n undefined,\n target.group.calcTransformMatrix(),\n )\n : this.getScenePoint(e);\n const { key: corner = '', control } = target.getActiveControl() || {},\n actionHandler =\n alreadySelected && control\n ? control.getActionHandler(e, target, control)?.bind(control)\n : dragHandler,\n action = getActionFromCorner(alreadySelected, corner, e, target),\n altKey = e[this.centeredKey as ModifierKey],\n origin = this._shouldCenterTransform(target, action, altKey)\n ? ({ x: CENTER, y: CENTER } as const)\n : this._getOriginFromCorner(target, corner),\n /**\n * relative to target's containing coordinate plane\n * both agree on every point\n **/\n transform: Transform = {\n target: target,\n action,\n actionHandler,\n actionPerformed: false,\n corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n theta: degreesToRadians(target.angle),\n width: target.width,\n height: target.height,\n shiftKey: e.shiftKey,\n altKey,\n original: {\n ...saveObjectTransform(target),\n originX: origin.x,\n originY: origin.y,\n },\n };\n\n this._currentTransform = transform;\n\n this.fire('before:transform', {\n e,\n transform,\n });\n }\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor(value: CSSStyleDeclaration['cursor']): void {\n this.upperCanvasEl.style.cursor = value;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection(ctx: CanvasRenderingContext2D): void {\n const { x, y, deltaX, deltaY } = this._groupSelector!,\n start = new Point(x, y).transform(this.viewportTransform),\n extent = new Point(x + deltaX, y + deltaY).transform(\n this.viewportTransform,\n ),\n strokeOffset = this.selectionLineWidth / 2;\n let minX = Math.min(start.x, extent.x),\n minY = Math.min(start.y, extent.y),\n maxX = Math.max(start.x, extent.x),\n maxY = Math.max(start.y, extent.y);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n minX += strokeOffset;\n minY += strokeOffset;\n maxX -= strokeOffset;\n maxY -= strokeOffset;\n // selection border\n // @TODO: is _setLineDash still necessary on modern canvas?\n FabricObject.prototype._setLineDash.call(\n this,\n ctx,\n this.selectionDashArray,\n );\n ctx.strokeRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n /**\n * Method that determines what object we are clicking on\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @return {FabricObject | null} the target found\n */\n findTarget(e: TPointerEvent): FabricObject | undefined {\n if (this.skipTargetFind) {\n return undefined;\n }\n\n const pointer = this.getViewportPoint(e),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects();\n\n this.targets = [];\n\n if (activeObject && aObjects.length >= 1) {\n if (activeObject.findControl(pointer, isTouchEvent(e))) {\n // if we hit the corner of the active object, let's return that.\n return activeObject;\n } else if (\n aObjects.length > 1 &&\n // check pointer is over active selection and possibly perform `subTargetCheck`\n this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active selection does not select sub targets like normal groups\n return activeObject;\n } else if (\n activeObject === this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active object is not an active selection\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n const subTargets = this.targets;\n this.targets = [];\n const target = this.searchPossibleTargets(this._objects, pointer);\n if (\n e[this.altSelectionKey as ModifierKey] &&\n target &&\n target !== activeObject\n ) {\n // alt selection: select active object even though it is not the top most target\n // restore targets\n this.targets = subTargets;\n return activeObject;\n }\n return target;\n }\n }\n }\n\n return this.searchPossibleTargets(this._objects, pointer);\n }\n\n /**\n * Checks if the point is inside the object selection area including padding\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point in scene coordinates\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n private _pointIsInObjectSelectionArea(obj: FabricObject, point: Point) {\n // getCoords will already take care of group de-nesting\n let coords = obj.getCoords();\n const viewportZoom = this.getZoom();\n const padding = obj.padding / viewportZoom;\n if (padding) {\n const [tl, tr, br, bl] = coords;\n // what is the angle of the object?\n // we could use getTotalAngle, but is way easier to look at it\n // from how coords are oriented, since if something went wrong\n // at least we are consistent.\n const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x),\n cosP = cos(angleRadians) * padding,\n sinP = sin(angleRadians) * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP;\n\n coords = [\n new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP),\n new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP),\n new Point(br.x + cosPMinusSinP, br.y + cosPSinP),\n new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP),\n ];\n // in case of padding we calculate the new coords on the fly.\n // otherwise we have to maintain 2 sets of coordinates for everything.\n // we can reiterate on storing them.\n // if this is slow, for now the semplification is large and doesn't impact\n // rendering.\n // the idea behind this is that outside target check we don't need ot know\n // where those coords are\n }\n return Intersection.isPointInPolygon(point, coords);\n }\n\n /**\n * Checks point is inside the object selection condition. Either area with padding\n * or over pixels if perPixelTargetFind is enabled\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point from viewport.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget(obj: FabricObject, pointer: Point): boolean {\n if (\n obj &&\n obj.visible &&\n obj.evented &&\n this._pointIsInObjectSelectionArea(\n obj,\n sendPointToPlane(pointer, undefined, this.viewportTransform),\n )\n ) {\n if (\n (this.perPixelTargetFind || obj.perPixelTargetFind) &&\n !(obj as unknown as IText).isEditing\n ) {\n if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {FabricObject} **top most object from given `objects`** that contains pointer\n * @private\n */\n _searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n // Cache all targets where their bounding box contains point.\n let i = objects.length;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n const target = objects[i];\n if (this._checkTarget(target, pointer)) {\n if (isCollection(target) && target.subTargetCheck) {\n const subTarget = this._searchPossibleTargets(\n target._objects as FabricObject[],\n pointer,\n );\n subTarget && this.targets.push(subTarget);\n }\n return target;\n }\n }\n }\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @see {@link _searchPossibleTargets}\n * @param {FabricObject[]} [objects] objects array to look into\n * @param {Point} [pointer] coordinates from viewport to check.\n * @return {FabricObject} **top most object on screen** that contains pointer\n */\n searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n const target = this._searchPossibleTargets(objects, pointer);\n\n // if we found something in this.targets, and the group is interactive, return the innermost subTarget\n // that is still interactive\n // TODO: reverify why interactive. the target should be returned always, but selected only\n // if interactive.\n if (\n target &&\n isCollection(target) &&\n target.interactive &&\n this.targets[0]\n ) {\n /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */\n const targets = this.targets;\n for (let i = targets.length - 1; i > 0; i--) {\n const t = targets[i];\n if (!(isCollection(t) && t.interactive)) {\n // one of the subtargets was not interactive. that is the last subtarget we can return.\n // we can't dig more deep;\n return t;\n }\n }\n return targets[0];\n }\n\n return target;\n }\n\n /**\n * @returns point existing in the same plane as the {@link HTMLCanvasElement},\n * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}.\n * This means that changes to the {@link viewportTransform} do not change the values of the point\n * and it remains unchanged from the viewer's perspective.\n *\n * @example\n * const scenePoint = sendPointToPlane(\n * this.getViewportPoint(e),\n * undefined,\n * canvas.viewportTransform\n * );\n *\n */\n getViewportPoint(e: TPointerEvent) {\n if (this._pointer) {\n return this._pointer;\n }\n return this.getPointer(e, true);\n }\n\n /**\n * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in).\n * This means that changes to the {@link viewportTransform} do not change the values of the point,\n * however, from the viewer's perspective, the point is changed.\n *\n * @example\n * const viewportPoint = sendPointToPlane(\n * this.getScenePoint(e),\n * canvas.viewportTransform\n * );\n *\n */\n getScenePoint(e: TPointerEvent) {\n if (this._absolutePointer) {\n return this._absolutePointer;\n }\n return this.getPointer(e);\n }\n\n /**\n * Returns pointer relative to canvas.\n *\n * @deprecated This method is deprecated since v6 to protect you from misuse.\n * Use {@link getViewportPoint} or {@link getScenePoint} instead.\n *\n * @param {Event} e\n * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene\n * @return {Point}\n */\n getPointer(e: TPointerEvent, fromViewport = false): Point {\n const upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect();\n let pointer = getPointer(e),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0;\n\n if (!boundsWidth || !boundsHeight) {\n if (TOP in bounds && BOTTOM in bounds) {\n boundsHeight = Math.abs(bounds.top - bounds.bottom);\n }\n if (RIGHT in bounds && LEFT in bounds) {\n boundsWidth = Math.abs(bounds.right - bounds.left);\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!fromViewport) {\n pointer = sendPointToPlane(pointer, undefined, this.viewportTransform);\n }\n\n const retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n // If bounds are not available (i.e. not visible), do not apply scale.\n const cssScale =\n boundsWidth === 0 || boundsHeight === 0\n ? new Point(1, 1)\n : new Point(\n upperCanvasEl.width / boundsWidth,\n upperCanvasEl.height / boundsHeight,\n );\n\n return pointer.multiply(cssScale);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: TSize,\n options?: TCanvasSizeOptions,\n ) {\n // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract\n this._resetTransformEventData();\n super._setDimensionsImpl(dimensions, options);\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush &&\n this.freeDrawingBrush._setBrushStyles(this.contextTop);\n }\n }\n\n protected _createCacheCanvas() {\n this.pixelFindCanvasEl = createCanvasElement();\n this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', {\n willReadFrequently: true,\n })!;\n this.setTargetFindTolerance(this.targetFindTolerance);\n }\n\n /**\n * Returns context of top canvas where interactions are drawn\n * @returns {CanvasRenderingContext2D}\n */\n getTopContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns context of canvas where object selection is drawn\n * @alias\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement(): HTMLCanvasElement {\n return this.elements.upper.el;\n }\n\n /**\n * Returns currently active object\n * @return {FabricObject | null} active object\n */\n getActiveObject(): FabricObject | undefined {\n return this._activeObject;\n }\n\n /**\n * Returns an array with the current selected objects\n * @return {FabricObject[]} active objects array\n */\n getActiveObjects(): FabricObject[] {\n const active = this._activeObject;\n return isActiveSelection(active)\n ? active.getObjects()\n : active\n ? [active]\n : [];\n }\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {FabricObject[]} oldObjects old activeObject\n * @param {TPointerEvent} e mouse event triggering the selection events\n */\n _fireSelectionEvents(oldObjects: FabricObject[], e?: TPointerEvent) {\n let somethingChanged = false,\n invalidate = false;\n const objects = this.getActiveObjects(),\n added: FabricObject[] = [],\n removed: FabricObject[] = [];\n\n oldObjects.forEach((target) => {\n if (!objects.includes(target)) {\n somethingChanged = true;\n target.fire('deselected', {\n e,\n target,\n });\n removed.push(target);\n }\n });\n\n objects.forEach((target) => {\n if (!oldObjects.includes(target)) {\n somethingChanged = true;\n target.fire('selected', {\n e,\n target,\n });\n added.push(target);\n }\n });\n\n if (oldObjects.length > 0 && objects.length > 0) {\n invalidate = true;\n somethingChanged &&\n this.fire('selection:updated', {\n e,\n selected: added,\n deselected: removed,\n });\n } else if (objects.length > 0) {\n invalidate = true;\n this.fire('selection:created', {\n e,\n selected: added,\n });\n } else if (oldObjects.length > 0) {\n invalidate = true;\n this.fire('selection:cleared', {\n e,\n deselected: removed,\n });\n }\n invalidate && (this._objectsToRender = undefined);\n }\n\n /**\n * Sets given object as the only active object on canvas\n * @param {FabricObject} object Object to set as an active one\n * @param {TPointerEvent} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n setActiveObject(object: FabricObject, e?: TPointerEvent) {\n // we can't inline this, since _setActiveObject will change what getActiveObjects returns\n const currentActives = this.getActiveObjects();\n const selected = this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return selected;\n }\n\n /**\n * This is supposed to be equivalent to setActiveObject but without firing\n * any event. There is commitment to have this stay this way.\n * This is the functional part of setActiveObject.\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n _setActiveObject(object: FabricObject, e?: TPointerEvent) {\n const prevActiveObject = this._activeObject;\n if (prevActiveObject === object) {\n return false;\n }\n // after calling this._discardActiveObject, this,_activeObject could be undefined\n if (!this._discardActiveObject(e, object) && this._activeObject) {\n // refused to deselect\n return false;\n }\n if (object.onSelect({ e })) {\n return false;\n }\n\n this._activeObject = object;\n\n if (isActiveSelection(object) && prevActiveObject !== object) {\n object.set('canvas', this);\n }\n object.setCoords();\n\n return true;\n }\n\n /**\n * This is supposed to be equivalent to discardActiveObject but without firing\n * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way.\n * This is the functional part of discardActiveObject.\n * @param {Event} [e] Event (passed along when firing \"object:deselected\")\n * @param {Object} object the next object to set as active, reason why we are discarding this\n * @return {Boolean} true if the active object has been discarded\n */\n _discardActiveObject(\n e?: TPointerEvent,\n object?: FabricObject,\n ): this is { _activeObject: undefined } {\n const obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e, object })) {\n return false;\n }\n if (this._currentTransform && this._currentTransform.target === obj) {\n this.endCurrentTransform(e);\n }\n if (isActiveSelection(obj) && obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n }\n this._activeObject = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {Boolean} true if the active object has been discarded\n */\n discardActiveObject(e?: TPointerEvent): this is { _activeObject: undefined } {\n const currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n e,\n deselected: [activeObject!],\n });\n }\n const discarded = this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return discarded;\n }\n\n /**\n * End the current transform.\n * You don't usually need to call this method unless you are interrupting a user initiated transform\n * because of some other event ( a press of key combination, or something that block the user UX )\n * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event\n */\n endCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform;\n this._finalizeCurrentTransform(e);\n if (transform && transform.target) {\n // this could probably go inside _finalizeCurrentTransform\n transform.target.isMoving = false;\n }\n this._currentTransform = null;\n }\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform!,\n target = transform.target,\n options = {\n e,\n target,\n transform,\n action: transform.action,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed) {\n this.fire('object:modified', options);\n target.fire(MODIFIED, options);\n }\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n super.setViewportTransform(vpt);\n const activeObject = this._activeObject;\n if (activeObject) {\n activeObject.setCoords();\n }\n }\n\n /**\n * @override clears active selection ref and interactive canvas elements and contexts\n */\n destroy() {\n // dispose of active selection\n const activeObject = this._activeObject;\n if (isActiveSelection(activeObject)) {\n activeObject.removeAll();\n activeObject.dispose();\n }\n\n delete this._activeObject;\n\n super.destroy();\n\n // free resources\n\n // pixel find canvas\n // @ts-expect-error disposing\n this.pixelFindContext = null;\n // @ts-expect-error disposing\n this.pixelFindCanvasEl = undefined;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n // discard active object and fire events\n this.discardActiveObject();\n // make sure we clear the active object in case it refused to be discarded\n this._activeObject = undefined;\n this.clearContext(this.contextTop);\n super.clear();\n }\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls(ctx: CanvasRenderingContext2D) {\n const activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: 'toObject' | 'toDatalessObject',\n propertiesToInclude: string[],\n ): Record {\n // If the object is part of the current selection group, it should\n // be transformed appropriately\n // i.e. it should be serialised as it would appear if the selection group\n // were to be destroyed.\n const originalProperties = this._realizeGroupTransformOnObject(instance),\n object = super._toObject(instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n instance.set(originalProperties);\n return object;\n }\n\n /**\n * Realizes an object's group transformation on it\n * @private\n * @param {FabricObject} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n private _realizeGroupTransformOnObject(\n instance: FabricObject,\n ): Partial {\n const { group } = instance;\n if (group && isActiveSelection(group) && this._activeObject === group) {\n const layoutProps = [\n 'angle',\n 'flipX',\n 'flipY',\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n ] as (keyof typeof instance)[];\n const originalValues = pick(instance, layoutProps);\n addTransformToObject(instance, group.calcOwnMatrix());\n return originalValues;\n } else {\n return {};\n }\n }\n\n /**\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n // If the object is in a selection group, simulate what would happen to that\n // object when the group is deselected\n const originalProperties = this._realizeGroupTransformOnObject(instance);\n super._setSVGObject(markup, instance, reviver);\n instance.set(originalProperties);\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport type { ITextBehavior } from '../shapes/IText/ITextBehavior';\nimport { removeFromArray } from '../util/internals/removeFromArray';\nimport type { Canvas } from './Canvas';\n\n/**\n * In charge of synchronizing all interactive text instances of a canvas\n */\nexport class TextEditingManager {\n private targets: ITextBehavior[] = [];\n private declare target?: ITextBehavior;\n private __disposer: VoidFunction;\n\n constructor(canvas: Canvas) {\n const cb = () => {\n const { hiddenTextarea } =\n (canvas.getActiveObject() as ITextBehavior) || {};\n hiddenTextarea && hiddenTextarea.focus();\n };\n const el = canvas.upperCanvasEl;\n el.addEventListener('click', cb);\n this.__disposer = () => el.removeEventListener('click', cb);\n }\n\n exitTextEditing() {\n this.target = undefined;\n this.targets.forEach((target) => {\n if (target.isEditing) {\n target.exitEditing();\n }\n });\n }\n\n add(target: ITextBehavior) {\n this.targets.push(target);\n }\n\n remove(target: ITextBehavior) {\n this.unregister(target);\n removeFromArray(this.targets, target);\n }\n\n register(target: ITextBehavior) {\n this.target = target;\n }\n\n unregister(target: ITextBehavior) {\n if (target === this.target) {\n this.target = undefined;\n }\n }\n\n onMouseMove(e: TPointerEvent) {\n this.target?.isEditing && this.target.updateSelectionOnMouseMove(e);\n }\n\n clear() {\n this.targets = [];\n this.target = undefined;\n }\n\n dispose() {\n this.clear();\n this.__disposer();\n // @ts-expect-error disposing\n delete this.__disposer;\n }\n}\n","import { classRegistry } from '../ClassRegistry';\nimport { NONE } from '../constants';\nimport type {\n CanvasEvents,\n DragEventData,\n ObjectEvents,\n TPointerEvent,\n TPointerEventNames,\n Transform,\n} from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\nimport type { Group } from '../shapes/Group';\nimport type { IText } from '../shapes/IText/IText';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { isTouchEvent, stopEvent } from '../util/dom_event';\nimport { getDocumentFromElement, getWindowFromElement } from '../util/dom_misc';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { isActiveSelection } from '../util/typeAssertions';\nimport type { CanvasOptions, TCanvasOptions } from './CanvasOptions';\nimport { SelectableCanvas } from './SelectableCanvas';\nimport { TextEditingManager } from './TextEditingManager';\n\nconst addEventOptions = { passive: false } as EventListenerOptions;\n\nconst getEventPoints = (canvas: Canvas, e: TPointerEvent) => {\n const viewportPoint = canvas.getViewportPoint(e);\n const scenePoint = canvas.getScenePoint(e);\n return {\n viewportPoint,\n scenePoint,\n pointer: viewportPoint,\n absolutePointer: scenePoint,\n };\n};\n\n// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers\n// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.\n// few bytes but why give it away.\nconst addListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.addEventListener(...args);\nconst removeListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.removeEventListener(...args);\n\nconst syntheticEventConfig = {\n mouse: {\n in: 'over',\n out: 'out',\n targetIn: 'mouseover',\n targetOut: 'mouseout',\n canvasIn: 'mouse:over',\n canvasOut: 'mouse:out',\n },\n drag: {\n in: 'enter',\n out: 'leave',\n targetIn: 'dragenter',\n targetOut: 'dragleave',\n canvasIn: 'drag:enter',\n canvasOut: 'drag:leave',\n },\n} as const;\n\ntype TSyntheticEventContext = {\n mouse: { e: TPointerEvent };\n drag: DragEventData;\n};\n\nexport class Canvas extends SelectableCanvas implements CanvasOptions {\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n declare mainTouchId?: number;\n\n declare enablePointerEvents: boolean;\n\n /**\n * Holds a reference to a setTimeout timer for event synchronization\n * @type number\n * @private\n */\n private declare _willAddMouseDown: number;\n\n /**\n * Holds a reference to an object on the canvas that is receiving the drag over event.\n * @type FabricObject\n * @private\n */\n private declare _draggedoverTarget?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas from where the drag operation started\n * @type FabricObject\n * @private\n */\n private declare _dragSource?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas that is the current drop target\n * May differ from {@link _draggedoverTarget}\n * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow\n * @type FabricObject\n * @private\n */\n private declare _dropTarget: FabricObject | undefined;\n\n private _isClick: boolean;\n\n textEditingManager = new TextEditingManager(this);\n\n constructor(el?: string | HTMLCanvasElement, options: TCanvasOptions = {}) {\n super(el, options);\n // bind event handlers\n (\n [\n '_onMouseDown',\n '_onTouchStart',\n '_onMouseMove',\n '_onMouseUp',\n '_onTouchEnd',\n '_onResize',\n // '_onGesture',\n // '_onDrag',\n // '_onShake',\n // '_onLongPress',\n // '_onOrientationChange',\n '_onMouseWheel',\n '_onMouseOut',\n '_onMouseEnter',\n '_onContextMenu',\n '_onDoubleClick',\n '_onDragStart',\n '_onDragEnd',\n '_onDragProgress',\n '_onDragOver',\n '_onDragEnter',\n '_onDragLeave',\n '_onDrop',\n ] as (keyof this)[]\n ).forEach((eventHandler) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n this[eventHandler] = (this[eventHandler] as Function).bind(this);\n });\n // register event handlers\n this.addOrRemove(addListener, 'add');\n }\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n private _getEventPrefix() {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n }\n\n addOrRemove(functor: any, _eventjsFunctor: 'add' | 'remove') {\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(getWindowFromElement(canvasElement), 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove,\n addEventOptions,\n );\n functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);\n functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragstart', this._onDragStart);\n functor(canvasElement, 'dragend', this._onDragEnd);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n // eventjs[eventjsFunctor](\n // canvasElement,\n // 'orientation',\n // this._onOrientationChange\n // );\n // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n // }\n }\n\n /**\n * Removes all event listeners\n */\n removeListeners() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n private _onMouseWheel(e: MouseEvent) {\n this.__onMouseWheel(e);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onMouseOut(e: TPointerEvent) {\n const target = this._hoveredTarget;\n const shared = {\n e,\n ...getEventPoints(this, e),\n };\n this.fire('mouse:out', { ...shared, target });\n this._hoveredTarget = undefined;\n target && target.fire('mouseout', { ...shared });\n this._hoveredTargets.forEach((nestedTarget) => {\n this.fire('mouse:out', { ...shared, target: nestedTarget });\n nestedTarget && nestedTarget.fire('mouseout', { ...shared });\n });\n this._hoveredTargets = [];\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n private _onMouseEnter(e: TPointerEvent) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', {\n e,\n ...getEventPoints(this, e),\n });\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n }\n\n /**\n * supports native like text dragging\n * @private\n * @param {DragEvent} e\n */\n private _onDragStart(e: DragEvent) {\n this._isClick = false;\n const activeObject = this.getActiveObject();\n if (activeObject && activeObject.onDragStart(e)) {\n this._dragSource = activeObject;\n const options = { e, target: activeObject };\n this.fire('dragstart', options);\n activeObject.fire('dragstart', options);\n addListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n return;\n }\n stopEvent(e);\n }\n\n /**\n * First we clear top context where the effects are being rendered.\n * Then we render the effects.\n * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.\n * @private\n */\n private _renderDragEffects(\n e: DragEvent,\n source?: FabricObject,\n target?: FabricObject,\n ) {\n let dirty = false;\n // clear top context\n const dropTarget = this._dropTarget;\n if (dropTarget && dropTarget !== source && dropTarget !== target) {\n dropTarget.clearContextTop();\n dirty = true;\n }\n source?.clearContextTop();\n target !== source && target?.clearContextTop();\n // render effects\n const ctx = this.contextTop;\n ctx.save();\n ctx.transform(...this.viewportTransform);\n if (source) {\n ctx.save();\n source.transform(ctx);\n source.renderDragSourceEffect(e);\n ctx.restore();\n dirty = true;\n }\n if (target) {\n ctx.save();\n target.transform(ctx);\n target.renderDropTargetEffect(e);\n ctx.restore();\n dirty = true;\n }\n ctx.restore();\n dirty && (this.contextTopDirty = true);\n }\n\n /**\n * supports native like text dragging\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n * @private\n * @param {DragEvent} e\n */\n private _onDragEnd(e: DragEvent) {\n const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE,\n dropTarget = didDrop ? this._activeObject : undefined,\n options = {\n e,\n target: this._dragSource as FabricObject,\n subTargets: this.targets,\n dragSource: this._dragSource as FabricObject,\n didDrop,\n dropTarget: dropTarget as FabricObject,\n };\n removeListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n this.fire('dragend', options);\n this._dragSource && this._dragSource.fire('dragend', options);\n delete this._dragSource;\n // we need to call mouse up synthetically because the browser won't\n this._onMouseUp(e);\n }\n\n /**\n * fire `drag` event on canvas and drag source\n * @private\n * @param {DragEvent} e\n */\n private _onDragProgress(e: DragEvent) {\n const options = {\n e,\n target: this._dragSource as FabricObject | undefined,\n dragSource: this._dragSource as FabricObject | undefined,\n dropTarget: this._draggedoverTarget as FabricObject,\n };\n this.fire('drag', options);\n this._dragSource && this._dragSource.fire('drag', options);\n }\n\n /**\n * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.\n * Override at will\n */\n protected findDragTargets(e: DragEvent) {\n this.targets = [];\n const target = this._searchPossibleTargets(\n this._objects,\n this.getViewportPoint(e),\n );\n return {\n target,\n targets: [...this.targets],\n };\n }\n\n /**\n * prevent default to allow drop event to be fired\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets\n * @private\n * @param {DragEvent} [e] Event object fired on Event.js shake\n */\n private _onDragOver(e: DragEvent) {\n const eventType = 'dragover';\n const { target, targets } = this.findDragTargets(e);\n const dragSource = this._dragSource as FabricObject;\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource,\n canDrop: false,\n dropTarget: undefined,\n };\n let dropTarget;\n // fire on canvas\n this.fire(eventType, options);\n // make sure we fire dragenter events before dragover\n // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it\n this._fireEnterLeaveEvents(target, options);\n if (target) {\n if (target.canDrop(e)) {\n dropTarget = target;\n }\n target.fire(eventType, options);\n }\n // propagate the event to subtargets\n for (let i = 0; i < targets.length; i++) {\n const subTarget = targets[i];\n // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)\n // TODO: verify if those should loop in inverse order then?\n // what is the order of subtargets?\n if (subTarget.canDrop(e)) {\n dropTarget = subTarget;\n }\n subTarget.fire(eventType, options);\n }\n // render drag effects now that relations between source and target is clear\n this._renderDragEffects(e, dragSource, dropTarget);\n this._dropTarget = dropTarget;\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragEnter(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n };\n this.fire('dragenter', options);\n // fire dragenter on targets\n this._fireEnterLeaveEvents(target, options);\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragLeave(e: DragEvent) {\n const options = {\n e,\n target: this._draggedoverTarget,\n subTargets: this.targets,\n dragSource: this._dragSource,\n };\n this.fire('dragleave', options);\n\n // fire dragleave on targets\n this._fireEnterLeaveEvents(undefined, options);\n this._renderDragEffects(e, this._dragSource);\n this._dropTarget = undefined;\n // clear targets\n this.targets = [];\n this._hoveredTargets = [];\n }\n\n /**\n * `drop:before` is a an event that allows you to schedule logic\n * before the `drop` event. Prefer `drop` event always, but if you need\n * to run some drop-disabling logic on an event, since there is no way\n * to handle event handlers ordering, use `drop:before`\n * @private\n * @param {Event} e\n */\n private _onDrop(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = this._basicEventHandler('drop:before', {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n ...getEventPoints(this, e),\n });\n // will be set by the drop target\n options.didDrop = false;\n // will be set by the drop target, used in case options.target refuses the drop\n options.dropTarget = undefined;\n // fire `drop`\n this._basicEventHandler('drop', options);\n // inform canvas of the drop\n // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it\n // use for side effects\n this.fire('drop:after', options);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onContextMenu(e: TPointerEvent): false {\n const target = this.findTarget(e),\n subTargets = this.targets || [];\n const options = this._basicEventHandler('contextmenu:before', {\n e,\n target,\n subTargets,\n });\n // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves\n this.stopContextMenu && stopEvent(e);\n this._basicEventHandler('contextmenu', options);\n return false;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onDoubleClick(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData();\n }\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId(evt: TouchEvent | PointerEvent): number {\n const changedTouches = (evt as TouchEvent).changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return (evt as PointerEvent).pointerId;\n }\n\n return -1;\n }\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent(evt: TPointerEvent): boolean {\n if ((evt as PointerEvent).isPrimary === true) {\n return true;\n }\n if ((evt as PointerEvent).isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {\n return true;\n }\n if ((evt as TouchEvent).changedTouches) {\n return (\n (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId\n );\n }\n return true;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart(e: TouchEvent) {\n e.preventDefault();\n if (this.mainTouchId === undefined) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(canvasElement);\n addListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n addListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(\n canvasElement,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown(e: TPointerEvent) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n const doc = getDocumentFromElement(canvasElement);\n addListener(doc, `${eventTypePrefix}up`, this._onMouseUp as EventListener);\n addListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd(e: TouchEvent) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n delete this.mainTouchId;\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(() => {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(\n this.upperCanvasEl,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n this._willAddMouseDown = 0;\n }, 400) as unknown as number;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp(e: TPointerEvent) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n addListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove(e: TPointerEvent) {\n const activeObject = this.getActiveObject();\n !this.allowTouchScrolling &&\n (!activeObject ||\n // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before\n // we must not prevent the event's default behavior in order for the window to start dragging\n !activeObject.shouldStartDragging(e)) &&\n e.preventDefault &&\n e.preventDefault();\n this.__onMouseMove(e);\n }\n\n /**\n * @private\n */\n _onResize() {\n this.calcOffset();\n this._resetTransformEventData();\n }\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender(target: FabricObject | undefined) {\n const activeObject = this.getActiveObject();\n // if just one of them is available or if they are both but are different objects\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return (\n !!activeObject !== !!target ||\n (activeObject && target && activeObject !== target)\n );\n }\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'up:before');\n\n const transform = this._currentTransform;\n const isClick = this._isClick;\n const target = this._target;\n\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'up');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n let shouldRender = false;\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n if (!isClick) {\n const targetWasActive = target === this._activeObject;\n this.handleSelection(e);\n if (!shouldRender) {\n shouldRender =\n this._shouldRender(target) ||\n (!targetWasActive && target === this._activeObject);\n }\n }\n let pointer, corner;\n if (target) {\n const found = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n const { key, control } = found || {};\n corner = key;\n if (\n target.selectable &&\n target !== this._activeObject &&\n target.activeOn === 'up'\n ) {\n this.setActiveObject(target, e);\n shouldRender = true;\n } else if (control) {\n const mouseUpHandler = control.getMouseUpHandler(e, target, control);\n if (mouseUpHandler) {\n pointer = this.getScenePoint(e);\n mouseUpHandler.call(control, e, transform!, pointer.x, pointer.y);\n }\n }\n target.isMoving = false;\n }\n // if we are ending up a transform on a different control or a new object\n // fire the original mouse up from the corner that started the transform\n if (\n transform &&\n (transform.target !== target || transform.corner !== corner)\n ) {\n const originalControl =\n transform.target && transform.target.controls[transform.corner],\n originalMouseUpHandler =\n originalControl &&\n originalControl.getMouseUpHandler(\n e,\n transform.target,\n originalControl,\n );\n pointer = pointer || this.getScenePoint(e);\n originalMouseUpHandler &&\n originalMouseUpHandler.call(\n originalControl,\n e,\n transform,\n pointer.x,\n pointer.y,\n );\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up');\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = undefined);\n if (shouldRender) {\n this.requestRenderAll();\n } else if (!isClick && !(this._activeObject as IText)?.isEditing) {\n this.renderTop();\n }\n }\n\n _basicEventHandler(\n eventType: T,\n options: (CanvasEvents & ObjectEvents)[T],\n ) {\n const { target, subTargets = [] } = options as {\n target?: FabricObject;\n subTargets: FabricObject[];\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n for (let i = 0; i < subTargets.length; i++) {\n subTargets[i] !== target && subTargets[i].fire(eventType, options);\n }\n return options;\n }\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {TPointerEvent} e event from mouse\n * @param {TPointerEventNames} eventType\n */\n _handleEvent(e: TPointerEvent, eventType: T) {\n const target = this._target,\n targets = this.targets || [],\n options: CanvasEvents[`mouse:${T}`] = {\n e,\n target,\n subTargets: targets,\n ...getEventPoints(this, e),\n transform: this._currentTransform,\n ...(eventType === 'up:before' || eventType === 'up'\n ? {\n isClick: this._isClick,\n currentTarget: this.findTarget(e),\n // set by the preceding `findTarget` call\n currentSubTargets: this.targets,\n }\n : {}),\n } as CanvasEvents[`mouse:${T}`];\n this.fire(`mouse:${eventType}`, options);\n // this may be a little be more complicated of what we want to handle\n target && target.fire(`mouse${eventType}`, options);\n for (let i = 0; i < targets.length; i++) {\n targets[i] !== target && targets[i].fire(`mouse${eventType}`, options);\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode(e: TPointerEvent) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e);\n this.requestRenderAll();\n }\n // TODO: this is a scene point so it should be renamed\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });\n this._handleEvent(e, 'down');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode(e: TPointerEvent) {\n if (this._isCurrentlyDrawing) {\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseMove(pointer, {\n e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode(e: TPointerEvent) {\n const pointer = this.getScenePoint(e);\n if (this.freeDrawingBrush) {\n this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({\n e: e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n } else {\n this._isCurrentlyDrawing = false;\n }\n this._handleEvent(e, 'up');\n }\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown(e: TPointerEvent) {\n this._isClick = true;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n\n let target: FabricObject | undefined = this._target;\n\n // if right/middle click just fire events\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'down');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n let shouldRender = this._shouldRender(target);\n let grouped = false;\n if (this.handleMultiSelection(e, target)) {\n // active object might have changed while grouping\n target = this._activeObject;\n grouped = true;\n shouldRender = true;\n } else if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n // we start a group selector rectangle if\n // selection is enabled\n // and there is no target, or the following 3 conditions are satisfied:\n // target is not selectable ( otherwise we selected it )\n // target is not editing\n // target is not already selected ( otherwise we drag )\n if (\n this.selection &&\n (!target ||\n (!target.selectable &&\n !(target as IText).isEditing &&\n target !== this._activeObject))\n ) {\n const p = this.getScenePoint(e);\n this._groupSelector = {\n x: p.x,\n y: p.y,\n deltaY: 0,\n deltaX: 0,\n };\n }\n\n if (target) {\n const alreadySelected = target === this._activeObject;\n if (target.selectable && target.activeOn === 'down') {\n this.setActiveObject(target, e);\n }\n const handle = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n if (target === this._activeObject && (handle || !grouped)) {\n this._setupCurrentTransform(e, target, alreadySelected);\n const control = handle ? handle.control : undefined,\n pointer = this.getScenePoint(e),\n mouseDownHandler =\n control && control.getMouseDownHandler(e, target, control);\n mouseDownHandler &&\n mouseDownHandler.call(\n control,\n e,\n this._currentTransform!,\n pointer.x,\n pointer.y,\n );\n }\n }\n // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering\n // run before firing the `down` event to give the dev a chance to populate it themselves\n shouldRender && (this._objectsToRender = undefined);\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n shouldRender && this.requestRenderAll();\n }\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData() {\n this._target = undefined;\n this._pointer = undefined;\n this._absolutePointer = undefined;\n }\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData(e: TPointerEvent) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getViewportPoint(e);\n this._absolutePointer = sendPointToPlane(\n this._pointer,\n undefined,\n this.viewportTransform,\n );\n this._target = this._currentTransform\n ? this._currentTransform.target\n : this.findTarget(e);\n }\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove(e: TPointerEvent) {\n this._isClick = false;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'move:before');\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n const groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n const pointer = this.getScenePoint(e);\n\n groupSelector.deltaX = pointer.x - groupSelector.x;\n groupSelector.deltaY = pointer.y - groupSelector.y;\n\n this.renderTop();\n } else if (!this._currentTransform) {\n const target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(e, target);\n } else {\n this._transformObject(e);\n }\n this.textEditingManager.onMouseMove(e);\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n }\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {\n const _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target,\n oldTarget: _hoveredTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n }\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Object} data Event object fired on dragover\n * @private\n */\n _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {\n const draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target,\n oldTarget: draggedoverTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._draggedoverTarget = target;\n }\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Object} data Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents(\n type: T,\n {\n target,\n oldTarget,\n fireCanvas,\n e,\n ...data\n }: TSyntheticEventContext[T] & {\n target?: FabricObject;\n oldTarget?: FabricObject;\n fireCanvas?: boolean;\n },\n ) {\n const { targetIn, targetOut, canvasIn, canvasOut } =\n syntheticEventConfig[type];\n const targetChanged = oldTarget !== target;\n\n if (oldTarget && targetChanged) {\n const outOpt: CanvasEvents[typeof canvasOut] = {\n ...data,\n e,\n target: oldTarget,\n nextTarget: target,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasOut, outOpt);\n oldTarget.fire(targetOut, outOpt);\n }\n if (target && targetChanged) {\n const inOpt: CanvasEvents[typeof canvasIn] = {\n ...data,\n e,\n target,\n previousTarget: oldTarget,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasIn, inOpt);\n target.fire(targetIn, inOpt);\n }\n }\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n }\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject(e: TPointerEvent) {\n const scenePoint = this.getScenePoint(e),\n transform = this._currentTransform!,\n target = transform.target,\n // transform pointer to target's containing coordinate plane\n // both pointer and object should agree on every point\n localPointer = target.group\n ? sendPointToPlane(\n scenePoint,\n undefined,\n target.group.calcTransformMatrix(),\n )\n : scenePoint;\n transform.shiftKey = e.shiftKey;\n transform.altKey = !!this.centeredKey && e[this.centeredKey];\n\n this._performTransformAction(e, transform, localPointer);\n transform.actionPerformed && this.requestRenderAll();\n }\n\n /**\n * @private\n */\n _performTransformAction(\n e: TPointerEvent,\n transform: Transform,\n pointer: Point,\n ) {\n const { action, actionHandler, target } = transform;\n\n const actionPerformed =\n !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y);\n actionPerformed && target.setCoords();\n\n // this object could be created from the function in the control handlers\n if (action === 'drag' && actionPerformed) {\n transform.target.isMoving = true;\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n }\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return;\n }\n let hoverCursor = target.hoverCursor || this.hoverCursor;\n const activeSelection = isActiveSelection(this._activeObject)\n ? this._activeObject\n : null,\n // only show proper corner when group selection is not active\n corner =\n (!activeSelection || target.group !== activeSelection) &&\n // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target.findControl(this.getViewportPoint(e));\n\n if (!corner) {\n if ((target as Group).subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets\n .concat()\n .reverse()\n .map((_target) => {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n } else {\n const control = corner.control;\n this.setCursor(control.cursorStyleHandler(e, control, target));\n }\n }\n\n /**\n * ## Handles multiple selection\n * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)\n * - sets the active object in case it is not set or in case there is a single active object left under active selection.\n * ---\n * - If the active object is the active selection we add/remove `target` from it\n * - If not, add the active object and `target` to the active selection and make it the active object.\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target target of event to select/deselect\n * @returns true if grouping occurred\n */\n protected handleMultiSelection(e: TPointerEvent, target?: FabricObject) {\n const activeObject = this._activeObject;\n const isAS = isActiveSelection(activeObject);\n if (\n // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.\n !!activeObject &&\n this._isSelectionKeyPressed(e) &&\n this.selection &&\n // on top of that the user also has to hit a target that is selectable.\n !!target &&\n target.selectable &&\n // group target and active object only if they are different objects\n // else we try to find a subtarget of `ActiveSelection`\n (activeObject !== target || isAS) &&\n // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`\n // if it is then we want to remove `target` from it\n (isAS ||\n (!target.isDescendantOf(activeObject) &&\n !activeObject.isDescendantOf(target))) &&\n // target accepts selection\n !target.onSelect({ e }) &&\n // make sure we are not on top of a control\n !activeObject.getActiveControl()\n ) {\n if (isAS) {\n const prevActiveObjects = activeObject.getObjects();\n if (target === activeObject) {\n const pointer = this.getViewportPoint(e);\n target =\n // first search active objects for a target to remove\n this.searchPossibleTargets(prevActiveObjects, pointer) ||\n // if not found, search under active selection for a target to add\n // `prevActiveObjects` will be searched but we already know they will not be found\n this.searchPossibleTargets(this._objects, pointer);\n // if nothing is found bail out\n if (!target || !target.selectable) {\n return false;\n }\n }\n if (target.group === activeObject) {\n // `target` is part of active selection => remove it\n activeObject.remove(target);\n this._hoveredTarget = target;\n this._hoveredTargets = [...this.targets];\n // if after removing an object we are left with one only...\n if (activeObject.size() === 1) {\n // activate last remaining object\n // deselecting the active selection will remove the remaining object from it\n this._setActiveObject(activeObject.item(0), e);\n }\n } else {\n // `target` isn't part of active selection => add it\n activeObject.multiSelectAdd(target);\n this._hoveredTarget = activeObject;\n this._hoveredTargets = [...this.targets];\n }\n this._fireSelectionEvents(prevActiveObjects, e);\n } else {\n (activeObject as IText).exitEditing &&\n (activeObject as IText).exitEditing();\n // add the active object and the target to the active selection and set it as the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n const newActiveSelection = new klass([], {\n /**\n * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd}\n * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref\n */\n canvas: this,\n });\n newActiveSelection.multiSelectAdd(activeObject, target);\n this._hoveredTarget = newActiveSelection;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(newActiveSelection, e);\n this._fireSelectionEvents([activeObject], e);\n }\n return true;\n }\n return false;\n }\n\n /**\n * ## Handles selection\n * - selects objects that are contained in (and possibly intersecting) the selection bounding box\n * - sets the active object\n * ---\n * runs on mouse up after a mouse move\n */\n protected handleSelection(e: TPointerEvent) {\n if (!this.selection || !this._groupSelector) {\n return false;\n }\n const { x, y, deltaX, deltaY } = this._groupSelector,\n point1 = new Point(x, y),\n point2 = point1.add(new Point(deltaX, deltaY)),\n tl = point1.min(point2),\n br = point1.max(point2),\n size = br.subtract(tl);\n\n const collectedObjects = this.collectObjects(\n {\n left: tl.x,\n top: tl.y,\n width: size.x,\n height: size.y,\n },\n { includeIntersecting: !this.selectionFullyContained },\n ) as FabricObject[];\n\n const objects =\n // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down\n // should it be handled as is?\n point1.eq(point2)\n ? collectedObjects[0]\n ? [collectedObjects[0]]\n : []\n : collectedObjects.length > 1\n ? collectedObjects\n .filter((object) => !object.onSelect({ e }))\n .reverse()\n : // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case\n collectedObjects;\n\n // set active object\n if (objects.length === 1) {\n // set as active object\n this.setActiveObject(objects[0], e);\n } else if (objects.length > 1) {\n // add to active selection and make it the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n this.setActiveObject(new klass(objects, { canvas: this }), e);\n }\n\n // cleanup\n this._groupSelector = null;\n return true;\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n clear() {\n this.textEditingManager.clear();\n super.clear();\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n destroy() {\n this.removeListeners();\n this.textEditingManager.dispose();\n super.destroy();\n }\n}\n","export const linearDefaultCoords = {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n};\n\nexport const radialDefaultCoords = {\n ...linearDefaultCoords,\n r1: 0,\n r2: 0,\n};\n","/**\n *\n * @param value value to check if NaN\n * @param [valueIfNaN]\n * @returns `fallback` is `value is NaN\n */\nexport const ifNaN = (value: number, valueIfNaN?: number) => {\n return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value;\n};\n","import { ifNaN } from '../util/internals/ifNaN';\nimport { capValue } from '../util/misc/capValue';\n\nconst RE_PERCENT = /^(\\d+\\.\\d+)%|(\\d+)%$/;\n\nexport function isPercent(value: string | null) {\n return value && RE_PERCENT.test(value);\n}\n\n/**\n *\n * @param value\n * @param valueIfNaN\n * @returns ∈ [0, 1]\n */\nexport function parsePercent(\n value: string | number | null | undefined,\n valueIfNaN?: number,\n) {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string'\n ? parseFloat(value) / (isPercent(value) ? 100 : 1)\n : NaN;\n return capValue(0, ifNaN(parsed, valueIfNaN), 1);\n}\n","import { Color } from '../../color/Color';\nimport { parsePercent } from '../../parser/percent';\nimport { ifNaN } from '../../util/internals/ifNaN';\nimport type { ColorStop } from '../typedefs';\n\nconst RE_KEY_VALUE_PAIRS = /\\s*;\\s*/;\nconst RE_KEY_VALUE = /\\s*:\\s*/;\n\nfunction parseColorStop(el: SVGStopElement, multiplier: number) {\n let colorValue, opacity;\n const style = el.getAttribute('style');\n if (style) {\n const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (let i = keyValuePairs.length; i--; ) {\n const [key, value] = keyValuePairs[i]\n .split(RE_KEY_VALUE)\n .map((s) => s.trim());\n if (key === 'stop-color') {\n colorValue = value;\n } else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n const color = new Color(\n colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)',\n );\n\n return {\n offset: parsePercent(el.getAttribute('offset'), 0),\n color: color.toRgb(),\n opacity:\n ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) *\n color.getAlpha() *\n multiplier,\n };\n}\n\nexport function parseColorStops(\n el: SVGGradientElement,\n opacityAttr: string | null,\n) {\n const colorStops: ColorStop[] = [],\n colorStopEls = el.getElementsByTagName('stop'),\n multiplier = parsePercent(opacityAttr, 1);\n for (let i = colorStopEls.length; i--; ) {\n colorStops.push(parseColorStop(colorStopEls[i], multiplier));\n }\n return colorStops;\n}\n","import type { GradientType, GradientUnits } from '../typedefs';\n\nexport function parseType(el: SVGGradientElement): GradientType {\n return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT'\n ? 'linear'\n : 'radial';\n}\n\nexport function parseGradientUnits(el: SVGGradientElement): GradientUnits {\n return el.getAttribute('gradientUnits') === 'userSpaceOnUse'\n ? 'pixels'\n : 'percentage';\n}\n","import { isPercent } from '../../parser/percent';\nimport type { TSize } from '../../typedefs';\nimport type { GradientCoords, GradientType, GradientUnits } from '../typedefs';\nimport { parseGradientUnits, parseType } from './misc';\n\nfunction convertPercentUnitsToValues<\n T extends GradientType,\n K extends keyof GradientCoords,\n>(\n valuesToConvert: Record,\n { width, height, gradientUnits }: TSize & { gradientUnits: GradientUnits },\n) {\n let finalValue;\n return (Object.keys(valuesToConvert) as K[]).reduce(\n (acc, prop) => {\n const propValue = valuesToConvert[prop];\n if (propValue === 'Infinity') {\n finalValue = 1;\n } else if (propValue === '-Infinity') {\n finalValue = 0;\n } else {\n finalValue =\n typeof propValue === 'string' ? parseFloat(propValue) : propValue;\n if (typeof propValue === 'string' && isPercent(propValue)) {\n finalValue *= 0.01;\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= width;\n }\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= height;\n }\n }\n }\n }\n acc[prop] = finalValue;\n return acc;\n },\n {} as Record,\n );\n}\n\nfunction getValue(el: SVGGradientElement, key: string) {\n return el.getAttribute(key);\n}\n\nexport function parseLinearCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'x1') || 0,\n y1: getValue(el, 'y1') || 0,\n x2: getValue(el, 'x2') || '100%',\n y2: getValue(el, 'y2') || 0,\n };\n}\n\nexport function parseRadialCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%',\n y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%',\n r1: 0,\n x2: getValue(el, 'cx') || '50%',\n y2: getValue(el, 'cy') || '50%',\n r2: getValue(el, 'r') || '50%',\n };\n}\n\nexport function parseCoords(el: SVGGradientElement, size: TSize) {\n return convertPercentUnitsToValues(\n parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el),\n {\n ...size,\n gradientUnits: parseGradientUnits(el),\n },\n );\n}\n","import { Color } from '../color/Color';\nimport { iMatrix } from '../constants';\nimport { parseTransformAttribute } from '../parser/parseTransformAttribute';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { linearDefaultCoords, radialDefaultCoords } from './constants';\nimport { parseColorStops } from './parser/parseColorStops';\nimport { parseCoords } from './parser/parseCoords';\nimport { parseType, parseGradientUnits } from './parser/misc';\nimport type {\n ColorStop,\n GradientCoords,\n GradientOptions,\n GradientType,\n GradientUnits,\n SVGOptions,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { isPath } from '../util/typeAssertions';\n\n/**\n * Gradient class\n * @class Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n */\nexport class Gradient<\n S,\n T extends GradientType = S extends GradientType ? S : 'linear',\n> {\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetX: number;\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetY: number;\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n declare gradientTransform?: TMat2D;\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type GradientUnits\n * @default 'pixels'\n */\n declare gradientUnits: GradientUnits;\n\n /**\n * Gradient type linear or radial\n * @type GradientType\n * @default 'linear'\n */\n declare type: T;\n\n /**\n * Defines how the gradient is located in space and spread\n * @type GradientCoords\n */\n declare coords: GradientCoords;\n\n /**\n * Defines how many colors a gradient has and how they are located on the axis\n * defined by coords\n * @type GradientCoords\n */\n declare colorStops: ColorStop[];\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number | string\n */\n declare readonly id: string | number;\n\n static type = 'Gradient';\n\n constructor(options: GradientOptions) {\n const {\n type = 'linear' as T,\n gradientUnits = 'pixels',\n coords = {},\n colorStops = [],\n offsetX = 0,\n offsetY = 0,\n gradientTransform,\n id,\n } = options || {};\n Object.assign(this, {\n type,\n gradientUnits,\n coords: {\n ...(type === 'radial' ? radialDefaultCoords : linearDefaultCoords),\n ...coords,\n },\n colorStops,\n offsetX,\n offsetY,\n gradientTransform,\n id: id ? `${id}_${uid()}` : uid(),\n });\n }\n\n /**\n * Adds another colorStop\n * @param {Record} colorStop Object with offset and color\n * @return {Gradient} thisArg\n */\n addColorStop(colorStops: Record) {\n for (const position in colorStops) {\n const color = new Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha(),\n });\n }\n return this;\n }\n\n /**\n * Returns object representation of a gradient\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object}\n */\n toObject(propertiesToInclude?: (keyof this | string)[]) {\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: this.type,\n coords: { ...this.coords },\n colorStops: this.colorStops.map((colorStop) => ({ ...colorStop })),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform\n ? [...this.gradientTransform]\n : undefined,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {FabricObject} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG(\n object: FabricObject,\n {\n additionalTransform: preTransform,\n }: { additionalTransform?: string } = {},\n ) {\n const markup = [],\n transform = (\n this.gradientTransform\n ? this.gradientTransform.concat()\n : iMatrix.concat()\n ) as TMat2D,\n gradientUnits =\n this.gradientUnits === 'pixels'\n ? 'userSpaceOnUse'\n : 'objectBoundingBox';\n // colorStops must be sorted ascending, and guarded against deep mutations\n const colorStops = this.colorStops\n .map((colorStop) => ({ ...colorStop }))\n .sort((a, b) => {\n return a.offset - b.offset;\n });\n\n let offsetX = -this.offsetX,\n offsetY = -this.offsetY;\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n } else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n // todo what about polygon/polyline?\n if (isPath(object) && this.gradientUnits !== 'percentage') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n\n const commonAttributes = [\n `id=\"SVGID_${this.id}\"`,\n `gradientUnits=\"${gradientUnits}\"`,\n `gradientTransform=\"${\n preTransform ? preTransform + ' ' : ''\n }${matrixToSVG(transform)}\"`,\n '',\n ].join(' ');\n\n if (this.type === 'linear') {\n const { x1, y1, x2, y2 } = this.coords;\n markup.push(\n '\\n',\n );\n } else if (this.type === 'radial') {\n const { x1, y1, x2, y2, r1, r2 } = this\n .coords as GradientCoords<'radial'>;\n const needsSwap = r1 > r2;\n // svg radial gradient has just 1 radius. the biggest.\n markup.push(\n '\\n',\n );\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops.reverse(); // mutates array\n colorStops.forEach((colorStop) => {\n colorStop.offset = 1 - colorStop.offset;\n });\n }\n const minRadius = Math.min(r1, r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n const maxRadius = Math.max(r1, r2),\n percentageShift = minRadius / maxRadius;\n colorStops.forEach((colorStop) => {\n colorStop.offset += percentageShift * (1 - colorStop.offset);\n });\n }\n }\n\n colorStops.forEach(({ color, offset, opacity }) => {\n markup.push(\n '\\n',\n );\n });\n\n markup.push(\n this.type === 'linear' ? '' : '',\n '\\n',\n );\n\n return markup.join('');\n }\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasGradient {\n const { x1, y1, x2, y2, r1, r2 } = this.coords as GradientCoords<'radial'>;\n const gradient =\n this.type === 'linear'\n ? ctx.createLinearGradient(x1, y1, x2, y2)\n : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);\n\n this.colorStops.forEach(({ color, opacity, offset }) => {\n gradient.addColorStop(\n offset,\n typeof opacity !== 'undefined'\n ? new Color(color).setAlpha(opacity).toRgba()\n : color,\n );\n });\n\n return gradient;\n }\n\n static async fromObject(\n options: GradientOptions<'linear'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'radial'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'linear'> | GradientOptions<'radial'>,\n ) {\n const { colorStops, gradientTransform } = options;\n return new this({\n ...options,\n colorStops: colorStops\n ? colorStops.map((colorStop) => ({ ...colorStop }))\n : undefined,\n gradientTransform: gradientTransform ? [...gradientTransform] : undefined,\n });\n }\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link Gradient} instance from an SVG element\n * @static\n * @memberOf Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {FabricObject} instance\n * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @return {Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n *\n * @example\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n static fromElement(\n el: SVGGradientElement,\n instance: FabricObject,\n svgOptions: SVGOptions,\n ): Gradient {\n const gradientUnits = parseGradientUnits(el);\n const center = instance._findCenterFromElement();\n return new this({\n id: el.getAttribute('id') || undefined,\n type: parseType(el),\n coords: parseCoords(el, {\n width: svgOptions.viewBoxWidth || svgOptions.width,\n height: svgOptions.viewBoxHeight || svgOptions.height,\n }),\n colorStops: parseColorStops(el, svgOptions.opacity),\n gradientUnits,\n gradientTransform: parseTransformAttribute(\n el.getAttribute('gradientTransform') || '',\n ),\n ...(gradientUnits === 'pixels'\n ? {\n offsetX: instance.width / 2 - center.x,\n offsetY: instance.height / 2 - center.y,\n }\n : {\n offsetX: 0,\n offsetY: 0,\n }),\n });\n }\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Gradient, 'gradient');\nclassRegistry.setClass(Gradient, 'linear');\nclassRegistry.setClass(Gradient, 'radial');\n","import { config } from '../config';\nimport type { Abortable, TCrossOrigin, TMat2D, TSize } from '../typedefs';\nimport { ifNaN } from '../util/internals/ifNaN';\nimport { uid } from '../util/internals/uid';\nimport { loadImage } from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { toFixed } from '../util/misc/toFixed';\nimport { classRegistry } from '../ClassRegistry';\nimport type {\n PatternRepeat,\n PatternOptions,\n SerializedPatternOptions,\n} from './types';\nimport { log } from '../util/internals/console';\n\n/**\n * @see {@link http://fabricjs.com/patterns demo}\n * @see {@link http://fabricjs.com/dynamic-patterns demo}\n */\nexport class Pattern {\n static type = 'Pattern';\n\n /**\n * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern'\n * or utils like isPattern, or instance of to indentify a pattern in your code.\n * Will be removed in future versiones\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n return 'pattern';\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * @type PatternRepeat\n * @defaults\n */\n repeat: PatternRepeat = 'repeat';\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX = 0;\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY = 0;\n\n /**\n * @type TCrossOrigin\n * @default\n */\n crossOrigin: TCrossOrigin = '';\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @todo verify if using the identity matrix as default makes the rest of the code more easy\n * @type Array\n * @default\n */\n declare patternTransform?: TMat2D;\n\n /**\n * The actual pixel source of the pattern\n */\n declare source: CanvasImageSource;\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number\n */\n declare readonly id: number;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {option.source} [source] the pattern source, eventually empty or a drawable\n */\n constructor(options: PatternOptions) {\n this.id = uid();\n Object.assign(this, options);\n }\n\n /**\n * @returns true if {@link source} is an element\n */\n isImageSource(): this is { source: HTMLImageElement } {\n return (\n !!this.source && typeof (this.source as HTMLImageElement).src === 'string'\n );\n }\n\n /**\n * @returns true if {@link source} is a element\n */\n isCanvasSource(): this is { source: HTMLCanvasElement } {\n return !!this.source && !!(this.source as HTMLCanvasElement).toDataURL;\n }\n\n sourceToString(): string {\n return this.isImageSource()\n ? this.source.src\n : this.isCanvasSource()\n ? this.source.toDataURL()\n : '';\n }\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasPattern | null {\n if (\n // if the image failed to load, return, and allow rest to continue loading\n !this.source ||\n // if an image\n (this.isImageSource() &&\n (!this.source.complete ||\n this.source.naturalWidth === 0 ||\n this.source.naturalHeight === 0))\n ) {\n return null;\n }\n\n return ctx.createPattern(this.source, this.repeat)!;\n }\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object} Object representation of a pattern instance\n */\n toObject(propertiesToInclude: string[] = []): Record {\n const { repeat, crossOrigin } = this;\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: 'pattern',\n source: this.sourceToString(),\n repeat,\n crossOrigin,\n offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform\n ? [...this.patternTransform]\n : null,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n */\n toSVG({ width, height }: TSize): string {\n const { source: patternSource, repeat, id } = this,\n patternOffsetX = ifNaN(this.offsetX / width, 0),\n patternOffsetY = ifNaN(this.offsetY / height, 0),\n patternWidth =\n repeat === 'repeat-y' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetX || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).width as number) / width,\n 0,\n ),\n patternHeight =\n repeat === 'repeat-x' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetY || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).height as number) / height,\n 0,\n );\n\n return [\n ``,\n ``,\n ``,\n '',\n ].join('\\n');\n }\n /* _TO_SVG_END_ */\n\n static async fromObject(\n {\n type,\n source,\n patternTransform,\n ...otherOptions\n }: SerializedPatternOptions,\n options?: Abortable,\n ): Promise {\n const img = await loadImage(source, {\n ...options,\n crossOrigin: otherOptions.crossOrigin,\n });\n return new this({\n ...otherOptions,\n patternTransform:\n patternTransform && (patternTransform.slice(0) as TMat2D),\n source: img,\n });\n }\n}\n\nclassRegistry.setClass(Pattern);\n// kept for compatibility reason\nclassRegistry.setClass(Pattern, 'pattern');\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport type { Shadow } from '../Shadow';\nimport type { Canvas } from '../canvas/Canvas';\nimport type { TBrushEventData } from './typedefs';\n\n/**\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nexport abstract class BaseBrush {\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color = 'rgb(0, 0, 0)';\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width = 1;\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type Shadow\n * @default\n */\n shadow: Shadow | null = null;\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: CanvasLineCap = 'round';\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: CanvasLineJoin = 'round';\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit = 10;\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: number[] | null = null;\n\n /**\n * When `true`, the free drawing is limited to the whiteboard size. Default to false.\n * @type Boolean\n * @default false\n */\n\n limitedToCanvasSize = false;\n\n /**\n * @todo add type\n */\n declare canvas: Canvas;\n\n constructor(canvas: Canvas) {\n this.canvas = canvas;\n }\n\n abstract _render(): void;\n abstract onMouseDown(pointer: Point, ev: TBrushEventData): void;\n abstract onMouseMove(pointer: Point, ev: TBrushEventData): void;\n /**\n * @returns true if brush should continue blocking interaction\n */\n abstract onMouseUp(ev: TBrushEventData): boolean | void;\n\n /**\n * Sets brush styles\n * @private\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.setLineDash(this.strokeDashArray || []);\n }\n\n /**\n * Sets the transformation on given context\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @private\n */\n protected _saveAndTransform(ctx: CanvasRenderingContext2D) {\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n protected needsFullRender() {\n const color = new Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n }\n\n /**\n * Sets brush shadow styles\n * @private\n */\n protected _setShadow() {\n if (!this.shadow || !this.canvas) {\n return;\n }\n\n const canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom() * canvas.getRetinaScaling();\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n }\n\n /**\n * Removes brush shadow styles\n * @private\n */\n protected _resetShadow() {\n const ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * Check is pointer is outside canvas boundaries\n * @param {Object} pointer\n * @private\n */\n protected _isOutSideCanvas(pointer: Point) {\n return (\n pointer.x < 0 ||\n pointer.x > this.canvas.getWidth() ||\n pointer.y < 0 ||\n pointer.y > this.canvas.getHeight()\n );\n }\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { toFixed } from '../util/misc/toFixed';\nimport {\n getBoundsOfCurve,\n joinPath,\n makePathSimpler,\n parsePath,\n} from '../util/path';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type {\n TComplexPathData,\n TPathSegmentInfo,\n TSimplePathData,\n} from '../util/path/typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type {\n TBBox,\n TClassProperties,\n TSVGReviver,\n TOptions,\n} from '../typedefs';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\ninterface UniquePathProps {\n sourcePath?: string;\n path?: TSimplePathData;\n}\n\nexport interface SerializedPathProps\n extends SerializedObjectProps,\n UniquePathProps {}\n\nexport interface PathProps extends FabricObjectProps, UniquePathProps {}\n\nexport interface IPathBBox extends TBBox {\n left: number;\n top: number;\n pathOffset: Point;\n}\n\nexport class Path<\n Props extends TOptions = Partial,\n SProps extends SerializedPathProps = SerializedPathProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Array of path points\n * @type Array\n * @default\n */\n declare path: TSimplePathData;\n\n declare pathOffset: Point;\n\n declare sourcePath?: string;\n\n declare segmentsInfo?: TPathSegmentInfo[];\n\n static type = 'Path';\n\n static cacheProperties = [...cacheProperties, 'path', 'fillRule'];\n\n /**\n * Constructor\n * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Partial} [options] Options object\n * @return {Path} thisArg\n */\n constructor(\n path: TComplexPathData | string,\n // todo: evaluate this spread here\n { path: _, left, top, ...options }: Partial = {},\n ) {\n super();\n Object.assign(this, Path.ownDefaults);\n this.setOptions(options);\n this._setPath(path || [], true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box\n * @returns {Point} top left position of the bounding box, useful for complementary positioning\n */\n _setPath(path: TComplexPathData | string, adjustPosition?: boolean) {\n this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));\n this.setBoundingBox(adjustPosition);\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = this._calcBoundsFromPath();\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands(ctx: CanvasRenderingContext2D) {\n const l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (const command of this.path) {\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n ctx.lineTo(command[1] + l, command[2] + t);\n break;\n\n case 'M': // moveTo, absolute\n ctx.moveTo(command[1] + l, command[2] + t);\n break;\n\n case 'C': // bezierCurveTo, absolute\n ctx.bezierCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n command[5] + l,\n command[6] + t,\n );\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n );\n break;\n\n case 'Z':\n ctx.closePath();\n break;\n }\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render(ctx: CanvasRenderingContext2D) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns string representation of an instance\n * @return {string} string representation of an instance\n */\n toString() {\n return `#`;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n path: this.path.map((pathCmd) => pathCmd.slice()),\n };\n }\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n delete o.path;\n o.sourcePath = this.sourcePath;\n }\n return o;\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const path = joinPath(this.path, config.NUM_FRACTION_DIGITS);\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @return the path command's translate transform attribute\n */\n _getOffsetTransform() {\n const digits = config.NUM_FRACTION_DIGITS;\n return ` translate(${toFixed(-this.pathOffset.x, digits)}, ${toFixed(\n -this.pathOffset.y,\n digits,\n )})`;\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n })\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n });\n }\n\n /**\n * Returns number representation of an instance complexity\n * @return {number} complexity of this instance\n */\n complexity() {\n return this.path.length;\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { width, height, pathOffset } = this._calcDimensions();\n this.set({ width, height, pathOffset });\n // using pathOffset because it match the use case.\n // if pathOffset change here we need to use left + width/2 , top + height/2\n adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER);\n }\n\n _calcBoundsFromPath(): TBBox {\n const bounds: XY[] = [];\n let subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0; // current y\n\n for (const command of this.path) {\n // current instruction\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n x = command[1];\n y = command[2];\n bounds.push({ x: subpathStartX, y: subpathStartY }, { x, y });\n break;\n\n case 'M': // moveTo, absolute\n x = command[1];\n y = command[2];\n subpathStartX = x;\n subpathStartY = y;\n break;\n\n case 'C': // bezierCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[3],\n command[4],\n command[5],\n command[6],\n ),\n );\n x = command[5];\n y = command[6];\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[1],\n command[2],\n command[3],\n command[4],\n ),\n );\n x = command[3];\n y = command[4];\n break;\n\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n }\n return makeBoundingBoxFromPoints(bounds);\n }\n\n /**\n * @private\n */\n _calcDimensions(): IPathBBox {\n const bbox = this._calcBoundsFromPath();\n\n return {\n ...bbox,\n pathOffset: new Point(\n bbox.left + bbox.width / 2,\n bbox.top + bbox.height / 2,\n ),\n };\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`)\n * @static\n * @memberOf Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'd'];\n\n /**\n * Creates an instance of Path from an object\n * @static\n * @memberOf Path\n * @param {Object} object\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'path',\n });\n }\n\n /**\n * Creates an instance of Path from an SVG element\n * @static\n * @memberOf Path\n * @param {HTMLElement} element to parse\n * @param {Partial} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Partial,\n cssRules?: CSSRules,\n ) {\n const { d, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(d, {\n ...parsedAttributes,\n ...options,\n // we pass undefined to instruct the constructor to position the object using the bbox\n left: undefined,\n top: undefined,\n });\n }\n}\n\nclassRegistry.setClass(Path);\nclassRegistry.setSVGClass(Path);\n\n/* _FROM_SVG_START_ */\n","import type { ModifierKey, TEvent } from '../EventTypeDefs';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Path } from '../shapes/Path';\nimport { getSmoothPathFromPoints, joinPath } from '../util/path';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\n/**\n * @private\n * @param {TSimplePathData} pathData SVG path commands\n * @returns {boolean}\n */\nfunction isEmptySVGPath(pathData: TSimplePathData): boolean {\n return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0';\n}\n\nexport class PencilBrush extends BaseBrush {\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate = 0.4;\n\n /**\n * Draws a straight line between last recorded point to current pointer\n * Used for `shift` functionality\n *\n * @type boolean\n * @default false\n */\n drawStraightLine = false;\n\n /**\n * The event modifier key that makes the brush draw a straight line.\n * If `null` or 'none' or any other string that is not a modifier key the feature is disabled.\n * @type {ModifierKey | undefined | null}\n */\n straightLineKey: ModifierKey | undefined | null = 'shiftKey';\n\n private declare _points: Point[];\n private declare _hasStraightLine: boolean;\n private declare oldEnd?: Point;\n\n constructor(canvas: Canvas) {\n super(canvas);\n this._points = [];\n this._hasStraightLine = false;\n }\n\n needsFullRender() {\n return super.needsFullRender() || this._hasStraightLine;\n }\n\n static drawSegment(ctx: CanvasRenderingContext2D, p1: Point, p2: Point) {\n const midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._addPoint(pointer);\n this._render();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this._addPoint(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n } else {\n const points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = PencilBrush.drawSegment(\n ctx,\n points[length - 2],\n points[length - 1],\n );\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp({ e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return true;\n }\n this.drawStraightLine = false;\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n }\n\n /**\n * @private\n * @param {Point} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing(pointer: Point) {\n this._reset();\n this._addPoint(pointer);\n this.canvas.contextTop.moveTo(pointer.x, pointer.y);\n }\n\n /**\n * @private\n * @param {Point} point Point to be added to points array\n */\n _addPoint(point: Point) {\n if (\n this._points.length > 1 &&\n point.eq(this._points[this._points.length - 1])\n ) {\n return false;\n }\n if (this.drawStraightLine && this._points.length > 1) {\n this._hasStraightLine = true;\n this._points.pop();\n }\n this._points.push(point);\n return true;\n }\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset() {\n this._points = [];\n this._setBrushStyles(this.canvas.contextTop);\n this._setShadow();\n this._hasStraightLine = false;\n }\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n * @param {CanvasRenderingContext2D} [ctx]\n */\n _render(ctx: CanvasRenderingContext2D = this.canvas.contextTop) {\n let p1 = this._points[0],\n p2 = this._points[1];\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n const width = this.width / 1000;\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (let i = 1; i < this._points.length; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n PencilBrush.drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * Converts points to SVG path\n * @param {Point[]} points Array of points\n * @return {TSimplePathData} SVG path commands\n */\n convertPointsToSVGPath(points: Point[]): TSimplePathData {\n const correction = this.width / 1000;\n return getSmoothPathFromPoints(points, correction);\n }\n\n /**\n * Creates a Path object to add on canvas\n * @param {TSimplePathData} pathData Path data\n * @return {Path} Path to add on canvas\n */\n createPath(pathData: TSimplePathData): Path {\n const path = new Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new Shadow(this.shadow);\n }\n\n return path;\n }\n\n /**\n * Decimate points array with the decimate value\n */\n decimatePoints(points: Point[], distance: number) {\n if (points.length <= 2) {\n return points;\n }\n let lastPoint = points[0],\n cDistance;\n const zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n l = points.length - 1,\n newPoints = [lastPoint];\n for (let i = 1; i < l - 1; i++) {\n cDistance =\n Math.pow(lastPoint.x - points[i].x, 2) +\n Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n // Add the last point from the original line to the end of the array.\n // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point.\n newPoints.push(points[l]);\n return newPoints;\n }\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new Path object\n * and add it to the canvas.\n */\n _finalizeAndAddPath() {\n const ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n const pathData = this.convertPointsToSVGPath(this._points);\n if (isEmptySVGPath(pathData)) {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n const path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', { path: path });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n}\n","import type { ObjectEvents } from '../EventTypeDefs';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { cos } from '../util/misc/cos';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { sin } from '../util/misc/sin';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { CSSRules } from '../parser/typedefs';\nimport { SCALE_X, SCALE_Y } from '../constants';\n\ninterface UniqueCircleProps {\n /**\n * Radius of this circle\n * @type Number\n * @default 0\n */\n radius: number;\n\n /**\n * Angle for the start of the circle, in degrees.\n * @type TDegree 0 - 359\n * @default 0\n */\n startAngle: number;\n\n /**\n * Angle for the end of the circle, in degrees\n * @type TDegree 1 - 360\n * @default 360\n */\n endAngle: number;\n\n /**\n * Orientation for the direction of the circle.\n * Setting to true will switch the arc of the circle to traverse from startAngle to endAngle in a counter-clockwise direction.\n * Note: this will only change how the circle is drawn, and does not affect rotational transformation.\n * @default false\n */\n counterClockwise: boolean;\n}\n\nexport interface SerializedCircleProps\n extends SerializedObjectProps,\n UniqueCircleProps {}\n\nexport interface CircleProps extends FabricObjectProps, UniqueCircleProps {}\n\nconst CIRCLE_PROPS = [\n 'radius',\n 'startAngle',\n 'endAngle',\n 'counterClockwise',\n] as const;\n\nexport const circleDefaultValues: Partial> = {\n radius: 0,\n startAngle: 0,\n endAngle: 360,\n counterClockwise: false,\n};\n\nexport class Circle<\n Props extends TOptions = Partial,\n SProps extends SerializedCircleProps = SerializedCircleProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueCircleProps\n{\n declare radius: number;\n declare startAngle: number;\n declare endAngle: number;\n declare counterClockwise: boolean;\n\n static type = 'Circle';\n\n static cacheProperties = [...cacheProperties, ...CIRCLE_PROPS];\n\n static ownDefaults = circleDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Circle.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Circle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n degreesToRadians(this.startAngle),\n degreesToRadians(this.endAngle),\n this.counterClockwise,\n );\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX(): number {\n return this.get('radius') * this.get(SCALE_X);\n }\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY(): number {\n return this.get('radius') * this.get(SCALE_Y);\n }\n\n /**\n * Sets radius of an object (and updates width accordingly)\n */\n setRadius(value: number) {\n this.radius = value;\n this.set({ width: value * 2, height: value * 2 });\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]);\n }\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n const angle = (this.endAngle - this.startAngle) % 360;\n\n if (angle === 0) {\n return [\n '\\n',\n ];\n } else {\n const { radius } = this;\n const start = degreesToRadians(this.startAngle),\n end = degreesToRadians(this.endAngle),\n startX = cos(start) * radius,\n startY = sin(start) * radius,\n endX = cos(end) * radius,\n endY = sin(end) * radius,\n largeFlag = angle > 180 ? 1 : 0,\n sweepFlag = this.counterClockwise ? 0 : 1;\n return [\n `\\n',\n ];\n }\n }\n /* _TO_SVG_END_ */\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement})\n * @static\n * @memberOf Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n static ATTRIBUTE_NAMES = ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES];\n\n /**\n * Returns {@link Circle} instance from an SVG element\n * @static\n * @memberOf Circle\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Partial Circle object to default missing properties on the element.\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ): Promise {\n const {\n left = 0,\n top = 0,\n radius = 0,\n ...otherParsedAttributes\n } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n ) as Partial;\n\n // this probably requires to be fixed for default origins not being top/left.\n\n return new this({\n ...otherParsedAttributes,\n radius,\n left: left - radius,\n top: top - radius,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * @todo how do we declare this??\n */\n static fromObject>(object: T) {\n return super._fromObject(object);\n }\n}\n\nclassRegistry.setClass(Circle);\nclassRegistry.setSVGClass(Circle);\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Circle } from '../shapes/Circle';\nimport { Group } from '../shapes/Group';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { CircleBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\nexport class CircleBrush extends BaseBrush {\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width = 10;\n\n declare points: CircleBrushPoint[];\n\n constructor(canvas: Canvas) {\n super(canvas);\n this.points = [];\n }\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Point} pointer\n */\n drawDot(pointer: Point) {\n const point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n }\n\n dot(ctx: CanvasRenderingContext2D, point: CircleBrushPoint) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Invoked on mouse down\n */\n onMouseDown(pointer: Point) {\n this.points = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n }\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render() {\n const ctx = this.canvas.contextTop,\n points = this.points;\n this._saveAndTransform(ctx);\n for (let i = 0; i < points.length; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n } else {\n this.drawDot(pointer);\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const circles: Circle[] = [];\n\n for (let i = 0; i < this.points.length; i++) {\n const point = this.points[i],\n circle = new Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: CENTER,\n originY: CENTER,\n fill: point.fill,\n });\n\n this.shadow && (circle.shadow = new Shadow(this.shadow));\n\n circles.push(circle);\n }\n const group = new Group(circles, { canvas: this.canvas });\n\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n /**\n * @param {Object} pointer\n * @return {Point} Just added pointer point\n */\n addPoint({ x, y }: Point) {\n const pointerPoint: CircleBrushPoint = {\n x,\n y,\n radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba(),\n };\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n}\n","import type { Point } from '../Point';\nimport { Group } from '../shapes/Group';\nimport { Shadow } from '../Shadow';\nimport { Rect } from '../shapes/Rect';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { SprayBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\n/**\n *\n * @param rects\n * @returns\n */\nfunction getUniqueRects(rects: Rect[]) {\n const uniqueRects: Record = {};\n const uniqueRectsArray: Rect[] = [];\n\n for (let i = 0, key: string; i < rects.length; i++) {\n key = `${rects[i].left}${rects[i].top}`;\n if (!uniqueRects[key]) {\n uniqueRects[key] = true;\n uniqueRectsArray.push(rects[i]);\n }\n }\n\n return uniqueRectsArray;\n}\n\nexport class SprayBrush extends BaseBrush {\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width = 10;\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density = 20;\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth = 1;\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance = 1;\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity = false;\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping = true;\n\n private declare sprayChunks: SprayBrushPoint[][];\n\n private declare sprayChunk: SprayBrushPoint[];\n\n /**\n * Constructor\n * @param {Canvas} canvas\n * @return {SprayBrush} Instance of a spray brush\n */\n constructor(canvas: Canvas) {\n super(canvas);\n this.sprayChunks = [];\n this.sprayChunk = [];\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point) {\n this.sprayChunks = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const rects: Rect[] = [];\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n const sprayChunk = this.sprayChunks[i];\n for (let j = 0; j < sprayChunk.length; j++) {\n const chunck = sprayChunk[j];\n const rect = new Rect({\n width: chunck.width,\n height: chunck.width,\n left: chunck.x + 1,\n top: chunck.y + 1,\n originX: CENTER,\n originY: CENTER,\n fill: this.color,\n });\n rects.push(rect);\n }\n }\n\n const group = new Group(\n this.optimizeOverlapping ? getUniqueRects(rects) : rects,\n {\n objectCaching: true,\n subTargetCheck: false,\n interactive: false,\n },\n );\n this.shadow && group.set('shadow', new Shadow(this.shadow));\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n renderChunck(sprayChunck: SprayBrushPoint[]) {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < sprayChunck.length; i++) {\n const point = sprayChunck[i];\n ctx.globalAlpha = point.opacity;\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n }\n\n /**\n * Render all spray chunks\n */\n _render() {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n this.renderChunck(this.sprayChunks[i]);\n }\n ctx.restore();\n }\n\n /**\n * @param {Point} pointer\n */\n addSprayChunk(pointer: Point) {\n this.sprayChunk = [];\n const radius = this.width / 2;\n\n for (let i = 0; i < this.density; i++) {\n this.sprayChunk.push({\n x: getRandomInt(pointer.x - radius, pointer.x + radius),\n y: getRandomInt(pointer.y - radius, pointer.y + radius),\n width: this.dotWidthVariance\n ? getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance,\n )\n : this.dotWidth,\n opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1,\n });\n }\n\n this.sprayChunks.push(this.sprayChunk);\n }\n}\n","import { Pattern } from '../Pattern';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { Canvas } from '../canvas/Canvas';\nimport { PencilBrush } from './PencilBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\nexport class PatternBrush extends PencilBrush {\n declare source?: CanvasImageSource;\n\n constructor(canvas: Canvas) {\n super(canvas);\n }\n\n getPatternSrc() {\n const dotWidth = 20,\n dotDistance = 5,\n patternCanvas = createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n if (patternCtx) {\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(\n dotWidth / 2,\n dotWidth / 2,\n dotWidth / 2,\n 0,\n Math.PI * 2,\n false,\n );\n patternCtx.closePath();\n patternCtx.fill();\n }\n return patternCanvas;\n }\n\n /**\n * Creates \"pattern\" instance property\n * @param {CanvasRenderingContext2D} ctx\n */\n getPattern(ctx: CanvasRenderingContext2D) {\n return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat');\n }\n\n /**\n * Sets brush styles\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n super._setBrushStyles(ctx);\n const pattern = this.getPattern(ctx);\n pattern && (ctx.strokeStyle = pattern);\n }\n\n /**\n * Creates path\n */\n createPath(pathData: TSimplePathData) {\n const path = super.createPath(pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new Pattern({\n source: this.source || this.getPatternSrc(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y,\n });\n return path;\n }\n}\n","import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\n// @TODO this code is terrible and Line should be a special case of polyline.\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineProps {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineProps {}\n\nexport class Line<\n Props extends TOptions = Partial,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueLineProps\n{\n /**\n * x value or first line edge\n * @type number\n * @default\n */\n declare x1: number;\n\n /**\n * y value or first line edge\n * @type number\n * @default\n */\n declare y1: number;\n\n /**\n * x value or second line edge\n * @type number\n * @default\n */\n declare x2: number;\n\n /**\n * y value or second line edge\n * @type number\n * @default\n */\n declare y2: number;\n\n static type = 'Line';\n\n static cacheProperties = [...cacheProperties, ...coordProps];\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {Line} thisArg\n */\n constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) {\n super();\n Object.assign(this, Line.ownDefaults);\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight() {\n const { x1, y1, x2, y2 } = this;\n this.width = Math.abs(x2 - x1);\n this.height = Math.abs(y2 - y1);\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ]);\n const position = new Point(left + width / 2, top + height / 2);\n this.setPositionByOrigin(position, CENTER, CENTER);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineProps)) {\n // this doesn't make sense very much, since setting x1 when top or left\n // are already set, is just going to show a strange result since the\n // line will move way more than the developer expect.\n // in fabric5 it worked only when the line didn't have extra transformations,\n // in fabric6 too. With extra transform they behave bad in different ways.\n // This needs probably a good rework or a tutorial if you have to create a dynamic line\n this._setWidthHeight();\n }\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n } else {\n ctx.strokeStyle = this.stroke ?? ctx.fillStyle;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n }\n\n /**\n * Recalculates line points given width and height\n * Those points are simply placed around the center,\n * This is not useful outside internal render functions and svg output\n * Is not meant to be for the developer.\n * @private\n */\n calcLinePoints(): UniqueLineProps {\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1,\n yMult = _y1 <= _y2 ? -1 : 1,\n x1 = (xMult * width) / 2,\n y1 = (yMult * height) / 2,\n x2 = (xMult * -width) / 2,\n y2 = (yMult * -height) / 2;\n\n return {\n x1,\n x2,\n y1,\n y2,\n };\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})\n * @static\n * @memberOf Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n /**\n * Returns Line instance from an SVG element\n * @static\n * @memberOf Line\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Line instance from an object representation\n * @static\n * @memberOf Line\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>({\n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject(\n {\n ...object,\n points: [x1, y1, x2, y2],\n },\n {\n extraParam: 'points',\n },\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n","import { classRegistry } from '../ClassRegistry';\nimport { FabricObject } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { TClassProperties, TOptions } from '../typedefs';\nimport type { ObjectEvents } from '../EventTypeDefs';\n\nexport const triangleDefaultValues: Partial> = {\n width: 100,\n height: 100,\n};\n\nexport class Triangle<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n static type = 'Triangle';\n\n static ownDefaults = triangleDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...Triangle.ownDefaults };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Triangle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = `${-widthBy2} ${heightBy2},0 ${-heightBy2},${widthBy2} ${heightBy2}`;\n return [''];\n }\n}\n\nclassRegistry.setClass(Triangle);\nclassRegistry.setSVGClass(Triangle);\n","import { SCALE_X, SCALE_Y, twoMathPi } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const ellipseDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueEllipseProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedEllipseProps\n extends SerializedObjectProps,\n UniqueEllipseProps {}\n\nexport interface EllipseProps extends FabricObjectProps, UniqueEllipseProps {}\n\nconst ELLIPSE_PROPS = ['rx', 'ry'] as const;\n\nexport class Ellipse<\n Props extends TOptions = Partial,\n SProps extends SerializedEllipseProps = SerializedEllipseProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements EllipseProps\n{\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Ellipse';\n\n static cacheProperties = [...cacheProperties, ...ELLIPSE_PROPS];\n\n static ownDefaults = ellipseDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Ellipse.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Ellipse.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {Ellipse} thisArg\n */\n _set(key: string, value: any) {\n super._set(key, value);\n switch (key) {\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n }\n return this;\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx() {\n return this.get('rx') * this.get(SCALE_X);\n }\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy() {\n return this.get('ry') * this.get(SCALE_Y);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, twoMathPi, false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement})\n * @static\n * @memberOf Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry'];\n\n /**\n * Returns {@link Ellipse} instance from an SVG element\n * @static\n * @memberOf Ellipse\n * @param {HTMLElement} element Element to parse\n * @return {Ellipse}\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n return new this(parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Ellipse);\nclassRegistry.setSVGClass(Ellipse);\n","import type { XY } from '../Point';\n\n/**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\nexport function parsePointsAttribute(points: string | null): XY[] {\n // points attribute is required and must not be empty\n if (!points) {\n return [];\n }\n\n // replace commas with whitespace and remove bookending whitespace\n const pointsSplit: string[] = points.replace(/,/g, ' ').trim().split(/\\s+/);\n\n const parsedPoints = [];\n\n for (let i = 0; i < pointsSplit.length; i += 2) {\n parsedPoints.push({\n x: parseFloat(pointsSplit[i]),\n y: parseFloat(pointsSplit[i + 1]),\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n return parsedPoints;\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { parsePointsAttribute } from '../parser/parsePointsAttribute';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { calcDimensionsMatrix, transformPoint } from '../util/misc/matrix';\nimport { projectStrokeOnPoints } from '../util/misc/projectStroke';\nimport type { TProjectStrokeOnPointsOptions } from '../util/misc/projectStroke/types';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport {\n CENTER,\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const polylineDefaultValues: Partial> = {\n /**\n * @deprecated transient option soon to be removed in favor of a different design\n */\n exactBoundingBox: false,\n};\n\nexport interface SerializedPolylineProps extends SerializedObjectProps {\n points: XY[];\n}\n\nexport class Polyline<\n Props extends TOptions = Partial,\n SProps extends SerializedPolylineProps = SerializedPolylineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Points array\n * @type Array\n * @default\n */\n declare points: XY[];\n\n /**\n * WARNING: Feature in progress\n * Calculate the exact bounding box taking in account strokeWidth on acute angles\n * this will be turned to true by default on fabric 6.0\n * maybe will be left in as an optimization since calculations may be slow\n * @deprecated transient option soon to be removed in favor of a different design\n * @type Boolean\n * @default false\n */\n declare exactBoundingBox: boolean;\n\n private declare initialized: true | undefined;\n\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polyline';\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Polyline.ownDefaults,\n };\n }\n\n /**\n * A list of properties that if changed trigger a recalculation of dimensions\n * @todo check if you really need to recalculate for all cases\n */\n static layoutProperties: (keyof Polyline)[] = [\n SKEW_X,\n SKEW_Y,\n 'strokeLineCap',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'strokeWidth',\n 'strokeUniform',\n 'points',\n ];\n\n declare pathOffset: Point;\n\n declare strokeOffset: Point;\n\n static cacheProperties = [...cacheProperties, 'points'];\n\n strokeDiff: Point;\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {Polyline} thisArg\n * @example\n * var poly = new Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n constructor(points: XY[] = [], options: Props = {} as Props) {\n super();\n Object.assign(this, Polyline.ownDefaults);\n this.setOptions(options);\n this.points = points;\n const { left, top } = options;\n this.initialized = true;\n this.setBoundingBox(true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n protected isOpen() {\n return true;\n }\n\n private _projectStrokeOnPoints(options: TProjectStrokeOnPointsOptions) {\n return projectStrokeOnPoints(this.points, options, this.isOpen());\n }\n\n /**\n * Calculate the polygon bounding box\n * @private\n */\n _calcDimensions(options?: Partial) {\n options = {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeUniform: this.strokeUniform,\n strokeWidth: this.strokeWidth,\n ...(options || {}),\n };\n const points = this.exactBoundingBox\n ? this._projectStrokeOnPoints(\n options as TProjectStrokeOnPointsOptions,\n ).map((projection) => projection.projectedPoint)\n : this.points;\n if (points.length === 0) {\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n pathOffset: new Point(),\n strokeOffset: new Point(),\n strokeDiff: new Point(),\n };\n }\n const bbox = makeBoundingBoxFromPoints(points),\n // Remove scale effect, since it's applied after\n matrix = calcDimensionsMatrix({ ...options, scaleX: 1, scaleY: 1 }),\n bboxNoStroke = makeBoundingBoxFromPoints(\n this.points.map((p) => transformPoint(p, matrix, true)),\n ),\n scale = new Point(this.scaleX, this.scaleY);\n let offsetX = bbox.left + bbox.width / 2,\n offsetY = bbox.top + bbox.height / 2;\n if (this.exactBoundingBox) {\n offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX));\n // Order of those assignments is important.\n // offsetY relies on offsetX being already changed by the line above\n offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY));\n }\n\n return {\n ...bbox,\n pathOffset: new Point(offsetX, offsetY),\n strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top)\n .subtract(new Point(bbox.left, bbox.top))\n .multiply(scale),\n strokeDiff: new Point(bbox.width, bbox.height)\n .subtract(new Point(bboxNoStroke.width, bboxNoStroke.height))\n .multiply(scale),\n };\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = makeBoundingBoxFromPoints(this.points);\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { left, top, width, height, pathOffset, strokeOffset, strokeDiff } =\n this._calcDimensions();\n this.set({ width, height, pathOffset, strokeOffset, strokeDiff });\n adjustPosition &&\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER,\n );\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return this.exactBoundingBox;\n }\n\n /**\n * @override stroke is taken in account in size\n */\n _getNonTransformedDimensions() {\n return this.exactBoundingBox\n ? // TODO: fix this\n new Point(this.width, this.height)\n : super._getNonTransformedDimensions();\n }\n\n /**\n * @override stroke and skewing are taken into account when projecting stroke on points,\n * therefore we don't want the default calculation to account for skewing as well.\n * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion.\n *\n * @private\n */\n _getTransformedDimensions(options: any = {}) {\n if (this.exactBoundingBox) {\n let size: Point;\n /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because\n the stroke projections are affected.\n When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on\n projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/\n if (\n Object.keys(options).some(\n (key) =>\n this.strokeUniform ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof TProjectStrokeOnPointsOptions,\n ),\n )\n ) {\n const { width, height } = this._calcDimensions(options);\n size = new Point(options.width ?? width, options.height ?? height);\n } else {\n size = new Point(\n options.width ?? this.width,\n options.height ?? this.height,\n );\n }\n return size.multiply(\n new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY),\n );\n } else {\n return super._getTransformedDimensions(options);\n }\n }\n\n /**\n * Recalculates dimensions when changing skew and scale\n * @private\n */\n _set(key: string, value: any) {\n const changed = this.initialized && this[key as keyof this] !== value;\n const output = super._set(key, value);\n if (\n this.exactBoundingBox &&\n changed &&\n (((key === SCALE_X || key === SCALE_Y) &&\n this.strokeUniform &&\n (this.constructor as typeof Polyline).layoutProperties.includes(\n 'strokeUniform',\n )) ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof Polyline,\n ))\n ) {\n this.setDimensions();\n }\n return output;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n points: this.points.map(({ x, y }) => ({ x, y })),\n };\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const points = [],\n diffX = this.pathOffset.x,\n diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n\n for (let i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS),\n ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS),\n ' ',\n );\n }\n return [\n `<${\n (this.constructor as typeof Polyline).type.toLowerCase() as\n | 'polyline'\n | 'polygon'\n } `,\n 'COMMON_PARTS',\n `points=\"${points.join('')}\" />\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (let i = 0; i < len; i++) {\n const point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n !this.isOpen() && ctx.closePath();\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity(): number {\n return this.points.length;\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement})\n * @static\n * @memberOf Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES];\n\n /**\n * Returns Polyline instance from an SVG element\n * @static\n * @memberOf Polyline\n * @param {HTMLElement} element Element to parser\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const points = parsePointsAttribute(element.getAttribute('points')),\n // we omit left and top to instruct the constructor to position the object using the bbox\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { left, top, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(points, {\n ...parsedAttributes,\n ...options,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Polyline instance from an object representation\n * @static\n * @memberOf Polyline\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'points',\n });\n }\n}\n\nclassRegistry.setClass(Polyline);\nclassRegistry.setSVGClass(Polyline);\n","import { classRegistry } from '../ClassRegistry';\nimport { Polyline, polylineDefaultValues } from './Polyline';\n\nexport class Polygon extends Polyline {\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polygon';\n\n protected isOpen() {\n return false;\n }\n}\n\nclassRegistry.setClass(Polygon);\nclassRegistry.setSVGClass(Polygon);\n","import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { TOptions } from '../../typedefs';\nimport { FabricObject } from '../Object/FabricObject';\nimport { styleProperties } from './constants';\nimport type { StylePropertiesType } from './constants';\nimport type { FabricText } from './Text';\nimport { pick } from '../../util';\nimport { pickBy } from '../../util/misc/pick';\n\nexport type CompleteTextStyleDeclaration = Pick<\n FabricText,\n StylePropertiesType\n>;\n\nexport type TextStyleDeclaration = Partial;\n\nexport type TextStyle = {\n [line: number | string]: { [char: number | string]: TextStyleDeclaration };\n};\n\nexport abstract class StyledText<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n declare abstract styles: TextStyle;\n protected declare abstract _textLines: string[][];\n protected declare _forceClearCache: boolean;\n static _styleProperties: Readonly = styleProperties;\n abstract get2DCursorLocation(\n selectionStart: number,\n skipWrapping?: boolean,\n ): { charIndex: number; lineIndex: number };\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex?: number): boolean {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex?: number): boolean {\n if (!this.styles) {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (const p1 in obj) {\n // eslint-disable-next-line\n for (const p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return false;\n }\n const obj = this.styles;\n let stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0;\n for (const p1 in obj) {\n letterCount = 0;\n for (const p2 in obj[p1]) {\n const styleObject = obj[p1][p2] || {},\n stylePropertyHasBeenSet = styleObject[property] !== undefined;\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property as keyof this]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (let i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n // @ts-expect-error conspiracy theory of TS\n this[property as keyof this] = stylePropertyValue;\n this.removeStyle(property);\n }\n }\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return;\n }\n const obj = this.styles;\n let line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n }\n\n private _extendStyles(index: number, style: TextStyleDeclaration): void {\n const { lineIndex, charIndex } = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex);\n }\n\n const newStyle = pickBy(\n {\n // first create a new object that is a merge of existing and new\n ...this._getStyleDeclaration(lineIndex, charIndex),\n ...style,\n // use the predicate to discard undefined values\n },\n (value) => value !== undefined,\n );\n\n // finally assign to the old position the new style\n this._setStyleDeclaration(lineIndex, charIndex, newStyle);\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number,\n endIndex?: number,\n complete?: boolean,\n ): TextStyleDeclaration[] {\n const styles: TextStyleDeclaration[] = [];\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n }\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition(position: number, complete?: boolean) {\n const { lineIndex, charIndex } = this.get2DCursorLocation(position);\n return complete\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex)\n : this._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} styles Styles object\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1\n */\n setSelectionStyles(styles: object, startIndex: number, endIndex?: number) {\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n }\n\n /**\n * Get a reference, not a clone, to the style object for a given character,\n * if no style is set for a line or char, return a new empty object.\n * This is tricky and confusing because when you get an empty object you can't\n * determine if it is a reference or a new one.\n * @TODO this should always return a reference or always a clone or undefined when necessary.\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n const lineStyle = this.styles && this.styles[lineIndex];\n return lineStyle ? lineStyle[charIndex] ?? {} : {};\n }\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): CompleteTextStyleDeclaration {\n return {\n // @ts-expect-error readonly\n ...pick(this, (this.constructor as typeof StyledText)._styleProperties),\n ...this._getStyleDeclaration(lineIndex, charIndex),\n } as CompleteTextStyleDeclaration;\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n this.styles[lineIndex][charIndex] = style;\n }\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n delete this.styles[lineIndex][charIndex];\n }\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n return !!this.styles[lineIndex];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n this.styles[lineIndex] = {};\n }\n\n protected _deleteLineStyle(lineIndex: number) {\n delete this.styles[lineIndex];\n }\n}\n","import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number,\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n },\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t',\n textSpans.join(''),\n '\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number,\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height,\n ),\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number,\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex),\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `${escapeXml(char)}`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset,\n ),\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number,\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number,\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean,\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ],\n )\n .join(' ');\n }\n}\n","import { cache } from '../../cache';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, STROKE } from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type {\n CompleteTextStyleDeclaration,\n TextStyle,\n TextStyleDeclaration,\n} from './StyledText';\nimport { StyledText } from './StyledText';\nimport { SHARED_ATTRIBUTES } from '../../parser/attributes';\nimport { parseAttributes } from '../../parser/parseAttributes';\nimport type {\n Abortable,\n TCacheCanvasDimensions,\n TClassProperties,\n TFiller,\n TOptions,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { graphemeSplit } from '../../util/lang_string';\nimport { createCanvasElement } from '../../util/misc/dom';\nimport type { TextStyleArray } from '../../util/misc/textStyles';\nimport {\n hasStyleChanged,\n stylesFromArray,\n stylesToArray,\n} from '../../util/misc/textStyles';\nimport { getPathSegmentsInfo, getPointOnPath } from '../../util/path';\nimport { cacheProperties } from '../Object/FabricObject';\nimport type { Path } from '../Path';\nimport { TextSVGExportMixin } from './TextSVGExportMixin';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { StylePropertiesType } from './constants';\nimport {\n additionalProps,\n textDefaultValues,\n textLayoutProperties,\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from './constants';\nimport { CENTER, LEFT, RIGHT, TOP, BOTTOM } from '../../constants';\nimport { isFiller } from '../../util/typeAssertions';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { CSSRules } from '../../parser/typedefs';\n\nlet measuringContext: CanvasRenderingContext2D | null;\n\n/**\n * Return a context for measurement of text string.\n * if created it gets stored for reuse\n */\nfunction getMeasuringContext() {\n if (!measuringContext) {\n const canvas = createCanvasElement();\n canvas.width = canvas.height = 0;\n measuringContext = canvas.getContext('2d');\n }\n return measuringContext;\n}\n\nexport type TPathSide = 'left' | 'right';\n\nexport type TPathAlign = 'baseline' | 'center' | 'ascender' | 'descender';\n\nexport type TextLinesInfo = {\n lines: string[];\n graphemeLines: string[][];\n graphemeText: string[];\n _unwrappedLines: string[][];\n};\n\n/**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * Override to customize measuring\n */\nexport type GraphemeBBox = {\n width: number;\n height: number;\n kernedWidth: number;\n left: number;\n deltaY: number;\n renderLeft?: number;\n renderTop?: number;\n angle?: number;\n};\n\n// @TODO this is not complete\ninterface UniqueTextProps {\n charSpacing: number;\n lineHeight: number;\n fontSize: number;\n fontWeight: string | number;\n fontFamily: string;\n fontStyle: string;\n pathSide: TPathSide;\n pathAlign: TPathAlign;\n underline: boolean;\n overline: boolean;\n linethrough: boolean;\n textAlign: string;\n direction: CanvasDirection;\n path?: Path;\n}\n\nexport interface SerializedTextProps\n extends SerializedObjectProps,\n UniqueTextProps {\n styles: TextStyleArray | TextStyle;\n}\n\nexport interface TextProps extends FabricObjectProps, UniqueTextProps {\n styles: TextStyle;\n}\n\n/**\n * Text class\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n */\nexport class FabricText<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends StyledText\n implements UniqueTextProps\n{\n /**\n * Properties that requires a text layout recalculation when changed\n * @type string[]\n * @protected\n */\n static textLayoutProperties: string[] = textLayoutProperties;\n\n /**\n * @private\n */\n declare _reNewline: RegExp;\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpacesAndTabs: RegExp;\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpaceAndTab: RegExp;\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reWords: RegExp;\n\n declare text: string;\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n declare fontSize: number;\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n declare fontWeight: string | number;\n\n /**\n * Font family\n * @type String\n * @default\n */\n declare fontFamily: string;\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n declare underline: boolean;\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n declare overline: boolean;\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n declare linethrough: boolean;\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n declare textAlign: string;\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n declare fontStyle: string;\n\n /**\n * Line height\n * @type Number\n * @default\n */\n declare lineHeight: number;\n\n /**\n * Superscript schema object (minimum overlap)\n */\n declare superscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (upwards)\n * @default -0.35\n */\n baseline: number;\n };\n\n /**\n * Subscript schema object (minimum overlap)\n */\n declare subscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (downwards)\n * @default 0.11\n */\n baseline: number;\n };\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n declare textBackgroundColor: string;\n\n declare styles: TextStyle;\n\n /**\n * Path that the text should follow.\n * since 4.6.0 the path will be drawn automatically.\n * if you want to make the path visible, give it a stroke and strokeWidth or fill value\n * if you want it to be hidden, assign visible = false to the path.\n * This feature is in BETA, and SVG import/export is not yet supported.\n * @type Path\n * @example\n * const textPath = new Text('Text on a path', {\n * top: 150,\n * left: 150,\n * textAlign: 'center',\n * charSpacing: -50,\n * path: new Path('M 0 0 C 50 -100 150 -100 200 0', {\n * strokeWidth: 1,\n * visible: false\n * }),\n * pathSide: 'left',\n * pathStartOffset: 0\n * });\n * @default\n */\n declare path?: Path;\n\n /**\n * Offset amount for text path starting position\n * Only used when text has a path\n * @type Number\n * @default\n */\n declare pathStartOffset: number;\n\n /**\n * Which side of the path the text should be drawn on.\n * Only used when text has a path\n * @type {TPathSide} 'left|right'\n * @default\n */\n declare pathSide: TPathSide;\n\n /**\n * How text is aligned to the path. This property determines\n * the perpendicular position of each character relative to the path.\n * (one of \"baseline\", \"center\", \"ascender\", \"descender\")\n * This feature is in BETA, and its behavior may change\n * @type TPathAlign\n * @default\n */\n declare pathAlign: TPathAlign;\n\n /**\n * @private\n */\n declare _fontSizeFraction: number;\n\n /**\n * @private\n */\n declare offsets: { underline: number; linethrough: number; overline: number };\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n declare _fontSizeMult: number;\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n declare charSpacing: number;\n\n /**\n * Baseline shift, styles only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n declare deltaY: number;\n\n /**\n * WARNING: EXPERIMENTAL. NOT SUPPORTED YET\n * determine the direction of the text.\n * This has to be set manually together with textAlign and originX for proper\n * experience.\n * some interesting link for the future\n * https://www.w3.org/International/questions/qa-bidi-unicode-controls\n * @since 4.5.0\n * @type {CanvasDirection} 'ltr|rtl'\n * @default\n */\n declare direction: CanvasDirection;\n\n /**\n * contains characters bounding boxes\n * This variable is considered to be protected.\n * But for how mixins are implemented right now, we can't leave it private\n * @protected\n */\n __charBounds: GraphemeBBox[][] = [];\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n declare CACHE_FONT_SIZE: number;\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n declare MIN_TEXT_WIDTH: number;\n\n /**\n * contains the the text of the object, divided in lines as they are displayed\n * on screen. Wrapping will divide the text independently of line breaks\n * @type {string[]}\n * @default\n */\n declare textLines: string[];\n\n /**\n * same as textlines, but each line is an array of graphemes as split by splitByGrapheme\n * @type {string[]}\n * @default\n */\n declare _textLines: string[][];\n\n declare _unwrappedTextLines: string[][];\n declare _text: string[];\n declare cursorWidth: number;\n declare __lineHeights: number[];\n declare __lineWidths: number[];\n declare initialized?: true;\n\n static cacheProperties = [...cacheProperties, ...additionalProps];\n\n static ownDefaults = textDefaultValues;\n\n static type = 'Text';\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...FabricText.ownDefaults };\n }\n\n constructor(text: string, options?: Props) {\n super();\n Object.assign(this, FabricText.ownDefaults);\n this.setOptions(options);\n if (!this.styles) {\n this.styles = {};\n }\n this.text = text;\n this.initialized = true;\n if (this.path) {\n this.setPathInfo();\n }\n this.initDimensions();\n this.setCoords();\n }\n\n /**\n * If text has a path, it will add the extra information needed\n * for path and text calculations\n */\n setPathInfo() {\n const path = this.path;\n if (path) {\n path.segmentsInfo = getPathSegmentsInfo(path.path);\n }\n }\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText(): TextLinesInfo {\n const newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n }\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions() {\n this._splitText();\n this._clearCache();\n this.dirty = true;\n if (this.path) {\n this.width = this.path.width;\n this.height = this.path.height;\n } else {\n this.width =\n this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n this.height = this.calcTextHeight();\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n }\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces() {\n let diffSpace,\n currentLineWidth,\n numberOfSpaces,\n accumulatedSpace,\n line,\n charBound,\n spaces;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n if (\n this.textAlign !== JUSTIFY &&\n (i === len - 1 || this.isEndOfWrapping(i))\n ) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (\n currentLineWidth < this.width &&\n (spaces = this.textLines[i].match(this._reSpacesAndTabs))\n ) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (let j = 0; j <= line.length; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n } else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n return lineIndex === this._textLines.length - 1;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always 1 for text and Itext. Textbox has its own implementation\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1;\n missingNewlineOffset(_lineIndex: number): 1 {\n return 1;\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor\n * @param {Number} selectionStart\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(selectionStart: number, skipWrapping?: boolean) {\n const lines = skipWrapping ? this._unwrappedTextLines : this._textLines;\n let i: number;\n for (i = 0; i < lines.length; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart,\n };\n }\n selectionStart -=\n lines[i].length + this.missingNewlineOffset(i, skipWrapping);\n }\n return {\n lineIndex: i - 1,\n charIndex:\n lines[i - 1].length < selectionStart\n ? lines[i - 1].length\n : selectionStart,\n };\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString(): string {\n return `#`;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const dims = super._getCacheCanvasDimensions();\n const fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const path = this.path;\n path && !path.isNotVisible() && path._render(ctx);\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n }\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles(\n ctx: CanvasRenderingContext2D,\n charStyle?: any,\n forMeasuring?: boolean,\n ) {\n ctx.textBaseline = 'alphabetic';\n if (this.path) {\n switch (this.pathAlign) {\n case CENTER:\n ctx.textBaseline = 'middle';\n break;\n case 'ascender':\n ctx.textBaseline = TOP;\n break;\n case 'descender':\n ctx.textBaseline = BOTTOM;\n break;\n }\n }\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n }\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of Text object\n */\n calcTextWidth(): number {\n let maxWidth = this.getLineWidth(0);\n\n for (let i = 1, len = this._textLines.length; i < len; i++) {\n const currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n }\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: string[],\n left: number,\n top: number,\n lineIndex: number,\n ) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n }\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground(ctx: CanvasRenderingContext2D) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n const originalFill = ctx.fillStyle,\n leftOffset = this._getLeftOffset();\n let lineTopOffset = this._getTopOffset();\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (\n !this.textBackgroundColor &&\n !this.styleHas('textBackgroundColor', i)\n ) {\n lineTopOffset += heightOfLine;\n continue;\n }\n const jlen = this._textLines[i].length;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxWidth = 0;\n let boxStart = 0;\n let drawStart;\n let currentColor;\n let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < jlen; j++) {\n // at this point charbox are either standard or full with pathInfo if there is a path.\n const charBox = this.__charBounds[i][j] as Required;\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (this.path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillStyle = currentColor;\n currentColor &&\n ctx.fillRect(\n -charBox.width / 2,\n (-heightOfLine / this.lineHeight) * (1 - this._fontSizeFraction),\n charBox.width,\n heightOfLine / this.lineHeight,\n );\n ctx.restore();\n } else if (currentColor !== lastColor) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = lastColor;\n lastColor &&\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor && !this.path) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar(\n _char: string,\n charStyle: CompleteTextStyleDeclaration,\n previousChar: string | undefined,\n prevCharStyle: CompleteTextStyleDeclaration | Record,\n ) {\n const fontCache = cache.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n couple = previousChar + _char,\n stylesAreEqual =\n previousChar &&\n fontDeclaration === this._getFontDeclaration(prevCharStyle),\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE;\n let width: number | undefined,\n coupleWidth: number | undefined,\n previousWidth: number | undefined,\n kernedWidth: number | undefined;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth!;\n }\n if (\n width === undefined ||\n previousWidth === undefined ||\n coupleWidth === undefined\n ) {\n const ctx = getMeasuringContext()!;\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n // safe to use the non-null since if undefined we defined it before.\n kernedWidth = coupleWidth - previousWidth!;\n }\n }\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth! * fontMultiplier,\n };\n }\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar(line: number, _char: number): number {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n }\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n */\n measureLine(lineIndex: number) {\n const lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n }\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine(lineIndex: number) {\n let width = 0,\n prevGrapheme: string | undefined,\n graphemeInfo: GraphemeBBox | undefined;\n\n const reverse = this.pathSide === RIGHT,\n path = this.path,\n line = this._textLines[lineIndex],\n llength = line.length,\n lineBounds = new Array(llength);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (let i = 0; i < llength; i++) {\n const grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[llength] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize,\n deltaY: 0,\n } as GraphemeBBox;\n if (path && path.segmentsInfo) {\n let positionInPath = 0;\n const totalPathLength =\n path.segmentsInfo[path.segmentsInfo.length - 1].length;\n switch (this.textAlign) {\n case LEFT:\n positionInPath = reverse ? totalPathLength - width : 0;\n break;\n case CENTER:\n positionInPath = (totalPathLength - width) / 2;\n break;\n case RIGHT:\n positionInPath = reverse ? 0 : totalPathLength - width;\n break;\n //todo - add support for justify\n }\n positionInPath += this.pathStartOffset * (reverse ? -1 : 1);\n for (\n let i = reverse ? llength - 1 : 0;\n reverse ? i >= 0 : i < llength;\n reverse ? i-- : i++\n ) {\n graphemeInfo = lineBounds[i];\n if (positionInPath > totalPathLength) {\n positionInPath %= totalPathLength;\n } else if (positionInPath < 0) {\n positionInPath += totalPathLength;\n }\n // it would probably much faster to send all the grapheme position for a line\n // and calculate path position/angle at once.\n this._setGraphemeOnPath(positionInPath, graphemeInfo);\n positionInPath += graphemeInfo.kernedWidth;\n }\n }\n return { width: width, numOfSpaces: 0 };\n }\n\n /**\n * Calculate the angle and the left,top position of the char that follow a path.\n * It appends it to graphemeInfo to be reused later at rendering\n * @private\n * @param {Number} positionInPath to be measured\n * @param {GraphemeBBox} graphemeInfo current grapheme box information\n * @param {Object} startingPoint position of the point\n */\n _setGraphemeOnPath(positionInPath: number, graphemeInfo: GraphemeBBox) {\n const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,\n path = this.path!;\n\n // we are at currentPositionOnPath. we want to know what point on the path is.\n const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo)!;\n graphemeInfo.renderLeft = info.x - path.pathOffset.x;\n graphemeInfo.renderTop = info.y - path.pathOffset.y;\n graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0);\n }\n\n /**\n *\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n * @returns {GraphemeBBox} grapheme bbox\n */\n _getGraphemeBox(\n grapheme: string,\n lineIndex: number,\n charIndex: number,\n prevGrapheme?: string,\n skipLeft?: boolean,\n ): GraphemeBBox {\n const style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1)\n : {},\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle);\n let kernedWidth = info.kernedWidth,\n width = info.width,\n charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n const box: GraphemeBBox = {\n width,\n left: 0,\n height: style.fontSize,\n kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n const previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left =\n previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n }\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine(lineIndex: number): number {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n // char 0 is measured before the line cycle because it needs to char\n // emptylines\n let maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return (this.__lineHeights[lineIndex] =\n maxHeight * this.lineHeight * this._fontSizeMult);\n }\n\n /**\n * Calculate text box height\n */\n calcTextHeight() {\n let lineHeight,\n height = 0;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;\n }\n return height;\n }\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset(): number {\n return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;\n }\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset(): number {\n return -this.height / 2;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon(\n ctx: CanvasRenderingContext2D,\n method: 'fillText' | 'strokeText',\n ) {\n ctx.save();\n let lineHeights = 0;\n const left = this._getLeftOffset(),\n top = this._getTopOffset();\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i,\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill && !this.styleHas(FILL)) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke(ctx: CanvasRenderingContext2D) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n }\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: Array,\n left: number,\n top: number,\n lineIndex: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n path = this.path,\n shortCut =\n !isJustify &&\n this.charSpacing === 0 &&\n this.isEmptyStyles(lineIndex) &&\n !path,\n isLtr = this.direction === 'ltr',\n sign = this.direction === 'ltr' ? 1 : -1,\n // this was changed in the PR #7674\n // currentDirection = ctx.canvas.getAttribute('dir');\n currentDirection = ctx.direction;\n\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n drawingLeft;\n\n ctx.save();\n if (currentDirection !== this.direction) {\n ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');\n ctx.direction = isLtr ? 'ltr' : 'rtl';\n ctx.textAlign = isLtr ? LEFT : RIGHT;\n }\n top -= (lineHeight * this._fontSizeFraction) / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top);\n ctx.restore();\n return;\n }\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing || path;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i] as Required;\n if (boxWidth === 0) {\n left += sign * (charBox.kernedWidth - charBox.width);\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, false);\n }\n if (timeToRender) {\n if (path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n -boxWidth / 2,\n 0,\n );\n ctx.restore();\n } else {\n drawingLeft = left;\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n drawingLeft,\n top,\n );\n }\n charsToRender = '';\n actualStyle = nextStyle;\n left += sign * boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {TFiller} filler a fabric gradient instance\n * @return {CanvasPattern} a pattern to use as fill/stroke style\n */\n _applyPatternGradientTransformText(filler: TFiller) {\n const pCanvas = createCanvasElement(),\n // TODO: verify compatibility with strokeUniform\n width = this.width + this.strokeWidth,\n height = this.height + this.strokeWidth,\n pCtx = pCanvas.getContext('2d')!;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.fillStyle = filler.toLive(pCtx)!;\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fill();\n return pCtx.createPattern(pCanvas, 'no-repeat')!;\n }\n\n handleFiller(\n ctx: CanvasRenderingContext2D,\n property: `${T}Style`,\n filler: TFiller | string,\n ): { offsetX: number; offsetY: number } {\n let offsetX: number, offsetY: number;\n if (isFiller(filler)) {\n if (\n (filler as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n offsetX = -this.width / 2;\n offsetY = -this.height / 2;\n ctx.translate(offsetX, offsetY);\n ctx[property] = this._applyPatternGradientTransformText(filler);\n return { offsetX, offsetY };\n } else {\n // is a simple gradient or pattern\n ctx[property] = filler.toLive(ctx)!;\n return this._applyPatternGradientTransform(ctx, filler);\n }\n } else {\n // is a color\n ctx[property] = filler;\n }\n return { offsetX: 0, offsetY: 0 };\n }\n\n /**\n * This function prepare the canvas for a stroke style, and stroke and strokeWidth\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined\n * @returns\n */\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n {\n stroke,\n strokeWidth,\n }: Pick,\n ) {\n ctx.lineWidth = strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineDashOffset = this.strokeDashOffset;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n return this.handleFiller(ctx, 'strokeStyle', stroke!);\n }\n\n /**\n * This function prepare the canvas for a ill style, and fill\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with ill defined\n * @returns\n */\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n return this.handleFiller(ctx, 'fillStyle', fill!);\n }\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n lineIndex: number,\n charIndex: number,\n _char: string,\n left: number,\n top: number,\n ) {\n const decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke =\n method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n ctx.save();\n\n ctx.font = this._getFontDeclaration(fullDecl);\n\n if (decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl.deltaY) {\n top += decl.deltaY;\n }\n\n if (shouldFill) {\n const fillOffsets = this._setFillStyles(ctx, fullDecl);\n ctx.fillText(\n _char,\n left - fillOffsets.offsetX,\n top - fillOffsets.offsetY,\n );\n }\n\n if (shouldStroke) {\n const strokeOffsets = this._setStrokeStyles(ctx, fullDecl);\n ctx.strokeText(\n _char,\n left - strokeOffsets.offsetX,\n top - strokeOffsets.offsetY,\n );\n }\n\n ctx.restore();\n }\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSuperscript(start: number, end: number) {\n this._setScript(start, end, this.superscript);\n }\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSubscript(start: number, end: number) {\n this._setScript(start, end, this.subscript);\n }\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n */\n protected _setScript(\n start: number,\n end: number,\n schema: {\n size: number;\n baseline: number;\n },\n ) {\n const loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(\n loc.lineIndex,\n loc.charIndex,\n 'fontSize',\n ),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline,\n };\n this.setSelectionStyles(style, start, end);\n }\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset(lineIndex: number): number {\n const lineWidth = this.getLineWidth(lineIndex),\n lineDiff = this.width - lineWidth,\n textAlign = this.textAlign,\n direction = this.direction,\n isEndOfWrapping = this.isEndOfWrapping(lineIndex);\n let leftOffset = 0;\n if (\n textAlign === JUSTIFY ||\n (textAlign === JUSTIFY_CENTER && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_RIGHT && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_LEFT && !isEndOfWrapping)\n ) {\n return 0;\n }\n if (textAlign === CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === RIGHT) {\n leftOffset = lineDiff;\n }\n if (textAlign === JUSTIFY_CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === JUSTIFY_RIGHT) {\n leftOffset = lineDiff;\n }\n if (direction === 'rtl') {\n if (\n textAlign === RIGHT ||\n textAlign === JUSTIFY ||\n textAlign === JUSTIFY_RIGHT\n ) {\n leftOffset = 0;\n } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) {\n leftOffset = -lineDiff;\n } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) {\n leftOffset = -lineDiff / 2;\n }\n }\n return leftOffset;\n }\n\n /**\n * @private\n */\n _clearCache() {\n this._forceClearCache = false;\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n }\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth(lineIndex: number): number {\n if (this.__lineWidths[lineIndex] !== undefined) {\n return this.__lineWidths[lineIndex];\n }\n\n const { width } = this.measureLine(lineIndex);\n this.__lineWidths[lineIndex] = width;\n return width;\n }\n\n _getWidthOfCharSpacing() {\n if (this.charSpacing !== 0) {\n return (this.fontSize * this.charSpacing) / 1000;\n }\n return 0;\n }\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the character number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt(\n lineIndex: number,\n charIndex: number,\n property: T,\n ): this[T] {\n const charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n return (charStyle[property] ?? this[property]) as this[T];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration(\n ctx: CanvasRenderingContext2D,\n type: 'underline' | 'linethrough' | 'overline',\n ) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n let topOffset = this._getTopOffset();\n const leftOffset = this._getLeftOffset(),\n path = this.path,\n charSpacing = this._getWidthOfCharSpacing(),\n offsetY = this.offsets[type];\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n const line = this._textLines[i];\n const maxHeight = heightOfLine / this.lineHeight;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxStart = 0;\n let boxWidth = 0;\n let lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n let lastFill = this.getValueOfPropertyAt(i, 0, FILL);\n let currentDecoration;\n let currentFill;\n const top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n let size = this.getHeightOfChar(i, 0);\n let dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n const charBox = this.__charBounds[i][j] as Required;\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, FILL);\n const currentSize = this.getHeightOfChar(i, j);\n const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if (path && currentDecoration && currentFill) {\n ctx.save();\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillRect(\n -charBox.kernedWidth / 2,\n offsetY * currentSize + currentDy,\n charBox.kernedWidth,\n this.fontSize / 15,\n );\n ctx.restore();\n } else if (\n (currentDecoration !== lastDecoration ||\n currentFill !== lastFill ||\n currentSize !== size ||\n currentDy !== dy) &&\n boxWidth > 0\n ) {\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n if (lastDecoration && lastFill) {\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth,\n this.fontSize / 15,\n );\n }\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = currentSize;\n dy = currentDy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentFill as string;\n currentDecoration &&\n currentFill &&\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15,\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration(\n {\n fontFamily = this.fontFamily,\n fontStyle = this.fontStyle,\n fontWeight = this.fontWeight,\n fontSize = this.fontSize,\n }: Partial<\n Pick<\n TextStyleDeclaration,\n 'fontFamily' | 'fontStyle' | 'fontWeight' | 'fontSize'\n >\n > = {},\n forMeasuring?: boolean,\n ): string {\n const parsedFontFamily =\n fontFamily.includes(\"'\") ||\n fontFamily.includes('\"') ||\n fontFamily.includes(',') ||\n FabricText.genericFonts.includes(fontFamily.toLowerCase())\n ? fontFamily\n : `\"${fontFamily}\"`;\n return [\n fontStyle,\n fontWeight,\n `${forMeasuring ? this.CACHE_FONT_SIZE : fontSize}px`,\n parsedFontFamily,\n ].join(' ');\n }\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n if (!this.visible) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n if (this._forceClearCache) {\n this.initDimensions();\n }\n super.render(ctx);\n }\n\n /**\n * Override this method to customize grapheme splitting\n * @todo the util `graphemeSplit` needs to be injectable in some way.\n * is more comfortable to inject the correct util rather than having to override text\n * in the middle of the prototype chain\n * @param {string} value\n * @returns {string[]} array of graphemes\n */\n graphemeSplit(value: string): string[] {\n return graphemeSplit(value);\n }\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns Lines in the text\n */\n _splitTextIntoLines(text: string): TextLinesInfo {\n const lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'];\n let newText: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n newLines[i] = this.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines,\n };\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject([...additionalProps, ...propertiesToInclude] as K[]),\n styles: stylesToArray(this.styles, this.text),\n ...(this.path ? { path: this.path.toObject() } : {}),\n };\n }\n\n set(key: string | any, value?: any) {\n const { textLayoutProperties } = this.constructor as typeof FabricText;\n super.set(key, value);\n let needsDims = false;\n let isAddingPath = false;\n if (typeof key === 'object') {\n for (const _key in key) {\n if (_key === 'path') {\n this.setPathInfo();\n }\n needsDims = needsDims || textLayoutProperties.includes(_key);\n isAddingPath = isAddingPath || _key === 'path';\n }\n } else {\n needsDims = textLayoutProperties.includes(key);\n isAddingPath = key === 'path';\n }\n if (isAddingPath) {\n this.setPathInfo();\n }\n if (needsDims && this.initialized) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity(): number {\n return 1;\n }\n\n static genericFonts = [\n 'sans-serif',\n 'serif',\n 'cursive',\n 'fantasy',\n 'monospace',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})\n * @static\n * @memberOf Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'font-family',\n 'font-style',\n 'font-weight',\n 'font-size',\n 'letter-spacing',\n 'text-decoration',\n 'text-anchor',\n );\n\n /**\n * Returns FabricText instance from an SVG element (not yet implemented)\n * @static\n * @memberOf Text\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n FabricText.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n const {\n textAnchor = LEFT as typeof LEFT | typeof CENTER | typeof RIGHT,\n textDecoration = '',\n dx = 0,\n dy = 0,\n top = 0,\n left = 0,\n fontSize = DEFAULT_SVG_FONT_SIZE,\n strokeWidth = 1,\n ...restOfOptions\n } = { ...options, ...parsedAttributes };\n\n const textContent = (element.textContent || '')\n .replace(/^\\s+|\\s+$|\\n+/g, '')\n .replace(/\\s+/g, ' ');\n\n // this code here is probably the usual issue for SVG center find\n // this can later looked at again and probably removed.\n\n const text = new this(textContent, {\n left: left + dx,\n top: top + dy,\n underline: textDecoration.includes('underline'),\n overline: textDecoration.includes('overline'),\n linethrough: textDecoration.includes('line-through'),\n // we initialize this as 0\n strokeWidth: 0,\n fontSize,\n ...restOfOptions,\n }),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff =\n (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff;\n\n let offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (textAnchor === CENTER) {\n offX = text.getScaledWidth() / 2;\n }\n if (textAnchor === RIGHT) {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top:\n text.top -\n (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) /\n text.lineHeight,\n strokeWidth,\n });\n return text;\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns FabricText instance from an object representation\n * @param {Object} object plain js Object to create an instance from\n * @returns {Promise}\n */\n static fromObject<\n T extends TOptions,\n S extends FabricText,\n >(object: T) {\n return this._fromObject(\n {\n ...object,\n styles: stylesFromArray(object.styles || {}, object.text),\n },\n {\n extraParam: 'text',\n },\n );\n }\n}\n\napplyMixins(FabricText, [TextSVGExportMixin]);\nclassRegistry.setClass(FabricText);\nclassRegistry.setSVGClass(FabricText);\n","import type {\n DragEventData,\n DropEventData,\n TPointerEvent,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { IText } from './IText';\nimport { setStyle } from '../../util/dom_style';\nimport { cloneStyles } from '../../util/internals/cloneStyles';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, NONE } from '../../constants';\n\n/**\n * #### Dragging IText/Textbox Lifecycle\n * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection}\n * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection\n * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session\n * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur\n * - canvas fires relevant drag events that are handled by the handlers defined in this scope\n * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior\n * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown`\n */\nexport class DraggableTextDelegate {\n readonly target: IText;\n private __mouseDownInPlace = false;\n private __dragStartFired = false;\n private __isDraggingOver = false;\n private __dragStartSelection?: {\n selectionStart: number;\n selectionEnd: number;\n };\n private __dragImageDisposer?: VoidFunction;\n private _dispose?: () => void;\n\n constructor(target: IText) {\n this.target = target;\n const disposers = [\n this.target.on('dragenter', this.dragEnterHandler.bind(this)),\n this.target.on('dragover', this.dragOverHandler.bind(this)),\n this.target.on('dragleave', this.dragLeaveHandler.bind(this)),\n this.target.on('dragend', this.dragEndHandler.bind(this)),\n this.target.on('drop', this.dropHandler.bind(this)),\n ];\n this._dispose = () => {\n disposers.forEach((d) => d());\n this._dispose = undefined;\n };\n }\n\n isPointerOverSelection(e: TPointerEvent) {\n const target = this.target;\n const newSelection = target.getSelectionStartFromPointer(e);\n return (\n target.isEditing &&\n newSelection >= target.selectionStart &&\n newSelection <= target.selectionEnd &&\n target.selectionStart < target.selectionEnd\n );\n }\n\n /**\n * @public override this method to disable dragging and default to mousedown logic\n */\n start(e: TPointerEvent) {\n return (this.__mouseDownInPlace = this.isPointerOverSelection(e));\n }\n\n /**\n * @public override this method to disable dragging without discarding selection\n */\n isActive() {\n return this.__mouseDownInPlace;\n }\n\n /**\n * Ends interaction and sets cursor in case of a click\n * @returns true if was active\n */\n end(e: TPointerEvent) {\n const active = this.isActive();\n if (active && !this.__dragStartFired) {\n // mousedown has been blocked since `active` is true => cursor has not been set.\n // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection.\n // meaning this is actually a click, `active` is a false positive.\n this.target.setCursorByClick(e);\n this.target.initDelayedCursor(true);\n }\n this.__mouseDownInPlace = false;\n this.__dragStartFired = false;\n this.__isDraggingOver = false;\n return active;\n }\n\n getDragStartSelection() {\n return this.__dragStartSelection;\n }\n\n /**\n * Override to customize the drag image\n * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage\n */\n setDragImage(\n e: DragEvent,\n {\n selectionStart,\n selectionEnd,\n }: {\n selectionStart: number;\n selectionEnd: number;\n },\n ) {\n const target = this.target;\n const canvas = target.canvas!;\n const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1);\n const boundaries = target._getCursorBoundaries(selectionStart);\n const selectionPosition = new Point(\n boundaries.left + boundaries.leftOffset,\n boundaries.top + boundaries.topOffset,\n ).multiply(flipFactor);\n const pos = selectionPosition.transform(target.calcTransformMatrix());\n const pointer = canvas.getScenePoint(e);\n const diff = pointer.subtract(pos);\n const retinaScaling = target.getCanvasRetinaScaling();\n const bbox = target.getBoundingRect();\n const correction = pos.subtract(new Point(bbox.left, bbox.top));\n const vpt = canvas.viewportTransform;\n const offset = correction.add(diff).transform(vpt, true);\n // prepare instance for drag image snapshot by making all non selected text invisible\n const bgc = target.backgroundColor;\n const styles = cloneStyles(target.styles);\n target.backgroundColor = '';\n const styleOverride = {\n stroke: 'transparent',\n fill: 'transparent',\n textBackgroundColor: 'transparent',\n };\n target.setSelectionStyles(styleOverride, 0, selectionStart);\n target.setSelectionStyles(styleOverride, selectionEnd, target.text.length);\n target.dirty = true;\n const dragImage = target.toCanvasElement({\n enableRetinaScaling: canvas.enableRetinaScaling,\n viewportTransform: true,\n });\n // restore values\n target.backgroundColor = bgc;\n target.styles = styles;\n target.dirty = true;\n // position drag image offscreen\n setStyle(dragImage, {\n position: 'fixed',\n left: `${-dragImage.width}px`,\n border: NONE,\n width: `${dragImage.width / retinaScaling}px`,\n height: `${dragImage.height / retinaScaling}px`,\n });\n this.__dragImageDisposer && this.__dragImageDisposer();\n this.__dragImageDisposer = () => {\n dragImage.remove();\n };\n getDocumentFromElement(\n (e.target || this.target.hiddenTextarea)! as HTMLElement,\n ).body.appendChild(dragImage);\n e.dataTransfer?.setDragImage(dragImage, offset.x, offset.y);\n }\n\n /**\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source\n */\n onDragStart(e: DragEvent): boolean {\n this.__dragStartFired = true;\n const target = this.target;\n const active = this.isActive();\n if (active && e.dataTransfer) {\n const selection = (this.__dragStartSelection = {\n selectionStart: target.selectionStart,\n selectionEnd: target.selectionEnd,\n });\n const value = target._text\n .slice(selection.selectionStart, selection.selectionEnd)\n .join('');\n const data = { text: target.text, value, ...selection };\n e.dataTransfer.setData('text/plain', value);\n e.dataTransfer.setData(\n 'application/fabric',\n JSON.stringify({\n value: value,\n styles: target.getSelectionStyles(\n selection.selectionStart,\n selection.selectionEnd,\n true,\n ),\n }),\n );\n e.dataTransfer.effectAllowed = 'copyMove';\n this.setDragImage(e, data);\n }\n target.abortCursorAnimation();\n return active;\n }\n\n /**\n * use {@link targetCanDrop} to respect overriding\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target\n */\n canDrop(e: DragEvent): boolean {\n if (\n this.target.editable &&\n !this.target.getActiveControl() &&\n !e.defaultPrevented\n ) {\n if (this.isActive() && this.__dragStartSelection) {\n // drag source trying to drop over itself\n // allow dropping only outside of drag start selection\n const index = this.target.getSelectionStartFromPointer(e);\n const dragStartSelection = this.__dragStartSelection;\n return (\n index < dragStartSelection.selectionStart ||\n index > dragStartSelection.selectionEnd\n );\n }\n return true;\n }\n return false;\n }\n\n /**\n * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly\n */\n protected targetCanDrop(e: DragEvent) {\n return this.target.canDrop(e);\n }\n\n dragEnterHandler({ e }: DragEventData) {\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n }\n }\n\n dragOverHandler(ev: DragEventData) {\n const { e } = ev;\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n } else if (this.__isDraggingOver && !canDrop) {\n // drop state has changed\n this.__isDraggingOver = false;\n }\n if (this.__isDraggingOver) {\n // can be dropped, inform browser\n e.preventDefault();\n // inform event subscribers\n ev.canDrop = true;\n ev.dropTarget = this.target;\n }\n }\n\n dragLeaveHandler() {\n if (this.__isDraggingOver || this.isActive()) {\n this.__isDraggingOver = false;\n }\n }\n\n /**\n * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer}\n * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop\n */\n dropHandler(ev: DropEventData) {\n const { e } = ev;\n const didDrop = e.defaultPrevented;\n this.__isDraggingOver = false;\n // inform browser that the drop has been accepted\n e.preventDefault();\n let insert = e.dataTransfer?.getData('text/plain');\n if (insert && !didDrop) {\n const target = this.target;\n const canvas = target.canvas!;\n let insertAt = target.getSelectionStartFromPointer(e);\n const { styles } = (\n e.dataTransfer!.types.includes('application/fabric')\n ? JSON.parse(e.dataTransfer!.getData('application/fabric'))\n : {}\n ) as { styles: TextStyleDeclaration[] };\n const trailing = insert[Math.max(0, insert.length - 1)];\n const selectionStartOffset = 0;\n // drag and drop in same instance\n if (this.__dragStartSelection) {\n const selectionStart = this.__dragStartSelection.selectionStart;\n const selectionEnd = this.__dragStartSelection.selectionEnd;\n if (insertAt > selectionStart && insertAt <= selectionEnd) {\n insertAt = selectionStart;\n } else if (insertAt > selectionEnd) {\n insertAt -= selectionEnd - selectionStart;\n }\n target.removeChars(selectionStart, selectionEnd);\n // prevent `dragend` from handling event\n delete this.__dragStartSelection;\n }\n // remove redundant line break\n if (\n target._reNewline.test(trailing) &&\n (target._reNewline.test(target._text[insertAt]) ||\n insertAt === target._text.length)\n ) {\n insert = insert.trimEnd();\n }\n // inform subscribers\n ev.didDrop = true;\n ev.dropTarget = target;\n // finalize\n target.insertChars(insert, styles, insertAt);\n // can this part be moved in an outside event? andrea to check.\n canvas.setActiveObject(target);\n target.enterEditing(e);\n target.selectionStart = Math.min(\n insertAt + selectionStartOffset,\n target._text.length,\n );\n target.selectionEnd = Math.min(\n target.selectionStart + insert.length,\n target._text.length,\n );\n target.hiddenTextarea!.value = target.text;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n target.fire(CHANGED, {\n index: insertAt + selectionStartOffset,\n action: 'drop',\n });\n canvas.fire('text:changed', { target });\n canvas.contextTopDirty = true;\n canvas.requestRenderAll();\n }\n }\n\n /**\n * fired only on the drag source after drop (if occurred)\n * handle changes to the drag source in case of a drop on another object or a cancellation\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n */\n dragEndHandler({ e }: DragEventData) {\n if (this.isActive() && this.__dragStartFired) {\n // once the drop event finishes we check if we need to change the drag source\n // if the drag source received the drop we bail out since the drop handler has already handled logic\n if (this.__dragStartSelection) {\n const target = this.target;\n const canvas = this.target.canvas!;\n const { selectionStart, selectionEnd } = this.__dragStartSelection;\n const dropEffect = e.dataTransfer?.dropEffect || NONE;\n if (dropEffect === NONE) {\n // pointer is back over selection\n target.selectionStart = selectionStart;\n target.selectionEnd = selectionEnd;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n } else {\n target.clearContextTop();\n if (dropEffect === 'move') {\n target.removeChars(selectionStart, selectionEnd);\n target.selectionStart = target.selectionEnd = selectionStart;\n target.hiddenTextarea &&\n (target.hiddenTextarea.value = target.text);\n target._updateTextarea();\n target.fire(CHANGED, {\n index: selectionStart,\n action: 'dragend',\n });\n canvas.fire('text:changed', { target });\n canvas.requestRenderAll();\n }\n target.exitEditing();\n }\n }\n }\n\n this.__dragImageDisposer && this.__dragImageDisposer();\n delete this.__dragImageDisposer;\n delete this.__dragStartSelection;\n this.__isDraggingOver = false;\n }\n\n dispose() {\n this._dispose && this._dispose();\n }\n}\n","import type {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends FabricText {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean,\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n },\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1),\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n this.canvas.fire('text:editing:entered', {\n target: this as unknown as IText,\n e,\n });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[],\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text,\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value,\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight,\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight,\n ),\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire(MODIFIED);\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true,\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration },\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle,\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength,\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start,\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number,\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\n","import { config } from '../../config';\nimport { getFabricDocument, getEnv } from '../../env';\nimport { capValue } from '../../util/misc/capValue';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextBehavior } from './ITextBehavior';\nimport type { TKeyMapIText } from './constants';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\nimport type { IText } from './IText';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\n\nexport abstract class ITextKeyBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextBehavior {\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behavior for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the IText or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = Object.assign({}, this.keysMap);\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\n */\n declare keysMap: TKeyMapIText;\n\n declare keysMapRtl: TKeyMapIText;\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n declare ctrlKeysMapUp: TKeyMapIText;\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n declare ctrlKeysMapDown: TKeyMapIText;\n\n declare hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * DOM container to append the hiddenTextarea.\n * An alternative to attaching to the document.body.\n * Useful to reduce laggish redraw of the full document.body tree and\n * also with modals event capturing that won't let the textarea take focus.\n * @type HTMLElement\n * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare fromPaste: boolean;\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea() {\n const doc =\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument();\n const textarea = doc.createElement('textarea');\n Object.entries({\n autocapitalize: 'off',\n autocorrect: 'off',\n autocomplete: 'off',\n spellcheck: 'false',\n 'data-fabric': 'textarea',\n wrap: 'off',\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\n const { top, left, fontSize } = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\n\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\n\n Object.entries({\n blur: 'blur',\n keydown: 'onKeyDown',\n keyup: 'onKeyUp',\n input: 'onInput',\n copy: 'copy',\n cut: 'copy',\n paste: 'paste',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate',\n compositionend: 'onCompositionEnd',\n } as Record).map(([eventName, handler]) =>\n textarea.addEventListener(\n eventName,\n (this[handler] as EventListener).bind(this),\n ),\n );\n this.hiddenTextarea = textarea;\n }\n\n /**\n * Override this method to customize cursor behavior on textbox blur\n */\n blur() {\n this.abortCursorAnimation();\n }\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {KeyboardEvent} e Event object\n */\n onKeyDown(e: KeyboardEvent) {\n if (!this.isEditing) {\n return;\n }\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\n if (e.keyCode in keyMap) {\n // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n }\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {KeyboardEvent} e Event object\n */\n onKeyUp(e: KeyboardEvent) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n }\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\n const fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n const updateAndFire = () => {\n this.updateFromTextArea();\n this.fire(CHANGED);\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this as unknown as IText });\n this.canvas.requestRenderAll();\n }\n };\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n updateAndFire();\n return;\n }\n // decisions about style changes.\n const nextText = this._splitTextIntoLines(\n this.hiddenTextarea.value,\n ).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd;\n let copiedStyle: TextStyleDeclaration[] | undefined,\n removedText,\n charDiff = nextCharCount - charCount,\n removeFrom,\n removeTo;\n\n const textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value,\n );\n const backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(\n selectionStart,\n selectionStart - charDiff,\n );\n }\n }\n const insertedText = nextText.slice(\n textareaSelection.selectionEnd - charDiff,\n textareaSelection.selectionEnd,\n );\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(\n selectionStart,\n selectionStart + 1,\n false,\n );\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(\n () =>\n // this return an array of references, but that is fine since we are\n // copying the style later.\n copiedStyle![0],\n );\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differences between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n const { copyPasteData } = getEnv();\n if (\n fromPaste &&\n insertedText.join('') === copyPasteData.copiedText &&\n !config.disableStyleCopyPaste\n ) {\n copiedStyle = copyPasteData.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n updateAndFire();\n }\n\n /**\n * Composition start\n */\n onCompositionStart() {\n this.inCompositionMode = true;\n }\n\n /**\n * Composition end\n */\n onCompositionEnd() {\n this.inCompositionMode = false;\n }\n\n onCompositionUpdate({ target }: CompositionEvent) {\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\n this.compositionStart = selectionStart;\n this.compositionEnd = selectionEnd;\n this.updateTextareaPosition();\n }\n\n /**\n * Copies selected text\n */\n copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n const { copyPasteData } = getEnv();\n copyPasteData.copiedText = this.getSelectedText();\n if (!config.disableStyleCopyPaste) {\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\n this.selectionStart,\n this.selectionEnd,\n true,\n );\n } else {\n copyPasteData.copiedTextStyle = undefined;\n }\n this._copyDone = true;\n }\n\n /**\n * Pastes text\n */\n paste() {\n this.fromPaste = true;\n }\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n }\n\n /**\n * Gets start offset of a selection\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (\n lineIndex === this._textLines.length - 1 ||\n e.metaKey ||\n e.keyCode === 34\n ) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return (\n textAfterCursor.length +\n indexOnOtherLine +\n 1 +\n this.missingNewlineOffset(lineIndex)\n );\n }\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n }\n\n /**\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return (\n -this._textLines[lineIndex - 1].length +\n indexOnOtherLine -\n textBeforeCursor.length +\n (1 - missingNewlineOffset)\n );\n }\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine(lineIndex: number, width: number) {\n const line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n let widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n const leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n }\n\n /**\n * Moves cursor down\n * @param {KeyboardEvent} e Event object\n */\n moveCursorDown(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n }\n\n /**\n * Moves cursor up\n * @param {KeyboardEvent} e Event object\n */\n moveCursorUp(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n }\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\n const offset = this[`get${direction}CursorOffset`](\n e,\n this._selectionDirection === RIGHT,\n );\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n const max = this.text.length;\n this.selectionStart = capValue(0, this.selectionStart, max);\n this.selectionEnd = capValue(0, this.selectionEnd, max);\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift(offset: number) {\n const newSelection =\n this._selectionDirection === LEFT\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(\n this.selectionStart,\n this.selectionEnd,\n newSelection,\n );\n return offset !== 0;\n }\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift(offset: number) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n }\n\n /**\n * Moves cursor left\n * @param {KeyboardEvent} e Event object\n */\n moveCursorLeft(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n }\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n *\n * @todo refactor not to use method name composition\n */\n _move(\n e: KeyboardEvent,\n prop: 'selectionStart' | 'selectionEnd',\n direction: 'Left' | 'Right',\n ): boolean {\n let newValue: number | undefined;\n if (e.altKey) {\n newValue = this[`findWordBoundary${direction}`](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this[`findLineBoundary${direction}`](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n return false;\n }\n\n /**\n * @private\n */\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Left');\n }\n\n /**\n * @private\n */\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Right');\n }\n\n /**\n * Moves cursor left without keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\n let change = true;\n this._selectionDirection = LEFT;\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (\n this.selectionEnd === this.selectionStart &&\n this.selectionStart !== 0\n ) {\n change = this._moveLeft(e, 'selectionStart');\n }\n this.selectionEnd = this.selectionStart;\n return change;\n }\n\n /**\n * Moves cursor left while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === RIGHT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = LEFT;\n return this._moveLeft(e, 'selectionStart');\n }\n }\n\n /**\n * Moves cursor right\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRight(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n }\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\n const actionName = `moveCursor${direction}${\n e.shiftKey ? 'WithShift' : 'WithoutShift'\n }` as const;\n this._currentCursorOpacity = 1;\n if (this[actionName](e)) {\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor right while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorRightWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === LEFT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = RIGHT;\n return this._moveRight(e, 'selectionEnd');\n }\n }\n\n /**\n * Moves cursor right without keeping selection\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRightWithoutShift(e: KeyboardEvent) {\n let changed = true;\n this._selectionDirection = RIGHT;\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n }\n}\n","import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { stopEvent } from '../../util/dom_event';\nimport { invertTransform } from '../../util/misc/matrix';\nimport { DraggableTextDelegate } from './DraggableTextDelegate';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextKeyBehavior } from './ITextKeyBehavior';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\n\n/**\n * `LEFT_CLICK === 0`\n */\nconst notALeftClick = (e: Event) => !!(e as MouseEvent).button;\n\nexport abstract class ITextClickBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextKeyBehavior {\n private declare __lastSelected: boolean;\n private declare __lastClickTime: number;\n private declare __lastLastClickTime: number;\n private declare __lastPointer: XY | Record;\n private declare __newClickTime: number;\n\n protected draggableTextDelegate: DraggableTextDelegate;\n\n initBehavior() {\n // Initializes event handlers related to cursor or selection\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n this.on('mouseup', this.mouseUpHandler);\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n\n // Initializes \"dbclick\" event handler\n this.__lastClickTime = +new Date();\n // for triple click\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n\n // @ts-expect-error in reality it is an IText instance\n this.draggableTextDelegate = new DraggableTextDelegate(this);\n\n super.initBehavior();\n }\n\n /**\n * If this method returns true a mouse move operation over a text selection\n * will not prevent the native mouse event allowing the browser to start a drag operation.\n * shouldStartDragging can be read 'do not prevent default for mouse move event'\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns\n */\n shouldStartDragging() {\n return this.draggableTextDelegate.isActive();\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drag source,\n * @see also {@link DraggableTextDelegate#isActive}\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns {boolean} should handle event\n */\n onDragStart(e: DragEvent) {\n return this.draggableTextDelegate.onDragStart(e);\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drop target\n */\n canDrop(e: DragEvent) {\n return this.draggableTextDelegate.canDrop(e);\n }\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown(options: TPointerEventInfo) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n const newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastSelected = this.selected && !this.getActiveControl();\n }\n\n isTripleClick(newPointer: XY) {\n return (\n this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y\n );\n }\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler({ e }: TPointerEventInfo) {\n if (\n !this.canvas ||\n !this.editable ||\n notALeftClick(e) ||\n this.getActiveControl()\n ) {\n return;\n }\n\n if (this.draggableTextDelegate.start(e)) {\n return;\n }\n\n this.canvas.textEditingManager.register(this);\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore({ e }: TPointerEventInfo) {\n if (!this.canvas || !this.editable || notALeftClick(e)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n }\n\n /**\n * standard handler for mouse up, overridable\n * @private\n */\n mouseUpHandler({ e, transform }: TPointerEventInfo) {\n const didDrag = this.draggableTextDelegate.end(e);\n if (this.canvas) {\n this.canvas.textEditingManager.unregister(this);\n\n const activeObject = this.canvas._activeObject;\n if (activeObject && activeObject !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n if (\n !this.editable ||\n (this.group && !this.group.interactive) ||\n (transform && transform.actionPerformed) ||\n notALeftClick(e) ||\n didDrag\n ) {\n return;\n }\n\n if (this.__lastSelected && !this.getActiveControl()) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\n }\n } else {\n this.selected = true;\n }\n }\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {TPointerEvent} e Event object\n */\n setCursorByClick(e: TPointerEvent) {\n const newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {TPointerEvent} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer(e: TPointerEvent): number {\n const mouseOffset = this.canvas!.getScenePoint(e)\n .transform(invertTransform(this.calcTransformMatrix()))\n .add(new Point(-this._getLeftOffset(), -this._getTopOffset()));\n let height = 0,\n charIndex = 0,\n lineIndex = 0;\n\n for (let i = 0; i < this._textLines.length; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i);\n lineIndex = i;\n if (i > 0) {\n charIndex +=\n this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex));\n let width = lineLeftOffset;\n const charLength = this._textLines[lineIndex].length;\n const chars = this.__charBounds[lineIndex];\n for (let j = 0; j < charLength; j++) {\n // i removed something about flipX here, check.\n const charWidth = chars[j].kernedWidth;\n const widthAfter = width + charWidth;\n if (mouseOffset.x <= widthAfter) {\n // if the pointer is closer to the end of the char we increment charIndex\n // in order to position the cursor after the char\n if (\n Math.abs(mouseOffset.x - widthAfter) <=\n Math.abs(mouseOffset.x - width)\n ) {\n charIndex++;\n }\n break;\n }\n width = widthAfter;\n charIndex++;\n }\n\n return Math.min(\n // if object is horizontally flipped, mirror cursor location from the end\n this.flipX ? charLength - charIndex : charIndex,\n this._text.length,\n );\n }\n}\n","export type TKeyMapIText = Record<\n KeyboardEvent['keyCode'],\n CursorHandlingMethods\n>;\n\nexport type CursorHandlingMethods =\n | 'moveCursorUp'\n | 'moveCursorDown'\n | 'moveCursorLeft'\n | 'moveCursorRight'\n | 'exitEditing'\n | 'copy'\n | 'cut'\n | 'selectAll';\n\nconst MOVE_CURSOR_UP: CursorHandlingMethods = 'moveCursorUp';\nconst MOVE_CURSOR_DOWN: CursorHandlingMethods = 'moveCursorDown';\nconst MOVE_CURSOR_LEFT: CursorHandlingMethods = 'moveCursorLeft';\nconst MOVE_CURSOR_RIGHT: CursorHandlingMethods = 'moveCursorRight';\nconst EXIT_EDITING: CursorHandlingMethods = 'exitEditing';\n\n// @TODO look into import { Key } from 'ts-key-enum';\n// and transition from keyCode to Key\n// also reduce string duplication\nexport const keysMap: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_RIGHT,\n 36: MOVE_CURSOR_LEFT,\n 37: MOVE_CURSOR_LEFT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_RIGHT,\n 40: MOVE_CURSOR_DOWN,\n};\n\nexport const keysMapRtl: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_LEFT,\n 36: MOVE_CURSOR_RIGHT,\n 37: MOVE_CURSOR_RIGHT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_LEFT,\n 40: MOVE_CURSOR_DOWN,\n};\n\n/**\n * For functionalities on keyUp + ctrl || cmd\n */\nexport const ctrlKeysMapUp: TKeyMapIText = {\n 67: 'copy',\n // there was a reason this wasn't deleted. for now leave it here\n 88: 'cut',\n};\n\n/**\n * For functionalities on keyDown + ctrl || cmd\n */\nexport const ctrlKeysMapDown: TKeyMapIText = {\n 65: 'selectAll',\n};\n","import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, FILL, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions = Partial,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends ITextClickBehavior\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number,\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean,\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean,\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean,\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean,\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number,\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, FILL) as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight,\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true),\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries,\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight,\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, FILL);\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n","import type { TClassProperties, TOptions } from '../typedefs';\nimport { IText } from './IText/IText';\nimport { classRegistry } from '../ClassRegistry';\nimport { createTextboxDefaultControls } from '../controls/commonControls';\nimport { JUSTIFY } from './Text/constants';\nimport type { TextStyleDeclaration } from './Text/StyledText';\nimport type { SerializedITextProps, ITextProps } from './IText/IText';\nimport type { ITextEvents } from './IText/ITextBehavior';\nimport type { TextLinesInfo } from './Text/Text';\nimport type { Control } from '../controls/Control';\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textboxDefaultValues: Partial> = {\n minWidth: 20,\n dynamicMinWidth: 2,\n lockScalingFlip: true,\n noScaleCache: false,\n _wordJoiners: /[ \\t\\r]/,\n splitByGrapheme: false,\n};\n\nexport type GraphemeData = {\n wordsData: {\n word: string[];\n width: number;\n }[][];\n largestWordWidth: number;\n};\n\nexport type StyleMap = Record;\n\n// @TODO this is not complete\ninterface UniqueTextboxProps {\n minWidth: number;\n splitByGrapheme: boolean;\n dynamicMinWidth: number;\n _wordJoiners: RegExp;\n}\n\nexport interface SerializedTextboxProps\n extends SerializedITextProps,\n Pick {}\n\nexport interface TextboxProps extends ITextProps, UniqueTextboxProps {}\n\n/**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n */\nexport class Textbox<\n Props extends TOptions = Partial,\n SProps extends SerializedTextboxProps = SerializedTextboxProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends IText\n implements UniqueTextboxProps\n{\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n declare minWidth: number;\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n declare dynamicMinWidth: number;\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japanese\n * @type Boolean\n * @since 2.6.0\n */\n declare splitByGrapheme: boolean;\n\n declare _wordJoiners: RegExp;\n\n declare _styleMap: StyleMap;\n\n declare isWrapping: boolean;\n\n static type = 'Textbox';\n\n static textLayoutProperties = [...IText.textLayoutProperties, 'width'];\n\n static ownDefaults = textboxDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Textbox.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...Textbox.ownDefaults, ...options } as Props);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults object\n */\n static createControls(): { controls: Record } {\n return { controls: createTextboxDefaultControls() };\n }\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions() {\n if (!this.initialized) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n }\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap(textInfo: TextLinesInfo): StyleMap {\n let realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0;\n const map: StyleMap = {};\n\n for (let i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n } else if (\n !this.splitByGrapheme &&\n this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) &&\n i > 0\n ) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n }\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex: number): boolean {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return super.styleHas(property, lineIndex);\n }\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex: number): boolean {\n if (!this.styles) {\n return true;\n }\n let offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset: number,\n shouldLimit = false;\n const map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n const p2Number = parseInt(p2, 10);\n if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset!)) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n /**\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (!map) {\n return {};\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return super._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n const map = this._styleMap[lineIndex];\n super._setStyleDeclaration(map.line, map.offset + charIndex, style);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n const map = this._styleMap[lineIndex];\n super._deleteStyleDeclaration(map.line, map.offset + charIndex);\n }\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n const map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n const map = this._styleMap[lineIndex];\n super._setLineStyle(map.line);\n }\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText(lines: string[], desiredWidth: number): string[][] {\n this.isWrapping = true;\n // extract all thewords and the widths to optimally wrap lines.\n const data = this.getGraphemeDataForRender(lines);\n const wrapped: string[][] = [];\n for (let i = 0; i < data.wordsData.length; i++) {\n wrapped.push(...this._wrapLine(i, desiredWidth, data));\n }\n this.isWrapping = false;\n return wrapped;\n }\n\n /**\n * For each line of text terminated by an hard line stop,\n * measure each word width and extract the largest word from all.\n * The returned words here are the one that at the end will be rendered.\n * @param {string[]} lines the lines we need to measure\n *\n */\n getGraphemeDataForRender(lines: string[]): GraphemeData {\n const splitByGrapheme = this.splitByGrapheme,\n infix = splitByGrapheme ? '' : ' ';\n\n let largestWordWidth = 0;\n\n const data = lines.map((line, lineIndex) => {\n let offset = 0;\n const wordsOrGraphemes = splitByGrapheme\n ? this.graphemeSplit(line)\n : this.wordSplit(line);\n\n if (wordsOrGraphemes.length === 0) {\n return [{ word: [], width: 0 }];\n }\n\n return wordsOrGraphemes.map((word: string) => {\n // if using splitByGrapheme words are already in graphemes.\n const graphemeArray = splitByGrapheme\n ? [word]\n : this.graphemeSplit(word);\n const width = this._measureWord(graphemeArray, lineIndex, offset);\n largestWordWidth = Math.max(width, largestWordWidth);\n offset += graphemeArray.length + infix.length;\n return { word: graphemeArray, width };\n });\n });\n\n return {\n wordsData: data,\n largestWordWidth,\n };\n }\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * It gets called when charBounds are not available yet.\n * Override if necessary\n * Use with {@link Textbox#wordSplit}\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n */\n _measureWord(word: string[], lineIndex: number, charOffset = 0): number {\n let width = 0,\n prevGrapheme;\n const skipLeft = true;\n for (let i = 0, len = word.length; i < len; i++) {\n const box = this._getGraphemeBox(\n word[i],\n lineIndex,\n i + charOffset,\n prevGrapheme,\n skipLeft,\n );\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n }\n\n /**\n * Override this method to customize word splitting\n * Use with {@link Textbox#_measureWord}\n * @param {string} value\n * @returns {string[]} array of words\n */\n wordSplit(value: string): string[] {\n return value.split(this._wordJoiners);\n }\n\n /**\n * Wraps a line of text using the width of the Textbox as desiredWidth\n * and leveraging the known width o words from GraphemeData\n * @private\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {GraphemeData} graphemeData an object containing all the lines' words width.\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine(\n lineIndex: number,\n desiredWidth: number,\n { largestWordWidth, wordsData }: GraphemeData,\n reservedSpace = 0,\n ): string[][] {\n const additionalSpace = this._getWidthOfCharSpacing(),\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n infix = splitByGrapheme ? '' : ' ';\n\n let lineWidth = 0,\n line: string[] = [],\n // spaces in different languages?\n offset = 0,\n infixWidth = 0,\n lineJustStarted = true;\n\n desiredWidth -= reservedSpace;\n\n const maxWidth = Math.max(\n desiredWidth,\n largestWordWidth,\n this.dynamicMinWidth,\n );\n // layout words\n const data = wordsData[lineIndex];\n offset = 0;\n let i;\n for (i = 0; i < data.length; i++) {\n const { word, width: wordWidth } = data[i];\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n if (lineWidth > maxWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = splitByGrapheme\n ? 0\n : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n }\n\n i && graphemeLines.push(line);\n\n // TODO: this code is probably not necessary anymore.\n // it can be moved out of this function since largestWordWidth is now\n // known in advance\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n return graphemeLines;\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * This is important only for splitByGrapheme at the end of wrapping.\n * If we are not wrapping the offset is always 1\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1 {\n if (this.splitByGrapheme && !skipWrapping) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n }\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines(text: string) {\n const newText = super._splitTextIntoLines(text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (let i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n }\n\n getMinWidth() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n }\n\n _removeExtraneousStyles() {\n const linesToKeep = new Map();\n for (const prop in this._styleMap) {\n const propNumber = parseInt(prop, 10);\n if (this._textLines[propNumber]) {\n const lineIndex = this._styleMap[prop].line;\n linesToKeep.set(`${lineIndex}`, true);\n }\n }\n for (const prop in this.styles) {\n if (!linesToKeep.has(prop)) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([\n 'minWidth',\n 'splitByGrapheme',\n ...propertiesToInclude,\n ] as K[]) as Pick & SProps;\n }\n}\n\nclassRegistry.setClass(Textbox);\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport { sendPointToPlane } from '../../util/misc/planeChange';\nimport type { LayoutStrategyResult, StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { getObjectBounds } from './utils';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to match the clip path bounding box.\n */\nexport class ClipPathLayout extends LayoutStrategy {\n static readonly type = 'clip-path';\n\n shouldPerformLayout(context: StrictLayoutContext): boolean {\n return !!context.target.clipPath && super.shouldPerformLayout(context);\n }\n\n shouldLayoutClipPath() {\n return false;\n }\n\n calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n const { target } = context;\n const { clipPath, group } = target;\n if (!clipPath || !this.shouldPerformLayout(context)) {\n return;\n }\n // TODO: remove stroke calculation from this case\n const { width, height } = makeBoundingBoxFromPoints(\n getObjectBounds(target, clipPath as FabricObject),\n );\n const size = new Point(width, height);\n if (clipPath.absolutePositioned) {\n // we want the center point to exist in group's containing plane\n const clipPathCenter = sendPointToPlane(\n clipPath.getRelativeCenterPoint(),\n undefined,\n group ? group.calcTransformMatrix() : undefined,\n );\n return {\n center: clipPathCenter,\n size,\n };\n } else {\n // we want the center point to exist in group's containing plane, so we send it upwards\n const clipPathCenter = clipPath\n .getRelativeCenterPoint()\n .transform(target.calcOwnMatrix(), true);\n if (this.shouldPerformLayout(context)) {\n // the clip path is positioned relative to the group's center which is affected by the bbox\n // so we first calculate the bbox\n const { center = new Point(), correction = new Point() } =\n this.calcBoundingBox(objects, context) || {};\n return {\n center: center.add(clipPathCenter),\n correction: correction.subtract(clipPathCenter),\n size,\n };\n } else {\n return {\n center: target.getRelativeCenterPoint().add(clipPathCenter),\n size,\n };\n }\n }\n }\n}\n\nclassRegistry.setClass(ClipPathLayout);\n","import { Point } from '../../Point';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will keep target's initial size.\n */\nexport class FixedLayout extends LayoutStrategy {\n static readonly type = 'fixed';\n\n /**\n * @override respect target's initial size\n */\n getInitialSize(\n { target }: StrictLayoutContext & InitializationLayoutContext,\n { size }: Pick,\n ): Point {\n return new Point(target.width || size.x, target.height || size.y);\n }\n}\n\nclassRegistry.setClass(FixedLayout);\n","import { LayoutManager } from './LayoutManager';\nimport type { RegistrationContext, StrictLayoutContext } from './types';\nimport type { Group } from '../shapes/Group';\n\n/**\n * Today the LayoutManager class also takes care of subscribing event handlers\n * to update the group layout when the group is interactive and a transform is applied\n * to a child object.\n * The ActiveSelection is never interactive, but it could contain objects from\n * groups that are.\n * The standard LayoutManager would subscribe the children of the activeSelection to\n * perform layout changes to the active selection itself, what we need instead is that\n * the transformation applied to the active selection will trigger changes to the\n * original group of the children ( the one referenced under the parent property )\n * This subclass of the LayoutManager has a single duty to fill the gap of this difference.`\n */\nexport class ActiveSelectionLayoutManager extends LayoutManager {\n subscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n parent.layoutManager.subscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n\n /**\n * unsubscribe from parent only if all its children were deselected\n */\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const selectedObjects = activeSelection.getObjects();\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n !selectedObjects.some((object) => object.parent === parent) &&\n parent.layoutManager.unsubscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n}\n","import type { ControlRenderingStyleOverride } from '../controls/controlRendering';\nimport { classRegistry } from '../ClassRegistry';\nimport type { GroupProps } from './Group';\nimport { Group } from './Group';\nimport type { FabricObject } from './Object/FabricObject';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { TClassProperties } from '../typedefs';\nimport { log } from '../util/internals/console';\nimport { ActiveSelectionLayoutManager } from '../LayoutManager/ActiveSelectionLayoutManager';\n\nexport type MultiSelectionStacking = 'canvas-stacking' | 'selection-order';\n\nexport interface ActiveSelectionOptions extends GroupProps {\n multiSelectionStacking: MultiSelectionStacking;\n}\n\nconst activeSelectionDefaultValues: Partial> =\n {\n multiSelectionStacking: 'canvas-stacking',\n };\n\n/**\n * Used by Canvas to manage selection.\n *\n * @example\n * class MyActiveSelection extends ActiveSelection {\n * ...\n * }\n *\n * // override the default `ActiveSelection` class\n * classRegistry.setClass(MyActiveSelection)\n */\nexport class ActiveSelection extends Group {\n static type = 'ActiveSelection';\n\n static ownDefaults: Record = activeSelectionDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...ActiveSelection.ownDefaults };\n }\n\n /**\n * The ActiveSelection needs to use the ActiveSelectionLayoutManager\n * or selections on interactive groups may be broken\n */\n declare layoutManager: ActiveSelectionLayoutManager;\n\n /**\n * controls how selected objects are added during a multiselection event\n * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order\n * - `selection-order` adds the selected object to the top of the stack,\n * meaning that the stack is ordered by the order in which objects were selected\n * @default `canvas-stacking`\n */\n declare multiSelectionStacking: MultiSelectionStacking;\n\n constructor(\n objects: FabricObject[] = [],\n options: Partial = {},\n ) {\n super();\n Object.assign(this, ActiveSelection.ownDefaults);\n this.setOptions(options);\n const { left, top, layoutManager } = options;\n this.groupInit(objects, {\n left,\n top,\n layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(),\n });\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return true;\n }\n\n /**\n * @private\n * @override we don't want the selection monitor to be active\n */\n __objectSelectionMonitor() {\n // noop\n }\n\n /**\n * Adds objects with respect to {@link multiSelectionStacking}\n * @param targets object to add to selection\n */\n multiSelectAdd(...targets: FabricObject[]) {\n if (this.multiSelectionStacking === 'selection-order') {\n this.add(...targets);\n } else {\n // respect object stacking as it is on canvas\n // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf`\n targets.forEach((target) => {\n const index = this._objects.findIndex((obj) => obj.isInFrontOf(target));\n const insertAt =\n index === -1\n ? // `target` is in front of all other objects\n this.size()\n : index;\n this.insertAt(insertAt, target);\n });\n }\n }\n\n /**\n * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree\n */\n canEnterGroup(object: FabricObject) {\n if (\n this.getObjects().some(\n (o) => o.isDescendantOf(object) || object.isDescendantOf(o),\n )\n ) {\n // prevent circular object tree\n log(\n 'error',\n 'ActiveSelection: circular object trees are not supported, this call has no effect',\n );\n return false;\n }\n\n return super.canEnterGroup(object);\n }\n\n /**\n * Change an object so that it can be part of an active selection.\n * this method is called by multiselectAdd from canvas code.\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n // This condition check that the object has currently a group, and the group\n // is also its parent, meaning that is not in an active selection, but is\n // in a normal group.\n if (object.parent && object.parent === object.group) {\n // Disconnect the object from the group functionalities, but keep the ref parent intact\n // for later re-enter\n object.parent._exitGroup(object);\n // in this case the object is probably inside an active selection.\n } else if (object.group && object.parent !== object.group) {\n // in this case group.remove will also clear the old parent reference.\n object.group.remove(object);\n }\n // enter the active selection from a render perspective\n // the object will be in the objects array of both the ActiveSelection and the Group\n // but referenced in the group's _activeObjects so that it won't be rendered twice.\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * we want objects to retain their canvas ref when exiting instance\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n // return to parent\n object.parent && object.parent._enterGroup(object, true);\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n super._onAfterObjectsChange(type, targets);\n const groups = new Set();\n targets.forEach((object) => {\n const { parent } = object;\n parent && groups.add(parent);\n });\n if (type === LAYOUT_TYPE_REMOVED) {\n // invalidate groups' layout and mark as dirty\n groups.forEach((group) => {\n group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets);\n });\n } else {\n // mark groups as dirty\n groups.forEach((group) => {\n group._set('dirty', true);\n });\n }\n }\n\n /**\n * @override remove all objects\n */\n onDeselect() {\n this.removeAll();\n return false;\n }\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString() {\n return `#`;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache() {\n return false;\n }\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache() {\n return false;\n }\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride?: ControlRenderingStyleOverride,\n childrenOverride?: ControlRenderingStyleOverride,\n ) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n const options = {\n hasControls: false,\n ...childrenOverride,\n forActiveSelection: true,\n };\n for (let i = 0; i < this._objects.length; i++) {\n this._objects[i]._renderControls(ctx, options);\n }\n super._renderControls(ctx, styleOverride);\n ctx.restore();\n }\n}\n\nclassRegistry.setClass(ActiveSelection);\nclassRegistry.setClass(ActiveSelection, 'activeSelection');\n","/**\n * Canvas 2D filter backend.\n */\nimport type { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TPipelineResources } from './typedefs';\n\nexport class Canvas2dFilterBackend {\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters(\n filters: BaseFilter>[],\n sourceElement: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n targetCanvas: HTMLCanvasElement,\n ): T2DPipelineState | void {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const pipelineState: T2DPipelineState = {\n sourceWidth,\n sourceHeight,\n imageData,\n originalEl: sourceElement,\n originalImageData,\n canvasEl: targetCanvas,\n ctx,\n filterBackend: this,\n };\n filters.forEach((filter) => {\n filter.applyTo(pipelineState);\n });\n const { imageData: imageDataPostFilter } = pipelineState;\n if (\n imageDataPostFilter.width !== sourceWidth ||\n imageDataPostFilter.height !== sourceHeight\n ) {\n targetCanvas.width = imageDataPostFilter.width;\n targetCanvas.height = imageDataPostFilter.height;\n }\n ctx.putImageData(imageDataPostFilter, 0, 0);\n return pipelineState;\n }\n}\n","import { config } from '../config';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n TWebGLPipelineState,\n TProgramCache,\n TTextureCache,\n TPipelineResources,\n} from './typedefs';\nimport type { BaseFilter } from './BaseFilter';\n\nexport class WebGLFilterBackend {\n declare tileSize: number;\n\n /**\n * Define ...\n **/\n aPosition: Float32Array = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n\n /**\n * If GLPut data is the fastest operation, or if forced, this buffer will be used\n * to transfer the data back in the 2d logic\n **/\n declare imageBuffer?: ArrayBuffer;\n\n declare canvas: HTMLCanvasElement;\n\n /**\n * The Webgl context that will execute the operations for filtering\n **/\n declare gl: WebGLRenderingContext;\n\n /**\n * Keyed map for shader cache\n **/\n declare programCache: TProgramCache;\n\n /**\n * Keyed map for texture cache\n **/\n declare textureCache: TTextureCache;\n\n /**\n * Contains GPU info for debug\n **/\n declare gpuInfo: any;\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n constructor({ tileSize = config.textureSize } = {}) {\n this.tileSize = tileSize;\n this.setupGLContext(tileSize, tileSize);\n this.captureGPUInfo();\n }\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext(width: number, height: number): void {\n this.dispose();\n this.createWebGLCanvas(width, height);\n }\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas(width: number, height: number): void {\n const canvas = createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n const glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false,\n },\n gl = canvas.getContext('webgl', glOptions) as WebGLRenderingContext;\n\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n }\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {TexImageSource} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters(\n filters: BaseFilter>[],\n source: TexImageSource,\n width: number,\n height: number,\n targetCanvas: HTMLCanvasElement,\n cacheKey?: string,\n ): TWebGLPipelineState | undefined {\n const gl = this.gl;\n const ctx = targetCanvas.getContext('2d');\n if (!gl || !ctx) {\n return;\n }\n let cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n const pipelineState: TWebGLPipelineState = {\n originalWidth:\n (source as HTMLImageElement).width ||\n // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state?\n (source as HTMLImageElement).originalWidth ||\n 0,\n originalHeight:\n (source as HTMLImageElement).height ||\n // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state?\n (source as HTMLImageElement).originalHeight ||\n 0,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n ),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture:\n cachedTexture ||\n this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n )!,\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas,\n };\n const tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach((filter: any) => {\n filter && filter.applyTo(pipelineState);\n });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n }\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose() {\n if (this.canvas) {\n // we are disposing, we don't care about the fact\n // that the canvas shouldn't be null.\n // @ts-expect-error disposing\n this.canvas = null;\n // @ts-expect-error disposing\n this.gl = null;\n }\n this.clearWebGLCaches();\n }\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches() {\n this.programCache = {};\n this.textureCache = {};\n }\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the texture to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {number} width The width to initialize the texture at.\n * @param {number} height The height to initialize the texture.\n * @param {TexImageSource} textureImageSource A source for the texture data.\n * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture.\n * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR\n * @returns {WebGLTexture}\n */\n createTexture(\n gl: WebGLRenderingContext,\n width: number,\n height: number,\n textureImageSource?: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ) {\n const {\n NEAREST,\n TEXTURE_2D,\n RGBA,\n UNSIGNED_BYTE,\n CLAMP_TO_EDGE,\n TEXTURE_MAG_FILTER,\n TEXTURE_MIN_FILTER,\n TEXTURE_WRAP_S,\n TEXTURE_WRAP_T,\n } = gl;\n const texture = gl.createTexture();\n gl.bindTexture(TEXTURE_2D, texture);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n RGBA,\n UNSIGNED_BYTE,\n textureImageSource,\n );\n } else {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n width,\n height,\n 0,\n RGBA,\n UNSIGNED_BYTE,\n null,\n );\n }\n return texture;\n }\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture(\n uniqueId: string,\n textureImageSource: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ): WebGLTexture | null {\n const { textureCache } = this;\n if (textureCache[uniqueId]) {\n return textureCache[uniqueId];\n } else {\n const texture = this.createTexture(\n this.gl,\n (textureImageSource as HTMLImageElement).width,\n (textureImageSource as HTMLImageElement).height,\n textureImageSource,\n filter,\n );\n if (texture) {\n textureCache[uniqueId] = texture;\n }\n return texture;\n }\n }\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey(cacheKey: string) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2D(gl: WebGLRenderingContext, pipelineState: TWebGLPipelineState) {\n const glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n const sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(\n glCanvas,\n 0,\n sourceY,\n targetCanvas.width,\n targetCanvas.height,\n 0,\n 0,\n targetCanvas.width,\n targetCanvas.height,\n );\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2DPutImageData(\n this: Required,\n gl: WebGLRenderingContext,\n pipelineState: TWebGLPipelineState,\n ) {\n const targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n if (!ctx) {\n return;\n }\n const u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n const imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n }\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n const gl = this.gl,\n gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n const ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n }\n}\n\nfunction resizeCanvasIfNeeded(pipelineState: TWebGLPipelineState): void {\n const targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width,\n height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n","import { config } from '../config';\nimport { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { Canvas2dFilterBackend } from './Canvas2dFilterBackend';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\n\nexport type FilterBackend = WebGLFilterBackend | Canvas2dFilterBackend;\n\nlet filterBackend: FilterBackend;\n\n/**\n * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend\n */\nexport function initFilterBackend(): FilterBackend {\n const { WebGLProbe } = getEnv();\n WebGLProbe.queryWebGL(createCanvasElement());\n if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) {\n return new WebGLFilterBackend({ tileSize: config.textureSize });\n } else {\n return new Canvas2dFilterBackend();\n }\n}\n\n/**\n * Get the current fabricJS filter backend or initialize one if not available yet\n * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior),\n * pass `false` to get the backend ref without mutating it\n */\nexport function getFilterBackend(strict = true): FilterBackend {\n if (!filterBackend && strict) {\n filterBackend = initFilterBackend();\n }\n return filterBackend;\n}\n\nexport function setFilterBackend(backend: FilterBackend) {\n filterBackend = backend;\n}\n","import { getFabricDocument, getEnv } from '../env';\nimport type { BaseFilter } from '../filters/BaseFilter';\nimport { getFilterBackend } from '../filters/FilterBackend';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type {\n TClassProperties,\n TCrossOrigin,\n TSize,\n Abortable,\n TOptions,\n} from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { findScaleToCover, findScaleToFit } from '../util/misc/findScaleTo';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n loadImage,\n} from '../util/misc/objectEnlive';\nimport { parsePreserveAspectRatioAttribute } from '../util/misc/svgParsing';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { WebGLFilterBackend } from '../filters/WebGLFilterBackend';\nimport { FILL, NONE } from '../constants';\nimport { getDocumentFromElement } from '../util/dom_misc';\nimport type { CSSRules } from '../parser/typedefs';\nimport type { Resize } from '../filters/Resize';\nimport type { TCachedFabricObject } from './Object/Object';\nimport { log } from '../util/internals/console';\n\n// @todo Would be nice to have filtering code not imported directly.\n\nexport type ImageSource =\n | HTMLImageElement\n | HTMLVideoElement\n | HTMLCanvasElement;\n\ninterface UniqueImageProps {\n srcFromAttribute: boolean;\n minimumScaleTrigger: number;\n cropX: number;\n cropY: number;\n imageSmoothing: boolean;\n filters: BaseFilter>[];\n resizeFilter?: Resize;\n}\n\nexport const imageDefaultValues: Partial> = {\n strokeWidth: 0,\n srcFromAttribute: false,\n minimumScaleTrigger: 0.5,\n cropX: 0,\n cropY: 0,\n imageSmoothing: true,\n};\n\nexport interface SerializedImageProps extends SerializedObjectProps {\n src: string;\n crossOrigin: TCrossOrigin;\n filters: any[];\n resizeFilter?: any;\n cropX: number;\n cropY: number;\n}\n\nexport interface ImageProps extends FabricObjectProps, UniqueImageProps {}\n\nconst IMAGE_PROPS = ['cropX', 'cropY'] as const;\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n */\nexport class FabricImage<\n Props extends TOptions = Partial,\n SProps extends SerializedImageProps = SerializedImageProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements ImageProps\n{\n /**\n * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default false\n */\n declare srcFromAttribute: boolean;\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleX = 1;\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleY = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingX = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingY = 1;\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n declare minimumScaleTrigger: number;\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n declare cacheKey: string;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropX: number;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropY: number;\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n declare imageSmoothing: boolean;\n\n declare preserveAspectRatio: string;\n\n protected declare src: string;\n\n declare filters: BaseFilter>[];\n declare resizeFilter: Resize;\n\n declare _element: ImageSource;\n declare _filteredEl?: HTMLCanvasElement;\n declare _originalElement: ImageSource;\n\n static type = 'Image';\n\n static cacheProperties = [...cacheProperties, ...IMAGE_PROPS];\n\n static ownDefaults = imageDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...FabricImage.ownDefaults,\n };\n }\n /**\n * Constructor\n * Image can be initialized with any canvas drawable or a string.\n * The string should be a url and will be loaded as an image.\n * Canvas and Image element work out of the box, while videos require extra code to work.\n * Please check video element events for seeking.\n * @param {ImageSource | string} element Image element\n * @param {Object} [options] Options object\n */\n constructor(elementId: string, options?: Props);\n constructor(element: ImageSource, options?: Props);\n constructor(arg0: ImageSource | string, options?: Props) {\n super();\n this.filters = [];\n Object.assign(this, FabricImage.ownDefaults);\n this.setOptions(options);\n this.cacheKey = `texture${uid()}`;\n this.setElement(\n typeof arg0 === 'string'\n ? ((\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument()\n ).getElementById(arg0) as ImageSource)\n : arg0,\n options,\n );\n }\n\n /**\n * Returns image element which this instance if based on\n */\n getElement() {\n return this._element;\n }\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Partial} [size] Options object\n */\n setElement(element: ImageSource, size: Partial = {}) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._element = element;\n this._originalElement = element;\n this._setWidthHeight(size);\n element.classList.add(FabricImage.CSS_CANVAS);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal filters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n }\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture(key: string) {\n const backend = getFilterBackend(false);\n if (backend instanceof WebGLFilterBackend) {\n backend.evictCachesForKey(key);\n }\n }\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose() {\n super.dispose();\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._cacheContext = null;\n (\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'] as const\n ).forEach((elementKey) => {\n const el = this[elementKey];\n el && getEnv().dispose(el);\n // @ts-expect-error disposing\n this[elementKey] = undefined;\n });\n }\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin(): string | null {\n return (\n this._originalElement &&\n ((this._originalElement as any).crossOrigin || null)\n );\n }\n\n /**\n * Returns original size of an image\n */\n getOriginalSize() {\n const element = this.getElement() as any;\n if (!element) {\n return {\n width: 0,\n height: 0,\n };\n }\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height,\n };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n const w = this.width / 2,\n h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const filters: Record[] = [];\n this.filters.forEach((filterObj) => {\n filterObj && filters.push(filterObj.toObject());\n });\n return {\n ...super.toObject([...IMAGE_PROPS, ...propertiesToInclude]),\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters,\n ...(this.resizeFilter\n ? { resizeFilter: this.resizeFilter.toObject() }\n : {}),\n };\n }\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height.\n * @return {Boolean}\n */\n hasCrop() {\n return (\n !!this.cropX ||\n !!this.cropY ||\n this.width < this._element.width ||\n this.height < this._element.height\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @return {string[]} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const imageMarkup: string[] = [],\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2;\n let svgString: string[] = [],\n strokeSvg: string[] = [],\n clipPath = '',\n imageRendering = '';\n if (!element) {\n return [];\n }\n if (this.hasCrop()) {\n const clipPathId = uid();\n svgString.push(\n '\\n',\n '\\t\\n',\n '\\n',\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n if (!this.imageSmoothing) {\n imageRendering = ' image-rendering=\"optimizeSpeed\"';\n }\n imageMarkup.push(\n '\\t element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n }\" width=\"${\n element.width || (element as HTMLImageElement).naturalWidth\n }\" height=\"${\n element.height || (element as HTMLImageElement).naturalHeight\n }\"${imageRendering}${clipPath}>\\n`,\n );\n\n if (this.stroke || this.strokeDashArray) {\n const origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n `\\t\\n`,\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== FILL) {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n }\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc(filtered?: boolean): string {\n const element = filtered ? this._element : this._originalElement;\n if (element) {\n if ((element as HTMLCanvasElement).toDataURL) {\n return (element as HTMLCanvasElement).toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src') || '';\n } else {\n return (element as HTMLImageElement).src;\n }\n } else {\n return this.src || '';\n }\n }\n\n /**\n * Alias for getSrc\n * @param filtered\n * @deprecated\n */\n getSvgSrc(filtered?: boolean) {\n return this.getSrc(filtered);\n }\n\n /**\n * Loads and sets source of an image\\\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n * @param {String} src Source string (URL)\n * @param {LoadImageOptions} [options] Options object\n */\n setSrc(src: string, { crossOrigin, signal }: LoadImageOptions = {}) {\n return loadImage(src, { crossOrigin, signal }).then((img) => {\n typeof crossOrigin !== 'undefined' && this.set({ crossOrigin });\n this.setElement(img);\n });\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString() {\n return `#`;\n }\n\n applyResizeFilters() {\n const filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.x,\n scaleY = objectScale.y,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n const canvasEl = createCanvasElement(),\n sourceWidth = elementToFilter.width,\n sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n getFilterBackend().applyFilters(\n [filter],\n elementToFilter,\n sourceWidth,\n sourceHeight,\n this._element,\n );\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n }\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n */\n applyFilters(\n filters: BaseFilter>[] = this.filters || [],\n ) {\n filters = filters.filter((filter) => filter && !filter.isNeutralState());\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(`${this.cacheKey}_filtered`);\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n // this is unsafe and needs to be rethinkend\n this._filteredEl = undefined;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return;\n }\n\n const imgElement = this._originalElement,\n sourceWidth =\n (imgElement as HTMLImageElement).naturalWidth || imgElement.width,\n sourceHeight =\n (imgElement as HTMLImageElement).naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the _element a reference to _originalElement\n // we need to create a new element to host the filtered pixels\n const canvasEl = createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n } else if (this._filteredEl) {\n // if the _element is it own element,\n // and we also have a _filteredEl, then we clean up _filteredEl\n // and we assign it to _element.\n // in this way we invalidate the eventual old resize filtered element\n this._element = this._filteredEl;\n this._filteredEl\n .getContext('2d')!\n .clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n getFilterBackend().applyFilters(\n filters,\n this._originalElement,\n sourceWidth,\n sourceHeight,\n this._element as HTMLCanvasElement,\n );\n if (\n this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height\n ) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY =\n this._element.height / this._originalElement.height;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(\n this: TCachedFabricObject,\n ctx: CanvasRenderingContext2D,\n ) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n super.drawCacheOnCanvas(ctx);\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache() {\n return this.needsItsOwnCache();\n }\n\n _renderFill(ctx: CanvasRenderingContext2D) {\n const elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n const scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n // crop values cannot be lesser than 0.\n cropX = Math.max(this.cropX, 0),\n cropY = Math.max(this.cropY, 0),\n elWidth =\n (elementToDraw as HTMLImageElement).naturalWidth || elementToDraw.width,\n elHeight =\n (elementToDraw as HTMLImageElement).naturalHeight ||\n elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = Math.min(w * scaleX, elWidth - sX),\n sH = Math.min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = Math.min(w, elWidth / scaleX - cropX),\n maxDestH = Math.min(h, elHeight / scaleY - cropY);\n\n elementToDraw &&\n ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n }\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize() {\n const scale = this.getTotalObjectScaling();\n return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY;\n }\n\n /**\n * @private\n * @deprecated unused\n */\n _resetWidthHeight() {\n this.set(this.getOriginalSize());\n }\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n */\n _setWidthHeight({ width, height }: Partial = {}) {\n const size = this.getOriginalSize();\n this.width = width || size.width;\n this.height = height || size.height;\n }\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n */\n parsePreserveAspectRatioAttribute() {\n const pAR = parsePreserveAspectRatioAttribute(\n this.preserveAspectRatio || '',\n ),\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = { width: pWidth, height: pHeight };\n let rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset;\n\n if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX,\n scaleY,\n offsetLeft,\n offsetTop,\n cropX,\n cropY,\n };\n }\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n static CSS_CANVAS = 'canvas-img';\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'width',\n 'height',\n 'preserveAspectRatio',\n 'xlink:href',\n 'crossOrigin',\n 'image-rendering',\n ];\n\n /**\n * Creates an instance of FabricImage from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n { filters: f, resizeFilter: rf, src, crossOrigin, type, ...object }: T,\n options?: Abortable,\n ) {\n return Promise.all([\n loadImage(src!, { ...options, crossOrigin }),\n f && enlivenObjects>(f, options),\n // TODO: redundant - handled by enlivenObjectEnlivables\n rf && enlivenObjects>([rf], options),\n enlivenObjectEnlivables(object, options),\n ]).then(([el, filters = [], [resizeFilter] = [], hydratedProps = {}]) => {\n return new this(el, {\n ...object,\n // TODO: this creates a difference between image creation and restoring from JSON\n src,\n filters,\n resizeFilter,\n ...hydratedProps,\n });\n });\n }\n\n /**\n * Creates an instance of Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {LoadImageOptions} [options] Options object\n * @returns {Promise}\n */\n static fromURL>(\n url: string,\n { crossOrigin = null, signal }: LoadImageOptions = {},\n imageOptions?: T,\n ): Promise {\n return loadImage(url, { crossOrigin, signal }).then(\n (img) => new this(img, imageOptions),\n );\n }\n\n /**\n * Returns {@link FabricImage} instance from an SVG element\n * @static\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} callback Callback to execute when Image object is created\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable = {},\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return this.fromURL(\n parsedAttributes['xlink:href'],\n options,\n parsedAttributes,\n ).catch((err) => {\n log('log', 'Unable to parse Image', err);\n return null;\n });\n }\n}\n\nclassRegistry.setClass(FabricImage);\nclassRegistry.setSVGClass(FabricImage);\n","import { svgNS } from './constants';\nimport {\n parsePreserveAspectRatioAttribute,\n parseUnit,\n} from '../util/misc/svgParsing';\nimport { svgViewBoxElementsRegEx, reViewBoxAttrValue } from './constants';\nimport { NONE } from '../constants';\n\nexport type ParsedViewboxTransform = Partial<{\n width: number;\n height: number;\n minX: number;\n minY: number;\n viewBoxWidth: number;\n viewBoxHeight: number;\n}>;\n\n/**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\nexport function applyViewboxTransform(\n element: Element,\n): ParsedViewboxTransform {\n if (!svgViewBoxElementsRegEx.test(element.nodeName)) {\n return {};\n }\n const viewBoxAttr: string | null = element.getAttribute('viewBox');\n let scaleX = 1;\n let scaleY = 1;\n let minX = 0;\n let minY = 0;\n let matrix;\n let el;\n const widthAttr = element.getAttribute('width');\n const heightAttr = element.getAttribute('height');\n const x = element.getAttribute('x') || 0;\n const y = element.getAttribute('y') || 0;\n const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr);\n const missingViewBox = !goodViewbox;\n const missingDimAttr =\n !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%';\n\n let translateMatrix = '';\n let widthDiff = 0;\n let heightDiff = 0;\n\n if (missingViewBox) {\n if (\n (x || y) &&\n element.parentNode &&\n element.parentNode.nodeName !== '#document'\n ) {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (missingViewBox && missingDimAttr) {\n return {\n width: 0,\n height: 0,\n };\n }\n\n const parsedDim: ParsedViewboxTransform = {\n width: 0,\n height: 0,\n };\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr!);\n parsedDim.height = parseUnit(heightAttr!);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n\n const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue)!;\n minX = -parseFloat(pasedViewBox[1]);\n minY = -parseFloat(pasedViewBox[2]);\n const viewBoxWidth = parseFloat(pasedViewBox[3]);\n const viewBoxHeight = parseFloat(pasedViewBox[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n const preserveAspectRatio = parsePreserveAspectRatioAttribute(\n element.getAttribute('preserveAspectRatio') || '',\n );\n if (preserveAspectRatio.alignX !== NONE) {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY;\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (\n scaleX === 1 &&\n scaleY === 1 &&\n minX === 0 &&\n minY === 0 &&\n x === 0 &&\n y === 0\n ) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode!.nodeName !== '#document') {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n }\n\n matrix =\n translateMatrix +\n ' matrix(' +\n scaleX +\n ' 0' +\n ' 0 ' +\n scaleY +\n ' ' +\n (minX * scaleX + widthDiff) +\n ' ' +\n (minY * scaleY + heightDiff) +\n ') ';\n // seems unused.\n // parsedDim.viewboxTransform = parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n}\n","export const getTagName = (node: Element) => node.tagName.replace('svg:', '');\n","import { svgInvalidAncestors } from './constants';\nimport { getSvgRegex } from './getSvgRegex';\nimport { getTagName } from './getTagName';\n\nconst svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n\nexport function hasInvalidAncestor(element: Element) {\n let _element: Element | null = element;\n while (_element && (_element = _element.parentElement)) {\n if (\n _element &&\n _element.nodeName &&\n svgInvalidAncestorsRegEx.test(getTagName(_element)) &&\n !_element.getAttribute('instantiated_by_use')\n ) {\n return true;\n }\n }\n return false;\n}\n","export function getMultipleNodes(\n doc: Document,\n nodeNames: string[],\n): Element[] {\n let nodeName,\n nodeArray: Element[] = [],\n nodeList,\n i,\n len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagNameNS(\n 'http://www.w3.org/2000/svg',\n nodeName,\n );\n nodeArray = nodeArray.concat(Array.from(nodeList));\n }\n return nodeArray;\n}\n","import { svgNS } from './constants';\nimport { getMultipleNodes } from './getMultipleNodes';\nimport { applyViewboxTransform } from './applyViewboxTransform';\nimport { parseStyleString } from './parseStyleString';\n\nexport function parseUseDirectives(doc: Document) {\n const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);\n const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];\n\n for (const useElement of nodelist) {\n const useAttributes: NamedNodeMap = useElement.attributes;\n\n const useAttrMap: Record = {};\n for (const attr of useAttributes) {\n attr.value && (useAttrMap[attr.name] = attr.value);\n }\n\n const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);\n\n if (xlink === '') {\n return;\n }\n const referencedElement = doc.getElementById(xlink);\n if (referencedElement === null) {\n // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink\n return;\n }\n let clonedOriginal = referencedElement.cloneNode(true) as Element;\n\n const originalAttributes: NamedNodeMap = clonedOriginal.attributes;\n\n const originalAttrMap: Record = {};\n for (const attr of originalAttributes) {\n attr.value && (originalAttrMap[attr.name] = attr.value);\n }\n\n // Transform attribute needs to be merged in a particular way\n const { x = 0, y = 0, transform = '' } = useAttrMap;\n const currentTrans = `${transform} ${\n originalAttrMap.transform || ''\n } translate(${x}, ${y})`;\n\n applyViewboxTransform(clonedOriginal);\n\n if (/^svg$/i.test(clonedOriginal.nodeName)) {\n // if is an SVG, create a group and apply all the attributes on top of it\n const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');\n Object.entries(originalAttrMap).forEach(([name, value]) =>\n el3.setAttributeNS(svgNS, name, value),\n );\n el3.append(...clonedOriginal.childNodes);\n clonedOriginal = el3;\n }\n\n for (const attr of useAttributes) {\n if (!attr) {\n continue;\n }\n const { name, value } = attr;\n if (skipAttributes.includes(name)) {\n continue;\n }\n\n if (name === 'style') {\n // when use has a style, merge the two styles, with the ref being priority (not use)\n // priority is by feature. an attribute for fill on the original element\n // will overwrite the fill in style or attribute for tha use\n const styleRecord: Record = {};\n parseStyleString(value!, styleRecord);\n // cleanup styleRecord from attributes of original\n Object.entries(originalAttrMap).forEach(([name, value]) => {\n styleRecord[name] = value;\n });\n // now we can put in the style of the original that will overwrite the original attributes\n parseStyleString(originalAttrMap.style || '', styleRecord);\n const mergedStyles = Object.entries(styleRecord)\n .map((entry) => entry.join(':'))\n .join(';');\n clonedOriginal.setAttribute(name, mergedStyles);\n } else {\n // set the attribute from use element only if the original does not have it already\n !originalAttrMap[name] && clonedOriginal.setAttribute(name, value!);\n }\n }\n\n clonedOriginal.setAttribute('transform', currentTrans);\n clonedOriginal.setAttribute('instantiated_by_use', '1');\n clonedOriginal.removeAttribute('id');\n useElement.parentNode!.replaceChild(clonedOriginal, useElement);\n }\n}\n","const gradientsAttrs = [\n 'gradientTransform',\n 'x1',\n 'x2',\n 'y1',\n 'y2',\n 'gradientUnits',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n];\nconst xlinkAttr = 'xlink:href';\n\nexport function recursivelyParseGradientsXlink(\n doc: Document,\n gradient: Element,\n) {\n const xLink = gradient.getAttribute(xlinkAttr)?.slice(1) || '',\n referencedGradient = doc.getElementById(xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient as Element);\n }\n if (referencedGradient) {\n gradientsAttrs.forEach((attr) => {\n const value = referencedGradient.getAttribute(attr);\n if (!gradient.hasAttribute(attr) && value) {\n gradient.setAttribute(attr, value);\n }\n });\n if (!gradient.children.length) {\n const referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n }\n gradient.removeAttribute(xlinkAttr);\n}\n","import { getMultipleNodes } from './getMultipleNodes';\nimport { recursivelyParseGradientsXlink } from './recursivelyParseGradientsXlink';\n\nconst tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient',\n];\n\n/**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\nexport function getGradientDefs(\n doc: Document,\n): Record {\n const elList = getMultipleNodes(doc, tagArray);\n const gradientDefs: Record = {};\n let j = elList.length;\n while (j--) {\n const el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n const id = el.getAttribute('id');\n if (id) {\n gradientDefs[id] = el as SVGGradientElement;\n }\n }\n return gradientDefs;\n}\n","import type { CSSRules } from './typedefs';\n\n/**\n * Returns CSS rules for a given SVG document\n * @param {HTMLElement} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\nexport function getCSSRules(doc: Document) {\n const styles = doc.getElementsByTagName('style');\n let i;\n let len;\n const allRules: CSSRules = {};\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n const styleContents = (styles[i].textContent || '').replace(\n // remove comments\n /\\/\\*[\\s\\S]*?\\*\\//g,\n '',\n );\n\n if (styleContents.trim() === '') {\n continue;\n }\n // recovers all the rule in this form `body { style code... }`\n // rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n styleContents\n .split('}')\n // remove empty rules and remove everything if we didn't split in at least 2 pieces\n .filter((rule, index, array) => array.length > 1 && rule.trim())\n // at this point we have hopefully an array of rules `body { style code... `\n .forEach((rule) => {\n // if there is more than one opening bracket and the rule starts with '@', it is likely\n // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below\n // can not handle it.\n if (\n (rule.match(/{/g) || []).length > 1 &&\n rule.trim().startsWith('@')\n ) {\n return;\n }\n\n const match = rule.split('{'),\n ruleObj: Record = {},\n declaration = match[1].trim(),\n propertyValuePairs = declaration.split(';').filter(function (pair) {\n return pair.trim();\n });\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n const pair = propertyValuePairs[i].split(':'),\n property = pair[0].trim(),\n value = pair[1].trim();\n ruleObj[property] = value;\n }\n rule = match[0].trim();\n rule.split(',').forEach((_rule) => {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n allRules[_rule] = {\n ...(allRules[_rule] || {}),\n ...ruleObj,\n };\n });\n });\n }\n return allRules;\n}\n","import { Gradient } from '../gradient/Gradient';\nimport { Group } from '../shapes/Group';\nimport { FabricImage } from '../shapes/Image';\nimport { classRegistry } from '../ClassRegistry';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../util/misc/matrix';\nimport { removeTransformMatrixForSvgParsing } from '../util/transform_matrix_removal';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { Point } from '../Point';\nimport { CENTER, FILL, STROKE } from '../constants';\nimport { getGradientDefs } from './getGradientDefs';\nimport { getCSSRules } from './getCSSRules';\nimport type { LoadImageOptions } from '../util';\nimport type { CSSRules, TSvgReviverCallback } from './typedefs';\nimport type { ParsedViewboxTransform } from './applyViewboxTransform';\nimport type { SVGOptions } from '../gradient';\nimport { getTagName } from './getTagName';\nimport { parseTransformAttribute } from './parseTransformAttribute';\n\nconst findTag = (el: Element) =>\n classRegistry.getSVGClass(getTagName(el).toLowerCase());\n\ntype StorageType = {\n fill: SVGGradientElement;\n stroke: SVGGradientElement;\n clipPath: Element[];\n};\n\ntype NotParsedFabricObject = FabricObject & {\n fill: string;\n stroke: string;\n clipPath?: string;\n clipRule?: CanvasFillRule;\n};\n\nexport class ElementsParser {\n declare elements: Element[];\n declare options: LoadImageOptions & ParsedViewboxTransform;\n declare reviver?: TSvgReviverCallback;\n declare regexUrl: RegExp;\n declare doc: Document;\n declare clipPaths: Record;\n declare gradientDefs: Record;\n declare cssRules: CSSRules;\n\n constructor(\n elements: Element[],\n options: LoadImageOptions & ParsedViewboxTransform,\n reviver: TSvgReviverCallback | undefined,\n doc: Document,\n clipPaths: Record,\n ) {\n this.elements = elements;\n this.options = options;\n this.reviver = reviver;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n this.clipPaths = clipPaths;\n this.gradientDefs = getGradientDefs(doc);\n this.cssRules = getCSSRules(doc);\n }\n\n parse(): Promise> {\n return Promise.all(\n this.elements.map((element) => this.createObject(element)),\n );\n }\n\n async createObject(el: Element): Promise {\n const klass = findTag(el);\n if (klass) {\n const obj: NotParsedFabricObject = await klass.fromElement(\n el,\n this.options,\n this.cssRules,\n );\n this.resolveGradient(obj, el, FILL);\n this.resolveGradient(obj, el, STROKE);\n if (obj instanceof FabricImage && obj._originalElement) {\n removeTransformMatrixForSvgParsing(\n obj,\n obj.parsePreserveAspectRatioAttribute(),\n );\n } else {\n removeTransformMatrixForSvgParsing(obj);\n }\n await this.resolveClipPath(obj, el);\n this.reviver && this.reviver(el, obj);\n return obj;\n }\n return null;\n }\n\n extractPropertyDefinition(\n obj: NotParsedFabricObject,\n property: 'fill' | 'stroke' | 'clipPath',\n storage: Record,\n ): StorageType[typeof property] | undefined {\n const value = obj[property]!,\n regex = this.regexUrl;\n if (!regex.test(value)) {\n return undefined;\n }\n // verify: can we remove the 'g' flag? and remove lastIndex changes?\n regex.lastIndex = 0;\n // we passed the regex test, so we know is not null;\n const id = regex.exec(value)![1];\n regex.lastIndex = 0;\n // @todo fix this\n return storage[id];\n }\n\n resolveGradient(\n obj: NotParsedFabricObject,\n el: Element,\n property: 'fill' | 'stroke',\n ) {\n const gradientDef = this.extractPropertyDefinition(\n obj,\n property,\n this.gradientDefs,\n ) as SVGGradientElement;\n if (gradientDef) {\n const opacityAttr = el.getAttribute(property + '-opacity');\n const gradient = Gradient.fromElement(gradientDef, obj, {\n ...this.options,\n opacity: opacityAttr,\n } as SVGOptions);\n obj.set(property, gradient);\n }\n }\n\n // TODO: resolveClipPath could be run once per clippath with minor work per object.\n // is a refactor that i m not sure is worth on this code\n async resolveClipPath(obj: NotParsedFabricObject, usingElement: Element) {\n const clipPathElements = this.extractPropertyDefinition(\n obj,\n 'clipPath',\n this.clipPaths,\n ) as Element[];\n if (clipPathElements) {\n const objTransformInv = invertTransform(obj.calcTransformMatrix());\n const clipPathTag = clipPathElements[0].parentElement!;\n let clipPathOwner = usingElement;\n while (\n clipPathOwner.parentElement &&\n clipPathOwner.getAttribute('clip-path') !== obj.clipPath\n ) {\n clipPathOwner = clipPathOwner.parentElement;\n }\n // move the clipPath tag as sibling to the real element that is using it\n clipPathOwner.parentElement!.appendChild(clipPathTag!);\n\n // this multiplication order could be opposite.\n // but i don't have an svg to test it\n // at the first SVG that has a transform on both places and is misplaced\n // try to invert this multiplication order\n const finalTransform = parseTransformAttribute(\n `${clipPathOwner.getAttribute('transform') || ''} ${\n clipPathTag.getAttribute('originalTransform') || ''\n }`,\n );\n\n clipPathTag.setAttribute(\n 'transform',\n `matrix(${finalTransform.join(',')})`,\n );\n\n const container = await Promise.all(\n clipPathElements.map((clipPathElement) => {\n return findTag(clipPathElement)\n .fromElement(clipPathElement, this.options, this.cssRules)\n .then((enlivedClippath: NotParsedFabricObject) => {\n removeTransformMatrixForSvgParsing(enlivedClippath);\n enlivedClippath.fillRule = enlivedClippath.clipRule!;\n delete enlivedClippath.clipRule;\n return enlivedClippath;\n });\n }),\n );\n const clipPath =\n container.length === 1 ? container[0] : new Group(container);\n const gTransform = multiplyTransformMatrices(\n objTransformInv,\n clipPath.calcTransformMatrix(),\n );\n if (clipPath.clipPath) {\n await this.resolveClipPath(clipPath, clipPathOwner);\n }\n const { scaleX, scaleY, angle, skewX, translateX, translateY } =\n qrDecompose(gTransform);\n clipPath.set({\n flipX: false,\n flipY: false,\n });\n clipPath.set({\n scaleX,\n scaleY,\n angle,\n skewX,\n skewY: 0,\n });\n clipPath.setPositionByOrigin(\n new Point(translateX, translateY),\n CENTER,\n CENTER,\n );\n obj.clipPath = clipPath;\n } else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n return;\n }\n }\n}\n","import { applyViewboxTransform } from './applyViewboxTransform';\nimport { svgValidTagNamesRegEx } from './constants';\nimport { hasInvalidAncestor } from './hasInvalidAncestor';\nimport { parseUseDirectives } from './parseUseDirectives';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { ElementsParser } from './elements_parser';\nimport { log, SignalAbortedError } from '../util/internals/console';\nimport { getTagName } from './getTagName';\n\nconst isValidSvgTag = (el: Element) =>\n svgValidTagNamesRegEx.test(getTagName(el));\n\nexport const createEmptyResponse = (): SVGParsingOutput => ({\n objects: [],\n elements: [],\n options: {},\n allElements: [],\n});\n\n/**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {HTMLElement} doc SVG document to parse\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {SVGParsingOutput}\n * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n */\nexport async function parseSVGDocument(\n doc: Document,\n reviver?: TSvgReviverCallback,\n { crossOrigin, signal }: LoadImageOptions = {},\n): Promise {\n if (signal && signal.aborted) {\n log('log', new SignalAbortedError('parseSVGDocument'));\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n }\n const documentElement = doc.documentElement;\n parseUseDirectives(doc);\n\n const descendants = Array.from(documentElement.getElementsByTagName('*')),\n options = {\n ...applyViewboxTransform(documentElement),\n crossOrigin,\n signal,\n };\n\n const elements = descendants.filter((el) => {\n applyViewboxTransform(el);\n return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n if (!elements || (elements && !elements.length)) {\n return {\n ...createEmptyResponse(),\n options,\n allElements: descendants,\n };\n }\n const localClipPaths: Record = {};\n descendants\n .filter((el) => getTagName(el) === 'clipPath')\n .forEach((el) => {\n el.setAttribute('originalTransform', el.getAttribute('transform') || '');\n const id = el.getAttribute('id')!;\n localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(\n (el) => isValidSvgTag(el),\n );\n });\n\n // Precedence of rules: style > class > attribute\n const elementParser = new ElementsParser(\n elements,\n options,\n reviver,\n doc,\n localClipPaths,\n );\n\n const instances = await elementParser.parse();\n\n return {\n objects: instances,\n elements,\n options,\n allElements: descendants,\n };\n}\n","import { getFabricWindow } from '../env';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { parseSVGDocument } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\n\n/**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string representing the svg\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromString(\n string: string,\n reviver?: TSvgReviverCallback,\n options?: LoadImageOptions,\n): Promise {\n const parser = new (getFabricWindow().DOMParser)(),\n // should we use `image/svg+xml` here?\n doc = parser.parseFromString(string.trim(), 'text/xml');\n return parseSVGDocument(doc, reviver, options);\n}\n","import { request } from '../util/internals/dom_request';\nimport { parseSVGDocument, createEmptyResponse } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\n\n/**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {string} url where the SVG is\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromURL(\n url: string,\n reviver?: TSvgReviverCallback,\n options: LoadImageOptions = {},\n): Promise {\n // need to handle error properly\n return new Promise((resolve, reject) => {\n const onComplete = (r: XMLHttpRequest) => {\n const xml = r.responseXML;\n if (xml) {\n resolve(xml);\n }\n reject();\n };\n\n request(url.replace(/^\\n\\s*/, '').trim(), {\n onComplete,\n signal: options.signal,\n });\n })\n .then((parsedDoc) => parseSVGDocument(parsedDoc, reviver, options))\n .catch(() => {\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n });\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Polyline } from '../shapes/Polyline';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { MODIFY_POLY } from '../constants';\n\nconst ACTION_NAME: TModificationEvents = MODIFY_POLY;\n\ntype TTransformAnchor = Transform & { pointIndex: number };\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nexport const createPolyPositionHandler = (pointIndex: number) => {\n return function (dim: Point, finalMatrix: TMat2D, polyObject: Polyline) {\n const { points, pathOffset } = polyObject;\n return new Point(points[pointIndex])\n .subtract(pathOffset)\n .transform(\n multiplyTransformMatrices(\n polyObject.getViewportTransform(),\n polyObject.calcTransformMatrix(),\n ),\n );\n };\n};\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nexport const polyActionHandler = (\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) => {\n const { target, pointIndex } = transform;\n const poly = target as Polyline;\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n poly.calcOwnMatrix(),\n );\n\n poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);\n poly.setDimensions();\n\n return true;\n};\n\n/**\n * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.\n */\nexport const factoryPolyActionHandler = (\n pointIndex: number,\n fn: TransformActionHandler,\n) => {\n return function (\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n ) {\n const poly = transform.target as Polyline,\n anchorPoint = new Point(\n poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1],\n ),\n anchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix()),\n actionPerformed = fn(eventData, { ...transform, pointIndex }, x, y);\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n poly.left -= diff.x;\n poly.top -= diff.y;\n\n return actionPerformed;\n };\n};\n\nexport const createPolyActionHandler = (pointIndex: number) =>\n wrapWithFireEvent(\n ACTION_NAME,\n factoryPolyActionHandler(pointIndex, polyActionHandler),\n );\n\nexport function createPolyControls(\n poly: Polyline,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n numOfControls: number,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n arg0: number | Polyline,\n options: Partial = {},\n) {\n const controls = {} as Record;\n for (\n let idx = 0;\n idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length);\n idx++\n ) {\n controls[`p${idx}`] = new Control({\n actionName: ACTION_NAME,\n positionHandler: createPolyPositionHandler(idx),\n actionHandler: createPolyActionHandler(idx),\n ...options,\n });\n }\n return controls;\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Path } from '../shapes/Path';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport type { TSimpleParseCommandType } from '../util/path/typedefs';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\nconst ACTION_NAME: TModificationEvents = 'modifyPath' as const;\n\ntype TTransformAnchor = Transform;\n\nexport type PathPointControlStyle = {\n controlFill?: string;\n controlStroke?: string;\n connectionDashArray?: number[];\n};\n\nconst calcPathPointPosition = (\n pathObject: Path,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n const command = path[commandIndex];\n return new Point(\n (command[pointIndex] as number) - pathOffset.x,\n (command[pointIndex + 1] as number) - pathOffset.y,\n ).transform(\n multiplyTransformMatrices(\n pathObject.getViewportTransform(),\n pathObject.calcTransformMatrix(),\n ),\n );\n};\n\nconst movePathPoint = (\n pathObject: Path,\n x: number,\n y: number,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n\n const anchorCommand =\n path[(commandIndex > 0 ? commandIndex : path.length) - 1];\n const anchorPoint = new Point(\n anchorCommand[pointIndex] as number,\n anchorCommand[pointIndex + 1] as number,\n );\n\n const anchorPointInParentPlane = anchorPoint\n .subtract(pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n pathObject.calcOwnMatrix(),\n );\n\n path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;\n path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;\n pathObject.setDimensions();\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(pathObject.pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n pathObject.left -= diff.x;\n pathObject.top -= diff.y;\n pathObject.set('dirty', true);\n return true;\n};\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nfunction pathPositionHandler(\n this: PathPointControl,\n dim: Point,\n finalMatrix: TMat2D,\n pathObject: Path,\n) {\n const { commandIndex, pointIndex } = this;\n return calcPathPointPosition(pathObject, commandIndex, pointIndex);\n}\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nfunction pathActionHandler(\n this: PathPointControl,\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) {\n const { target } = transform;\n const { commandIndex, pointIndex } = this;\n const actionPerformed = movePathPoint(\n target as Path,\n x,\n y,\n commandIndex,\n pointIndex,\n );\n if (actionPerformed) {\n fireEvent(this.actionName as TModificationEvents, {\n ...commonEventInfo(eventData, transform, x, y),\n commandIndex,\n pointIndex,\n });\n }\n return actionPerformed;\n}\n\nconst indexFromPrevCommand = (previousCommandType: TSimpleParseCommandType) =>\n previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;\n\nclass PathPointControl extends Control {\n declare commandIndex: number;\n declare pointIndex: number;\n declare controlFill: string;\n declare controlStroke: string;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const overrides: ControlRenderingStyleOverride = {\n ...styleOverride,\n cornerColor: this.controlFill,\n cornerStrokeColor: this.controlStroke,\n transparentCorners: !this.controlFill,\n };\n super.render(ctx, left, top, overrides, fabricObject);\n }\n}\n\nclass PathControlPointControl extends PathPointControl {\n declare connectionDashArray?: number[];\n declare connectToCommandIndex: number;\n declare connectToPointIndex: number;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n this: PathControlPointControl,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const { path } = fabricObject;\n const {\n commandIndex,\n pointIndex,\n connectToCommandIndex,\n connectToPointIndex,\n } = this;\n ctx.save();\n ctx.strokeStyle = this.controlStroke;\n if (this.connectionDashArray) {\n ctx.setLineDash(this.connectionDashArray);\n }\n const [commandType] = path[commandIndex];\n const point = calcPathPointPosition(\n fabricObject,\n connectToCommandIndex,\n connectToPointIndex,\n );\n\n if (commandType === 'Q') {\n // one control point connects to 2 points\n const point2 = calcPathPointPosition(\n fabricObject,\n commandIndex,\n pointIndex + 2,\n );\n ctx.moveTo(point2.x, point2.y);\n ctx.lineTo(left, top);\n } else {\n ctx.moveTo(left, top);\n }\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n ctx.restore();\n\n super.render(ctx, left, top, styleOverride, fabricObject);\n }\n}\n\nconst createControl = (\n commandIndexPos: number,\n pointIndexPos: number,\n isControlPoint: boolean,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n },\n connectToCommandIndex?: number,\n connectToPointIndex?: number,\n) =>\n new (isControlPoint ? PathControlPointControl : PathPointControl)({\n commandIndex: commandIndexPos,\n pointIndex: pointIndexPos,\n actionName: ACTION_NAME,\n positionHandler: pathPositionHandler,\n actionHandler: pathActionHandler,\n connectToCommandIndex,\n connectToPointIndex,\n ...options,\n ...(isControlPoint ? options.controlPointStyle : options.pointStyle),\n } as Partial);\n\nexport function createPathControls(\n path: Path,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n } = {},\n): Record {\n const controls = {} as Record;\n let previousCommandType: TSimpleParseCommandType = 'M';\n path.path.forEach((command, commandIndex) => {\n const commandType = command[0];\n\n if (commandType !== 'Z') {\n controls[`c_${commandIndex}_${commandType}`] = createControl(\n commandIndex,\n command.length - 2,\n false,\n options,\n );\n }\n switch (commandType) {\n case 'C':\n controls[`c_${commandIndex}_C_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex - 1,\n indexFromPrevCommand(previousCommandType),\n );\n controls[`c_${commandIndex}_C_CP_2`] = createControl(\n commandIndex,\n 3,\n true,\n options,\n commandIndex,\n 5,\n );\n break;\n case 'Q':\n controls[`c_${commandIndex}_Q_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex,\n 3,\n );\n break;\n }\n previousCommandType = commandType;\n });\n return controls;\n}\n","import { getFabricWindow } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\n\nexport const isWebGLPipelineState = (\n options: TWebGLPipelineState | T2DPipelineState,\n): options is TWebGLPipelineState => {\n return (options as TWebGLPipelineState).webgl !== undefined;\n};\n\n/**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * drawImage should be faster, but is also bugged for a small combination of old hardware\n * and drivers.\n * putImageData is faster than drawImage for that specific operation.\n */\nexport const isPutImageFaster = (width: number, height: number): boolean => {\n const targetCanvas = createCanvasElement();\n const sourceCanvas = createCanvasElement();\n const gl = sourceCanvas.getContext('webgl')!;\n // eslint-disable-next-line no-undef\n const imageBuffer = new ArrayBuffer(width * height * 4);\n\n const testContext = {\n imageBuffer: imageBuffer,\n } as unknown as Required;\n const testPipelineState = {\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas,\n } as unknown as TWebGLPipelineState;\n let startTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2D.call(\n testContext,\n gl,\n testPipelineState,\n );\n const drawImageTime = getFabricWindow().performance.now() - startTime;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(\n testContext,\n gl,\n testPipelineState,\n );\n const putImageDataTime = getFabricWindow().performance.now() - startTime;\n\n return drawImageTime > putImageDataTime;\n};\n","export const highPsourceCode = `precision highp float`;\n\nexport const identityFragmentShader = `\n ${highPsourceCode};\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }`;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }`;\n","import { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n T2DPipelineState,\n TWebGLAttributeLocationMap,\n TWebGLPipelineState,\n TWebGLProgramCacheItem,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport {\n highPsourceCode,\n identityFragmentShader,\n vertexSource,\n} from './shaders/baseFilter';\nimport type { Abortable } from '../typedefs';\nimport { FabricError } from '../util/internals/console';\n\nconst regex = new RegExp(highPsourceCode, 'g');\n\nexport class BaseFilter<\n Name extends string,\n OwnProps extends Record = object,\n> {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n get type(): Name {\n return (this.constructor as typeof BaseFilter).type as Name;\n }\n\n /**\n * The class type. Used to identify which class this is.\n * This is used for serialization purposes and internally it can be used\n * to identify classes. As a developer you could use `instance of Class`\n * but to avoid importing all the code and blocking tree shaking we try\n * to avoid doing that.\n */\n static type = 'BaseFilter';\n\n /**\n * Contains the uniform locations for the fragment shader.\n * uStepW and uStepH are handled by the BaseFilter, each filter class\n * needs to specify all the one that are needed\n */\n static uniformLocations: string[] = [];\n\n declare static defaults: Record;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor({\n type,\n ...options\n }: { type?: never } & Partial & Record = {}) {\n Object.assign(\n this,\n (this.constructor as typeof BaseFilter).defaults,\n options,\n );\n }\n\n protected getFragmentSource(): string {\n return identityFragmentShader;\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram(\n gl: WebGLRenderingContext,\n fragmentSource: string = this.getFragmentSource(),\n vertexSource: string = this.getVertexSource(),\n ) {\n const {\n WebGLProbe: { GLPrecision = 'highp' },\n } = getEnv();\n if (GLPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(\n regex,\n highPsourceCode.replace('highp', GLPrecision),\n );\n }\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n const program = gl.createProgram();\n\n if (!vertexShader || !fragmentShader || !program) {\n throw new FabricError(\n 'Vertex, fragment shader or program creation error',\n );\n }\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n vertexShader,\n )}`,\n );\n }\n\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n fragmentShader,\n )}`,\n );\n }\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new FabricError(\n `Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}`,\n );\n }\n\n const uniformLocations = this.getUniformLocations(gl, program) || {};\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n\n return {\n program,\n attributeLocations: this.getAttributeLocations(gl, program),\n uniformLocations,\n };\n }\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLAttributeLocationMap {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n }\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLUniformLocationMap {\n const locations = (this.constructor as unknown as typeof BaseFilter)\n .uniformLocations;\n\n const uniformLocations: Record = {};\n for (let i = 0; i < locations.length; i++) {\n uniformLocations[locations[i]] = gl.getUniformLocation(\n program,\n locations[i],\n );\n }\n return uniformLocations;\n }\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData(\n gl: WebGLRenderingContext,\n attributeLocations: Record,\n aPositionData: Float32Array,\n ) {\n const attributeLocation = attributeLocations.aPosition;\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n }\n\n _setupFrameBuffer(options: TWebGLPipelineState) {\n const gl = options.context;\n if (options.passes > 1) {\n const width = options.destinationWidth;\n const height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(\n gl,\n width,\n height,\n );\n }\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n options.targetTexture,\n 0,\n );\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n }\n\n _swapTextures(options: TWebGLPipelineState) {\n options.passes--;\n options.pass++;\n const temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n }\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isNeutralState(options?: any): boolean {\n return false;\n }\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(_options: T2DPipelineState): void {\n // override by subclass\n }\n\n /**\n * Returns a string that represent the current selected shader code for the filter.\n * Used to force recompilation when parameters change or to retrieve the shader from cache\n * @type string\n **/\n getCacheKey(): string {\n return this.type;\n }\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n * @return {WebGLProgram} the compiled program shader\n */\n retrieveShader(options: TWebGLPipelineState): TWebGLProgramCacheItem {\n const key = this.getCacheKey();\n if (!options.programCache[key]) {\n options.programCache[key] = this.createProgram(options.context);\n }\n return options.programCache[key];\n }\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context;\n const shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n bindAdditionalTexture(\n gl: WebGLRenderingContext,\n texture: WebGLTexture,\n textureUnit: number,\n ) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n }\n\n unbindAdditionalTexture(gl: WebGLRenderingContext, textureUnit: number) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n }\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program.\n * @param {Object} _uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData(\n _gl: WebGLRenderingContext,\n _uniformLocations: TWebGLUniformLocationMap,\n ): void {\n // override by subclass\n }\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer(options: T2DPipelineState) {\n if (!options.helpLayer) {\n const helpLayer = createCanvasElement();\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n }\n\n /**\n * Returns object representation of an instance\n * It will automatically export the default values of a filter,\n * stored in the static defaults property.\n * @return {Object} Object representation of an instance\n */\n toObject(): { type: Name } & OwnProps {\n const defaultKeys = Object.keys(\n (this.constructor as typeof BaseFilter).defaults || {},\n ) as (keyof OwnProps)[];\n\n return {\n type: this.type,\n ...defaultKeys.reduce((acc, key) => {\n acc[key] = this[\n key as keyof this\n ] as unknown as (typeof acc)[typeof key];\n return acc;\n }, {} as OwnProps),\n };\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n static async fromObject(\n { type, ...filterOptions }: Record,\n _options: Abortable,\n ): Promise> {\n return new this(filterOptions);\n }\n}\n","export const blendColorFragmentSource = {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen:\n 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion:\n 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: `\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n `,\n tint: `\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n `,\n} as const;\n","import { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { blendColorFragmentSource } from './shaders/blendColor';\n\nexport type TBlendMode =\n | 'multiply'\n | 'add'\n | 'difference'\n | 'screen'\n | 'subtract'\n | 'darken'\n | 'lighten'\n | 'overlay'\n | 'exclusion'\n | 'tint';\n\ntype BlendColorOwnProps = {\n color: string;\n mode: TBlendMode;\n alpha: number;\n};\n\nexport const blendColorDefaultValues: BlendColorOwnProps = {\n color: '#F95C63',\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Color Blend filter class\n * @example\n * const filter = new BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendColor extends BaseFilter<'BlendColor', BlendColorOwnProps> {\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n * @type String\n * @default\n **/\n declare color: BlendColorOwnProps['color'];\n\n /**\n * Blend mode for the filter: one of multiply, add, difference, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n * @type String\n * @default\n **/\n declare mode: BlendColorOwnProps['mode'];\n /**\n * alpha value. represent the strength of the blend color operation.\n * @type Number\n * @default\n **/\n declare alpha: BlendColorOwnProps['alpha'];\n\n static defaults = blendColorDefaultValues;\n\n static type = 'BlendColor';\n\n static uniformLocations = ['uColor'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n protected getFragmentSource(): string {\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ${blendColorFragmentSource[this.mode]}\n }\n }\n `;\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const source = new Color(this.color).getSource();\n const tr = source[0] * this.alpha;\n const tg = source[1] * this.alpha;\n const tb = source[2] * this.alpha;\n const alpha1 = 1 - this.alpha;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n break;\n case 'screen':\n data[i] = 255 - ((255 - r) * (255 - tr)) / 255;\n data[i + 1] = 255 - ((255 - g) * (255 - tg)) / 255;\n data[i + 2] = 255 - ((255 - b) * (255 - tb)) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] =\n tr < 128\n ? (2 * r * tr) / 255\n : 255 - (2 * (255 - r) * (255 - tr)) / 255;\n data[i + 1] =\n tg < 128\n ? (2 * g * tg) / 255\n : 255 - (2 * (255 - g) * (255 - tg)) / 255;\n data[i + 2] =\n tb < 128\n ? (2 * b * tb) / 255\n : 255 - (2 * (255 - b) * (255 - tb)) / 255;\n break;\n case 'exclusion':\n data[i] = tr + r - (2 * tr * r) / 255;\n data[i + 1] = tg + g - (2 * tg * g) / 255;\n data[i + 2] = tb + b - (2 * tb * b) / 255;\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource();\n source[0] = (this.alpha * source[0]) / 255;\n source[1] = (this.alpha * source[1]) / 255;\n source[2] = (this.alpha * source[2]) / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n }\n}\n\nclassRegistry.setClass(BlendColor);\n","import type { TBlendImageMode } from '../BlendImage';\n\nexport const fragmentSource: Record = {\n multiply: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n `,\n mask: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n `,\n} as const;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n ` as const;\n","import { FabricImage } from '../shapes/Image';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport type { WebGLFilterBackend } from './WebGLFilterBackend';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource, vertexSource } from './shaders/blendImage';\n\nexport type TBlendImageMode = 'multiply' | 'mask';\n\ntype BlendImageOwnProps = {\n mode: TBlendImageMode;\n alpha: number;\n};\n\nexport const blendImageDefaultValues: BlendImageOwnProps = {\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Image Blend filter class\n * @example\n * const filter = new filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendImage extends BaseFilter<'BlendImage', BlendImageOwnProps> {\n /**\n * Image to make the blend operation with.\n **/\n declare image: FabricImage;\n\n /**\n * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will\n * multiply the values of each channel (R, G, B, and A) of the filter image by\n * their corresponding values in the base image. 'mask' will only look at the\n * alpha channel of the filter image, and apply those values to the base\n * image's alpha channel.\n * @type String\n * @default\n **/\n declare mode: BlendImageOwnProps['mode'];\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n declare alpha: BlendImageOwnProps['alpha'];\n\n static type = 'BlendImage';\n\n static defaults = blendImageDefaultValues;\n\n static uniformLocations = ['uTransformMatrix', 'uImage'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource(): string {\n return fragmentSource[this.mode];\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture!, gl.TEXTURE1);\n super.applyToWebGL(options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n }\n\n createTexture(backend: WebGLFilterBackend, image: FabricImage) {\n return backend.getCachedTexture(image.cacheKey, image.getElement());\n }\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix() {\n const image = this.image,\n { width, height } = image.getElement();\n return [\n 1 / image.scaleX,\n 0,\n 0,\n 0,\n 1 / image.scaleY,\n 0,\n -image.left / width,\n -image.top / height,\n 1,\n ];\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({\n imageData: { data, width, height },\n filterBackend: { resources },\n }: T2DPipelineState) {\n const image = this.image;\n if (!resources.blendImage) {\n resources.blendImage = createCanvasElement();\n }\n const canvas1 = resources.blendImage;\n const context = canvas1.getContext('2d')!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(\n image.scaleX,\n 0,\n 0,\n image.scaleY,\n image.left,\n image.top,\n );\n context.drawImage(image.getElement(), 0, 0, width, height);\n const blendData = context.getImageData(0, 0, width, height).data;\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n const tr = blendData[i];\n const tg = blendData[i + 1];\n const tb = blendData[i + 2];\n const ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n data[i + 3] = (a * ta) / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n }\n\n /**\n * Returns object representation of an instance\n * TODO: Handle the possibility of missing image better.\n * As of now a BlendImage filter without image can't be used with fromObject\n * @return {Object} Object representation of an instance\n */\n toObject(): {\n type: 'BlendImage';\n image: ReturnType;\n } & BlendImageOwnProps {\n return {\n ...super.toObject(),\n image: this.image && this.image.toObject(),\n };\n }\n\n /**\n * Create filter instance from an object representation\n * @static\n * @param {object} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static async fromObject(\n { type, image, ...filterOptions }: Record,\n options: { signal: AbortSignal },\n ): Promise> {\n return FabricImage.fromObject(image, options).then(\n (enlivedImage) =>\n new this({ ...filterOptions, image: enlivedImage }) as BlendImage,\n );\n }\n}\n\nclassRegistry.setClass(BlendImage);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n ` as const;\n","import { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n TWebGLPipelineState,\n T2DPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/blur';\n\ntype BlurOwnProps = {\n blur: number;\n};\n\nexport const blurDefaultValues: BlurOwnProps = {\n blur: 0,\n};\n\n/**\n * Blur filter class\n * @example\n * const filter = new Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Blur extends BaseFilter<'Blur', BlurOwnProps> {\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range between 0 and 1.\n * @type Number\n * @default\n */\n declare blur: BlurOwnProps['blur'];\n\n declare horizontal: boolean;\n declare aspectRatio: number;\n\n static type = 'Blur';\n\n static defaults = blurDefaultValues;\n\n static uniformLocations = ['uDelta'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(options: T2DPipelineState) {\n options.imageData = this.simpleBlur(options);\n }\n\n simpleBlur({\n ctx,\n imageData,\n filterBackend: { resources },\n }: T2DPipelineState) {\n const { width, height } = imageData;\n if (!resources.blurLayer1) {\n resources.blurLayer1 = createCanvasElement();\n resources.blurLayer2 = createCanvasElement();\n }\n const canvas1 = resources.blurLayer1!;\n const canvas2 = resources.blurLayer2!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n const ctx1 = canvas1.getContext('2d')!,\n ctx2 = canvas2.getContext('2d')!,\n nSamples = 15,\n blur = this.blur * 0.06 * 0.5;\n let random, percent, j, i;\n\n // load first canvas\n ctx1.putImageData(imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n ctx.drawImage(canvas1, 0, 0);\n const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.uDelta, delta);\n }\n\n isNeutralState() {\n return this.blur === 0;\n }\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta() {\n let blurScale = 1;\n const delta = [0, 0];\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n const blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n return delta;\n }\n}\n\nclassRegistry.setClass(Blur);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/brightness';\n\ntype BrightnessOwnProps = {\n brightness: number;\n};\n\nexport const brightnessDefaultValues: BrightnessOwnProps = {\n brightness: 0,\n};\n\n/**\n * Brightness filter class\n * @example\n * const filter = new Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Brightness extends BaseFilter<'Brightness', BrightnessOwnProps> {\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n declare brightness: BrightnessOwnProps['brightness'];\n\n static type = 'Brightness';\n\n static defaults = brightnessDefaultValues;\n\n static uniformLocations = ['uBrightness'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const brightness = Math.round(this.brightness * 255);\n for (let i = 0; i < data.length; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n }\n\n isNeutralState() {\n return this.brightness === 0;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n }\n}\n\nclassRegistry.setClass(Brightness);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TMatColorMatrix,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/colorMatrix';\n\ntype ColorMatrixOwnProps = {\n matrix: TMatColorMatrix;\n colorsOnly: boolean;\n};\n\nexport const colorMatrixDefaultValues: ColorMatrixOwnProps = {\n matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\n colorsOnly: true,\n};\n\n/**\n * Color Matrix filter class\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo}\n * @example Kodachrome filter\n * const filter = new ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class ColorMatrix<\n Name extends string = 'ColorMatrix',\n OwnProps extends object = ColorMatrixOwnProps,\n> extends BaseFilter {\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n declare matrix: ColorMatrixOwnProps['matrix'];\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario\n * to save some calculation\n * @type Boolean\n * @default true\n */\n declare colorsOnly: ColorMatrixOwnProps['colorsOnly'];\n\n static type = 'ColorMatrix';\n\n static defaults = colorMatrixDefaultValues;\n\n static uniformLocations = ['uColorMatrix', 'uConstants'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n m = this.matrix,\n colorsOnly = this.colorsOnly;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n } else {\n const a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] =\n r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] =\n r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const m = this.matrix,\n matrix = [\n m[0],\n m[1],\n m[2],\n m[3],\n m[5],\n m[6],\n m[7],\n m[8],\n m[10],\n m[11],\n m[12],\n m[13],\n m[15],\n m[16],\n m[17],\n m[18],\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n }\n\n toObject() {\n return {\n ...super.toObject(),\n matrix: [...this.matrix] as TMatColorMatrix,\n };\n }\n}\n\nclassRegistry.setClass(ColorMatrix);\n","import { ColorMatrix } from './ColorMatrix';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TMatColorMatrix } from './typedefs';\n\ntype FixedFiltersOwnProps = {\n colorsOnly: boolean;\n};\n\nexport function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) {\n const newClass = class extends ColorMatrix {\n static type = key;\n\n static defaults = {\n colorsOnly: false,\n matrix,\n };\n\n //@ts-expect-error TS wants matrix to be exported.\n toObject(): { type: string } & FixedFiltersOwnProps {\n return { type: this.type, colorsOnly: this.colorsOnly };\n }\n };\n classRegistry.setClass(newClass, key);\n return newClass as typeof ColorMatrix;\n}\n\nexport const Brownie = createColorMatrixFilter(\n 'Brownie',\n [\n 0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449,\n 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Vintage = createColorMatrixFilter(\n 'Vintage',\n [\n 0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0,\n 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Kodachrome = createColorMatrixFilter(\n 'Kodachrome',\n [\n 1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0,\n 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Technicolor = createColorMatrixFilter(\n 'Technicolor',\n [\n 1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0,\n -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Polaroid = createColorMatrixFilter(\n 'Polaroid',\n [\n 1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016,\n 1.483, 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Sepia = createColorMatrixFilter(\n 'Sepia',\n [\n 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131,\n 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const BlackWhite = createColorMatrixFilter(\n 'BlackWhite',\n [\n 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0,\n 1, 0,\n ],\n);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLPipelineState } from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\n\ntype ComposedOwnProps = {\n subFilters: BaseFilter[];\n};\n\n/**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\nexport class Composed extends BaseFilter<'Composed', ComposedOwnProps> {\n /**\n * A non sparse array of filters to apply\n */\n declare subFilters: ComposedOwnProps['subFilters'];\n\n static type = 'Composed';\n\n constructor(\n options: { subFilters?: BaseFilter[] } & Record<\n string,\n any\n > = {},\n ) {\n super(options);\n this.subFilters = options.subFilters || [];\n }\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n options.passes += this.subFilters.length - 1;\n }\n this.subFilters.forEach((filter) => {\n filter.applyTo(options);\n });\n }\n\n /**\n * Serialize this filter into JSON.\n * @returns {Object} A JSON representation of this filter.\n */\n //@ts-expect-error TS doesn't like this toObject\n toObject(): {\n type: 'Composed';\n subFilters: ReturnType['toObject']>[];\n } {\n return {\n type: this.type,\n subFilters: this.subFilters.map((filter) => filter.toObject()),\n };\n }\n\n isNeutralState() {\n return !this.subFilters.some((filter) => !filter.isNeutralState());\n }\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n * @static\n * @param {oject} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject(\n object: Record,\n options: { signal: AbortSignal },\n ): Promise {\n return Promise.all(\n ((object.subFilters || []) as BaseFilter[]).map(\n (filter) =>\n classRegistry\n .getClass(filter.type)\n .fromObject(filter, options),\n ),\n ).then(\n (enlivedFilters) => new this({ subFilters: enlivedFilters }) as Composed,\n );\n }\n}\n\nclassRegistry.setClass(Composed);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/constrast';\n\ntype ContrastOwnProps = {\n contrast: number;\n};\n\nexport const contrastDefaultValues: ContrastOwnProps = {\n contrast: 0,\n};\n\n/**\n * Contrast filter class\n * @example\n * const filter = new Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Contrast extends BaseFilter<'Contrast', ContrastOwnProps> {\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n declare contrast: ContrastOwnProps['contrast'];\n\n static type = 'Contrast';\n\n static defaults = contrastDefaultValues;\n\n static uniformLocations = ['uContrast'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n isNeutralState() {\n return this.contrast === 0;\n }\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const contrast = Math.floor(this.contrast * 255),\n contrastF = (259 * (contrast + 255)) / (255 * (259 - contrast));\n\n for (let i = 0; i < data.length; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n }\n}\n\nclassRegistry.setClass(Contrast);\n","export const fragmentSource = {\n Convolute_3_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_3_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_5_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_5_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_7_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_7_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_9_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_9_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/convolute';\n\nexport type ConvoluteOwnProps = {\n opaque: boolean;\n matrix: number[];\n};\n\nexport const convoluteDefaultValues: ConvoluteOwnProps = {\n opaque: false,\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n};\n\n/**\n * Adapted from html5rocks article\n * @example Sharpen filter\n * const filter = new Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Blur filter\n * const filter = new Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter\n * const filter = new Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter with opaqueness\n * const filter = new Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Convolute extends BaseFilter<'Convolute', ConvoluteOwnProps> {\n /*\n * Opaque value (true/false)\n */\n declare opaque: ConvoluteOwnProps['opaque'];\n\n /*\n * matrix for the filter, max 9x9\n */\n declare matrix: ConvoluteOwnProps['matrix'];\n\n static type = 'Convolute';\n\n static defaults = convoluteDefaultValues;\n\n static uniformLocations = ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize'];\n\n getCacheKey() {\n return `${this.type}_${Math.sqrt(this.matrix.length)}_${\n this.opaque ? 1 : 0\n }` as keyof typeof fragmentSource;\n }\n\n getFragmentSource() {\n return fragmentSource[this.getCacheKey()];\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0;\n let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n }\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject() {\n return {\n ...super.toObject(),\n opaque: this.opaque,\n matrix: [...this.matrix],\n };\n }\n}\n\nclassRegistry.setClass(Convolute);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/gamma';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nconst GAMMA = 'Gamma' as const;\n\nexport type GammaInput = [number, number, number];\n\nexport type GammaOwnProps = {\n gamma: GammaInput;\n};\n\nexport const gammaDefaultValues: GammaOwnProps = {\n gamma: [1, 1, 1],\n};\n\n/**\n * Gamma filter class\n * @example\n * const filter = new Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Gamma extends BaseFilter {\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n declare gamma: GammaOwnProps['gamma'];\n declare rgbValues?: {\n r: Uint8Array;\n g: Uint8Array;\n b: Uint8Array;\n };\n\n static type = GAMMA;\n\n static defaults = gammaDefaultValues;\n\n static uniformLocations = ['uGamma'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n constructor(options: { gamma?: GammaInput } = {}) {\n super(options);\n this.gamma =\n options.gamma ||\n ((\n this.constructor as typeof Gamma\n ).defaults.gamma.concat() as GammaInput);\n }\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const gamma = this.gamma,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2];\n\n if (!this.rgbValues) {\n this.rgbValues = {\n r: new Uint8Array(256),\n g: new Uint8Array(256),\n b: new Uint8Array(256),\n };\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n const rgb = this.rgbValues;\n for (let i = 0; i < 256; i++) {\n rgb.r[i] = Math.pow(i / 255, rInv) * 255;\n rgb.g[i] = Math.pow(i / 255, gInv) * 255;\n rgb.b[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (let i = 0; i < data.length; i += 4) {\n data[i] = rgb.r[data[i]];\n data[i + 1] = rgb.g[data[i + 1]];\n data[i + 2] = rgb.b[data[i + 2]];\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n }\n\n isNeutralState() {\n const { gamma } = this;\n return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1;\n }\n\n toObject(): { type: typeof GAMMA; gamma: GammaInput } {\n return {\n type: GAMMA,\n gamma: this.gamma.concat() as GammaInput,\n };\n }\n}\n\nclassRegistry.setClass(Gamma);\n","import type { TGrayscaleMode } from '../Grayscale';\n\nexport const fragmentSource: Record = {\n average: `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n `,\n lightness: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n luminosity: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/grayscale';\n\nexport type TGrayscaleMode = 'average' | 'lightness' | 'luminosity';\n\ntype GrayscaleOwnProps = {\n mode: TGrayscaleMode;\n};\n\nexport const grayscaleDefaultValues: GrayscaleOwnProps = {\n mode: 'average',\n};\n\n/**\n * Grayscale image filter class\n * @example\n * const filter = new Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Grayscale extends BaseFilter<'Grayscale', GrayscaleOwnProps> {\n declare mode: TGrayscaleMode;\n\n static type = 'Grayscale';\n\n static defaults = grayscaleDefaultValues;\n\n static uniformLocations = ['uMode'];\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0, value: number; i < data.length; i += 4) {\n switch (this.mode) {\n case 'average':\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n break;\n case 'lightness':\n value =\n (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) /\n 2;\n break;\n case 'luminosity':\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n break;\n }\n\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n }\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource() {\n return fragmentSource[this.mode];\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n }\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState() {\n return false;\n }\n}\n\nclassRegistry.setClass(Grayscale);\n","import { cos } from '../util/misc/cos';\nimport { sin } from '../util/misc/sin';\nimport { ColorMatrix } from './ColorMatrix';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\n\nexport type HueRotationOwnProps = {\n rotation: number;\n};\n\nexport const hueRotationDefaultValues: HueRotationOwnProps = {\n rotation: 0,\n};\n\n/**\n * HueRotation filter class\n * @example\n * const filter = new HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class HueRotation extends ColorMatrix<\n 'HueRotation',\n HueRotationOwnProps\n> {\n /**\n * HueRotation value, from -1 to 1.\n */\n declare rotation: HueRotationOwnProps['rotation'];\n\n static type = 'HueRotation';\n\n static defaults = hueRotationDefaultValues;\n\n calculateMatrix() {\n const rad = this.rotation * Math.PI,\n cosine = cos(rad),\n sine = sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sine,\n OneMinusCos = 1 - cosine;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\n this.matrix[0] = cosine + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cosine + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cosine + aThird * OneMinusCos;\n }\n\n isNeutralState() {\n return this.rotation === 0;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n this.calculateMatrix();\n super.applyTo(options);\n }\n\n //@ts-expect-error TS and classes with different methods\n toObject(): { type: 'HueRotation'; rotation: number } {\n return {\n type: this.type,\n rotation: this.rotation,\n };\n }\n}\n\nclassRegistry.setClass(HueRotation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/invert';\n\nexport type InvertOwnProps = {\n alpha: boolean;\n invert: boolean;\n};\n\nexport const invertDefaultValues: InvertOwnProps = {\n alpha: false,\n invert: true,\n};\n\n/**\n * @example\n * const filter = new Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Invert extends BaseFilter<'Invert', InvertOwnProps> {\n /**\n * Invert also alpha.\n * @param {Boolean} alpha\n * @default\n **/\n declare alpha: InvertOwnProps['alpha'];\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n declare invert: InvertOwnProps['invert'];\n\n static type = 'Invert';\n\n static defaults = invertDefaultValues;\n\n static uniformLocations = ['uInvert', 'uAlpha'];\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0; i < data.length; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n\n if (this.alpha) {\n data[i + 3] = 255 - data[i + 3];\n }\n }\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState() {\n return !this.invert;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1i(uniformLocations.uInvert, Number(this.invert));\n gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha));\n }\n}\n\nclassRegistry.setClass(Invert);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/noise';\n\nexport type NoiseOwnProps = {\n noise: number;\n};\n\nexport const noiseDefaultValues: NoiseOwnProps = {\n noise: 0,\n};\n\n/**\n * Noise filter class\n * @example\n * const filter = new Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Noise extends BaseFilter<'Noise', NoiseOwnProps> {\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n declare noise: NoiseOwnProps['noise'];\n\n static type = 'Noise';\n\n static defaults = noiseDefaultValues;\n\n static uniformLocations = ['uNoise', 'uSeed'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const noise = this.noise;\n for (let i = 0; i < data.length; i += 4) {\n const rand = (0.5 - Math.random()) * noise;\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n }\n\n isNeutralState() {\n return this.noise === 0;\n }\n}\n\nclassRegistry.setClass(Noise);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/pixelate';\n\nexport type PixelateOwnProps = {\n blocksize: number;\n};\n\nexport const pixelateDefaultValues: PixelateOwnProps = {\n blocksize: 4,\n};\n\n/**\n * Pixelate filter class\n * @example\n * const filter = new Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Pixelate extends BaseFilter<'Pixelate', PixelateOwnProps> {\n declare blocksize: PixelateOwnProps['blocksize'];\n\n static type = 'Pixelate';\n\n static defaults = pixelateDefaultValues;\n\n static uniformLocations = ['uBlocksize'];\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data, width, height } }: T2DPipelineState) {\n for (let i = 0; i < height; i += this.blocksize) {\n for (let j = 0; j < width; j += this.blocksize) {\n const index = i * 4 * width + j * 4;\n const r = data[index];\n const g = data[index + 1];\n const b = data[index + 2];\n const a = data[index + 3];\n\n for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) {\n for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) {\n const index = _i * 4 * width + _j * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n }\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState() {\n return this.blocksize === 1;\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n }\n}\n\nclassRegistry.setClass(Pixelate);\n","export const fragmentShader = `\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n`;\n","import { classRegistry } from '../ClassRegistry';\nimport { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport { fragmentShader } from './shaders/removeColor';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nexport type RemoveColorOwnProps = {\n color: string;\n distance: number;\n useAlpha: boolean;\n};\n\nexport const removeColorDefaultValues: RemoveColorOwnProps = {\n color: '#FFFFFF',\n distance: 0.02,\n useAlpha: false,\n};\n\n/**\n * Remove white filter class\n * @example\n * const filter = new RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class RemoveColor extends BaseFilter<\n 'RemoveColor',\n RemoveColorOwnProps\n> {\n /**\n * Color to remove, in any format understood by {@link Color}.\n * @param {String} type\n * @default\n */\n declare color: RemoveColorOwnProps['color'];\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n declare distance: RemoveColorOwnProps['distance'];\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n declare useAlpha: RemoveColorOwnProps['useAlpha'];\n\n static type = 'RemoveColor';\n\n static defaults = removeColorDefaultValues;\n\n static uniformLocations = ['uLow', 'uHigh'];\n\n getFragmentSource() {\n return fragmentShader;\n }\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const distance = this.distance * 255,\n source = new Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n if (\n r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]\n ) {\n data[i + 3] = 0;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource(),\n distance = this.distance,\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1,\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1,\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n }\n}\n\nclassRegistry.setClass(RemoveColor);\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { XY } from '../Point';\n\nexport type TResizeType = 'bilinear' | 'hermite' | 'sliceHack' | 'lanczos';\n\nexport type ResizeOwnProps = {\n resizeType: TResizeType;\n scaleX: number;\n scaleY: number;\n lanczosLobes: number;\n};\n\nexport const resizeDefaultValues: ResizeOwnProps = {\n resizeType: 'hermite',\n scaleX: 1,\n scaleY: 1,\n lanczosLobes: 3,\n};\n\ntype ResizeDuring2DResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n};\n\ntype ResizeDuringWEBGLResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n horizontal: boolean;\n width: number;\n height: number;\n taps: number[];\n tempScale: number;\n dH: number;\n dW: number;\n};\n\n/**\n * Resize image filter class\n * @example\n * const filter = new Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Resize extends BaseFilter<'Resize', ResizeOwnProps> {\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @default\n */\n declare resizeType: ResizeOwnProps['resizeType'];\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n declare scaleX: ResizeOwnProps['scaleX'];\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n declare scaleY: ResizeOwnProps['scaleY'];\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n declare lanczosLobes: ResizeOwnProps['lanczosLobes'];\n\n static type = 'Resize';\n\n static defaults = resizeDefaultValues;\n\n static uniformLocations = ['uDelta', 'uTaps'];\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n this: ResizeDuringWEBGLResize,\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform2fv(\n uniformLocations.uDelta,\n this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height],\n );\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n }\n\n getFilterWindow(this: ResizeDuringWEBGLResize) {\n const scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n }\n\n getCacheKey(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return `${this.type}_${filterWindow}`;\n }\n\n getFragmentSource(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return this.generateShader(filterWindow);\n }\n\n getTaps(this: ResizeDuringWEBGLResize) {\n const lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n }\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader(filterWindow: number) {\n const offsets = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = `${i}.0 * uDelta`;\n }\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[${filterWindow}];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ${offsets\n .map(\n (offset, i) => `\n color += texture2D(uTexture, vTexCoord + ${offset}) * uTaps[${i}] + texture2D(uTexture, vTexCoord - ${offset}) * uTaps[${i}];\n sum += 2.0 * uTaps[${i}];\n `,\n )\n .join('\\n')}\n gl_FragColor = color / sum;\n }\n `;\n }\n\n applyToForWebgl(this: ResizeDuringWEBGLResize, options: TWebGLPipelineState) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n super.applyTo(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n super.applyTo(options);\n options.sourceHeight = options.destinationHeight;\n }\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n (this as unknown as ResizeDuringWEBGLResize).applyToForWebgl(options);\n } else {\n (this as unknown as ResizeDuring2DResize).applyTo2d(options);\n }\n }\n\n isNeutralState() {\n return this.scaleX === 1 && this.scaleY === 1;\n }\n\n lanczosCreate(lobes: number) {\n return (x: number) => {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.1920929e-7 && x > -1.1920929e-7) {\n return 1.0;\n }\n x *= Math.PI;\n const xx = x / lobes;\n return ((Math.sin(x) / x) * Math.sin(xx)) / xx;\n };\n }\n\n applyTo2d(this: ResizeDuring2DResize, options: T2DPipelineState) {\n const imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n const oW = imageData.width;\n const oH = imageData.height;\n const dW = Math.round(oW * scaleX);\n const dH = Math.round(oH * scaleY);\n let newData: ImageData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n } else {\n // this should never trigger, is here just for safety net.\n newData = new ImageData(dW, dH);\n }\n options.imageData = newData;\n }\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo(\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const imageData = options.imageData;\n const mult = 0.5;\n let doneW = false;\n let doneH = false;\n let stepW = oW * mult;\n let stepH = oH * mult;\n const resources = options.filterBackend.resources;\n let sX = 0;\n let sY = 0;\n const dX = oW;\n let dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = createCanvasElement();\n }\n const tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n const ctx = tmpCanvas.getContext('2d')!;\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = Math.floor(dW);\n dH = Math.floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < Math.floor(stepW * mult)) {\n stepW = Math.floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n if (dH < Math.floor(stepH * mult)) {\n stepH = Math.floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n }\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ): ImageData {\n function process(u: number): ImageData {\n let v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = Math.floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = Math.floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = Math.floor(1000 * Math.abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = Math.floor(1000 * Math.abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(\n Math.sqrt(\n Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2),\n ) / 1000,\n );\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n } else {\n return destImg;\n }\n }\n\n const srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = Math.ceil((ratioX * this.lanczosLobes) / 2),\n range2Y = Math.ceil((ratioY * this.lanczosLobes) / 2),\n cacheLanc: Record> = {},\n center: XY = { x: 0, y: 0 },\n icenter: XY = { x: 0, y: 0 };\n\n return process(0);\n }\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n let a;\n let b;\n let c;\n let d;\n let x;\n let y;\n let i;\n let j;\n let xDiff;\n let yDiff;\n let chnl;\n let color;\n let offset = 0;\n let origPix;\n const ratioX = this.rcpScaleX;\n const ratioY = this.rcpScaleY;\n const w4 = 4 * (oW - 1);\n const img = options.imageData;\n const pixels = img.data;\n const destImage = options.ctx.createImageData(dW, dH);\n const destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = Math.floor(ratioX * j);\n y = Math.floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color =\n a * (1 - xDiff) * (1 - yDiff) +\n b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) +\n d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n }\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = Math.ceil(ratioW / 2),\n ratioHHalf = Math.ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n for (let j = 0; j < dH; j++) {\n for (let i = 0; i < dW; i++) {\n const x2 = (i + j * dW) * 4;\n let weight = 0;\n let weights = 0;\n let weightsAlpha = 0;\n let gxR = 0;\n let gxG = 0;\n let gxB = 0;\n let gxA = 0;\n const centerY = (j + 0.5) * ratioH;\n for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW,\n w0 = dy * dy;\n for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf;\n const w = Math.sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = (weight * data[dx + 3]) / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n }\n}\n\nclassRegistry.setClass(Resize);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/saturation';\n\nexport type SaturationOwnProps = {\n saturation: number;\n};\n\nexport const saturationDefaultValues: SaturationOwnProps = {\n saturation: 0,\n};\n\n/**\n * Saturate filter class\n * @example\n * const filter = new Saturation({\n * saturation: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Saturation extends BaseFilter<'Saturation', SaturationOwnProps> {\n /**\n * Saturation value, from -1 to 1.\n * Increases/decreases the color saturation.\n * A value of 0 has no effect.\n *\n * @param {Number} saturation\n * @default\n */\n declare saturation: SaturationOwnProps['saturation'];\n\n static type = 'Saturation';\n\n static defaults = saturationDefaultValues;\n\n static uniformLocations = ['uSaturation'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.saturation;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n }\n\n isNeutralState() {\n return this.saturation === 0;\n }\n}\n\nclassRegistry.setClass(Saturation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/vibrance';\n\nexport type VibranceOwnProps = {\n vibrance: number;\n};\n\nexport const vibranceDefaultValues: VibranceOwnProps = {\n vibrance: 0,\n};\n\n/**\n * Vibrance filter class\n * @example\n * const filter = new Vibrance({\n * vibrance: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Vibrance extends BaseFilter<'Vibrance', VibranceOwnProps> {\n /**\n * Vibrance value, from -1 to 1.\n * Increases/decreases the saturation of more muted colors with less effect on saturated colors.\n * A value of 0 has no effect.\n *\n * @param {Number} vibrance\n * @default\n */\n declare vibrance: VibranceOwnProps['vibrance'];\n\n static type = 'Vibrance';\n\n static defaults = vibranceDefaultValues;\n\n static uniformLocations = ['uVibrance'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.vibrance;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;\n const amt = ((Math.abs(max - avg) * 2) / 255) * adjust;\n data[i] += max !== data[i] ? (max - data[i]) * amt : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uVibrance, -this.vibrance);\n }\n\n isNeutralState() {\n return this.vibrance === 0;\n }\n}\n\nclassRegistry.setClass(Vibrance);\n"],"names":["BaseConfiguration","constructor","_defineProperty","window","devicePixelRatio","Configuration","config","configure","arguments","length","undefined","Object","assign","addFonts","paths","fontPaths","_objectSpread","removeFonts","fontFamilys","forEach","fontFamily","clearFonts","restoreDefaults","keys","defaults","reduce","acc","key","log","severity","_len","optionalParams","Array","_key","console","FabricError","Error","message","options","concat","SignalAbortedError","context","GLProbe","WebGLProbe","testPrecision","gl","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","queryWebGL","canvas","getContext","maxTextureSize","getParameter","MAX_TEXTURE_SIZE","GLPrecision","find","getExtension","loseContext","isSupported","textureSize","copyPasteData","getEnv","document","isTouchSupported","navigator","maxTouchPoints","dispose","env","setEnv","value","getBrowserEnv","getFabricDocument","getFabricWindow","getDevicePixelRatio","_config$devicePixelRa","Math","max","Cache","getFontCache","_ref","fontStyle","fontWeight","toLowerCase","charWidthsCache","fontCache","cacheKey","clearFontCache","limitDimsByArea","ar","perfLimitSizeTotal","roughWidth","sqrt","floor","cache","VERSION","version","noop","halfPI","PI","twoMathPi","PiBy180","iMatrix","freeze","DEFAULT_SVG_FONT_SIZE","ALIASING_LIMIT","kRect","CENTER","LEFT","TOP","BOTTOM","RIGHT","NONE","reNewline","MOVING","SCALING","ROTATING","ROTATE","SKEWING","RESIZING","MODIFY_POLY","MODIFY_PATH","CHANGED","SCALE","SCALE_X","SCALE_Y","SKEW_X","SKEW_Y","FILL","STROKE","MODIFIED","JSON","SVG","ClassRegistry","Map","has","classType","getClass","get","setClass","classConstructor","set","type","getSVGClass","SVGTagName","setSVGClass","classRegistry","AnimationRegistry","remove","index","indexOf","splice","cancelAll","animations","animation","abort","cancelByCanvas","filter","_animation$target","target","cancelByTarget","runningAnimations","Observable","on","arg0","handler","__eventListeners","entries","eventName","off","push","once","disposers","_ref2","d","disposer","onceHandler","args","call","_removeEventListener","eventListener","_ref3","fire","_this$__eventListener","listenersForEvent","i","removeFromArray","array","idx","cos","angle","angleSlice","abs","sin","sign","Point","y","x","add","that","addEquals","scalarAdd","scalar","scalarAddEquals","subtract","subtractEquals","scalarSubtract","scalarSubtractEquals","multiply","scalarMultiply","scalarMultiplyEquals","divide","scalarDivide","scalarDivideEquals","eq","lt","lte","gt","gte","lerp","t","min","distanceFrom","dx","dy","midPointFrom","toString","setXY","setX","setY","setFromPoint","swap","clone","rotate","radians","origin","ZERO","sinus","cosinus","p","rotated","transform","ignoreOffset","isCollection","fabricObject","isArray","_objects","createCollectionMixin","Base","Collection","_onObjectAdded","object","_onObjectRemoved","_onStackOrderChanged","objects","size","insertAt","_len2","_key2","removed","_len3","_key3","forEachObject","callback","getObjects","_len4","types","_key4","o","isType","item","isEmpty","contains","deep","includes","some","obj","complexity","memo","current","sendObjectToBack","unshift","bringObjectToFront","sendObjectBackwards","intersecting","newIdx","findNewLowerIndex","bringObjectForward","findNewUpperIndex","moveObjectTo","isOverlapping","collectObjects","left","top","width","height","includeIntersecting","tl","br","selectable","visible","intersectsWithRect","isContainedWithinRect","containsPoint","CommonMethods","_setOptions","prop","_setObject","_set","toggle","property","requestAnimFrame","requestAnimationFrame","cancelAnimFrame","handle","cancelAnimationFrame","id","uid","createCanvasElement","element","createElement","createImage","copyCanvasElement","_newCanvas$getContext","newCanvas","drawImage","toDataURL","canvasEl","format","quality","isHTMLCanvas","degreesToRadians","degrees","radiansToDegrees","isIdentityMatrix","mat","every","transformPoint","invertTransform","a","r","multiplyTransformMatrices","b","is2x2","multiplyTransformMatrixArray","matrices","reduceRight","product","curr","calcPlaneRotation","atan2","qrDecompose","denom","pow","scaleX","scaleY","skewX","skewY","translateX","translateY","createTranslateMatrix","createRotateMatrix","angleRadiant","cosValue","sinValue","createScaleMatrix","angleToSkew","tan","createSkewXMatrix","skewValue","createSkewYMatrix","calcDimensionsMatrix","flipX","flipY","matrix","composeMatrix","scaleMatrix","loadImage","url","signal","crossOrigin","Promise","resolve","reject","aborted","img","err","src","addEventListener","done","onload","onerror","removeEventListener","enlivenObjects","reviver","instances","all","map","fromObject","then","fabricInstance","catch","error","instance","finally","enlivenObjectEnlivables","serializedObject","promises","values","enlived","pick","source","pickBy","predicate","ColorNameMap","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","reRGBa","reHSLa","reHex","hue2rgb","q","rgb2Hsl","g","maxValue","minValue","h","s","l","round","fromAlphaToFloat","parseFloat","endsWith","hexify","toUpperCase","padStart","greyAverage","avg","Color","color","setSource","_source","_tryParsingColor","sourceFromHex","sourceFromRgb","sourceFromHsl","isUnrecognised","getSource","toRgb","toRgba","join","toHsl","toHsla","toHex","fullHex","toHexa","slice","getAlpha","setAlpha","alpha","toGrayscale","toBlackWhite","threshold","average","bOrW","overlayWith","otherColor","otherAlpha","otherSource","R","G","B","fromRgb","fromRgba","match","parsedValue","fromHsl","fromHsla","match1degrees","parseAngletoDegrees","fromHex","isShortNotation","expandedValue","split","hex","hexCouple","parseInt","lowercase","numeric","toFixed","number","fractionDigits","Number","getSvgAttributes","commonAttributes","parseUnit","fontSize","unit","exec","dpi","DPI","parseAlign","align","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","alignX","alignY","meetOrSlice","matrixToSVG","NUM_FRACTION_DIGITS","colorPropToSVG","inlineStyle","colorValue","opacityValue","toLive","opacity","createSVGRect","svgColor","w","isFiller","filler","isSerializableFiller","toObject","isPattern","offsetX","isTextObject","_renderText","isPath","_renderPathCommands","isActiveSelection","getScrollLeftTop","doc","getDocumentFromElement","elementLoop","docElement","documentElement","body","scrollLeft","scrollTop","parentNode","host","nodeType","style","position","el","ownerDocument","getWindowFromElement","_el$ownerDocument","defaultView","setCanvasDimensions","ctx","retinaScaling","setAttribute","scale","setCSSDimensions","getElementOffset","_getWindowFromElement","offset","elemStyle","getComputedStyle","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","box","docElem","getBoundingClientRect","scrollLeftTop","clientLeft","clientTop","makeElementUnselectable","onselectstart","userSelect","StaticCanvasDOMManager","createLowerCanvas","lower","getElementById","hasAttribute","_originalCanvasStyle","cssText","classList","cleanupDOM","removeAttribute","setDimensions","calcOffset","staticCanvasDefaults","backgroundVpt","backgroundColor","overlayVpt","overlayColor","includeDefaultValues","svgViewportTransformation","renderOnAddRemove","skipOffscreen","enableRetinaScaling","imageSmoothingEnabled","controlsAboveOverlay","allowTouchScrolling","viewportTransform","StaticCanvas","lowerCanvasEl","_this$elements$lower","elements","contextContainer","_this$elements$lower2","getDefaults","ownDefaults","initElements","_setDimensionsImpl","skipControlsDrawing","calcViewportBoundaries","requestRenderAll","setCoords","getRetinaScaling","_offset","getWidth","getHeight","setWidth","setHeight","dimensions","cssOnly","backstoreOnly","hasLostContext","getZoom","setViewportTransform","vpt","zoomToPoint","point","before","newPoint","after","setZoom","absolutePan","relativePan","getElement","clearContext","clearRect","clear","backgroundImage","overlayImage","renderAll","cancelRequestedRender","destroyed","renderCanvas","renderAndReset","nextRenderHandle","disposed","iVpt","vptCoords","tr","bl","drawControls","_ctx","v","path","clipPath","patternQuality","_renderBackground","save","_renderObjects","restore","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","__cleanupTask","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","len","render","_renderBackgroundOrOverlay","fill","needsVpt","isAFiller","beginPath","moveTo","lineTo","closePath","fillStyle","offsetY","m","gradientTransform","patternTransform","getCenter","getCenterPoint","centerObjectH","_centerObject","centerObjectV","centerObject","viewportCenterObject","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","center","toDatalessJSON","propertiesToInclude","toDatalessObject","_toObjectMethod","toJSON","methodName","clipPathData","excludeFromExport","_toObject","__serializeBgOverlay","originalValue","data","bgImage","bgColor","background","overlay","toSVG","markup","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","optViewBox","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","additionalTransform","fontList","styles","styleRow","fontListMarkup","_setSVGObject","bgOrOverlay","repeat","finalWidth","finalHeight","shouldInvert","loadFromJSON","json","serialized","parse","enlivedMap","properties","cloneWithoutData","multiplier","finalMultiplier","toCanvasElement","scaledWidth","scaledHeight","zoom","originalWidth","originalHeight","originalSkipControlsDrawing","newZoom","vp","newVp","originalRetina","objectsToRender","task","destroy","kill","touchEvents","getTouchInfo","event","touchProp","changedTouches","getPointer","scroll","_evt","clientX","clientY","isTouchEvent","pointerType","stopEvent","e","preventDefault","stopPropagation","makeBoundingBoxFromPoints","points","removeTransformFromObject","inverted","finalTransform","calcOwnMatrix","applyTransformToObject","addTransformToObject","_qrDecompose","otherOptions","_objectWithoutProperties","_excluded","setPositionByOrigin","resetObjectTransform","saveObjectTransform","sizeAfterTransform","dimX","dimY","bbox","calcPlaneChangeMatrix","from","to","sendPointToPlane","sendVectorToPlane","sendObjectToPlane","fireEvent","_target$canvas","originOffset","bottom","right","resolveOrigin","originValue","NOT_ALLOWED_CURSOR","getActionFromCorner","alreadySelected","corner","control","controls","getActionName","isTransformCentered","originX","originY","invertOrigin","isLocked","lockingKey","commonEventInfo","eventData","pointer","findCornerQuadrant","getTotalAngle","cornerAngle","normalizePoint","getRelativeCenterPoint","translateToGivenOrigin","p2","getLocalPoint","padding","localPoint","dragHandler","newLeft","newTop","moveX","moveY","FabricObjectSVGExportMixin","getSvgStyles","skipShadow","fillRule","strokeWidth","strokeDashArray","strokeDashOffset","strokeLineCap","strokeLineJoin","strokeMiterLimit","visibility","getSvgFilter","stroke","shadow","getSvgCommons","getSvgTransform","full","calcTransformMatrix","svgTransform","_toSVG","_reviver","_createBaseSVGMarkup","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","withShadow","styleInfo","shadowInfo","vectorEffect","strokeUniform","absoluteClipPath","absolutePositioned","clipPathMarkup","addPaintOrder","paintFirst","getSvgRegex","arr","RegExp","reNum","String","raw","_templateObject","_taggedTemplateLiteral","svgNS","reFontDeclaration","svgValidTagNames","svgViewBoxElements","svgInvalidAncestors","svgValidParents","attributesMap","cx","cy","display","fSize","cPath","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgValidParentsRegEx","reViewBoxAttrValue","unitVectorX","zero","rotateVector","vector","createVector","magnitude","calcAngleBetweenVectors","crossProduct","dotProduct","calcVectorRotation","getUnitVector","getOrthonormalVector","counterClockwise","isBetweenVectors","AxB","AxT","BxT","shadowOffsetRegex","reOffsetsAndBlur","shadowDefaultValues","blur","affectStroke","nonScaling","Shadow","parseShadow","shadowStr","replace","BLUR_BOX","fBoxX","fBoxY","capValue","stateProperties","cacheProperties","fabricObjectDefaultValues","minScaleLimit","objectCaching","centeredRotation","centeredScaling","dirty","interactiveObjectDefaultValues","noScaleCache","lockMovementX","lockMovementY","lockRotation","lockScalingX","lockScalingY","lockSkewingX","lockSkewingY","lockScalingFlip","cornerSize","touchCornerSize","transparentCorners","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","hasControls","borderColor","borderDashArray","borderOpacityWhenMoving","borderScaleFactor","hasBorders","selectionBackgroundColor","evented","perPixelTargetFind","activeOn","hoverCursor","moveCursor","normalize","c","asin","elastic","defaultEasing","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","normA","normS","normP","easeOutElastic","normC","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeOutBounce","easeInBounce","easeInOutBounce","easeInQuad","easeOutQuad","easeInOutQuad","defaultAbort","AnimationBase","startValue","byValue","duration","delay","easing","onStart","onChange","onComplete","tick","bind","_onStart","_onChange","_onComplete","_abort","endValue","calculate","state","_state","isDone","start","firstTick","timestamp","startTime","Date","register","setTimeout","durationMs","boundDurationMs","durationProgress","valueProgress","unregister","ValueAnimation","timeElapsed","ArrayAnimation","defaultColorEasing","wrapColorCallback","rgba","ColorAnimation","startColor","endColor","isArrayAnimation","animate","animateColor","Intersection","status","append","isPointContained","T","A","infinite","AB","AT","isPointInPolygon","other","hits","inter","intersectSegmentSegment","intersectLineLine","a1","a2","b1","b2","aInfinite","bInfinite","a2xa1x","a2ya1y","b2xb1x","b2yb1y","a1xb1x","a1yb1y","uaT","ubT","uB","ua","ub","segmentsCoincide","intersectSegmentLine","s1","s2","l1","l2","intersectLinePolygon","result","intersectSegmentPolygon","intersectPolygonPolygon","points1","points2","coincidences","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","ObjectGeometry","getX","getXY","getY","getRelativeX","setRelativeX","getRelativeY","setRelativeY","relativePosition","getRelativeXY","group","setRelativeXY","isStrokeAccountedForInDimensions","getCoords","aCoords","calcACoords","coords","intersection","intersectsWithObject","isContainedWithinObject","getBoundingRect","isOnScreen","isPartiallyOnScreen","allPointsAreOutside","getScaledWidth","_getTransformedDimensions","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","getCanvasRetinaScaling","_this$canvas","getViewportTransform","_this$canvas2","rotateMatrix","tMatrix","finalMatrix","dim","transformMatrixKey","skipGroup","prefix","matrixCache","ownMatrixCache","_getNonTransformedDimensions","_calculateCurrentDimensions","dimOptions","preScalingStrokeValue","postScalingStrokeValue","noSkew","finalDimensions","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","translateToOriginPoint","relCenter","getPointByOrigin","pos","_getLeftTopCoords","FabricObject","name","setOptions","_createCacheCanvas","_cacheContext","_updateCacheCanvas","_limitCacheSize","dims","maxCacheSideLimit","minCacheSideLimit","limX","limY","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","minCacheSize","dimensionsChanged","zoomChanged","drawingWidth","drawingHeight","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","sizeShrinking","getHeightOfLine","ceil","setTransform","translate","needFullTransform","contextTop","getObjectScaling","retina","getObjectOpacity","_constrainScale","isChanged","parent","isNotVisible","_setupCompositeOperation","drawSelectionBackground","_setOpacity","_setShadow","drawCacheOnCanvas","_removeCacheCanvas","drawObject","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","isOnACache","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_render","_drawClipPath","skipCanvas","fillRect","_removeShadow","globalAlpha","_setStrokeStyles","decl","lineWidth","lineCap","lineDashOffset","lineJoin","miterLimit","gradientUnits","_applyPatternForTransformedGradient","strokeStyle","_applyPatternGradientTransform","_setFillStyles","_setLineDash","dashArray","setLineDash","sx","sy","multX","multY","scaling","shadowColor","shadowBlur","browserShadowBlurConstant","shadowOffsetX","shadowOffsetY","_renderPaintInOrder","_renderStroke","_renderFill","_pCtx$createPattern","pCanvas","pCtx","createPattern","_findCenterFromElement","objectForm","cloneAsImage","ImageClass","origParams","originalGroup","originalShadow","canvasProvider","withoutTransform","withoutShadow","boundingRect","shadowOffset","originalCanvas","setOnGroup","animatable","_animate","propIsColor","colorProperties","animationOptions","isDescendantOf","getAncestors","ancestors","findCommonAncestors","fork","otherFork","common","otherAncestors","ancestor","j","hasCommonAncestors","commonAncestors","isInFrontOf","ancestorData","firstCommonAncestor","headOfFork","pop","headOfOtherFork","thisIndex","otherIndex","propertiesToSerialize","customProperties","toFixedBound","val","_removeDefaultValues","hasStaticDefaultValues","baseValues","getPrototypeOf","baseValue","_fromObject","serializedObjectOptions","_ref4","extraParam","_excluded2","enlivedObjectOptions","wrapWithFireEvent","actionHandler","extraEventInfo","actionPerformed","wrapWithFixedAnchor","centerPoint","constraint","changeObjectWidth","strokePadding","oldWidth","newWidth","changeWidth","renderCircleControl","styleOverride","xSize","sizeX","ySize","sizeY","myLeft","myTop","arc","renderSquareControl","xSizeBy2","ySizeBy2","strokeRect","Control","shouldActivate","controlKey","_fabricObject$canvas","getActiveObject","isControlVisible","getActionHandler","getMouseDownHandler","mouseDownHandler","getMouseUpHandler","mouseUpHandler","cursorStyleHandler","cursorStyle","actionName","getVisibility","_fabricObject$_contro","_fabricObject$_contro2","_controlsVisibility","setVisibility","positionHandler","currentControl","calcCornerCoords","objectCornerSize","centerX","centerY","isTouch","touchSizeX","touchSizeY","rotationStyleHandler","rotateObjectWithSnapping","ex","ey","theta","pivotPoint","lastAngle","curAngle","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","hasRotated","rotationWithSnapping","scaleIsProportional","uniformIsToggled","uniScaleKey","uniformScaling","scalingIsForbidden","by","scaleProportionally","lockX","lockY","scaleMap","scaleCursorStyleHandler","n","scaleObject","forbidScaling","signX","signY","gestureScale","distance","original","originalDistance","oldScaleX","oldScaleY","scaleObjectFromCorner","scaleObjectX","scaleObjectY","scalingEqually","scalingX","scalingY","AXIS_KEYS","counterAxis","skew","lockSkewing","flip","skewMap","skewCursorStyleHandler","skewObject","axis","skewingSide","skewKey","skewingBefore","skewingStart","shearingStart","shearing","skewing","atan","changed","dimBefore","dimAfter","compensationFactor","skewHandler","originKey","lockSkewingKey","flipKey","counterOriginKey","counterFlipKey","counterOriginFactor","skewingDirection","finalHandler","skewHandlerX","skewHandlerY","isAltAction","altActionKey","scaleOrSkewActionName","isAlternative","scaleSkewCursorStyleHandler","scalingXOrSkewingY","scalingYOrSkewingX","createObjectDefaultControls","ml","mr","mb","mt","mtr","withConnection","createResizeControls","createTextboxDefaultControls","InteractiveFabricObject","createControls","targetCanvas","_currentTransform","action","startsWith","getActiveControl","__corner","coord","oCoords","findControl","forTouch","cornerEntries","touchCorner","calcOCoords","rMatrix","positionMatrix","startMatrix","transformOptions","forEachControl","_calcCornerCoords","fn","_activeObject","wh","strokeBorders","_drawBorders","drawControlsConnectingLines","_renderControls","styleOptions","shouldDrawBorders","shouldDrawControls","isMoving","drawBorders","forActiveSelection","shouldStroke","setControlVisible","setControlsVisibility","clearContextTop","restoreManually","onDeselect","_options","onSelect","shouldStartDragging","_e","onDragStart","canDrop","renderDragSourceEffect","renderDropTargetEffect","applyMixins","derivedCtor","constructors","baseCtor","getOwnPropertyNames","prototype","defineProperty","getOwnPropertyDescriptor","create","isTransparent","tolerance","getImageData","alphaChannel","rotatePoint","findIndexRight","StrokeProjectionsBase","strokeProjectionMagnitude","strokeUniformScalar","createSideVector","projectOrthogonally","applySkew","calcOrthogonalProjection","isSkewed","scaleUnitVector","unitVector","zeroVector","StrokeLineJoinProjections","getOrthogonalRotationFactor","vector1","vector2","C","AC","bisector","orthogonalProjection","correctSide","projectBevel","projections","projectMiter","hypotUnitScalar","miterVector","projectRoundNoSkew","startCircle","endCircle","radiusOnAxisX","radiusOnAxisY","projectRoundWithSkew","circleRadius","newY","furthestY","newX","furthestX","projectRound","isStraightLine","newOrigin","proj0","proj1","comparisonVector","isProj0Start","projectPoints","project","originPoint","projectedPoint","StrokeLineCapProjections","projectButt","projection","projectSquare","strokePointingOut","projectedA","projectStrokeOnPoints","openPath","reduced","cloneStyles","newObj","keyInner","capitalize","string","firstLetterOnly","charAt","escapeXml","graphemeSplit","textstring","graphemes","chr","getWholeChar","str","code","charCodeAt","isNaN","next","prev","hasStyleChanged","prevStyle","thisStyle","forTextSpans","textBackgroundColor","deltaY","overline","underline","linethrough","stylesToArray","text","textLines","stylesArray","charIndex","chars","end","stylesFromArray","stylesObject","styleIndex","SHARED_ATTRIBUTES","selectorMatches","selector","nodeName","classNames","getAttribute","azAz","matcher","splitClassNames","doesSomeParentMatch","selectors","parentMatching","parentElement","elementMatchesRule","firstMatching","getGlobalStylesForElement","cssRules","rule","normalizeAttr","attr","_attributesMap","regex","cleanupSvgAttribute","attributeValue","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_templateObject6","transforms","transformList","_templateObject7","reTransformList","reTransform","reTransformAll","parseTransformAttribute","test","matchAll","transformMatch","matchedParams","operation","rawArgs","arg1","arg2","arg3","arg4","arg5","arg","normalizeValue","parentAttributes","parsed","ouputValue","transformMatrix","fillIndex","strokeIndex","parseFontDeclaration","oStyle","lineHeight","parseStyleObject","parseStyleString","chunk","parseStyleAttribute","colorAttributesMap","setStrokeFillOpacity","attributes","colorAttr","parseAttributes","parentFontSize","ownAttributes","normalizedStyle","normalizedAttr","normalizedValue","font","mergedAttrs","rectDefaultValues","rx","ry","RECT_PROPS","Rect","_initRxRy","isRounded","bezierCurveTo","fromElement","_parseAttributes","ATTRIBUTE_NAMES","restOfparsedAttributes","Boolean","LAYOUT_TYPE_INITIALIZATION","LAYOUT_TYPE_ADDED","LAYOUT_TYPE_REMOVED","LAYOUT_TYPE_IMPERATIVE","LAYOUT_TYPE_OBJECT_MODIFIED","LAYOUT_TYPE_OBJECT_MODIFYING","getObjectBounds","destinationGroup","currentGroup","objectCenter","accountForStroke","strokeUniformVector","scalingStrokeWidth","sizeVector","LayoutStrategy","calcLayoutResult","shouldPerformLayout","calcBoundingBox","prevStrategy","strategy","shouldLayoutClipPath","getInitialSize","overrides","bboxSize","bboxLeftTop","bboxCenter","actualSize","relativeCorrection","FitContentLayout","LAYOUT_MANAGER","LayoutManager","_subscriptions","performLayout","strictContext","bubbles","_prevLayoutStrategy","onBeforeLayout","layoutResult","getLayoutResult","commitLayout","onAfterLayout","attachHandlers","trigger","subscribe","unsubscribe","_context","delete","unsubscribeTargets","targets","subscribeTargets","tricklingContext","layoutManager","prevCenter","nextCenter","correction","layoutObjects","_context$x","_context$y","layoutObject","_","bubblingContext","NoopLayoutManager","groupDefaultValues","subTargetCheck","interactive","Group","groupInit","_options$layoutManage","__objectSelectionTracker","__objectSelectionMonitor","__objectSelectionDisposer","enterGroup","canEnterGroup","_filterObjectsBeforeEnteringGroup","allowedObjects","_onAfterObjectsChange","removeParentTransform","exitGroup","_shouldSetNestedCoords","removeAll","_activeObjects","selected","activeObjects","_watchObject","watch","_enterGroup","activeObject","_exitGroup","ownCache","preserveObjectStacking","triggerLayout","__serializeObjects","method","_includeDefaultValues","originalDefaults","_createSVGBgRect","fillStroke","commons","svgString","bg","abortable","hydratedOptions","layoutClass","strategyClass","groupSVGElements","findScaleToFit","destination","findScaleToCover","commaWsp","reArcCommandPoints","rePathCommand","repeatedCommands","M","segmentToBezier","theta1","theta2","cosTh","sinTh","cx1","cy1","mT","fromX","fromY","costh1","sinth1","costh2","sinth2","toX","toY","cp1X","cp1Y","cp2X","cp2Y","arcToSegments","large","sweep","rotateX","root","sinTheta","px","py","rx2","ry2","py2","px2","pl","_rx","_ry","mTheta","calcVectorAngle","dtheta","segments","mDelta","th3","ux","uy","vx","vy","ta","tb","CB1","CB2","CB3","CB4","getBoundsOfCurve","begx","begy","cp1x","cp1y","cp2x","cp2y","endx","endy","argsString","cachesBoundsOfCurve","boundsOfCurveCache","tvalues","bounds","b2ac","sqrtb2ac","t1","t2","jlen","iterator","getPointOnCubicBezierIterator","fromArcToBeziers","fx","fy","rot","tx","ty","segsNorm","makePathSimpler","x1","y1","destinationPath","previous","controlX","controlY","parsedCommand","converted","calcLineLength","x2","y2","pct","c1","c2","c3","c4","QB1","QB2","QB3","getTangentCubicIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","qb1","qb2","qb3","tangentX","tangentY","getPointOnQuadraticBezierIterator","getTangentQuadraticIterator","invT","pathIterator","tempP","tmpLen","perc","findPercentageForDistance","segInfo","nextLen","nextStep","lastPerc","angleFinder","getPathSegmentsInfo","totalLength","tempInfo","info","basicInfo","command","destX","destY","getPointOnPath","infos","segPercent","segment","rePathCmdAll","regExpArcCommandPoints","reMyNum","commandLengths","parsePath","pathString","_pathString$match","chain","matchStr","commandLetter","commandLength","paramArr","lastIndex","out","newCommand","transformedCommand","getSmoothPathFromPoints","p1","multSignX","multSignY","manyPoints","midPoint","transformPath","pathOffset","pathSegment","newSegment","getRegularPolygonPath","numVertexes","radius","interiorAngle","rotationAdjustment","rad","joinPath","pathData","setStyle","elementStyle","setProperty","mergeClipPaths","_b$group","getRandomInt","random","request","xhr","XMLHttpRequest","removeListener","ontimeout","onreadystatechange","readyState","open","send","_assignTransformMatrixProps","removeTransformMatrixForSvgParsing","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","CanvasDOMManager","containerClass","upperCanvasEl","createUpperCanvas","upper","applyCanvasStyle","container","createContainerElement","replaceChild","className","removeChild","canvasDefaults","centeredKey","selection","selectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","defaultCursor","freeDrawingCursor","notAllowedCursor","targetFindTolerance","skipTargetFind","stopContextMenu","fireRightClick","fireMiddleClick","enablePointerEvents","SelectableCanvas","_this$elements$upper","_this$elements$upper2","wrapperEl","_objectsToRender","deselected","_discardActiveObject","_hoveredTarget","_hoveredTargets","_chooseObjectsToRender","contextTopDirty","_groupSelector","isDrawingMode","renderTopLayer","_isCurrentlyDrawing","freeDrawingBrush","_drawSelection","renderTop","setTargetFindTolerance","pixelFindCanvasEl","pixelFindContext","isTargetTransparent","selectionBgc","enhancedTolerance","_isSelectionKeyPressed","sKey","_shouldClearSelection","getActiveObjects","_shouldCenterTransform","modifierKeyPressed","centerTransform","_getOriginFromCorner","controlName","_setupCurrentTransform","_control$getActionHan","getScenePoint","altKey","lastX","lastY","shiftKey","setCursor","cursor","deltaX","extent","strokeOffset","minX","minY","maxX","maxY","findTarget","getViewportPoint","aObjects","searchPossibleTargets","subTargets","altSelectionKey","_pointIsInObjectSelectionArea","viewportZoom","angleRadians","cosP","sinP","cosPSinP","cosPMinusSinP","_checkTarget","isEditing","_searchPossibleTargets","subTarget","_pointer","_absolutePointer","fromViewport","boundsWidth","boundsHeight","cssScale","_resetTransformEventData","_setBrushStyles","willReadFrequently","getTopContext","getSelectionContext","getSelectionElement","active","_fireSelectionEvents","oldObjects","somethingChanged","invalidate","added","setActiveObject","currentActives","_setActiveObject","prevActiveObject","endCurrentTransform","discardActiveObject","discarded","_finalizeCurrentTransform","_scaling","originalProperties","_realizeGroupTransformOnObject","layoutProps","originalValues","TextEditingManager","cb","hiddenTextarea","focus","__disposer","exitTextEditing","exitEditing","onMouseMove","_this$target","updateSelectionOnMouseMove","addEventOptions","passive","getEventPoints","viewportPoint","scenePoint","absolutePointer","addListener","syntheticEventConfig","mouse","in","targetIn","targetOut","canvasIn","canvasOut","drag","Canvas","eventHandler","addOrRemove","_getEventPrefix","functor","_eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","removeListeners","_onMouseUp","_onTouchEnd","__onMouseWheel","shared","nestedTarget","_isClick","_dragSource","_onDragProgress","_renderDragEffects","dropTarget","_dropTarget","didDrop","dataTransfer","dropEffect","dragSource","_draggedoverTarget","findDragTargets","eventType","_fireEnterLeaveEvents","_basicEventHandler","_cacheTransformEventData","_handleEvent","getPointerId","evt","identifier","pointerId","_isMainEvent","isPrimary","touches","mainTouchId","__onMouseDown","__onMouseUp","_willAddMouseDown","clearTimeout","__onMouseMove","_shouldRender","_this$_activeObject","isClick","_target","button","_onMouseUpInDrawingMode","shouldRender","targetWasActive","handleSelection","found","originalControl","originalMouseUpHandler","_setCursorFromEvent","currentTarget","currentSubTargets","_onMouseDownInDrawingMode","onMouseDown","_onMouseMoveInDrawingMode","onMouseUp","grouped","handleMultiSelection","groupSelector","_fireOverOutEvents","_transformObject","textEditingManager","fireSyntheticInOutEvents","oldTarget","fireCanvas","draggedoverTarget","targetChanged","outOpt","nextTarget","inOpt","previousTarget","localPointer","_performTransformAction","activeSelection","reverse","isAS","prevActiveObjects","multiSelectAdd","klass","newActiveSelection","point1","point2","collectedObjects","linearDefaultCoords","radialDefaultCoords","ifNaN","valueIfNaN","RE_PERCENT","isPercent","parsePercent","NaN","RE_KEY_VALUE_PAIRS","RE_KEY_VALUE","parseColorStop","keyValuePairs","parseColorStops","opacityAttr","colorStops","colorStopEls","getElementsByTagName","parseType","parseGradientUnits","convertPercentUnitsToValues","valuesToConvert","finalValue","propValue","getValue","parseLinearCoords","parseRadialCoords","parseCoords","Gradient","addColorStop","colorStop","preTransform","sort","needsSwap","minRadius","maxRadius","percentageShift","gradient","createLinearGradient","createRadialGradient","svgOptions","viewBoxWidth","viewBoxHeight","Pattern","isImageSource","isCanvasSource","sourceToString","complete","naturalWidth","naturalHeight","patternSource","patternOffsetX","patternOffsetY","patternWidth","patternHeight","BaseBrush","_saveAndTransform","needsFullRender","_resetShadow","_isOutSideCanvas","Path","_setPath","adjustPosition","setBoundingBox","_calcBoundsFromPath","quadraticCurveTo","pathCmd","sourcePath","_getOffsetTransform","digits","_calcDimensions","subpathStartX","subpathStartY","parsedAttributes","isEmptySVGPath","PencilBrush","_points","_hasStraightLine","drawSegment","drawStraightLine","straightLineKey","_prepareForDrawing","_addPoint","limitedToCanvasSize","oldEnd","_finalizeAndAddPath","_reset","convertPointsToSVGPath","createPath","decimatePoints","lastPoint","cDistance","adjustedDistance","newPoints","decimate","CIRCLE_PROPS","circleDefaultValues","startAngle","endAngle","Circle","setRadius","getRadiusX","getRadiusY","startX","startY","endX","endY","largeFlag","sweepFlag","otherParsedAttributes","CircleBrush","drawDot","addPoint","dot","originalRenderOnAddRemove","circles","circle","pointerPoint","getUniqueRects","rects","uniqueRects","uniqueRectsArray","SprayBrush","sprayChunks","sprayChunk","addSprayChunk","renderChunck","chunck","rect","optimizeOverlapping","sprayChunck","density","dotWidthVariance","dotWidth","randomOpacity","PatternBrush","getPatternSrc","dotDistance","patternCanvas","patternCtx","getPattern","pattern","topLeft","coordProps","Line","_setWidthHeight","calcLinePoints","origStrokeStyle","_this$stroke","_x1","_x2","_y1","_y2","xMult","yMult","triangleDefaultValues","Triangle","widthBy2","heightBy2","ellipseDefaultValues","ELLIPSE_PROPS","Ellipse","getRx","getRy","parsePointsAttribute","pointsSplit","parsedPoints","polylineDefaultValues","exactBoundingBox","Polyline","initialized","isOpen","_projectStrokeOnPoints","strokeDiff","bboxNoStroke","layoutProperties","_options$width","_options$height","_options$width2","_options$height2","output","diffX","diffY","Polygon","fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","textDefaultValues","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER","StyledText","isEmptyStyles","lineIndex","line","p3","styleHas","cleanStyle","stylesCount","letterCount","stylePropertyValue","allStyleObjectPropertiesMatch","graphemeCount","styleObject","stylePropertyHasBeenSet","_textLines","removeStyle","lineNum","charNum","_extendStyles","get2DCursorLocation","_getLineStyle","_setLineStyle","newStyle","_getStyleDeclaration","_setStyleDeclaration","getSelectionStyles","startIndex","endIndex","getStyleAtPosition","getCompleteStyleDeclaration","setSelectionStyles","_forceClearCache","_lineStyle$charIndex","lineStyle","_styleProperties","_deleteStyleDeclaration","_deleteLineStyle","multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","TextSVGExportMixin","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textBgRects","textSpans","noShadow","textDecoration","getSvgTextDecoration","textTopOffset","textLeftOffset","lineOffset","_getLineLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","fillStyles","dySpan","isJustify","actualStyle","nextStyle","charsToRender","charBox","boxWidth","timeToRender","__charBounds","kernedWidth","leftOffset","heightOfLine","boxStart","currentColor","lastColor","getValueOfPropertyAt","_getSVGLineTopOffset","lineTopOffset","lastHeight","useWhiteSpace","decoration","measuringContext","getMeasuringContext","FabricText","setPathInfo","initDimensions","segmentsInfo","_splitText","newLines","_splitTextIntoLines","lines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","calcTextHeight","enlargeSpaces","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","charBound","spaces","isEndOfWrapping","getLineWidth","missingNewlineOffset","_lineIndex","selectionStart","skipWrapping","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","_getLeftOffset","_getTopOffset","lineLeftOffset","drawStart","renderLeft","_measureChar","_char","previousChar","prevCharStyle","fontDeclaration","couple","stylesAreEqual","fontMultiplier","coupleWidth","previousWidth","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","prevGrapheme","graphemeInfo","llength","lineBounds","grapheme","_getGraphemeBox","positionInPath","totalPathLength","_setGraphemeOnPath","numOfSpaces","centerPosition","skipLeft","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","shortCut","isLtr","currentDirection","drawingLeft","_renderChar","_applyPatternGradientTransformText","handleFiller","fullDecl","shouldFill","fillOffsets","fillText","strokeOffsets","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","lineDiff","__lineWidths","_charStyle$property","topOffset","lastDecoration","lastFill","currentDecoration","currentFill","currentSize","currentDy","parsedFontFamily","genericFonts","newLine","newText","needsDims","isAddingPath","_options$parsedAttrib","textAnchor","restOfOptions","textContent","textHeightScaleFactor","lineHeightDiff","scaledDiff","textHeight","offX","DraggableTextDelegate","dragEnterHandler","dragOverHandler","dragLeaveHandler","dragEndHandler","dropHandler","_dispose","isPointerOverSelection","newSelection","getSelectionStartFromPointer","selectionEnd","__mouseDownInPlace","isActive","__dragStartFired","setCursorByClick","initDelayedCursor","__isDraggingOver","getDragStartSelection","__dragStartSelection","setDragImage","_e$dataTransfer","flipFactor","boundaries","_getCursorBoundaries","selectionPosition","diff","bgc","dragImage","border","__dragImageDisposer","appendChild","setData","stringify","effectAllowed","abortCursorAnimation","editable","defaultPrevented","dragStartSelection","targetCanDrop","ev","_e$dataTransfer2","insert","getData","trailing","selectionStartOffset","removeChars","trimEnd","insertChars","enterEditing","_updateTextarea","_e$dataTransfer3","reNonWord","ITextBehavior","initBehavior","_tick","_onTickComplete","_animateCursor","toValue","_currentCursorOpacity","renderCursorOrSelection","_currentTickState","cursorDuration","_this$_currentTickCom","_currentTickCompleteState","restart","cursorDelay","shouldClear","cursorAnimation","restartCursorIfNeeded","selectAll","_fireSelectionChanged","getSelectedText","findWordBoundaryLeft","startFrom","_reSpace","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","selectWord","newSelectionStart","newSelectionEnd","selectLine","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","activeElement","currentStart","currentEnd","__selectionStartOnMouseDown","editingBorderColor","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","graphemeEnd","fromGraphemeToStringSelection","cursorOffsetCache","inCompositionMode","updateTextareaPosition","updateFromTextArea","textarea","_calcTextareaPosition","desiredPosition","compositionStart","cursorLocation","charHeight","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","_exitEditing","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","styleObj","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","_selectionDirection","ITextKeyBehavior","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","hiddenTextareaContainer","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","onKeyDown","keyMap","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","updateAndFire","nextText","charCount","nextCharCount","removedText","charDiff","removeFrom","removeTo","textareaSelection","backDelete","copiedText","disableStyleCopyPaste","copiedTextStyle","onCompositionStart","onCompositionEnd","onCompositionUpdate","compositionEnd","_getWidthBeforeCursor","widthBeforeCursor","bound","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","textAfterCursor","getUpCursorOffset","textBeforeCursor","widthOfCharsOnLine","indexOnLine","charWidth","foundMatch","leftEdge","rightEdge","offsetFromLeftEdge","offsetFromRightEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","newValue","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","moveCursorRightWithShift","moveCursorRightWithoutShift","notALeftClick","ITextClickBehavior","_mouseDownHandler","_mouseDownHandlerBefore","doubleClickHandler","tripleClickHandler","__lastClickTime","__lastLastClickTime","__lastPointer","draggableTextDelegate","__newClickTime","newPointer","isTripleClick","__lastSelected","didDrag","mouseOffset","charLength","widthAfter","MOVE_CURSOR_UP","MOVE_CURSOR_DOWN","MOVE_CURSOR_LEFT","MOVE_CURSOR_RIGHT","EXIT_EDITING","protectedDefaultValues","iTextDefaultValues","cursorColor","caching","IText","setSelectionStart","_updateAndFire","setSelectionEnd","renderCursor","renderSelection","skipCaching","_getCursorBoundariesOffsets","__getCursorBoundariesOffsets","renderCursorAt","_renderCursor","_renderSelection","dragSelection","startLine","endLine","startChar","endChar","realLineHeight","boxEnd","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","cursorPosition","textboxDefaultValues","minWidth","dynamicMinWidth","_wordJoiners","splitByGrapheme","Textbox","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextLineIndex","nextOffset","shouldLimit","mapNextLine","p2Number","_wrapText","desiredWidth","getGraphemeDataForRender","wrapped","wordsData","_wrapLine","infix","largestWordWidth","wordsOrGraphemes","wordSplit","word","graphemeArray","_measureWord","charOffset","reservedSpace","additionalSpace","infixWidth","lineJustStarted","wordWidth","getMinWidth","linesToKeep","propNumber","ClipPathLayout","clipPathCenter","FixedLayout","ActiveSelectionLayoutManager","parents","Set","selectedObjects","activeSelectionDefaultValues","multiSelectionStacking","ActiveSelection","findIndex","groups","childrenOverride","Canvas2dFilterBackend","applyFilters","filters","sourceElement","sourceWidth","sourceHeight","imageData","originalImageData","pipelineState","originalEl","filterBackend","applyTo","imageDataPostFilter","putImageData","WebGLFilterBackend","tileSize","Float32Array","setupGLContext","captureGPUInfo","createWebGLCanvas","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","destinationWidth","destinationHeight","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","aPosition","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","resizeCanvasIfNeeded","copyGLTo2D","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","NEAREST","RGBA","UNSIGNED_BYTE","CLAMP_TO_EDGE","TEXTURE_MAG_FILTER","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","texture","texParameteri","texImage2D","uniqueId","evictCachesForKey","glCanvas","sourceY","copyGLTo2DPutImageData","dWidth","dHeight","numBytes","u8","Uint8Array","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","imgData","ImageData","gpuInfo","renderer","vendor","ext","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","initFilterBackend","enableGLFiltering","getFilterBackend","strict","setFilterBackend","backend","imageDefaultValues","srcFromAttribute","minimumScaleTrigger","imageSmoothing","IMAGE_PROPS","FabricImage","setElement","_element","removeTexture","_originalElement","CSS_CANVAS","resizeFilter","applyResizeFilters","elementKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","imageMarkup","strokeSvg","imageRendering","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","_filterScalingX","_filterScalingY","_lastScaleX","_lastScaleY","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","pAR","preserveAspectRatio","pWidth","pHeight","rWidth","rHeight","f","rf","hydratedProps","fromURL","imageOptions","applyViewboxTransform","viewBoxAttr","widthAttr","heightAttr","goodViewbox","missingViewBox","missingDimAttr","translateMatrix","widthDiff","heightDiff","parsedDim","pasedViewBox","createElementNS","firstChild","getTagName","node","tagName","svgInvalidAncestorsRegEx","hasInvalidAncestor","getMultipleNodes","nodeNames","nodeArray","nodeList","getElementsByTagNameNS","parseUseDirectives","nodelist","skipAttributes","useElement","useAttributes","useAttrMap","xlink","href","referencedElement","clonedOriginal","cloneNode","originalAttributes","originalAttrMap","currentTrans","el3","setAttributeNS","childNodes","styleRecord","mergedStyles","entry","gradientsAttrs","xlinkAttr","recursivelyParseGradientsXlink","_gradient$getAttribut","xLink","referencedGradient","children","referenceClone","tagArray","getGradientDefs","elList","gradientDefs","getCSSRules","allRules","styleContents","ruleObj","declaration","propertyValuePairs","pair","_rule","findTag","ElementsParser","clipPaths","regexUrl","createObject","resolveGradient","resolveClipPath","extractPropertyDefinition","storage","gradientDef","usingElement","clipPathElements","objTransformInv","clipPathTag","clipPathOwner","clipPathElement","enlivedClippath","clipRule","gTransform","isValidSvgTag","createEmptyResponse","allElements","parseSVGDocument","descendants","localClipPaths","elementParser","loadSVGFromString","parser","DOMParser","parseFromString","loadSVGFromURL","xml","responseXML","parsedDoc","ACTION_NAME","createPolyPositionHandler","pointIndex","polyObject","polyActionHandler","poly","mouseLocalPosition","factoryPolyActionHandler","anchorPoint","anchorPointInParentPlane","newAnchorPointInParentPlane","createPolyActionHandler","createPolyControls","calcPathPointPosition","pathObject","commandIndex","movePathPoint","anchorCommand","pathPositionHandler","pathActionHandler","indexFromPrevCommand","previousCommandType","PathPointControl","controlFill","controlStroke","PathControlPointControl","connectToCommandIndex","connectToPointIndex","connectionDashArray","commandType","createControl","commandIndexPos","pointIndexPos","isControlPoint","controlPointStyle","pointStyle","createPathControls","isWebGLPipelineState","isPutImageFaster","sourceCanvas","ArrayBuffer","testContext","testPipelineState","performance","now","drawImageTime","putImageDataTime","highPsourceCode","identityFragmentShader","vertexSource","BaseFilter","getFragmentSource","getVertexSource","createProgram","vertexShader","VERTEX_SHADER","program","getShaderInfoLog","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","attributeLocations","getAttributeLocations","getAttribLocation","locations","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","finish","_swapTextures","temp","applyToWebGL","applyTo2d","getCacheKey","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","_gl","_uniformLocations","createHelpLayer","helpLayer","defaultKeys","filterOptions","blendColorFragmentSource","screen","difference","lighten","darken","exclusion","tint","blendColorDefaultValues","mode","BlendColor","tg","alpha1","uniform4fv","uColor","mask","blendImageDefaultValues","BlendImage","image","TEXTURE1","calculateMatrix","resources","blendImage","canvas1","blendData","uniform1i","uImage","uniformMatrix3fv","uTransformMatrix","enlivedImage","blurDefaultValues","Blur","aspectRatio","horizontal","simpleBlur","blurLayer1","blurLayer2","canvas2","ctx1","ctx2","nSamples","percent","newImageData","delta","chooseRightDelta","uniform2fv","uDelta","blurScale","brightnessDefaultValues","brightness","Brightness","uBrightness","colorMatrixDefaultValues","colorsOnly","ColorMatrix","constants","uniformMatrix4fv","uColorMatrix","uConstants","createColorMatrixFilter","_Class","newClass","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","Composed","subFilters","enlivedFilters","contrastDefaultValues","contrast","Contrast","contrastF","uContrast","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","convoluteDefaultValues","opaque","Convolute","weights","side","halfSide","sw","sh","createImageData","dst","alphaFac","dstOff","scx","scy","srcOff","wt","uniform1fv","uMatrix","GAMMA","gammaDefaultValues","gamma","Gamma","rInv","gInv","bInv","rgbValues","rgb","uniform3fv","uGamma","lightness","luminosity","grayscaleDefaultValues","Grayscale","uMode","hueRotationDefaultValues","rotation","HueRotation","cosine","sine","aThird","aThirdSqtSin","OneMinusCos","invertDefaultValues","invert","Invert","uInvert","uAlpha","noiseDefaultValues","noise","Noise","rand","uNoise","uSeed","pixelateDefaultValues","blocksize","Pixelate","_i","_j","uBlocksize","removeColorDefaultValues","useAlpha","RemoveColor","lowC","highC","uLow","uHigh","resizeDefaultValues","resizeType","lanczosLobes","Resize","uTaps","taps","getFilterWindow","tempScale","filterWindow","generateShader","getTaps","lobeFunction","lanczosCreate","applyToForWebgl","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","oW","oH","newData","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","mult","doneW","doneH","stepW","stepH","dX","dY","tmpCanvas","process","u","weight","fX","fY","ratioX","icenter","ratioY","range2X","cacheLanc","range2Y","lanczos","rcpRatioX","rcpRatioY","srcData","destData","destImg","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","yy","w0","saturationDefaultValues","saturation","Saturation","adjust","uSaturation","vibranceDefaultValues","vibrance","Vibrance","amt","uVibrance"],"mappings":"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EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,SAAS,EAAE,SAAS;AACpBxL,EAAAA,GAAG,EAAE,SAAS;AACdyL,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,KAAK,EAAE,MAAM;AACbC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,MAAM,EAAE,MAAM;AACdC,EAAAA,WAAW,EAAE,SAAA;AACf,CAAC;;ACzJD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,MAAM,GAAGA,MACpB,kJAAkJ,CAAA;;AAEpJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,MAAM,GAAGA,MACpB,kKAAkK,CAAA;;AAEpK;AACA;AACA;AACO,MAAMC,KAAK,GAAGA,MAAM,2CAA2C;;AC/GtE;AACA;AACA;AACA;AACA;AACA;AACO,MAA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"} \ No newline at end of file diff --git a/dist/index.node.mjs b/dist/index.node.mjs new file mode 100644 index 00000000000..06c2e909f13 --- /dev/null +++ b/dist/index.node.mjs @@ -0,0 +1,28044 @@ +import { JSDOM } from 'jsdom'; +import utils from 'jsdom/lib/jsdom/living/generated/utils.js'; + +function _defineProperty(e, r, t) { + return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { + value: t, + enumerable: !0, + configurable: !0, + writable: !0 + }) : e[r] = t, e; +} +function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; +} +function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; +} +function _objectWithoutProperties(e, t) { + if (null == e) return {}; + var o, + r, + i = _objectWithoutPropertiesLoose(e, t); + if (Object.getOwnPropertySymbols) { + var n = Object.getOwnPropertySymbols(e); + for (r = 0; r < n.length; r++) o = n[r], t.indexOf(o) >= 0 || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); + } + return i; +} +function _objectWithoutPropertiesLoose(r, e) { + if (null == r) return {}; + var t = {}; + for (var n in r) if ({}.hasOwnProperty.call(r, n)) { + if (e.indexOf(n) >= 0) continue; + t[n] = r[n]; + } + return t; +} +function _taggedTemplateLiteral(e, t) { + return t || (t = e.slice(0)), Object.freeze(Object.defineProperties(e, { + raw: { + value: Object.freeze(t) + } + })); +} +function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); +} +function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : i + ""; +} + +class BaseConfiguration { + constructor() { + /** + * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value, + * which is unitless and not rendered equally across browsers. + * + * Values that work quite well (as of October 2017) are: + * - Chrome: 1.5 + * - Edge: 1.75 + * - Firefox: 0.9 + * - Safari: 0.95 + * + * @since 2.0.0 + * @type Number + * @default 1 + */ + _defineProperty(this, "browserShadowBlurConstant", 1); + /** + * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion. + */ + _defineProperty(this, "DPI", 96); + /** + * Device Pixel Ratio + * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html + */ + _defineProperty(this, "devicePixelRatio", typeof window !== 'undefined' ? window.devicePixelRatio : 1); + // eslint-disable-line no-restricted-globals + /** + * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine. + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "perfLimitSizeTotal", 2097152); + /** + * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000 + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "maxCacheSideLimit", 4096); + /** + * Lowest pixel limit for cache canvases, set at 256PX + * @since 1.7.14 + * @type Number + * @default + */ + _defineProperty(this, "minCacheSideLimit", 256); + /** + * When 'true', style information is not retained when copy/pasting text, making + * pasted text use destination style. + * Defaults to 'false'. + * @type Boolean + * @default + * @deprecated + */ + _defineProperty(this, "disableStyleCopyPaste", false); + /** + * Enable webgl for filtering picture is available + * A filtering backend will be initialized, this will both take memory and + * time since a default 2048x2048 canvas will be created for the gl context + * @since 2.0.0 + * @type Boolean + * @default + */ + _defineProperty(this, "enableGLFiltering", true); + /** + * if webgl is enabled and available, textureSize will determine the size + * of the canvas backend + * + * In order to support old hardware set to `2048` to avoid OOM + * + * @since 2.0.0 + * @type Number + * @default + */ + _defineProperty(this, "textureSize", 4096); + /** + * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on + * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true + * this has to be set before instantiating the filtering backend ( before filtering the first image ) + * @type Boolean + * @default false + */ + _defineProperty(this, "forceGLPutImageData", false); + /** + * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better + * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from + * the curve is very hard to hit any cache. + * Enable only if you know why it could be useful. + * Candidate for removal/simplification + * @default false + */ + _defineProperty(this, "cachesBoundsOfCurve", false); + /** + * Map of font files + * Map of font files + */ + _defineProperty(this, "fontPaths", {}); + /** + * Defines the number of fraction digits to use when serializing object values. + * Used in exporting methods (`toObject`, `toJSON`, `toSVG`) + * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc. + */ + _defineProperty(this, "NUM_FRACTION_DIGITS", 4); + } +} +class Configuration extends BaseConfiguration { + constructor(config) { + super(); + this.configure(config); + } + configure() { + let config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + Object.assign(this, config); + } + + /** + * Map of font files + */ + addFonts() { + let paths = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.fontPaths = _objectSpread2(_objectSpread2({}, this.fontPaths), paths); + } + removeFonts() { + let fontFamilys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + fontFamilys.forEach(fontFamily => { + delete this.fontPaths[fontFamily]; + }); + } + clearFonts() { + this.fontPaths = {}; + } + restoreDefaults(keys) { + const defaults = new BaseConfiguration(); + const config = (keys === null || keys === void 0 ? void 0 : keys.reduce((acc, key) => { + acc[key] = defaults[key]; + return acc; + }, {})) || defaults; + this.configure(config); + } +} +const config = new Configuration(); + +const log = function (severity) { + for (var _len = arguments.length, optionalParams = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + optionalParams[_key - 1] = arguments[_key]; + } + return ( + // eslint-disable-next-line no-restricted-syntax + console[severity]('fabric', ...optionalParams) + ); +}; +class FabricError extends Error { + constructor(message, options) { + super("fabric: ".concat(message), options); + } +} +class SignalAbortedError extends FabricError { + constructor(context) { + super("".concat(context, " 'options.signal' is in 'aborted' state")); + } +} + +class GLProbe {} + +/** + * Lazy initialize WebGL constants + */ +class WebGLProbe extends GLProbe { + /** + * Tests if webgl supports certain precision + * @param {WebGL} Canvas WebGL context to test on + * @param {GLPrecision} Precision to test can be any of following + * @returns {Boolean} Whether the user's browser WebGL supports given precision. + */ + testPrecision(gl, precision) { + const fragmentSource = "precision ".concat(precision, " float;\nvoid main(){}"); + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + if (!fragmentShader) { + return false; + } + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS); + } + + /** + * query browser for WebGL + */ + queryWebGL(canvas) { + const gl = canvas.getContext('webgl'); + if (gl) { + this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); + this.GLPrecision = ['highp', 'mediump', 'lowp'].find(precision => this.testPrecision(gl, precision)); + gl.getExtension('WEBGL_lose_context').loseContext(); + log('log', "WebGL: max texture size ".concat(this.maxTextureSize)); + } + } + isSupported(textureSize) { + return !!this.maxTextureSize && this.maxTextureSize >= textureSize; + } +} + +/* eslint-disable no-restricted-globals */ +const copyPasteData$1 = {}; +const getEnv$2 = () => { + return { + document, + window, + isTouchSupported: 'ontouchstart' in window || 'ontouchstart' in document || window && window.navigator && window.navigator.maxTouchPoints > 0, + WebGLProbe: new WebGLProbe(), + dispose() { + // noop + }, + copyPasteData: copyPasteData$1 + }; +}; + +/** + * This file is consumed by fabric. + * The `./node` and `./browser` files define the env variable that is used by this module. + * The `./browser` module is defined to be the default env and doesn't set the env at all. + * This is done in order to support isomorphic usage for browser and node applications + * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env. + */ + +let env; + +/** + * Sets the environment variables used by fabric.\ + * This is exposed for special cases, such as configuring a test environment, and should be used with care. + * + * **CAUTION**: Must be called before using the package. + * + * @example + * Passing `window` and `document` objects to fabric (in case they are mocked or something) + * import { getEnv, setEnv } from 'fabric'; + * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in. + * setEnv({ ...getEnv(), window, document }); + * // done with setup, using fabric is now safe + */ +const setEnv = value => { + env = value; +}; + +/** + * In order to support SSR we **MUST** access the browser env only after the window has loaded + */ +const getEnv$1 = () => env || (env = getEnv$2()); +const getFabricDocument = () => getEnv$1().document; +const getFabricWindow = () => getEnv$1().window; + +/** + * @returns the config value if defined, fallbacks to the environment value + */ +const getDevicePixelRatio = () => { + var _config$devicePixelRa; + return Math.max((_config$devicePixelRa = config.devicePixelRatio) !== null && _config$devicePixelRa !== void 0 ? _config$devicePixelRa : getFabricWindow().devicePixelRatio, 1); +}; + +/** + * @todo GL rendering in node is possible: + * - https://github.com/stackgl/headless-gl + * - https://github.com/akira-cn/node-canvas-webgl + */ +class NodeGLProbe extends GLProbe { + queryWebGL() { + // noop + } + isSupported() { + return false; + } +} + +/* eslint-disable no-restricted-globals */ + +const { + implForWrapper: jsdomImplForWrapper +} = utils; +const copyPasteData = {}; +const { + window: JSDOMWindow +} = new JSDOM(decodeURIComponent('%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E'), { + resources: 'usable', + // needed for `requestAnimationFrame` + pretendToBeVisual: true +}); +const getNodeCanvas = canvasEl => { + const impl = jsdomImplForWrapper(canvasEl); + return impl._canvas || impl._image; +}; +const dispose = element => { + const impl = jsdomImplForWrapper(element); + if (impl) { + impl._image = null; + impl._canvas = null; + // unsure if necessary + impl._currentSrc = null; + impl._attributes = null; + impl._classList = null; + } +}; +const getEnv = () => { + return { + document: JSDOMWindow.document, + window: JSDOMWindow, + isTouchSupported: false, + WebGLProbe: new NodeGLProbe(), + dispose, + copyPasteData + }; +}; + +class Cache { + constructor() { + /** + * Cache of widths of chars in text rendering. + */ + _defineProperty(this, "charWidthsCache", {}); + /** + * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it. + * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing + * you do not get any speed benefit and you get a big object in memory. + * The object was a private variable before, while now is appended to the lib so that you have access to it and you + * can eventually clear it. + * It was an internal variable, is accessible since version 2.3.4 + */ + _defineProperty(this, "boundsOfCurveCache", {}); + } + /** + * @return {Object} reference to cache + */ + getFontCache(_ref) { + let { + fontFamily, + fontStyle, + fontWeight + } = _ref; + fontFamily = fontFamily.toLowerCase(); + if (!this.charWidthsCache[fontFamily]) { + this.charWidthsCache[fontFamily] = {}; + } + const fontCache = this.charWidthsCache[fontFamily]; + const cacheKey = "".concat(fontStyle.toLowerCase(), "_").concat((fontWeight + '').toLowerCase()); + if (!fontCache[cacheKey]) { + fontCache[cacheKey] = {}; + } + return fontCache[cacheKey]; + } + + /** + * Clear char widths cache for the given font family or all the cache if no + * fontFamily is specified. + * Use it if you know you are loading fonts in a lazy way and you are not waiting + * for custom fonts to load properly when adding text objects to the canvas. + * If a text object is added when its own font is not loaded yet, you will get wrong + * measurement and so wrong bounding boxes. + * After the font cache is cleared, either change the textObject text content or call + * initDimensions() to trigger a recalculation + * @param {String} [fontFamily] font family to clear + */ + clearFontCache(fontFamily) { + fontFamily = (fontFamily || '').toLowerCase(); + if (!fontFamily) { + this.charWidthsCache = {}; + } else if (this.charWidthsCache[fontFamily]) { + delete this.charWidthsCache[fontFamily]; + } + } + + /** + * Given current aspect ratio, determines the max width and height that can + * respect the total allowed area for the cache. + * @param {number} ar aspect ratio + * @return {number[]} Limited dimensions X and Y + */ + limitDimsByArea(ar) { + const { + perfLimitSizeTotal + } = config; + const roughWidth = Math.sqrt(perfLimitSizeTotal * ar); + // we are not returning a point on purpose, to avoid circular dependencies + // this is an internal utility + return [Math.floor(roughWidth), Math.floor(perfLimitSizeTotal / roughWidth)]; + } +} +const cache = new Cache(); + +var version = "6.4.2"; + +// use this syntax so babel plugin see this import here +const VERSION = version; +// eslint-disable-next-line @typescript-eslint/no-empty-function +function noop() {} +const halfPI = Math.PI / 2; +const twoMathPi = Math.PI * 2; +const PiBy180 = Math.PI / 180; +const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]); +const DEFAULT_SVG_FONT_SIZE = 16; +const ALIASING_LIMIT = 2; + +/* "magic number" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */ +const kRect = 1 - 0.5522847498; +const CENTER = 'center'; +const LEFT = 'left'; +const TOP = 'top'; +const BOTTOM = 'bottom'; +const RIGHT = 'right'; +const NONE = 'none'; +const reNewline = /\r?\n/; +const MOVING = 'moving'; +const SCALING = 'scaling'; +const ROTATING = 'rotating'; +const ROTATE = 'rotate'; +const SKEWING = 'skewing'; +const RESIZING = 'resizing'; +const MODIFY_POLY = 'modifyPoly'; +const MODIFY_PATH = 'modifyPath'; +const CHANGED = 'changed'; +const SCALE = 'scale'; +const SCALE_X = 'scaleX'; +const SCALE_Y = 'scaleY'; +const SKEW_X = 'skewX'; +const SKEW_Y = 'skewY'; +const FILL = 'fill'; +const STROKE = 'stroke'; +const MODIFIED = 'modified'; + +/* + * This Map connects the objects type value with their + * class implementation. It used from any object to understand which are + * the classes to enlive when requesting a object.type = 'path' for example. + * Objects uses it for clipPath, Canvas uses it for everything. + * This is necessary for generic code to run and enlive instances from serialized representation. + * You can customize which classes get enlived from SVG parsing using this classRegistry. + * The Registry start empty and gets filled in depending which files you import. + * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from + * different sources you will need to import all fabric because you may need all classes. + */ + +const JSON$1 = 'json'; +const SVG = 'svg'; +class ClassRegistry { + constructor() { + this[JSON$1] = new Map(); + this[SVG] = new Map(); + } + has(classType) { + return this[JSON$1].has(classType); + } + getClass(classType) { + const constructor = this[JSON$1].get(classType); + if (!constructor) { + throw new FabricError("No class registered for ".concat(classType)); + } + return constructor; + } + setClass(classConstructor, classType) { + if (classType) { + this[JSON$1].set(classType, classConstructor); + } else { + this[JSON$1].set(classConstructor.type, classConstructor); + // legacy + // @TODO: needs to be removed in fabric 7 or 8 + this[JSON$1].set(classConstructor.type.toLowerCase(), classConstructor); + } + } + getSVGClass(SVGTagName) { + return this[SVG].get(SVGTagName); + } + setSVGClass(classConstructor, SVGTagName) { + this[SVG].set(SVGTagName !== null && SVGTagName !== void 0 ? SVGTagName : classConstructor.type.toLowerCase(), classConstructor); + } +} +const classRegistry = new ClassRegistry(); + +/** + * Array holding all running animations + */ +class AnimationRegistry extends Array { + /** + * Remove a single animation using an animation context + * @param {AnimationBase} context + */ + remove(context) { + const index = this.indexOf(context); + index > -1 && this.splice(index, 1); + } + + /** + * Cancel all running animations on the next frame + */ + cancelAll() { + const animations = this.splice(0); + animations.forEach(animation => animation.abort()); + return animations; + } + + /** + * Cancel all running animations attached to a canvas on the next frame + * @param {StaticCanvas} canvas + */ + cancelByCanvas(canvas) { + if (!canvas) { + return []; + } + const animations = this.filter(animation => { + var _animation$target; + return animation.target === canvas || typeof animation.target === 'object' && ((_animation$target = animation.target) === null || _animation$target === void 0 ? void 0 : _animation$target.canvas) === canvas; + }); + animations.forEach(animation => animation.abort()); + return animations; + } + + /** + * Cancel all running animations for target on the next frame + * @param target + */ + cancelByTarget(target) { + if (!target) { + return []; + } + const animations = this.filter(animation => animation.target === target); + animations.forEach(animation => animation.abort()); + return animations; + } +} +const runningAnimations = new AnimationRegistry(); + +/** + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events} + * @see {@link http://fabricjs.com/events|Events demo} + */ +class Observable { + constructor() { + _defineProperty(this, "__eventListeners", {}); + } + /** + * Observes specified event + * @alias on + * @param {string} eventName Event name (eg. 'after:render') + * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function that receives a notification when an event of the specified type occurs + * @return {Function} disposer + */ + on(arg0, handler) { + if (!this.__eventListeners) { + this.__eventListeners = {}; + } + if (typeof arg0 === 'object') { + // one object with key/value pairs was passed + Object.entries(arg0).forEach(_ref => { + let [eventName, handler] = _ref; + this.on(eventName, handler); + }); + return () => this.off(arg0); + } else if (handler) { + const eventName = arg0; + if (!this.__eventListeners[eventName]) { + this.__eventListeners[eventName] = []; + } + this.__eventListeners[eventName].push(handler); + return () => this.off(eventName, handler); + } else { + // noop + return () => false; + } + } + + /** + * Observes specified event **once** + * @alias once + * @param {string} eventName Event name (eg. 'after:render') + * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + * @param {Function} handler Function that receives a notification when an event of the specified type occurs + * @return {Function} disposer + */ + + once(arg0, handler) { + if (typeof arg0 === 'object') { + // one object with key/value pairs was passed + const disposers = []; + Object.entries(arg0).forEach(_ref2 => { + let [eventName, handler] = _ref2; + disposers.push(this.once(eventName, handler)); + }); + return () => disposers.forEach(d => d()); + } else if (handler) { + const disposer = this.on(arg0, function onceHandler() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + handler.call(this, ...args); + disposer(); + }); + return disposer; + } else { + // noop + return () => false; + } + } + + /** + * @private + * @param {string} eventName + * @param {Function} [handler] + */ + _removeEventListener(eventName, handler) { + if (!this.__eventListeners[eventName]) { + return; + } + if (handler) { + const eventListener = this.__eventListeners[eventName]; + const index = eventListener.indexOf(handler); + index > -1 && eventListener.splice(index, 1); + } else { + this.__eventListeners[eventName] = []; + } + } + + /** + * Unsubscribe all event listeners for eventname. + * Do not use this pattern. You could kill internal fabricJS events. + * We know we should have protected events for internal flows, but we don't have yet + * @deprecated + * @param {string} eventName event name (eg. 'after:render') + */ + + /** + * unsubscribe an event listener + * @param {string} eventName event name (eg. 'after:render') + * @param {TEventCallback} handler event listener to unsubscribe + */ + + /** + * unsubscribe event listeners + * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler}) + */ + + /** + * unsubscribe all event listeners + */ + + off(arg0, handler) { + if (!this.__eventListeners) { + return; + } + + // remove all key/value pairs (event name -> event handler) + if (typeof arg0 === 'undefined') { + for (const eventName in this.__eventListeners) { + this._removeEventListener(eventName); + } + } + // one object with key/value pairs was passed + else if (typeof arg0 === 'object') { + Object.entries(arg0).forEach(_ref3 => { + let [eventName, handler] = _ref3; + this._removeEventListener(eventName, handler); + }); + } else { + this._removeEventListener(arg0, handler); + } + } + + /** + * Fires event with an optional options object + * @param {String} eventName Event name to fire + * @param {Object} [options] Options object + */ + fire(eventName, options) { + var _this$__eventListener; + if (!this.__eventListeners) { + return; + } + const listenersForEvent = (_this$__eventListener = this.__eventListeners[eventName]) === null || _this$__eventListener === void 0 ? void 0 : _this$__eventListener.concat(); + if (listenersForEvent) { + for (let i = 0; i < listenersForEvent.length; i++) { + listenersForEvent[i].call(this, options || {}); + } + } + } +} + +/** + * Removes value from an array. + * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf` + * @param {Array} array + * @param {*} value + * @return {Array} original array + */ +const removeFromArray = (array, value) => { + const idx = array.indexOf(value); + if (idx !== -1) { + array.splice(idx, 1); + } + return array; +}; + +/** + * Calculate the cos of an angle, avoiding returning floats for known results + * This function is here just to avoid getting 0.999999999999999 when dealing + * with numbers that are really 1 or 0. + * @param {TRadian} angle the angle + * @return {Number} the cosin value for angle. + */ +const cos = angle => { + if (angle === 0) { + return 1; + } + const angleSlice = Math.abs(angle) / halfPI; + switch (angleSlice) { + case 1: + case 3: + return 0; + case 2: + return -1; + } + return Math.cos(angle); +}; + +/** + * Calculate the cos of an angle, avoiding returning floats for known results + * This function is here just to avoid getting 0.999999999999999 when dealing + * with numbers that are really 1 or 0. + * @param {TRadian} angle the angle + * @return {Number} the sin value for angle. + */ +const sin = angle => { + if (angle === 0) { + return 0; + } + const angleSlice = angle / halfPI; + const value = Math.sign(angle); + switch (angleSlice) { + case 1: + return value; + case 2: + return 0; + case 3: + return -value; + } + return Math.sin(angle); +}; + +/** + * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com) + */ +class Point { + constructor() { + let arg0 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + if (typeof arg0 === 'object') { + this.x = arg0.x; + this.y = arg0.y; + } else { + this.x = arg0; + this.y = y; + } + } + + /** + * Adds another point to this one and returns another one + * @param {XY} that + * @return {Point} new Point instance with added values + */ + add(that) { + return new Point(this.x + that.x, this.y + that.y); + } + + /** + * Adds another point to this one + * @param {XY} that + * @return {Point} thisArg + * @chainable + * @deprecated + */ + addEquals(that) { + this.x += that.x; + this.y += that.y; + return this; + } + + /** + * Adds value to this point and returns a new one + * @param {Number} scalar + * @return {Point} new Point with added value + */ + scalarAdd(scalar) { + return new Point(this.x + scalar, this.y + scalar); + } + + /** + * Adds value to this point + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarAddEquals(scalar) { + this.x += scalar; + this.y += scalar; + return this; + } + + /** + * Subtracts another point from this point and returns a new one + * @param {XY} that + * @return {Point} new Point object with subtracted values + */ + subtract(that) { + return new Point(this.x - that.x, this.y - that.y); + } + + /** + * Subtracts another point from this point + * @param {XY} that + * @return {Point} thisArg + * @chainable + * @deprecated + */ + subtractEquals(that) { + this.x -= that.x; + this.y -= that.y; + return this; + } + + /** + * Subtracts value from this point and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarSubtract(scalar) { + return new Point(this.x - scalar, this.y - scalar); + } + + /** + * Subtracts value from this point + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarSubtractEquals(scalar) { + this.x -= scalar; + this.y -= scalar; + return this; + } + + /** + * Multiplies this point by another value and returns a new one + * @param {XY} that + * @return {Point} + */ + multiply(that) { + return new Point(this.x * that.x, this.y * that.y); + } + + /** + * Multiplies this point by a value and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarMultiply(scalar) { + return new Point(this.x * scalar, this.y * scalar); + } + + /** + * Multiplies this point by a value + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarMultiplyEquals(scalar) { + this.x *= scalar; + this.y *= scalar; + return this; + } + + /** + * Divides this point by another and returns a new one + * @param {XY} that + * @return {Point} + */ + divide(that) { + return new Point(this.x / that.x, this.y / that.y); + } + + /** + * Divides this point by a value and returns a new one + * @param {Number} scalar + * @return {Point} + */ + scalarDivide(scalar) { + return new Point(this.x / scalar, this.y / scalar); + } + + /** + * Divides this point by a value + * @param {Number} scalar + * @return {Point} thisArg + * @chainable + * @deprecated + */ + scalarDivideEquals(scalar) { + this.x /= scalar; + this.y /= scalar; + return this; + } + + /** + * Returns true if this point is equal to another one + * @param {XY} that + * @return {Boolean} + */ + eq(that) { + return this.x === that.x && this.y === that.y; + } + + /** + * Returns true if this point is less than another one + * @param {XY} that + * @return {Boolean} + */ + lt(that) { + return this.x < that.x && this.y < that.y; + } + + /** + * Returns true if this point is less than or equal to another one + * @param {XY} that + * @return {Boolean} + */ + lte(that) { + return this.x <= that.x && this.y <= that.y; + } + + /** + * Returns true if this point is greater another one + * @param {XY} that + * @return {Boolean} + */ + gt(that) { + return this.x > that.x && this.y > that.y; + } + + /** + * Returns true if this point is greater than or equal to another one + * @param {XY} that + * @return {Boolean} + */ + gte(that) { + return this.x >= that.x && this.y >= that.y; + } + + /** + * Returns new point which is the result of linear interpolation with this one and another one + * @param {XY} that + * @param {Number} t , position of interpolation, between 0 and 1 default 0.5 + * @return {Point} + */ + lerp(that) { + let t = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.5; + t = Math.max(Math.min(1, t), 0); + return new Point(this.x + (that.x - this.x) * t, this.y + (that.y - this.y) * t); + } + + /** + * Returns distance from this point and another one + * @param {XY} that + * @return {Number} + */ + distanceFrom(that) { + const dx = this.x - that.x, + dy = this.y - that.y; + return Math.sqrt(dx * dx + dy * dy); + } + + /** + * Returns the point between this point and another one + * @param {XY} that + * @return {Point} + */ + midPointFrom(that) { + return this.lerp(that); + } + + /** + * Returns a new point which is the min of this and another one + * @param {XY} that + * @return {Point} + */ + min(that) { + return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y)); + } + + /** + * Returns a new point which is the max of this and another one + * @param {XY} that + * @return {Point} + */ + max(that) { + return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y)); + } + + /** + * Returns string representation of this point + * @return {String} + */ + toString() { + return "".concat(this.x, ",").concat(this.y); + } + + /** + * Sets x/y of this point + * @param {Number} x + * @param {Number} y + * @chainable + */ + setXY(x, y) { + this.x = x; + this.y = y; + return this; + } + + /** + * Sets x of this point + * @param {Number} x + * @chainable + */ + setX(x) { + this.x = x; + return this; + } + + /** + * Sets y of this point + * @param {Number} y + * @chainable + */ + setY(y) { + this.y = y; + return this; + } + + /** + * Sets x/y of this point from another point + * @param {XY} that + * @chainable + */ + setFromPoint(that) { + this.x = that.x; + this.y = that.y; + return this; + } + + /** + * Swaps x/y of this point and another point + * @param {XY} that + */ + swap(that) { + const x = this.x, + y = this.y; + this.x = that.x; + this.y = that.y; + that.x = x; + that.y = y; + } + + /** + * return a cloned instance of the point + * @return {Point} + */ + clone() { + return new Point(this.x, this.y); + } + + /** + * Rotates `point` around `origin` with `radians` + * @static + * @memberOf fabric.util + * @param {XY} origin The origin of the rotation + * @param {TRadian} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ + rotate(radians) { + let origin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ZERO; + // TODO benchmark and verify the add and subtract how much cost + // and then in case early return if no origin is passed + const sinus = sin(radians), + cosinus = cos(radians); + const p = this.subtract(origin); + const rotated = new Point(p.x * cosinus - p.y * sinus, p.x * sinus + p.y * cosinus); + return rotated.add(origin); + } + + /** + * Apply transform t to point p + * @static + * @memberOf fabric.util + * @param {TMat2D} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {Point} The transformed point + */ + transform(t) { + let ignoreOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return new Point(t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]), t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5])); + } +} +const ZERO = new Point(0, 0); + +const isCollection = fabricObject => { + return !!fabricObject && Array.isArray(fabricObject._objects); +}; +function createCollectionMixin(Base) { + class Collection extends Base { + constructor() { + super(...arguments); + /** + * @type {FabricObject[]} + * @TODO needs to end up in the constructor too + */ + _defineProperty(this, "_objects", []); + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onObjectAdded(object) { + // subclasses should override this method + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onObjectRemoved(object) { + // subclasses should override this method + } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + _onStackOrderChanged(object) { + // subclasses should override this method + } + + /** + * Adds objects to collection + * Objects should be instances of (or inherit from) FabricObject + * @param {...FabricObject[]} objects to add + * @returns {number} new array length + */ + add() { + for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { + objects[_key] = arguments[_key]; + } + const size = this._objects.push(...objects); + objects.forEach(object => this._onObjectAdded(object)); + return size; + } + + /** + * Inserts an object into collection at specified index + * @param {number} index Index to insert object at + * @param {...FabricObject[]} objects Object(s) to insert + * @returns {number} new array length + */ + insertAt(index) { + for (var _len2 = arguments.length, objects = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + objects[_key2 - 1] = arguments[_key2]; + } + this._objects.splice(index, 0, ...objects); + objects.forEach(object => this._onObjectAdded(object)); + return this._objects.length; + } + + /** + * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`) + * @private + * @param {...FabricObject[]} objects objects to remove + * @returns {FabricObject[]} removed objects + */ + remove() { + const array = this._objects, + removed = []; + for (var _len3 = arguments.length, objects = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + objects[_key3] = arguments[_key3]; + } + objects.forEach(object => { + const index = array.indexOf(object); + // only call onObjectRemoved if an object was actually removed + if (index !== -1) { + array.splice(index, 1); + removed.push(object); + this._onObjectRemoved(object); + } + }); + return removed; + } + + /** + * Executes given function for each object in this group + * A simple shortcut for getObjects().forEach, before es6 was more complicated, + * now is just a shortcut. + * @param {Function} callback + * Callback invoked with current object as first argument, + * index - as second and an array of all objects - as third. + */ + forEachObject(callback) { + this.getObjects().forEach((object, index, objects) => callback(object, index, objects)); + } + + /** + * Returns an array of children objects of this instance + * @param {...String} [types] When specified, only objects of these types are returned + * @return {Array} + */ + getObjects() { + for (var _len4 = arguments.length, types = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + types[_key4] = arguments[_key4]; + } + if (types.length === 0) { + return [...this._objects]; + } + return this._objects.filter(o => o.isType(...types)); + } + + /** + * Returns object at specified index + * @param {Number} index + * @return {Object} object at index + */ + item(index) { + return this._objects[index]; + } + + /** + * Returns true if collection contains no objects + * @return {Boolean} true if collection is empty + */ + isEmpty() { + return this._objects.length === 0; + } + + /** + * Returns a size of a collection (i.e: length of an array containing its objects) + * @return {Number} Collection size + */ + size() { + return this._objects.length; + } + + /** + * Returns true if collection contains an object.\ + * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons** + * instead of `a.contains(b)` use `b.isDescendantOf(a)` + * @param {Object} object Object to check against + * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects` + * @return {Boolean} `true` if collection contains an object + */ + contains(object, deep) { + if (this._objects.includes(object)) { + return true; + } else if (deep) { + return this._objects.some(obj => obj instanceof Collection && obj.contains(object, true)); + } + return false; + } + + /** + * Returns number representation of a collection complexity + * @return {Number} complexity + */ + complexity() { + return this._objects.reduce((memo, current) => { + memo += current.complexity ? current.complexity() : 0; + return memo; + }, 0); + } + + /** + * Moves an object or the objects of a multiple selection + * to the bottom of the stack of drawn objects + * @param {fabric.Object} object Object to send to back + * @returns {boolean} true if change occurred + */ + sendObjectToBack(object) { + if (!object || object === this._objects[0]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.unshift(object); + this._onStackOrderChanged(object); + return true; + } + + /** + * Moves an object or the objects of a multiple selection + * to the top of the stack of drawn objects + * @param {fabric.Object} object Object to send + * @returns {boolean} true if change occurred + */ + bringObjectToFront(object) { + if (!object || object === this._objects[this._objects.length - 1]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.push(object); + this._onStackOrderChanged(object); + return true; + } + + /** + * Moves an object or a selection down in stack of drawn objects + * An optional parameter, `intersecting` allows to move the object in behind + * the first intersecting object. Where intersection is calculated with + * bounding box. If no intersection is found, there will not be change in the + * stack. + * @param {fabric.Object} object Object to send + * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object + * @returns {boolean} true if change occurred + */ + sendObjectBackwards(object, intersecting) { + if (!object) { + return false; + } + const idx = this._objects.indexOf(object); + if (idx !== 0) { + // if object is not on the bottom of stack + const newIdx = this.findNewLowerIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this._onStackOrderChanged(object); + return true; + } + return false; + } + + /** + * Moves an object or a selection up in stack of drawn objects + * An optional parameter, intersecting allows to move the object in front + * of the first intersecting object. Where intersection is calculated with + * bounding box. If no intersection is found, there will not be change in the + * stack. + * @param {fabric.Object} object Object to send + * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object + * @returns {boolean} true if change occurred + */ + bringObjectForward(object, intersecting) { + if (!object) { + return false; + } + const idx = this._objects.indexOf(object); + if (idx !== this._objects.length - 1) { + // if object is not on top of stack (last item in an array) + const newIdx = this.findNewUpperIndex(object, idx, intersecting); + removeFromArray(this._objects, object); + this._objects.splice(newIdx, 0, object); + this._onStackOrderChanged(object); + return true; + } + return false; + } + + /** + * Moves an object to specified level in stack of drawn objects + * @param {fabric.Object} object Object to send + * @param {number} index Position to move to + * @returns {boolean} true if change occurred + */ + moveObjectTo(object, index) { + if (object === this._objects[index]) { + return false; + } + removeFromArray(this._objects, object); + this._objects.splice(index, 0, object); + this._onStackOrderChanged(object); + return true; + } + findNewLowerIndex(object, idx, intersecting) { + let newIdx; + if (intersecting) { + newIdx = idx; + // traverse down the stack looking for the nearest intersecting object + for (let i = idx - 1; i >= 0; --i) { + if (object.isOverlapping(this._objects[i])) { + newIdx = i; + break; + } + } + } else { + newIdx = idx - 1; + } + return newIdx; + } + findNewUpperIndex(object, idx, intersecting) { + let newIdx; + if (intersecting) { + newIdx = idx; + // traverse up the stack looking for the nearest intersecting object + for (let i = idx + 1; i < this._objects.length; ++i) { + if (object.isOverlapping(this._objects[i])) { + newIdx = i; + break; + } + } + } else { + newIdx = idx + 1; + } + return newIdx; + } + + /** + * Given a bounding box, return all the objects of the collection that are contained in the bounding box. + * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well. + * This is meant to work with selection. Is not a generic method. + * @param {TBBox} bbox a bounding box in scene coordinates + * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting + * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise + */ + collectObjects(_ref) { + let { + left, + top, + width, + height + } = _ref; + let { + includeIntersecting = true + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const objects = [], + tl = new Point(left, top), + br = tl.add(new Point(width, height)); + + // we iterate reverse order to collect top first in case of click. + for (let i = this._objects.length - 1; i >= 0; i--) { + const object = this._objects[i]; + if (object.selectable && object.visible && (includeIntersecting && object.intersectsWithRect(tl, br) || object.isContainedWithinRect(tl, br) || includeIntersecting && object.containsPoint(tl) || includeIntersecting && object.containsPoint(br))) { + objects.push(object); + } + } + return objects; + } + } + + // https://github.com/microsoft/TypeScript/issues/32080 + return Collection; +} + +class CommonMethods extends Observable { + /** + * Sets object's properties from options, for initialization only + * @protected + * @param {Object} [options] Options object + */ + _setOptions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + for (const prop in options) { + this.set(prop, options[prop]); + } + } + + /** + * @private + */ + _setObject(obj) { + for (const prop in obj) { + this._set(prop, obj[prop]); + } + } + + /** + * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. + * @param {String|Object} key Property name or object (if object, iterate over the object properties) + * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) + */ + set(key, value) { + if (typeof key === 'object') { + this._setObject(key); + } else { + this._set(key, value); + } + return this; + } + _set(key, value) { + this[key] = value; + } + + /** + * Toggles specified property from `true` to `false` or from `false` to `true` + * @param {String} property Property to toggle + */ + toggle(property) { + const value = this.get(property); + if (typeof value === 'boolean') { + this.set(property, !value); + } + return this; + } + + /** + * Basic getter + * @param {String} property Property name + * @return {*} value of a property + */ + get(property) { + return this[property]; + } +} + +function requestAnimFrame(callback) { + return getFabricWindow().requestAnimationFrame(callback); +} +function cancelAnimFrame(handle) { + return getFabricWindow().cancelAnimationFrame(handle); +} + +let id = 0; +const uid = () => id++; + +/** + * Creates canvas element + * @return {CanvasElement} initialized canvas element + */ +const createCanvasElement = () => { + const element = getFabricDocument().createElement('canvas'); + if (!element || typeof element.getContext === 'undefined') { + throw new FabricError('Failed to create `canvas` element'); + } + return element; +}; + +/** + * Creates image element (works on client and node) + * @return {HTMLImageElement} HTML image element + */ +const createImage = () => getFabricDocument().createElement('img'); + +/** + * Creates a canvas element that is a copy of another and is also painted + * @param {CanvasElement} canvas to copy size and content of + * @return {CanvasElement} initialized canvas element + */ +const copyCanvasElement = canvas => { + var _newCanvas$getContext; + const newCanvas = createCanvasElement(); + newCanvas.width = canvas.width; + newCanvas.height = canvas.height; + (_newCanvas$getContext = newCanvas.getContext('2d')) === null || _newCanvas$getContext === void 0 || _newCanvas$getContext.drawImage(canvas, 0, 0); + return newCanvas; +}; + +/** + * since 2.6.0 moved from canvas instance to utility. + * possibly useless + * @param {CanvasElement} canvasEl to copy size and content of + * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too + * @param {Number} quality <= 1 and > 0 + * @return {String} data url + */ +const toDataURL = (canvasEl, format, quality) => canvasEl.toDataURL("image/".concat(format), quality); +const isHTMLCanvas = canvas => { + return !!canvas && canvas.getContext !== undefined; +}; + +/** + * Transforms degrees to radians. + * @param {TDegree} degrees value in degrees + * @return {TRadian} value in radians + */ +const degreesToRadians = degrees => degrees * PiBy180; + +/** + * Transforms radians to degrees. + * @param {TRadian} radians value in radians + * @return {TDegree} value in degrees + */ +const radiansToDegrees = radians => radians / PiBy180; + +const isIdentityMatrix = mat => mat.every((value, index) => value === iMatrix[index]); + +/** + * Apply transform t to point p + * @deprecated use {@link Point#transform} + * @param {Point | XY} p The point to transform + * @param {Array} t The transform + * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied + * @return {Point} The transformed point + */ +const transformPoint = (p, t, ignoreOffset) => new Point(p).transform(t, ignoreOffset); + +/** + * Invert transformation t + * @param {Array} t The transform + * @return {Array} The inverted transform + */ +const invertTransform = t => { + const a = 1 / (t[0] * t[3] - t[1] * t[2]), + r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0], + { + x, + y + } = new Point(t[4], t[5]).transform(r, true); + r[4] = -x; + r[5] = -y; + return r; +}; + +/** + * Multiply matrix A by matrix B to nest transformations + * @param {TMat2D} a First transformMatrix + * @param {TMat2D} b Second transformMatrix + * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices + * @return {TMat2D} The product of the two transform matrices + */ +const multiplyTransformMatrices = (a, b, is2x2) => [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4], is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5]]; + +/** + * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it + * + * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))` + * + * @param matrices an array of matrices + * @param [is2x2] flag to multiply matrices as 2x2 matrices + * @returns the multiplication product + */ +const multiplyTransformMatrixArray = (matrices, is2x2) => matrices.reduceRight((product, curr) => curr && product ? multiplyTransformMatrices(curr, product, is2x2) : curr || product, undefined) || iMatrix.concat(); +const calcPlaneRotation = _ref => { + let [a, b] = _ref; + return Math.atan2(b, a); +}; + +/** + * Decomposes standard 2x3 matrix into transform components + * @param {TMat2D} a transformMatrix + * @return {Object} Components of transform + */ +const qrDecompose = a => { + const angle = calcPlaneRotation(a), + denom = Math.pow(a[0], 2) + Math.pow(a[1], 2), + scaleX = Math.sqrt(denom), + scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, + skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom); + return { + angle: radiansToDegrees(angle), + scaleX, + scaleY, + skewX: radiansToDegrees(skewX), + skewY: 0, + translateX: a[4] || 0, + translateY: a[5] || 0 + }; +}; + +/** + * Generate a translation matrix + * + * A translation matrix in the form of + * [ 1 0 x ] + * [ 0 1 y ] + * [ 0 0 1 ] + * + * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details + * + * @param {number} x translation on X axis + * @param {number} [y] translation on Y axis + * @returns {TMat2D} matrix + */ +const createTranslateMatrix = function (x) { + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + return [1, 0, 0, 1, x, y]; +}; + +/** + * Generate a rotation matrix around around a point (x,y), defaulting to (0,0) + * + * A matrix in the form of + * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x] + * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y] + * [0 0 1 ] + * + * + * @param {TDegree} angle rotation in degrees + * @param {XY} [pivotPoint] pivot point to rotate around + * @returns {TMat2D} matrix + */ +function createRotateMatrix() { + let { + angle = 0 + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let { + x = 0, + y = 0 + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const angleRadiant = degreesToRadians(angle), + cosValue = cos(angleRadiant), + sinValue = sin(angleRadiant); + return [cosValue, sinValue, -sinValue, cosValue, x ? x - (cosValue * x - sinValue * y) : 0, y ? y - (sinValue * x + cosValue * y) : 0]; +} + +/** + * Generate a scale matrix around the point (0,0) + * + * A matrix in the form of + * [x 0 0] + * [0 y 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale + * + * @param {number} x scale on X axis + * @param {number} [y] scale on Y axis + * @returns {TMat2D} matrix + */ +const createScaleMatrix = function (x) { + let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + return [x, 0, 0, y, 0, 0]; +}; +const angleToSkew = angle => Math.tan(degreesToRadians(angle)); + +/** + * Generate a skew matrix for the X axis + * + * A matrix in the form of + * [1 x 0] + * [0 1 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx + * + * @param {TDegree} skewValue translation on X axis + * @returns {TMat2D} matrix + */ +const createSkewXMatrix = skewValue => [1, 0, angleToSkew(skewValue), 1, 0, 0]; + +/** + * Generate a skew matrix for the Y axis + * + * A matrix in the form of + * [1 0 0] + * [y 1 0] + * [0 0 1] + * + * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy + * + * @param {TDegree} skewValue translation on Y axis + * @returns {TMat2D} matrix + */ +const createSkewYMatrix = skewValue => [1, angleToSkew(skewValue), 0, 1, 0, 0]; + +/** + * Returns a transform matrix starting from an object of the same kind of + * the one returned from qrDecompose, useful also if you want to calculate some + * transformations from an object that is not enlived yet. + * is called DimensionsTransformMatrix because those properties are the one that influence + * the size of the resulting box of the object. + * @param {Object} options + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Boolean} [options.flipX] + * @param {Boolean} [options.flipY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @return {Number[]} transform matrix + */ +const calcDimensionsMatrix = _ref2 => { + let { + scaleX = 1, + scaleY = 1, + flipX = false, + flipY = false, + skewX = 0, + skewY = 0 + } = _ref2; + let matrix = createScaleMatrix(flipX ? -scaleX : scaleX, flipY ? -scaleY : scaleY); + if (skewX) { + matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true); + } + if (skewY) { + matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true); + } + return matrix; +}; + +/** + * Returns a transform matrix starting from an object of the same kind of + * the one returned from qrDecompose, useful also if you want to calculate some + * transformations from an object that is not enlived yet + * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs + * @param {Object} options + * @param {Number} [options.angle] + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Boolean} [options.flipX] + * @param {Boolean} [options.flipY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @param {Number} [options.translateX] + * @param {Number} [options.translateY] + * @return {Number[]} transform matrix + */ +const composeMatrix = options => { + const { + translateX = 0, + translateY = 0, + angle = 0 + } = options; + let matrix = createTranslateMatrix(translateX, translateY); + if (angle) { + matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ + angle + })); + } + const scaleMatrix = calcDimensionsMatrix(options); + if (!isIdentityMatrix(scaleMatrix)) { + matrix = multiplyTransformMatrices(matrix, scaleMatrix); + } + return matrix; +}; + +/** + * Loads image element from given url and resolve it, or catch. + * @param {String} url URL representing an image + * @param {LoadImageOptions} [options] image loading options + * @returns {Promise} the loaded image. + */ +const loadImage = function (url) { + let { + signal, + crossOrigin = null + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise(function (resolve, reject) { + if (signal && signal.aborted) { + return reject(new SignalAbortedError('loadImage')); + } + const img = createImage(); + let abort; + if (signal) { + abort = function (err) { + img.src = ''; + reject(err); + }; + signal.addEventListener('abort', abort, { + once: true + }); + } + const done = function () { + img.onload = img.onerror = null; + abort && (signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', abort)); + resolve(img); + }; + if (!url) { + done(); + return; + } + img.onload = done; + img.onerror = function () { + abort && (signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', abort)); + reject(new FabricError("Error loading ".concat(img.src))); + }; + crossOrigin && (img.crossOrigin = crossOrigin); + img.src = url; + }); +}; +/** + * @TODO type this correctly. + * Creates corresponding fabric instances from their object representations + * @param {Object[]} objects Objects to enliven + * @param {EnlivenObjectOptions} [options] + * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements, + * called after each fabric object created. + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ +const enlivenObjects = function (objects) { + let { + signal, + reviver = noop + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise((resolve, reject) => { + const instances = []; + signal && signal.addEventListener('abort', reject, { + once: true + }); + Promise.all(objects.map(obj => classRegistry.getClass(obj.type).fromObject(obj, { + signal + }).then(fabricInstance => { + reviver(obj, fabricInstance); + instances.push(fabricInstance); + return fabricInstance; + }))).then(resolve).catch(error => { + // cleanup + instances.forEach(instance => { + instance.dispose && instance.dispose(); + }); + reject(error); + }).finally(() => { + signal && signal.removeEventListener('abort', reject); + }); + }); +}; + +/** + * Creates corresponding fabric instances residing in an object, e.g. `clipPath` + * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path ) + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise>} the input object with enlived values + */ +const enlivenObjectEnlivables = function (serializedObject) { + let { + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return new Promise((resolve, reject) => { + const instances = []; + signal && signal.addEventListener('abort', reject, { + once: true + }); + // enlive every possible property + const promises = Object.values(serializedObject).map(value => { + if (!value) { + return value; + } + /** + * clipPath or shadow or gradient or text on a path or a pattern, + * or the backgroundImage or overlayImage of canvas + * If we have a type and there is a classe registered for it, we enlive it. + * If there is no class registered for it we return the value as is + * */ + if (value.type && classRegistry.has(value.type)) { + return enlivenObjects([value], { + signal + }).then(_ref => { + let [enlived] = _ref; + instances.push(enlived); + return enlived; + }); + } + return value; + }); + const keys = Object.keys(serializedObject); + Promise.all(promises).then(enlived => { + return enlived.reduce((acc, instance, index) => { + acc[keys[index]] = instance; + return acc; + }, {}); + }).then(resolve).catch(error => { + // cleanup + instances.forEach(instance => { + instance.dispose && instance.dispose(); + }); + reject(error); + }).finally(() => { + signal && signal.removeEventListener('abort', reject); + }); + }); +}; + +/** + * Populates an object with properties of another object + * @param {Object} source Source object + * @param {string[]} properties Properties names to include + * @returns object populated with the picked keys + */ +const pick = function (source) { + let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; + return keys.reduce((o, key) => { + if (key in source) { + o[key] = source[key]; + } + return o; + }, {}); +}; +const pickBy = (source, predicate) => { + return Object.keys(source).reduce((o, key) => { + if (predicate(source[key], key, source)) { + o[key] = source[key]; + } + return o; + }, {}); +}; + +/** + * Map of the 148 color names with HEX code + * @see: https://www.w3.org/TR/css3-color/#svg-color + */ +const ColorNameMap = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aqua: '#0FF', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000', + blanchedalmond: '#FFEBCD', + blue: '#00F', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#0FF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgrey: '#A9A9A9', + darkgreen: '#006400', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + fuchsia: '#F0F', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + gray: '#808080', + grey: '#808080', + green: '#008000', + greenyellow: '#ADFF2F', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgray: '#D3D3D3', + lightgrey: '#D3D3D3', + lightgreen: '#90EE90', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#789', + lightslategrey: '#789', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + lime: '#0F0', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#F0F', + maroon: '#800000', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + navy: '#000080', + oldlace: '#FDF5E6', + olive: '#808000', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + purple: '#800080', + rebeccapurple: '#639', + red: '#F00', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + silver: '#C0C0C0', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + teal: '#008080', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + white: '#FFF', + whitesmoke: '#F5F5F5', + yellow: '#FF0', + yellowgreen: '#9ACD32' +}; + +/** + * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`) + * Also matching rgba(r g b / a) as per new specs + * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb + * Formal syntax at the time of writing: + * = + * rgb( [ | none ]{3} [ / [ | none ] ]? ) | + * rgb( [ | none ]{3} [ / [ | none ] ]? ) + * = | + * + * For learners this is how you can read this regex + * Regular expression for matching an rgba or rgb CSS color value + * + * /^ # Beginning of the string + * rgba? # "rgb" or "rgba" + * \(\s* # Opening parenthesis and optional whitespace + * (\d{0,3} # 0 to three digits R channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the first color component + * %? # Optional percent sign after the first color component + * \s* # Optional whitespace + * [\s|,] # Separator between color components can be a space or comma + * \s* # Optional whitespace + * (\d{0,3} # 0 to three digits G channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the second color component + * %? # Optional percent sign after the second color component + * \s* # Optional whitespace + * [\s|,] # Separator between color components can be a space or comma + * \s* # Optional whitespace + * (\d{0,3} # 0 to three digits B channel + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for the third color component + * %? # Optional percent sign after the third color component + * \s* # Optional whitespace + * (?: # Beginning of non-capturing group for alpha value + * \s* # Optional whitespace + * [,/] # Comma or slash separator for alpha value + * \s* # Optional whitespace + * (\d{0,3} # Zero to three digits + * (?:\.\d+)? # Optional decimal with one or more digits + * ) # End of capturing group for alpha value + * %? # Optional percent sign after alpha value + * \s* # Optional whitespace + * )? # End of non-capturing group for alpha value (optional) + * \) # Closing parenthesis + * $ # End of the string + * + * The alpha channel can be in the format 0.4 .7 or 1 or 73% + * + * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color. + * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us + */ +const reRGBa = () => /^rgba?\(\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d{0,3}(?:\.\d+)?%?)\s*)?\)$/i; + +/** + * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5)) + * Also matching rgba(r g b / a) as per new specs + * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl + * Formal syntax at the time of writing: + * = + * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? ) + * + * = + * | + * + * + * = + * | + * + * + * For learners this is how you can read this regex + * Regular expression for matching an hsla or hsl CSS color value + * + * /^hsla?\( // Matches the beginning of the string and the opening parenthesis of "hsl" or "hsla" + * \s* // Matches any whitespace characters (space, tab, etc.) zero or more times + * (\d{0,3} // Hue: 0 to three digits - start capture in a group + * (?:\.\d+)? // Hue: Optional (non capture group) decimal with one or more digits. + * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad + * ) // Hue: End capture group + * \s* // Matches any whitespace characters zero or more times + * [\s|,] // Matches a space, tab or comma + * \s* // Matches any whitespace characters zero or more times + * (\d{0,3} // Saturation: 0 to three digits - start capture in a group + * (?:\.\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group + * %?) // Saturation: match optional % character and end capture group + * \s* // Matches any whitespace characters zero or more times + * [\s|,] // Matches a space, tab or comma + * \s* // Matches any whitespace characters zero or more times + * (\d{0,3} // Lightness: 0 to three digits - start capture in a group + * (?:\.\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group + * %?) // Lightness: match % character and end capture group + * \s* // Matches any whitespace characters zero or more times + * (?: // Alpha: Begins a non-capturing group for the alpha value + * \s* // Matches any whitespace characters zero or more times + * [,/] // Matches a comma or forward slash + * \s* // Matches any whitespace characters zero or more times + * (\d*(?:\.\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group + * \s* // Matches any whitespace characters zero or more times + * )? // Makes the alpha value group optional + * \) // Matches the closing parenthesis + * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode + * + * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color. + * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us. + */ +const reHSLa = () => /^hsla?\(\s*([+-]?\d{0,3}(?:\.\d+)?(?:deg|turn|rad)?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*[\s|,]\s*(\d{0,3}(?:\.\d+)?%?)\s*(?:\s*[,/]\s*(\d*(?:\.\d+)?%?)\s*)?\)$/i; + +/** + * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff) + */ +const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i; + +/** + * @param {Number} p + * @param {Number} q + * @param {Number} t + * @return {Number} + */ +const hue2rgb = (p, q, t) => { + if (t < 0) { + t += 1; + } + if (t > 1) { + t -= 1; + } + if (t < 1 / 6) { + return p + (q - p) * 6 * t; + } + if (t < 1 / 2) { + return q; + } + if (t < 2 / 3) { + return p + (q - p) * (2 / 3 - t) * 6; + } + return p; +}; + +/** + * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson} + * @param {Number} r Red color value + * @param {Number} g Green color value + * @param {Number} b Blue color value + * @param {Number} a Alpha color value pass through + * @return {TRGBColorSource} Hsl color + */ +const rgb2Hsl = (r, g, b, a) => { + r /= 255; + g /= 255; + b /= 255; + const maxValue = Math.max(r, g, b), + minValue = Math.min(r, g, b); + let h, s; + const l = (maxValue + minValue) / 2; + if (maxValue === minValue) { + h = s = 0; // achromatic + } else { + const d = maxValue - minValue; + s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue); + switch (maxValue) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a]; +}; +const fromAlphaToFloat = function () { + let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '1'; + return parseFloat(value) / (value.endsWith('%') ? 100 : 1); +}; + +/** + * Convert a value in the inclusive range [0, 255] to hex + */ +const hexify = value => Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0'); + +/** + * Calculate the grey average value for rgb and pass through alpha + */ +const greyAverage = _ref => { + let [r, g, b, a = 1] = _ref; + const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11); + return [avg, avg, avg, a]; +}; + +/** + * @class Color common color operations + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors} + */ +class Color { + /** + * + * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list + */ + constructor(color) { + _defineProperty(this, "isUnrecognised", false); + if (!color) { + // we default to black as canvas does + this.setSource([0, 0, 0, 1]); + } else if (color instanceof Color) { + this.setSource([...color._source]); + } else if (Array.isArray(color)) { + const [r, g, b, a = 1] = color; + this.setSource([r, g, b, a]); + } else { + this.setSource(this._tryParsingColor(color)); + } + } + + /** + * @private + * @param {string} [color] Color value to parse + * @returns {TRGBAColorSource} + */ + _tryParsingColor(color) { + if (color in ColorNameMap) { + color = ColorNameMap[color]; + } + return color === 'transparent' ? [255, 255, 255, 0] : Color.sourceFromHex(color) || Color.sourceFromRgb(color) || Color.sourceFromHsl(color) || + // color is not recognized + // we default to black as canvas does + // eslint-disable-next-line no-constant-binary-expression + (this.isUnrecognised = true) && [0, 0, 0, 1]; + } + + /** + * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @return {TRGBAColorSource} + */ + getSource() { + return this._source; + } + + /** + * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1]) + * @param {TRGBAColorSource} source + */ + setSource(source) { + this._source = source; + } + + /** + * Returns color representation in RGB format + * @return {String} ex: rgb(0-255,0-255,0-255) + */ + toRgb() { + const [r, g, b] = this.getSource(); + return "rgb(".concat(r, ",").concat(g, ",").concat(b, ")"); + } + + /** + * Returns color representation in RGBA format + * @return {String} ex: rgba(0-255,0-255,0-255,0-1) + */ + toRgba() { + return "rgba(".concat(this.getSource().join(','), ")"); + } + + /** + * Returns color representation in HSL format + * @return {String} ex: hsl(0-360,0%-100%,0%-100%) + */ + toHsl() { + const [h, s, l] = rgb2Hsl(...this.getSource()); + return "hsl(".concat(h, ",").concat(s, "%,").concat(l, "%)"); + } + + /** + * Returns color representation in HSLA format + * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1) + */ + toHsla() { + const [h, s, l, a] = rgb2Hsl(...this.getSource()); + return "hsla(".concat(h, ",").concat(s, "%,").concat(l, "%,").concat(a, ")"); + } + + /** + * Returns color representation in HEX format + * @return {String} ex: FF5555 + */ + toHex() { + const fullHex = this.toHexa(); + return fullHex.slice(0, 6); + } + + /** + * Returns color representation in HEXA format + * @return {String} ex: FF5555CC + */ + toHexa() { + const [r, g, b, a] = this.getSource(); + return "".concat(hexify(r)).concat(hexify(g)).concat(hexify(b)).concat(hexify(Math.round(a * 255))); + } + + /** + * Gets value of alpha channel for this color + * @return {Number} 0-1 + */ + getAlpha() { + return this.getSource()[3]; + } + + /** + * Sets value of alpha channel for this color + * @param {Number} alpha Alpha value 0-1 + * @return {Color} thisArg + */ + setAlpha(alpha) { + this._source[3] = alpha; + return this; + } + + /** + * Transforms color to its grayscale representation + * @return {Color} thisArg + */ + toGrayscale() { + this.setSource(greyAverage(this.getSource())); + return this; + } + + /** + * Transforms color to its black and white representation + * @param {Number} threshold + * @return {Color} thisArg + */ + toBlackWhite(threshold) { + const [average,,, a] = greyAverage(this.getSource()), + bOrW = average < (threshold || 127) ? 0 : 255; + this.setSource([bOrW, bOrW, bOrW, a]); + return this; + } + + /** + * Overlays color with another color + * @param {String|Color} otherColor + * @return {Color} thisArg + */ + overlayWith(otherColor) { + if (!(otherColor instanceof Color)) { + otherColor = new Color(otherColor); + } + const source = this.getSource(), + otherAlpha = 0.5, + otherSource = otherColor.getSource(), + [R, G, B] = source.map((value, index) => Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha)); + this.setSource([R, G, B, source[3]]); + return this; + } + + /** + * Returns new color object, when given a color in RGB format + * @memberOf Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255) + * @return {Color} + */ + static fromRgb(color) { + return Color.fromRgba(color); + } + + /** + * Returns new color object, when given a color in RGBA format + * @static + * @function + * @memberOf Color + * @param {String} color + * @return {Color} + */ + static fromRgba(color) { + return new Color(Color.sourceFromRgb(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format + * @memberOf Color + * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%) + * @return {TRGBAColorSource | undefined} source + */ + static sourceFromRgb(color) { + const match = color.match(reRGBa()); + if (match) { + const [r, g, b] = match.slice(1, 4).map(value => { + const parsedValue = parseFloat(value); + return value.endsWith('%') ? Math.round(parsedValue * 2.55) : parsedValue; + }); + return [r, g, b, fromAlphaToFloat(match[4])]; + } + } + + /** + * Returns new color object, when given a color in HSL format + * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%) + * @memberOf Color + * @return {Color} + */ + static fromHsl(color) { + return Color.fromHsla(color); + } + + /** + * Returns new color object, when given a color in HSLA format + * @static + * @function + * @memberOf Color + * @param {String} color + * @return {Color} + */ + static fromHsla(color) { + return new Color(Color.sourceFromHsl(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format. + * Adapted from https://github.com/mjijackson + * @memberOf Color + * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1) + * @return {TRGBAColorSource | undefined} source + * @see http://http://www.w3.org/TR/css3-color/#hsl-color + */ + static sourceFromHsl(color) { + const match = color.match(reHSLa()); + if (!match) { + return; + } + const match1degrees = Color.parseAngletoDegrees(match[1]); + const h = (match1degrees % 360 + 360) % 360 / 360, + s = parseFloat(match[2]) / 100, + l = parseFloat(match[3]) / 100; + let r, g, b; + if (s === 0) { + r = g = b = l; + } else { + const q = l <= 0.5 ? l * (s + 1) : l + s - l * s, + p = l * 2 - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), fromAlphaToFloat(match[4])]; + } + + /** + * Returns new color object, when given a color in HEX format + * @static + * @memberOf Color + * @param {String} color Color value ex: FF5555 + * @return {Color} + */ + static fromHex(color) { + return new Color(Color.sourceFromHex(color)); + } + + /** + * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format + * @static + * @memberOf Color + * @param {String} color ex: FF5555 or FF5544CC (RGBa) + * @return {TRGBAColorSource | undefined} source + */ + static sourceFromHex(color) { + if (color.match(reHex())) { + const value = color.slice(color.indexOf('#') + 1), + isShortNotation = value.length <= 4; + let expandedValue; + if (isShortNotation) { + expandedValue = value.split('').map(hex => hex + hex); + } else { + expandedValue = value.match(/.{2}/g); + } + const [r, g, b, a = 255] = expandedValue.map(hexCouple => parseInt(hexCouple, 16)); + return [r, g, b, a / 255]; + } + } + + /** + * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad) + * into degrees without the 'deg' suffix + * @static + * @memberOf Color + * @param {String} value ex: 0deg, 0.5turn, 2rad + * @return {Number} number in degrees or NaN if inputs are invalid + */ + static parseAngletoDegrees(value) { + const lowercase = value.toLowerCase(); + const numeric = parseFloat(lowercase); + if (lowercase.includes('rad')) { + return radiansToDegrees(numeric); + } + if (lowercase.includes('turn')) { + return numeric * 360; + } + + // Value is probably just a number already in degrees eg '50' + return numeric; + } +} + +/** + * A wrapper around Number#toFixed, which contrary to native method returns number, not string. + * @param {number|string} number number to operate on + * @param {number} fractionDigits number of fraction digits to "leave" + * @return {number} + */ +const toFixed = (number, fractionDigits) => parseFloat(Number(number).toFixed(fractionDigits)); + +/** + * Returns array of attributes for given svg that fabric parses + * @param {SVGElementName} type Type of svg element (eg. 'circle') + * @return {Array} string names of supported attributes + */ +const getSvgAttributes = type => { + const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class']; + switch (type) { + case 'linearGradient': + return commonAttributes.concat(['x1', 'y1', 'x2', 'y2', 'gradientUnits', 'gradientTransform']); + case 'radialGradient': + return commonAttributes.concat(['gradientUnits', 'gradientTransform', 'cx', 'cy', 'r', 'fx', 'fy', 'fr']); + case 'stop': + return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']); + } + return commonAttributes; +}; + +/** + * Converts from attribute value to pixel value if applicable. + * Returns converted pixels or original value not converted. + * @param {string} value number to operate on + * @param {number} fontSize + * @return {number} + */ +const parseUnit = function (value) { + let fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_SVG_FONT_SIZE; + const unit = /\D{0,2}$/.exec(value), + number = parseFloat(value); + const dpi = config.DPI; + switch (unit === null || unit === void 0 ? void 0 : unit[0]) { + case 'mm': + return number * dpi / 25.4; + case 'cm': + return number * dpi / 2.54; + case 'in': + return number * dpi; + case 'pt': + return number * dpi / 72; + // or * 4 / 3 + + case 'pc': + return number * dpi / 72 * 12; + // or * 16 + + case 'em': + return number * fontSize; + default: + return number; + } +}; +// align can be either none or undefined or a combination of mid/max +const parseAlign = align => { + //divide align in alignX and alignY + if (align && align !== NONE) { + return [align.slice(1, 4), align.slice(5, 8)]; + } else if (align === NONE) { + return [align, align]; + } + return ['Mid', 'Mid']; +}; + +/** + * Parse preserveAspectRatio attribute from element + * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio + * @param {string} attribute to be parsed + * @return {Object} an object containing align and meetOrSlice attribute + */ +const parsePreserveAspectRatioAttribute = attribute => { + const [firstPart, secondPart] = attribute.trim().split(' '); + const [alignX, alignY] = parseAlign(firstPart); + return { + meetOrSlice: secondPart || 'meet', + alignX, + alignY + }; +}; + +/** + * given an array of 6 number returns something like `"matrix(...numbers)"` + * @param {TMat2D} transform an array with 6 numbers + * @return {String} transform matrix for svg + */ +const matrixToSVG = transform => 'matrix(' + transform.map(value => toFixed(value, config.NUM_FRACTION_DIGITS)).join(' ') + ')'; + +/** + * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values + * we work around it by "moving" alpha channel into opacity attribute and setting fill's alpha to 1 + * @param prop + * @param value + * @param {boolean} inlineStyle The default is inline style, the separator used is ":", The other is "=" + * @returns + */ +const colorPropToSVG = function (prop, value) { + let inlineStyle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + let colorValue; + let opacityValue; + if (!value) { + colorValue = 'none'; + } else if (value.toLive) { + colorValue = "url(#SVGID_".concat(value.id, ")"); + } else { + const color = new Color(value), + opacity = color.getAlpha(); + colorValue = color.toRgb(); + if (opacity !== 1) { + opacityValue = opacity.toString(); + } + } + if (inlineStyle) { + return "".concat(prop, ": ").concat(colorValue, "; ").concat(opacityValue ? "".concat(prop, "-opacity: ").concat(opacityValue, "; ") : ''); + } else { + return "".concat(prop, "=\"").concat(colorValue, "\" ").concat(opacityValue ? "".concat(prop, "-opacity=\"").concat(opacityValue, "\" ") : ''); + } +}; +const createSVGRect = function (color, _ref) { + let { + left, + top, + width, + height + } = _ref; + let precision = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : config.NUM_FRACTION_DIGITS; + const svgColor = colorPropToSVG(FILL, color, false); + const [x, y, w, h] = [left, top, width, height].map(value => toFixed(value, precision)); + return ""); +}; + +const isFiller = filler => { + return !!filler && filler.toLive !== undefined; +}; +const isSerializableFiller = filler => { + return !!filler && typeof filler.toObject === 'function'; +}; +const isPattern = filler => { + return !!filler && filler.offsetX !== undefined && 'source' in filler; +}; +const isTextObject = fabricObject => { + return !!fabricObject && typeof fabricObject._renderText === 'function'; +}; +const isPath = fabricObject => { + // we could use instanceof but that would mean pulling in Text code for a simple check + // @todo discuss what to do and how to do + return !!fabricObject && typeof fabricObject._renderPathCommands === 'function'; +}; +const isActiveSelection = fabricObject => !!fabricObject && 'multiSelectionStacking' in fabricObject; + +/** + * Returns element scroll offsets + * @param {HTMLElement} element Element to operate on + * @return {Object} Object with left/top values + */ +function getScrollLeftTop(element) { + const doc = element && getDocumentFromElement(element); + let left = 0, + top = 0; + if (!element || !doc) { + return { + left, + top + }; + } + let elementLoop = element; + const docElement = doc.documentElement, + body = doc.body || { + scrollLeft: 0, + scrollTop: 0 + }; + // While loop checks (and then sets element to) .parentNode OR .host + // to account for ShadowDOM. We still want to traverse up out of ShadowDOM, + // but the .parentNode of a root ShadowDOM node will always be null, instead + // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938 + while (elementLoop && (elementLoop.parentNode || elementLoop.host)) { + elementLoop = elementLoop.parentNode || elementLoop.host; + if (elementLoop === doc) { + left = body.scrollLeft || docElement.scrollLeft || 0; + top = body.scrollTop || docElement.scrollTop || 0; + } else { + left += elementLoop.scrollLeft || 0; + top += elementLoop.scrollTop || 0; + } + if (elementLoop.nodeType === 1 && elementLoop.style.position === 'fixed') { + break; + } + } + return { + left, + top + }; +} +const getDocumentFromElement = el => el.ownerDocument || null; +const getWindowFromElement = el => { + var _el$ownerDocument; + return ((_el$ownerDocument = el.ownerDocument) === null || _el$ownerDocument === void 0 ? void 0 : _el$ownerDocument.defaultView) || null; +}; + +const setCanvasDimensions = function (el, ctx, _ref) { + let { + width, + height + } = _ref; + let retinaScaling = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1; + el.width = width; + el.height = height; + if (retinaScaling > 1) { + el.setAttribute('width', (width * retinaScaling).toString()); + el.setAttribute('height', (height * retinaScaling).toString()); + ctx.scale(retinaScaling, retinaScaling); + } +}; +const setCSSDimensions = (el, _ref2) => { + let { + width, + height + } = _ref2; + width && (el.style.width = typeof width === 'number' ? "".concat(width, "px") : width); + height && (el.style.height = typeof height === 'number' ? "".concat(height, "px") : height); +}; + +/** + * Returns offset for a given element + * @param {HTMLElement} element Element to get offset for + * @return {Object} Object with "left" and "top" properties + */ +function getElementOffset(element) { + var _getWindowFromElement; + const doc = element && getDocumentFromElement(element), + offset = { + left: 0, + top: 0 + }; + if (!doc) { + return offset; + } + const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {}; + offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0; + offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0; + offset.left += parseInt(elemStyle.paddingLeft, 10) || 0; + offset.top += parseInt(elemStyle.paddingTop, 10) || 0; + let box = { + left: 0, + top: 0 + }; + const docElem = doc.documentElement; + if (typeof element.getBoundingClientRect !== 'undefined') { + box = element.getBoundingClientRect(); + } + const scrollLeftTop = getScrollLeftTop(element); + return { + left: box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left, + top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top + }; +} + +/** + * Makes element unselectable + * @param {HTMLElement} element Element to make unselectable + * @return {HTMLElement} Element that was passed in + */ +function makeElementUnselectable(element) { + if (typeof element.onselectstart !== 'undefined') { + element.onselectstart = () => false; + } + element.style.userSelect = NONE; + return element; +} + +class StaticCanvasDOMManager { + constructor(arg0) { + /** + * Keeps a copy of the canvas style before setting retina scaling and other potions + * in order to return it to original state on dispose + * @type string + */ + _defineProperty(this, "_originalCanvasStyle", void 0); + _defineProperty(this, "lower", void 0); + const el = this.createLowerCanvas(arg0); + this.lower = { + el, + ctx: el.getContext('2d') + }; + } + createLowerCanvas(arg0) { + // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node + const el = isHTMLCanvas(arg0) ? arg0 : arg0 && getFabricDocument().getElementById(arg0) || createCanvasElement(); + if (el.hasAttribute('data-fabric')) { + throw new FabricError('Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?'); + } + this._originalCanvasStyle = el.style.cssText; + el.setAttribute('data-fabric', 'main'); + el.classList.add('lower-canvas'); + return el; + } + cleanupDOM(_ref) { + let { + width, + height + } = _ref; + const { + el + } = this.lower; + // restore canvas style and attributes + el.classList.remove('lower-canvas'); + el.removeAttribute('data-fabric'); + // restore canvas size to original size in case retina scaling was applied + el.setAttribute('width', "".concat(width)); + el.setAttribute('height', "".concat(height)); + el.style.cssText = this._originalCanvasStyle || ''; + this._originalCanvasStyle = undefined; + } + setDimensions(size, retinaScaling) { + const { + el, + ctx + } = this.lower; + setCanvasDimensions(el, ctx, size, retinaScaling); + } + setCSSDimensions(size) { + setCSSDimensions(this.lower.el, size); + } + + /** + * Calculates canvas element offset relative to the document + */ + calcOffset() { + return getElementOffset(this.lower.el); + } + dispose() { + getEnv$1().dispose(this.lower.el); + // @ts-expect-error disposing + delete this.lower; + } +} + +const staticCanvasDefaults = { + backgroundVpt: true, + backgroundColor: '', + overlayVpt: true, + overlayColor: '', + includeDefaultValues: true, + svgViewportTransformation: true, + renderOnAddRemove: true, + skipOffscreen: true, + enableRetinaScaling: true, + imageSmoothingEnabled: true, + /** + * @todo move to Canvas + */ + controlsAboveOverlay: false, + /** + * @todo move to Canvas + */ + allowTouchScrolling: false, + viewportTransform: [...iMatrix] +}; + +/** + * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset + * Better try to restrict with types to avoid confusion. + */ + +/** + * Static canvas class + * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo} + * @fires before:render + * @fires after:render + * @fires canvas:cleared + * @fires object:added + * @fires object:removed + */ +// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260 +let StaticCanvas$1 = class StaticCanvas extends createCollectionMixin(CommonMethods) { + // background + + // overlay + + // rendering config + + /** + * @todo move to Canvas + */ + + /** + * @todo move to Canvas + */ + + /** + * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries} + */ + + /** + * A reference to the canvas actual HTMLCanvasElement. + * Can be use to read the raw pixels, but never write or manipulate + * @type HTMLCanvasElement + */ + get lowerCanvasEl() { + var _this$elements$lower; + return (_this$elements$lower = this.elements.lower) === null || _this$elements$lower === void 0 ? void 0 : _this$elements$lower.el; + } + get contextContainer() { + var _this$elements$lower2; + return (_this$elements$lower2 = this.elements.lower) === null || _this$elements$lower2 === void 0 ? void 0 : _this$elements$lower2.ctx; + } + + /** + * If true the Canvas is in the process or has been disposed/destroyed. + * No more rendering operation will be executed on this canvas. + * @type boolean + */ + + /** + * Started the process of disposing but not done yet. + * WIll likely complete the render cycle already scheduled but stopping adding more. + * @type boolean + */ + + /** + * When true control drawing is skipped. + * This boolean is used to avoid toDataURL to export controls. + * Usage of this boolean to build up other flows and features is not supported + * @type Boolean + * @default false + */ + + // reference to + + static getDefaults() { + return StaticCanvas.ownDefaults; + } + constructor(el) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, this.constructor.getDefaults()); + this.set(options); + this.initElements(el); + this._setDimensionsImpl({ + width: this.width || this.elements.lower.el.width || 0, + height: this.height || this.elements.lower.el.height || 0 + }); + this.skipControlsDrawing = false; + this.viewportTransform = [...this.viewportTransform]; + this.calcViewportBoundaries(); + } + initElements(el) { + this.elements = new StaticCanvasDOMManager(el); + } + add() { + const size = super.add(...arguments); + arguments.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return size; + } + insertAt(index) { + for (var _len = arguments.length, objects = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + objects[_key - 1] = arguments[_key]; + } + const size = super.insertAt(index, ...objects); + objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return size; + } + remove() { + const removed = super.remove(...arguments); + removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll(); + return removed; + } + _onObjectAdded(obj) { + if (obj.canvas && obj.canvas !== this) { + log('warn', 'Canvas is trying to add an object that belongs to a different canvas.\n' + 'Resulting to default behavior: removing object from previous canvas and adding to new canvas'); + obj.canvas.remove(obj); + } + obj._set('canvas', this); + obj.setCoords(); + this.fire('object:added', { + target: obj + }); + obj.fire('added', { + target: this + }); + } + _onObjectRemoved(obj) { + obj._set('canvas', undefined); + this.fire('object:removed', { + target: obj + }); + obj.fire('removed', { + target: this + }); + } + _onStackOrderChanged() { + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * @private + * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html + * @return {Number} retinaScaling if applied, otherwise 1; + */ + getRetinaScaling() { + return this.enableRetinaScaling ? getDevicePixelRatio() : 1; + } + + /** + * Calculates canvas element offset relative to the document + * This method is also attached as "resize" event handler of window + */ + calcOffset() { + return this._offset = this.elements.calcOffset(); + } + + /** + * Returns canvas width (in px) + * @return {Number} + */ + getWidth() { + return this.width; + } + + /** + * Returns canvas height (in px) + * @return {Number} + */ + getHeight() { + return this.height; + } + + /** + * Sets width of this canvas instance + * @param {Number|String} value Value to set width to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @deprecated will be removed in 7.0 + */ + + setWidth(value, options) { + return this.setDimensions({ + width: value + }, options); + } + + /**s + * Sets height of this canvas instance + * @param {Number|String} value Value to set height to + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + * @deprecated will be removed in 7.0 + */ + + setHeight(value, options) { + return this.setDimensions({ + height: value + }, options); + } + + /** + * Internal use only + * @protected + */ + _setDimensionsImpl(dimensions) { + let { + cssOnly = false, + backstoreOnly = false + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + if (!cssOnly) { + const size = _objectSpread2({ + width: this.width, + height: this.height + }, dimensions); + this.elements.setDimensions(size, this.getRetinaScaling()); + this.hasLostContext = true; + this.width = size.width; + this.height = size.height; + } + if (!backstoreOnly) { + this.elements.setCSSDimensions(dimensions); + } + this.calcOffset(); + } + + /** + * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em) + * @param {Object} dimensions Object with width/height properties + * @param {Number|String} [dimensions.width] Width of canvas element + * @param {Number|String} [dimensions.height] Height of canvas element + * @param {Object} [options] Options object + * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions + * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions + */ + + setDimensions(dimensions, options) { + this._setDimensionsImpl(dimensions, options); + if (!options || !options.cssOnly) { + this.requestRenderAll(); + } + } + + /** + * Returns canvas zoom level + * @return {Number} + */ + getZoom() { + return this.viewportTransform[0]; + } + + /** + * Sets viewport transformation of this canvas instance + * @param {Array} vpt a Canvas 2D API transform matrix + */ + setViewportTransform(vpt) { + this.viewportTransform = vpt; + this.calcViewportBoundaries(); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Sets zoom level of this canvas instance, the zoom centered around point + * meaning that following zoom to point with the same point will have the visual + * effect of the zoom originating from that point. The point won't move. + * It has nothing to do with canvas center or visual center of the viewport. + * @param {Point} point to zoom with respect to + * @param {Number} value to set zoom to, less than 1 zooms out + */ + zoomToPoint(point, value) { + // TODO: just change the scale, preserve other transformations + const before = point, + vpt = [...this.viewportTransform]; + const newPoint = transformPoint(point, invertTransform(vpt)); + vpt[0] = value; + vpt[3] = value; + const after = transformPoint(newPoint, vpt); + vpt[4] += before.x - after.x; + vpt[5] += before.y - after.y; + this.setViewportTransform(vpt); + } + + /** + * Sets zoom level of this canvas instance + * @param {Number} value to set zoom to, less than 1 zooms out + */ + setZoom(value) { + this.zoomToPoint(new Point(0, 0), value); + } + + /** + * Pan viewport so as to place point at top left corner of canvas + * @param {Point} point to move to + */ + absolutePan(point) { + const vpt = [...this.viewportTransform]; + vpt[4] = -point.x; + vpt[5] = -point.y; + return this.setViewportTransform(vpt); + } + + /** + * Pans viewpoint relatively + * @param {Point} point (position vector) to move by + */ + relativePan(point) { + return this.absolutePan(new Point(-point.x - this.viewportTransform[4], -point.y - this.viewportTransform[5])); + } + + /** + * Returns <canvas> element corresponding to this instance + * @return {HTMLCanvasElement} + */ + getElement() { + return this.elements.lower.el; + } + + /** + * Clears specified context of canvas element + * @param {CanvasRenderingContext2D} ctx Context to clear + */ + clearContext(ctx) { + ctx.clearRect(0, 0, this.width, this.height); + } + + /** + * Returns context of canvas where objects are drawn + * @return {CanvasRenderingContext2D} + */ + getContext() { + return this.elements.lower.ctx; + } + + /** + * Clears all contexts (background, main, top) of an instance + */ + clear() { + this.remove(...this.getObjects()); + this.backgroundImage = undefined; + this.overlayImage = undefined; + this.backgroundColor = ''; + this.overlayColor = ''; + this.clearContext(this.getContext()); + this.fire('canvas:cleared'); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Renders the canvas + */ + renderAll() { + this.cancelRequestedRender(); + if (this.destroyed) { + return; + } + this.renderCanvas(this.getContext(), this._objects); + } + + /** + * Function created to be instance bound at initialization + * used in requestAnimationFrame rendering + * Let the fabricJS call it. If you call it manually you could have more + * animationFrame stacking on to of each other + * for an imperative rendering, use canvas.renderAll + * @private + */ + renderAndReset() { + this.nextRenderHandle = 0; + this.renderAll(); + } + + /** + * Append a renderAll request to next animation frame. + * unless one is already in progress, in that case nothing is done + * a boolean flag will avoid appending more. + */ + requestRenderAll() { + if (!this.nextRenderHandle && !this.disposed && !this.destroyed) { + this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset()); + } + } + + /** + * Calculate the position of the 4 corner of canvas with current viewportTransform. + * helps to determinate when an object is in the current rendering viewport + */ + calcViewportBoundaries() { + const width = this.width, + height = this.height, + iVpt = invertTransform(this.viewportTransform), + a = transformPoint({ + x: 0, + y: 0 + }, iVpt), + b = transformPoint({ + x: width, + y: height + }, iVpt), + // we don't support vpt flipping + // but the code is robust enough to mostly work with flipping + min = a.min(b), + max = a.max(b); + return this.vptCoords = { + tl: min, + tr: new Point(max.x, min.y), + bl: new Point(min.x, max.y), + br: max + }; + } + cancelRequestedRender() { + if (this.nextRenderHandle) { + cancelAnimFrame(this.nextRenderHandle); + this.nextRenderHandle = 0; + } + } + drawControls(_ctx) { + // Static canvas has no controls + } + + /** + * Renders background, objects, overlay and controls. + * @param {CanvasRenderingContext2D} ctx + * @param {Array} objects to render + */ + renderCanvas(ctx, objects) { + if (this.destroyed) { + return; + } + const v = this.viewportTransform, + path = this.clipPath; + this.calcViewportBoundaries(); + this.clearContext(ctx); + ctx.imageSmoothingEnabled = this.imageSmoothingEnabled; + // @ts-expect-error node-canvas stuff + ctx.patternQuality = 'best'; + this.fire('before:render', { + ctx + }); + this._renderBackground(ctx); + ctx.save(); + //apply viewport transform once for all rendering process + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + this._renderObjects(ctx, objects); + ctx.restore(); + if (!this.controlsAboveOverlay && !this.skipControlsDrawing) { + this.drawControls(ctx); + } + if (path) { + path._set('canvas', this); + // needed to setup a couple of variables + path.shouldCache(); + path._transformDone = true; + path.renderCache({ + forClipping: true + }); + this.drawClipPathOnCanvas(ctx, path); + } + this._renderOverlay(ctx); + if (this.controlsAboveOverlay && !this.skipControlsDrawing) { + this.drawControls(ctx); + } + this.fire('after:render', { + ctx + }); + if (this.__cleanupTask) { + this.__cleanupTask(); + this.__cleanupTask = undefined; + } + } + + /** + * Paint the cached clipPath on the lowerCanvasEl + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawClipPathOnCanvas(ctx, clipPath) { + const v = this.viewportTransform; + ctx.save(); + ctx.transform(...v); + // DEBUG: uncomment this line, comment the following + // ctx.globalAlpha = 0.4; + ctx.globalCompositeOperation = 'destination-in'; + clipPath.transform(ctx); + ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY); + ctx.drawImage(clipPath._cacheCanvas, -clipPath.cacheTranslationX, -clipPath.cacheTranslationY); + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} objects to render + */ + _renderObjects(ctx, objects) { + for (let i = 0, len = objects.length; i < len; ++i) { + objects[i] && objects[i].render(ctx); + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {string} property 'background' or 'overlay' + */ + _renderBackgroundOrOverlay(ctx, property) { + const fill = this["".concat(property, "Color")], + object = this["".concat(property, "Image")], + v = this.viewportTransform, + needsVpt = this["".concat(property, "Vpt")]; + if (!fill && !object) { + return; + } + const isAFiller = isFiller(fill); + if (fill) { + ctx.save(); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(this.width, 0); + ctx.lineTo(this.width, this.height); + ctx.lineTo(0, this.height); + ctx.closePath(); + ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */) : fill; + if (needsVpt) { + ctx.transform(...v); + } + if (isAFiller) { + ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0); + const m = fill.gradientTransform || fill.patternTransform; + m && ctx.transform(...m); + } + ctx.fill(); + ctx.restore(); + } + if (object) { + ctx.save(); + const { + skipOffscreen + } = this; + // if the object doesn't move with the viewport, + // the offscreen concept does not apply; + this.skipOffscreen = needsVpt; + if (needsVpt) { + ctx.transform(...v); + } + object.render(ctx); + this.skipOffscreen = skipOffscreen; + ctx.restore(); + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground(ctx) { + this._renderBackgroundOrOverlay(ctx, 'background'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderOverlay(ctx) { + this._renderBackgroundOrOverlay(ctx, 'overlay'); + } + + /** + * Returns coordinates of a center of canvas. + * Returned value is an object with top and left properties + * @return {Object} object with "top" and "left" number values + * @deprecated migrate to `getCenterPoint` + */ + getCenter() { + return { + top: this.height / 2, + left: this.width / 2 + }; + } + + /** + * Returns coordinates of a center of canvas. + * @return {Point} + */ + getCenterPoint() { + return new Point(this.width / 2, this.height / 2); + } + + /** + * Centers object horizontally in the canvas + */ + centerObjectH(object) { + return this._centerObject(object, new Point(this.getCenterPoint().x, object.getCenterPoint().y)); + } + + /** + * Centers object vertically in the canvas + * @param {FabricObject} object Object to center vertically + */ + centerObjectV(object) { + return this._centerObject(object, new Point(object.getCenterPoint().x, this.getCenterPoint().y)); + } + + /** + * Centers object vertically and horizontally in the canvas + * @param {FabricObject} object Object to center vertically and horizontally + */ + centerObject(object) { + return this._centerObject(object, this.getCenterPoint()); + } + + /** + * Centers object vertically and horizontally in the viewport + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObject(object) { + return this._centerObject(object, this.getVpCenter()); + } + + /** + * Centers object horizontally in the viewport, object.top is unchanged + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObjectH(object) { + return this._centerObject(object, new Point(this.getVpCenter().x, object.getCenterPoint().y)); + } + + /** + * Centers object Vertically in the viewport, object.top is unchanged + * @param {FabricObject} object Object to center vertically and horizontally + */ + viewportCenterObjectV(object) { + return this._centerObject(object, new Point(object.getCenterPoint().x, this.getVpCenter().y)); + } + + /** + * Calculate the point in canvas that correspond to the center of actual viewport. + * @return {Point} vpCenter, viewport center + */ + getVpCenter() { + return transformPoint(this.getCenterPoint(), invertTransform(this.viewportTransform)); + } + + /** + * @private + * @param {FabricObject} object Object to center + * @param {Point} center Center point + */ + _centerObject(object, center) { + object.setXY(center, CENTER, CENTER); + object.setCoords(); + this.renderOnAddRemove && this.requestRenderAll(); + } + + /** + * Returns dataless JSON representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {String} json string + */ + toDatalessJSON(propertiesToInclude) { + return this.toDatalessObject(propertiesToInclude); + } + + /** + * Returns object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject(propertiesToInclude) { + return this._toObjectMethod('toObject', propertiesToInclude); + } + + /** + * Returns Object representation of canvas + * this alias is provided because if you call JSON.stringify on an instance, + * the toJSON object will be invoked if it exists. + * Having a toJSON method means you can do JSON.stringify(myCanvas) + * @return {Object} JSON compatible object + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} + * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo} + * @example JSON without additional properties + * var json = canvas.toJSON(); + * @example JSON with additional properties included + * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']); + * @example JSON without default values + * var json = canvas.toJSON(); + */ + toJSON() { + return this.toObject(); + } + + /** + * Returns dataless object representation of canvas + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject(propertiesToInclude) { + return this._toObjectMethod('toDatalessObject', propertiesToInclude); + } + + /** + * @private + */ + _toObjectMethod(methodName, propertiesToInclude) { + const clipPath = this.clipPath; + const clipPathData = clipPath && !clipPath.excludeFromExport ? this._toObject(clipPath, methodName, propertiesToInclude) : null; + return _objectSpread2(_objectSpread2(_objectSpread2({ + version: VERSION + }, pick(this, propertiesToInclude)), {}, { + objects: this._objects.filter(object => !object.excludeFromExport).map(instance => this._toObject(instance, methodName, propertiesToInclude)) + }, this.__serializeBgOverlay(methodName, propertiesToInclude)), clipPathData ? { + clipPath: clipPathData + } : null); + } + + /** + * @private + */ + _toObject(instance, methodName, propertiesToInclude) { + let originalValue; + if (!this.includeDefaultValues) { + originalValue = instance.includeDefaultValues; + instance.includeDefaultValues = false; + } + const object = instance[methodName](propertiesToInclude); + if (!this.includeDefaultValues) { + instance.includeDefaultValues = !!originalValue; + } + return object; + } + + /** + * @private + */ + __serializeBgOverlay(methodName, propertiesToInclude) { + const data = {}, + bgImage = this.backgroundImage, + overlayImage = this.overlayImage, + bgColor = this.backgroundColor, + overlayColor = this.overlayColor; + if (isFiller(bgColor)) { + if (!bgColor.excludeFromExport) { + data.background = bgColor.toObject(propertiesToInclude); + } + } else if (bgColor) { + data.background = bgColor; + } + if (isFiller(overlayColor)) { + if (!overlayColor.excludeFromExport) { + data.overlay = overlayColor.toObject(propertiesToInclude); + } + } else if (overlayColor) { + data.overlay = overlayColor; + } + if (bgImage && !bgImage.excludeFromExport) { + data.backgroundImage = this._toObject(bgImage, methodName, propertiesToInclude); + } + if (overlayImage && !overlayImage.excludeFromExport) { + data.overlayImage = this._toObject(overlayImage, methodName, propertiesToInclude); + } + return data; + } + + /* _TO_SVG_START_ */ + + /** + * Returns SVG representation of canvas + * @function + * @param {Object} [options] Options object for SVG output + * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included + * @param {Object} [options.viewBox] SVG viewbox object + * @param {Number} [options.viewBox.x] x-coordinate of viewbox + * @param {Number} [options.viewBox.y] y-coordinate of viewbox + * @param {Number} [options.viewBox.width] Width of viewbox + * @param {Number} [options.viewBox.height] Height of viewbox + * @param {String} [options.encoding=UTF-8] Encoding of SVG output + * @param {String} [options.width] desired width of svg with or without units + * @param {String} [options.height] desired height of svg with or without units + * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation. + * @return {String} SVG string + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization} + * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo} + * @example Normal SVG output + * var svg = canvas.toSVG(); + * @example SVG output without preamble (without <?xml ../>) + * var svg = canvas.toSVG({suppressPreamble: true}); + * @example SVG output with viewBox attribute + * var svg = canvas.toSVG({ + * viewBox: { + * x: 100, + * y: 100, + * width: 200, + * height: 300 + * } + * }); + * @example SVG output with different encoding (default: UTF-8) + * var svg = canvas.toSVG({encoding: 'ISO-8859-1'}); + * @example Modify SVG output with reviver function + * var svg = canvas.toSVG(null, function(svg) { + * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', ''); + * }); + */ + toSVG() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let reviver = arguments.length > 1 ? arguments[1] : undefined; + options.reviver = reviver; + const markup = []; + this._setSVGPreamble(markup, options); + this._setSVGHeader(markup, options); + if (this.clipPath) { + markup.push("\n")); + } + this._setSVGBgOverlayColor(markup, 'background'); + this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver); + this._setSVGObjects(markup, reviver); + if (this.clipPath) { + markup.push('\n'); + } + this._setSVGBgOverlayColor(markup, 'overlay'); + this._setSVGBgOverlayImage(markup, 'overlayImage', reviver); + markup.push(''); + return markup.join(''); + } + + /** + * @private + */ + _setSVGPreamble(markup, options) { + if (options.suppressPreamble) { + return; + } + markup.push('\n', '\n'); + } + + /** + * @private + */ + _setSVGHeader(markup, options) { + const width = options.width || "".concat(this.width), + height = options.height || "".concat(this.height), + NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS, + optViewBox = options.viewBox; + let viewBox; + if (optViewBox) { + viewBox = "viewBox=\"".concat(optViewBox.x, " ").concat(optViewBox.y, " ").concat(optViewBox.width, " ").concat(optViewBox.height, "\" "); + } else if (this.svgViewportTransformation) { + const vpt = this.viewportTransform; + viewBox = "viewBox=\"".concat(toFixed(-vpt[4] / vpt[0], NUM_FRACTION_DIGITS), " ").concat(toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS), " ").concat(toFixed(this.width / vpt[0], NUM_FRACTION_DIGITS), " ").concat(toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS), "\" "); + } else { + viewBox = "viewBox=\"0 0 ".concat(this.width, " ").concat(this.height, "\" "); + } + markup.push('\n', 'Created with Fabric.js ', VERSION, '\n', '\n', this.createSVGFontFacesMarkup(), this.createSVGRefElementsMarkup(), this.createSVGClipPathMarkup(options), '\n'); + } + createSVGClipPathMarkup(options) { + const clipPath = this.clipPath; + if (clipPath) { + clipPath.clipPathId = "CLIPPATH_".concat(uid()); + return "\n").concat(clipPath.toClipPathSVG(options.reviver), "\n"); + } + return ''; + } + + /** + * Creates markup containing SVG referenced elements like patterns, gradients etc. + * @return {String} + */ + createSVGRefElementsMarkup() { + return ['background', 'overlay'].map(prop => { + const fill = this["".concat(prop, "Color")]; + if (isFiller(fill)) { + const shouldTransform = this["".concat(prop, "Vpt")], + vpt = this.viewportTransform, + object = { + // otherwise circular dependency + isType: () => false, + width: this.width / (shouldTransform ? vpt[0] : 1), + height: this.height / (shouldTransform ? vpt[3] : 1) + }; + return fill.toSVG(object, { + additionalTransform: shouldTransform ? matrixToSVG(vpt) : '' + }); + } + }).join(''); + } + + /** + * Creates markup containing SVG font faces, + * font URLs for font faces must be collected by developers + * and are not extracted from the DOM by fabricjs + * @param {Array} objects Array of fabric objects + * @return {String} + */ + createSVGFontFacesMarkup() { + const objects = [], + fontList = {}, + fontPaths = config.fontPaths; + this._objects.forEach(function add(object) { + objects.push(object); + if (isCollection(object)) { + object._objects.forEach(add); + } + }); + objects.forEach(obj => { + if (!isTextObject(obj)) { + return; + } + const { + styles, + fontFamily + } = obj; + if (fontList[fontFamily] || !fontPaths[fontFamily]) { + return; + } + fontList[fontFamily] = true; + if (!styles) { + return; + } + Object.values(styles).forEach(styleRow => { + Object.values(styleRow).forEach(_ref => { + let { + fontFamily = '' + } = _ref; + if (!fontList[fontFamily] && fontPaths[fontFamily]) { + fontList[fontFamily] = true; + } + }); + }); + }); + const fontListMarkup = Object.keys(fontList).map(fontFamily => "\t\t@font-face {\n\t\t\tfont-family: '".concat(fontFamily, "';\n\t\t\tsrc: url('").concat(fontPaths[fontFamily], "');\n\t\t}\n")).join(''); + if (fontListMarkup) { + return "\t\n"); + } + return ''; + } + + /** + * @private + */ + _setSVGObjects(markup, reviver) { + this.forEachObject(fabricObject => { + if (fabricObject.excludeFromExport) { + return; + } + this._setSVGObject(markup, fabricObject, reviver); + }); + } + + /** + * This is its own function because the Canvas ( non static ) requires extra code here + * @private + */ + _setSVGObject(markup, instance, reviver) { + markup.push(instance.toSVG(reviver)); + } + + /** + * @private + */ + _setSVGBgOverlayImage(markup, property, reviver) { + const bgOrOverlay = this[property]; + if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) { + markup.push(bgOrOverlay.toSVG(reviver)); + } + } + + /** + * @TODO this seems to handle patterns but fail at gradients. + * @private + */ + _setSVGBgOverlayColor(markup, property) { + const filler = this["".concat(property, "Color")]; + if (!filler) { + return; + } + if (isFiller(filler)) { + const repeat = filler.repeat || '', + finalWidth = this.width, + finalHeight = this.height, + shouldInvert = this["".concat(property, "Vpt")], + additionalTransform = shouldInvert ? matrixToSVG(invertTransform(this.viewportTransform)) : ''; + markup.push("\n")); + } else { + markup.push('\n'); + } + } + /* _TO_SVG_END_ */ + + /** + * Populates canvas with data from the specified JSON. + * JSON format must conform to the one of {@link fabric.Canvas#toJSON} + * + * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking + * + * @param {String|Object} json JSON string or object + * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created. + * @param {Object} [options] options + * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @return {Promise} instance + * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization} + * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo} + * @example loadFromJSON + * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll()); + * @example loadFromJSON with reviver + * canvas.loadFromJSON(json, function(o, object) { + * // `o` = json object + * // `object` = fabric.Object instance + * // ... do some stuff ... + * }).then((canvas) => { + * ... canvas is restored, add your code. + * }); + * + */ + loadFromJSON(json, reviver) { + let { + signal + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (!json) { + return Promise.reject(new FabricError('`json` is undefined')); + } + + // parse json if it wasn't already + const serialized = typeof json === 'string' ? JSON.parse(json) : json; + const { + objects = [], + backgroundImage, + background, + overlayImage, + overlay, + clipPath + } = serialized; + const renderOnAddRemove = this.renderOnAddRemove; + this.renderOnAddRemove = false; + return Promise.all([enlivenObjects(objects, { + reviver, + signal + }), enlivenObjectEnlivables({ + backgroundImage, + backgroundColor: background, + overlayImage, + overlayColor: overlay, + clipPath + }, { + signal + })]).then(_ref2 => { + let [enlived, enlivedMap] = _ref2; + this.clear(); + this.add(...enlived); + this.set(serialized); + this.set(enlivedMap); + this.renderOnAddRemove = renderOnAddRemove; + return this; + }); + } + + /** + * Clones canvas instance + * @param {string[]} [properties] Array of properties to include in the cloned canvas and children + */ + clone(properties) { + const data = this.toObject(properties); + const canvas = this.cloneWithoutData(); + return canvas.loadFromJSON(data); + } + + /** + * Clones canvas instance without cloning existing data. + * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size. + */ + cloneWithoutData() { + const el = createCanvasElement(); + el.width = this.width; + el.height = this.height; + return new this.constructor(el); + } + + /** + * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately + * @param {Object} [options] Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0 + * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects. + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + * @see {@link https://jsfiddle.net/xsjua1rd/ demo} + * @example Generate jpeg dataURL with lower quality + * var dataURL = canvas.toDataURL({ + * format: 'jpeg', + * quality: 0.8 + * }); + * @example Generate cropped png dataURL (clipping of canvas) + * var dataURL = canvas.toDataURL({ + * format: 'png', + * left: 100, + * top: 100, + * width: 200, + * height: 200 + * }); + * @example Generate double scaled png dataURL + * var dataURL = canvas.toDataURL({ + * format: 'png', + * multiplier: 2 + * }); + * @example Generate dataURL with objects that overlap a specified object + * var myObject; + * var dataURL = canvas.toDataURL({ + * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject) + * }); + */ + toDataURL() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const { + format = 'png', + quality = 1, + multiplier = 1, + enableRetinaScaling = false + } = options; + const finalMultiplier = multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1); + return toDataURL(this.toCanvasElement(finalMultiplier, options), format, quality); + } + + /** + * Create a new HTMLCanvas element painted with the current canvas content. + * No need to resize the actual one or repaint it. + * Will transfer object ownership to a new canvas, paint it, and set everything back. + * This is an intermediary step used to get to a dataUrl but also it is useful to + * create quick image copies of a canvas without passing for the dataUrl string + * @param {Number} [multiplier] a zoom factor. + * @param {Object} [options] Cropping informations + * @param {Number} [options.left] Cropping left offset. + * @param {Number} [options.top] Cropping top offset. + * @param {Number} [options.width] Cropping width. + * @param {Number} [options.height] Cropping height. + * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects. + */ + toCanvasElement() { + let multiplier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; + let { + width, + height, + left, + top, + filter + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const scaledWidth = (width || this.width) * multiplier, + scaledHeight = (height || this.height) * multiplier, + zoom = this.getZoom(), + originalWidth = this.width, + originalHeight = this.height, + originalSkipControlsDrawing = this.skipControlsDrawing, + newZoom = zoom * multiplier, + vp = this.viewportTransform, + translateX = (vp[4] - (left || 0)) * multiplier, + translateY = (vp[5] - (top || 0)) * multiplier, + newVp = [newZoom, 0, 0, newZoom, translateX, translateY], + originalRetina = this.enableRetinaScaling, + canvasEl = createCanvasElement(), + objectsToRender = filter ? this._objects.filter(obj => filter(obj)) : this._objects; + canvasEl.width = scaledWidth; + canvasEl.height = scaledHeight; + this.enableRetinaScaling = false; + this.viewportTransform = newVp; + this.width = scaledWidth; + this.height = scaledHeight; + this.skipControlsDrawing = true; + this.calcViewportBoundaries(); + this.renderCanvas(canvasEl.getContext('2d'), objectsToRender); + this.viewportTransform = vp; + this.width = originalWidth; + this.height = originalHeight; + this.calcViewportBoundaries(); + this.enableRetinaScaling = originalRetina; + this.skipControlsDrawing = originalSkipControlsDrawing; + return canvasEl; + } + + /** + * Waits until rendering has settled to destroy the canvas + * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed + * @throws if aborted by a consequent call + */ + dispose() { + !this.disposed && this.elements.cleanupDOM({ + width: this.width, + height: this.height + }); + runningAnimations.cancelByCanvas(this); + this.disposed = true; + return new Promise((resolve, reject) => { + const task = () => { + this.destroy(); + resolve(true); + }; + task.kill = reject; + if (this.__cleanupTask) { + this.__cleanupTask.kill('aborted'); + } + if (this.destroyed) { + resolve(false); + } else if (this.nextRenderHandle) { + this.__cleanupTask = task; + } else { + task(); + } + }); + } + + /** + * Clears the canvas element, disposes objects and frees resources. + * + * Invoked as part of the **async** operation of {@link dispose}. + * + * **CAUTION**: + * + * This method is **UNSAFE**. + * You may encounter a race condition using it if there's a requested render. + * Call this method only if you are sure rendering has settled. + * Consider using {@link dispose} as it is **SAFE** + * + * @private + */ + destroy() { + this.destroyed = true; + this.cancelRequestedRender(); + this.forEachObject(object => object.dispose()); + this._objects = []; + if (this.backgroundImage) { + this.backgroundImage.dispose(); + } + this.backgroundImage = undefined; + if (this.overlayImage) { + this.overlayImage.dispose(); + } + this.overlayImage = undefined; + this.elements.dispose(); + } + + /** + * Returns a string representation of an instance + * @return {String} string representation of an instance + */ + toString() { + return "#"); + } +}; +_defineProperty(StaticCanvas$1, "ownDefaults", staticCanvasDefaults); + +const touchEvents = ['touchstart', 'touchmove', 'touchend']; +function getTouchInfo(event) { + const touchProp = event.changedTouches; + if (touchProp && touchProp[0]) { + return touchProp[0]; + } + return event; +} +const getPointer = event => { + const element = event.target, + scroll = getScrollLeftTop(element), + _evt = getTouchInfo(event); + return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top); +}; +const isTouchEvent = event => touchEvents.includes(event.type) || event.pointerType === 'touch'; +const stopEvent = e => { + e.preventDefault(); + e.stopPropagation(); +}; + +/** + * Calculates bounding box (left, top, width, height) from given `points` + * @param {XY[]} points + * @return {Object} Object with left, top, width, height properties + */ +const makeBoundingBoxFromPoints = points => { + let left = 0, + top = 0, + width = 0, + height = 0; + for (let i = 0, len = points.length; i < len; i++) { + const { + x, + y + } = points[i]; + if (x > width || !i) width = x; + if (x < left || !i) left = x; + if (y > height || !i) height = y; + if (y < top || !i) top = y; + } + return { + left, + top, + width: width - left, + height: height - top + }; +}; + +const _excluded$i = ["translateX", "translateY", "scaleX", "scaleY"]; + +/** + * given an object and a transform, apply the inverse transform to the object, + * this is equivalent to remove from that object that transformation, so that + * added in a space with the removed transform, the object will be the same as before. + * Removing from an object a transform that scale by 2 is like scaling it by 1/2. + * Removing from an object a transform that rotate by 30deg is like rotating by 30deg + * in the opposite direction. + * This util is used to add objects inside transformed groups or nested groups. + * @param {FabricObject} object the object you want to transform + * @param {TMat2D} transform the destination transform + */ +const removeTransformFromObject = (object, transform) => { + const inverted = invertTransform(transform), + finalTransform = multiplyTransformMatrices(inverted, object.calcOwnMatrix()); + applyTransformToObject(object, finalTransform); +}; + +/** + * given an object and a transform, apply the transform to the object. + * this is equivalent to change the space where the object is drawn. + * Adding to an object a transform that scale by 2 is like scaling it by 2. + * This is used when removing an object from an active selection for example. + * @param {FabricObject} object the object you want to transform + * @param {Array} transform the destination transform + */ +const addTransformToObject = (object, transform) => applyTransformToObject(object, multiplyTransformMatrices(transform, object.calcOwnMatrix())); + +/** + * discard an object transform state and apply the one from the matrix. + * @param {FabricObject} object the object you want to transform + * @param {Array} transform the destination transform + */ +const applyTransformToObject = (object, transform) => { + const _qrDecompose = qrDecompose(transform), + { + translateX, + translateY, + scaleX, + scaleY + } = _qrDecompose, + otherOptions = _objectWithoutProperties(_qrDecompose, _excluded$i), + center = new Point(translateX, translateY); + object.flipX = false; + object.flipY = false; + Object.assign(object, otherOptions); + object.set({ + scaleX, + scaleY + }); + object.setPositionByOrigin(center, CENTER, CENTER); +}; +/** + * reset an object transform state to neutral. Top and left are not accounted for + * @param {FabricObject} target object to transform + */ +const resetObjectTransform = target => { + target.scaleX = 1; + target.scaleY = 1; + target.skewX = 0; + target.skewY = 0; + target.flipX = false; + target.flipY = false; + target.rotate(0); +}; + +/** + * Extract Object transform values + * @param {FabricObject} target object to read from + * @return {Object} Components of transform + */ +const saveObjectTransform = target => ({ + scaleX: target.scaleX, + scaleY: target.scaleY, + skewX: target.skewX, + skewY: target.skewY, + angle: target.angle, + left: target.left, + flipX: target.flipX, + flipY: target.flipY, + top: target.top +}); + +/** + * given a width and height, return the size of the bounding box + * that can contains the box with width/height with applied transform. + * Use to calculate the boxes around objects for controls. + * @param {Number} width + * @param {Number} height + * @param {TMat2D} t + * @returns {Point} size + */ +const sizeAfterTransform = (width, height, t) => { + const dimX = width / 2, + dimY = height / 2, + points = [new Point(-dimX, -dimY), new Point(dimX, -dimY), new Point(-dimX, dimY), new Point(dimX, dimY)].map(p => p.transform(t)), + bbox = makeBoundingBoxFromPoints(points); + return new Point(bbox.width, bbox.height); +}; + +/** + * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\ + * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`) + * @param [from] + * @param [to] + * @returns + */ +const calcPlaneChangeMatrix = function () { + let from = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : iMatrix; + let to = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + return multiplyTransformMatrices(invertTransform(to), from); +}; + +/** + * Sends a point from the source coordinate plane to the destination coordinate plane.\ + * From the canvas/viewer's perspective the point remains unchanged. + * + * @example Send point from canvas plane to group plane + * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 }); + * var group = new Group([obj], { strokeWidth: 0 }); + * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix()); + * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix()); + * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group + * + * @param {Point} point + * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane. + * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane. + * @returns {Point} transformed point + */ +const sendPointToPlane = function (point) { + let from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + let to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : iMatrix; + return point.transform(calcPlaneChangeMatrix(from, to)); +}; + +/** + * See {@link sendPointToPlane} + */ +const sendVectorToPlane = function (point) { + let from = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : iMatrix; + let to = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : iMatrix; + return point.transform(calcPlaneChangeMatrix(from, to), true); +}; + +/** + * + * A util that abstracts applying transform to objects.\ + * Sends `object` to the destination coordinate plane by applying the relevant transformations.\ + * Changes the space/plane where `object` is drawn.\ + * From the canvas/viewer's perspective `object` remains unchanged. + * + * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer + * let obj, obj2; + * let clipPath = new Circle({ radius: 50 }); + * obj.clipPath = clipPath; + * // render + * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix()); + * obj.clipPath = undefined; + * obj2.clipPath = clipPath; + * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer + * + * @example Clip an object's clip path with an existing object + * let obj, existingObj; + * let clipPath = new Circle({ radius: 50 }); + * obj.clipPath = clipPath; + * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix()); + * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo); + * clipPath.clipPath = existingObj; + * + * @param {FabricObject} object + * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas. + * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane. + * @returns {Matrix} the transform matrix that was applied to `object` + */ +const sendObjectToPlane = (object, from, to) => { + const t = calcPlaneChangeMatrix(from, to); + applyTransformToObject(object, multiplyTransformMatrices(t, object.calcOwnMatrix())); + return t; +}; + +const fireEvent = (eventName, options) => { + var _target$canvas; + const { + transform: { + target + } + } = options; + (_target$canvas = target.canvas) === null || _target$canvas === void 0 || _target$canvas.fire("object:".concat(eventName), _objectSpread2(_objectSpread2({}, options), {}, { + target + })); + target.fire(eventName, options); +}; + +const originOffset = { + left: -0.5, + top: -0.5, + center: 0, + bottom: 0.5, + right: 0.5 +}; +/** + * Resolves origin value relative to center + * @private + * @param {TOriginX | TOriginY} originValue originX / originY + * @returns number + */ + +const resolveOrigin = originValue => typeof originValue === 'string' ? originOffset[originValue] : originValue - 0.5; + +const NOT_ALLOWED_CURSOR = 'not-allowed'; + +/** + * @param {Boolean} alreadySelected true if target is already selected + * @param {String} corner a string representing the corner ml, mr, tl ... + * @param {Event} e Event object + * @param {FabricObject} [target] inserted back to help overriding. Unused + */ +const getActionFromCorner = (alreadySelected, corner, e, target) => { + if (!corner || !alreadySelected) { + return 'drag'; + } + const control = target.controls[corner]; + return control.getActionName(e, control, target); +}; + +/** + * Checks if transform is centered + * @param {Object} transform transform data + * @return {Boolean} true if transform is centered + */ +function isTransformCentered(transform) { + return resolveOrigin(transform.originX) === resolveOrigin(CENTER) && resolveOrigin(transform.originY) === resolveOrigin(CENTER); +} +function invertOrigin(origin) { + return -resolveOrigin(origin) + 0.5; +} +const isLocked = (target, lockingKey) => target[lockingKey]; +const commonEventInfo = (eventData, transform, x, y) => { + return { + e: eventData, + transform, + pointer: new Point(x, y) + }; +}; + +/** + * Combine control position and object angle to find the control direction compared + * to the object center. + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + * @param {Control} control the control class + * @return {Number} 0 - 7 a quadrant number + */ +function findCornerQuadrant(fabricObject, control) { + // angle is relative to canvas plane + const angle = fabricObject.getTotalAngle(), + cornerAngle = angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360; + return Math.round(cornerAngle % 360 / 45); +} + +/** + * @returns the normalized point (rotated relative to center) in local coordinates + */ +function normalizePoint(target, point, originX, originY) { + const center = target.getRelativeCenterPoint(), + p = typeof originX !== 'undefined' && typeof originY !== 'undefined' ? target.translateToGivenOrigin(center, CENTER, CENTER, originX, originY) : new Point(target.left, target.top), + p2 = target.angle ? point.rotate(-degreesToRadians(target.angle), center) : point; + return p2.subtract(p); +} + +/** + * Transforms a point to the offset from the given origin + * @param {Object} transform + * @param {String} originX + * @param {String} originY + * @param {number} x + * @param {number} y + * @return {Fabric.Point} the normalized point + */ +function getLocalPoint(_ref, originX, originY, x, y) { + var _target$canvas; + let { + target, + corner + } = _ref; + const control = target.controls[corner], + zoom = ((_target$canvas = target.canvas) === null || _target$canvas === void 0 ? void 0 : _target$canvas.getZoom()) || 1, + padding = target.padding / zoom, + localPoint = normalizePoint(target, new Point(x, y), originX, originY); + if (localPoint.x >= padding) { + localPoint.x -= padding; + } + if (localPoint.x <= -padding) { + localPoint.x += padding; + } + if (localPoint.y >= padding) { + localPoint.y -= padding; + } + if (localPoint.y <= padding) { + localPoint.y += padding; + } + localPoint.x -= control.offsetX; + localPoint.y -= control.offsetY; + return localPoint; +} + +/** + * Action handler + * @private + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if the translation occurred + */ +const dragHandler = (eventData, transform, x, y) => { + const { + target, + offsetX, + offsetY + } = transform, + newLeft = x - offsetX, + newTop = y - offsetY, + moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft, + moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop; + moveX && target.set(LEFT, newLeft); + moveY && target.set(TOP, newTop); + if (moveX || moveY) { + fireEvent(MOVING, commonEventInfo(eventData, transform, x, y)); + } + return moveX || moveY; +}; + +class FabricObjectSVGExportMixin { + /** + * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed. + * This reference is a UID in the fabric namespace and is temporary stored here. + * @type {String} + */ + + /** + * Returns styles-string for svg-export + * @param {Boolean} skipShadow a boolean to skip shadow filter output + * @return {String} + */ + getSvgStyles(skipShadow) { + const fillRule = this.fillRule ? this.fillRule : 'nonzero', + strokeWidth = this.strokeWidth ? this.strokeWidth : '0', + strokeDashArray = this.strokeDashArray ? this.strokeDashArray.join(' ') : NONE, + strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0', + strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt', + strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter', + strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4', + opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1', + visibility = this.visible ? '' : ' visibility: hidden;', + filter = skipShadow ? '' : this.getSvgFilter(), + fill = colorPropToSVG(FILL, this.fill), + stroke = colorPropToSVG(STROKE, this.stroke); + return [stroke, 'stroke-width: ', strokeWidth, '; ', 'stroke-dasharray: ', strokeDashArray, '; ', 'stroke-linecap: ', strokeLineCap, '; ', 'stroke-dashoffset: ', strokeDashOffset, '; ', 'stroke-linejoin: ', strokeLineJoin, '; ', 'stroke-miterlimit: ', strokeMiterLimit, '; ', fill, 'fill-rule: ', fillRule, '; ', 'opacity: ', opacity, ';', filter, visibility].join(''); + } + + /** + * Returns filter for svg shadow + * @return {String} + */ + getSvgFilter() { + return this.shadow ? "filter: url(#SVGID_".concat(this.shadow.id, ");") : ''; + } + + /** + * Returns id attribute for svg output + * @return {String} + */ + getSvgCommons() { + return [this.id ? "id=\"".concat(this.id, "\" ") : '', this.clipPath ? "clip-path=\"url(#".concat(this.clipPath.clipPathId, ")\" ") : ''].join(''); + } + + /** + * Returns transform-string for svg-export + * @param {Boolean} use the full transform or the single object one. + * @return {String} + */ + getSvgTransform(full) { + let additionalTransform = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(), + svgTransform = "transform=\"".concat(matrixToSVG(transform)); + return "".concat(svgTransform).concat(additionalTransform, "\" "); + } + + /** + * Returns svg representation of an instance + * This function is implemented in each subclass + * This is just because typescript otherwise cryies all the time + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG(_reviver) { + return ['']; + } + + /** + * Returns svg representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toSVG(reviver) { + return this._createBaseSVGMarkup(this._toSVG(reviver), { + reviver + }); + } + + /** + * Returns svg clipPath representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toClipPathSVG(reviver) { + return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(reviver), { + reviver + }); + } + + /** + * @private + */ + _createBaseClipPathSVGMarkup(objectMarkup) { + let { + reviver, + additionalTransform = '' + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const commonPieces = [this.getSvgTransform(true, additionalTransform), this.getSvgCommons()].join(''), + // insert commons in the markup, style and svgCommons + index = objectMarkup.indexOf('COMMON_PARTS'); + objectMarkup[index] = commonPieces; + return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join(''); + } + + /** + * @private + */ + _createBaseSVGMarkup(objectMarkup) { + let { + noStyle, + reviver, + withShadow, + additionalTransform + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const styleInfo = noStyle ? '' : "style=\"".concat(this.getSvgStyles(), "\" "), + shadowInfo = withShadow ? "style=\"".concat(this.getSvgFilter(), "\" ") : '', + clipPath = this.clipPath, + vectorEffect = this.strokeUniform ? 'vector-effect="non-scaling-stroke" ' : '', + absoluteClipPath = clipPath && clipPath.absolutePositioned, + stroke = this.stroke, + fill = this.fill, + shadow = this.shadow, + markup = [], + // insert commons in the markup, style and svgCommons + index = objectMarkup.indexOf('COMMON_PARTS'); + let clipPathMarkup; + if (clipPath) { + clipPath.clipPathId = "CLIPPATH_".concat(uid()); + clipPathMarkup = "\n").concat(clipPath.toClipPathSVG(reviver), "\n"); + } + if (absoluteClipPath) { + markup.push('\n'); + } + markup.push('\n'); + const commonPieces = [styleInfo, vectorEffect, noStyle ? '' : this.addPaintOrder(), ' ', additionalTransform ? "transform=\"".concat(additionalTransform, "\" ") : ''].join(''); + objectMarkup[index] = commonPieces; + if (isFiller(fill)) { + markup.push(fill.toSVG(this)); + } + if (isFiller(stroke)) { + markup.push(stroke.toSVG(this)); + } + if (shadow) { + markup.push(shadow.toSVG(this)); + } + if (clipPath) { + markup.push(clipPathMarkup); + } + markup.push(objectMarkup.join('')); + markup.push('\n'); + absoluteClipPath && markup.push('\n'); + return reviver ? reviver(markup.join('')) : markup.join(''); + } + addPaintOrder() { + return this.paintFirst !== FILL ? " paint-order=\"".concat(this.paintFirst, "\" ") : ''; + } +} + +function getSvgRegex(arr) { + return new RegExp('^(' + arr.join('|') + ')\\b', 'i'); +} + +var _templateObject$1; +const reNum = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"]))); +const svgNS = 'http://www.w3.org/2000/svg'; +const reFontDeclaration = new RegExp('(normal|italic)?\\s*(normal|small-caps)?\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + reNum + '))?\\s+(.*)'); +const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'], + svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'], + svgInvalidAncestors = ['pattern', 'defs', 'symbol', 'metadata', 'clipPath', 'mask', 'desc'], + svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'], + attributesMap = { + cx: LEFT, + x: LEFT, + r: 'radius', + cy: TOP, + y: TOP, + display: 'visible', + visibility: 'visible', + transform: 'transformMatrix', + 'fill-opacity': 'fillOpacity', + 'fill-rule': 'fillRule', + 'font-family': 'fontFamily', + 'font-size': 'fontSize', + 'font-style': 'fontStyle', + 'font-weight': 'fontWeight', + 'letter-spacing': 'charSpacing', + 'paint-order': 'paintFirst', + 'stroke-dasharray': 'strokeDashArray', + 'stroke-dashoffset': 'strokeDashOffset', + 'stroke-linecap': 'strokeLineCap', + 'stroke-linejoin': 'strokeLineJoin', + 'stroke-miterlimit': 'strokeMiterLimit', + 'stroke-opacity': 'strokeOpacity', + 'stroke-width': 'strokeWidth', + 'text-decoration': 'textDecoration', + 'text-anchor': 'textAnchor', + opacity: 'opacity', + 'clip-path': 'clipPath', + 'clip-rule': 'clipRule', + 'vector-effect': 'strokeUniform', + 'image-rendering': 'imageSmoothing' + }, + fSize = 'font-size', + cPath = 'clip-path'; +const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames); +const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements); +const svgValidParentsRegEx = getSvgRegex(svgValidParents); + +// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute +// matches, e.g.: +14.56e-12, etc. +const reViewBoxAttrValue = new RegExp('^' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*,?' + '\\s*(' + reNum + '+)\\s*' + '$'); + +const unitVectorX = new Point(1, 0); +const zero = new Point(); + +/** + * Rotates `vector` with `radians` + * @param {Point} vector The vector to rotate (x and y) + * @param {Number} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ +const rotateVector = (vector, radians) => vector.rotate(radians); + +/** + * Creates a vector from points represented as a point + * + * @param {Point} from + * @param {Point} to + * @returns {Point} vector + */ +const createVector = (from, to) => new Point(to).subtract(from); + +/** + * return the magnitude of a vector + * @return {number} + */ +const magnitude = point => point.distanceFrom(zero); + +/** + * Calculates the angle between 2 vectors + * @param {Point} a + * @param {Point} b + * @returns the angle in radians from `a` to `b` + */ +const calcAngleBetweenVectors = (a, b) => Math.atan2(crossProduct(a, b), dotProduct(a, b)); + +/** + * Calculates the angle between the x axis and the vector + * @param {Point} v + * @returns the angle in radians of `v` + */ +const calcVectorRotation = v => calcAngleBetweenVectors(unitVectorX, v); + +/** + * @param {Point} v + * @returns {Point} vector representing the unit vector pointing to the direction of `v` + */ +const getUnitVector = v => v.eq(zero) ? v : v.scalarDivide(magnitude(v)); + +/** + * @param {Point} v + * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true` + * @returns {Point} the unit orthogonal vector + */ +const getOrthonormalVector = function (v) { + let counterClockwise = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1)); +}; + +/** + * Cross product of two vectors in 2D + * @param {Point} a + * @param {Point} b + * @returns {number} the magnitude of Z vector + */ +const crossProduct = (a, b) => a.x * b.y - a.y * b.x; + +/** + * Dot product of two vectors in 2D + * @param {Point} a + * @param {Point} b + * @returns {number} + */ +const dotProduct = (a, b) => a.x * b.x + a.y * b.y; + +/** + * Checks if the vector is between two others. It is considered + * to be inside when the vector to be tested is between the + * initial vector and the final vector (included) in a counterclockwise direction. + * @param {Point} t vector to be tested + * @param {Point} a initial vector + * @param {Point} b final vector + * @returns {boolean} true if the vector is among the others + */ +const isBetweenVectors = (t, a, b) => { + if (t.eq(a) || t.eq(b)) return true; + const AxB = crossProduct(a, b), + AxT = crossProduct(a, t), + BxT = crossProduct(b, t); + return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0); +}; + +/** + * Regex matching shadow offsetX, offsetY and blur (ex: "2px 2px 10px rgba(0,0,0,0.2)", "rgb(0,255,0) 2px 2px") + * - (?:\s|^): This part captures either a whitespace character (\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group. + * - (-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down: + * - (-?\d+): Captures an optional minus sign followed by one or more digits (integer part of the number). + * - (?:\.\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number). + * - (?:px)?: Optionally captures the "px" unit. + * - (?:\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?. + * - (-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?: Similar to the previous step, this captures the vertical offset. + +(\d+(?:\.\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign. + +(?:\s+(-?\d+(?:\.\d*)?(?:px)?(?:\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and "px" unit. + +(?:$|\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character. + */ +// eslint-disable-next-line max-len + +const shadowOffsetRegex = '(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?'; +const reOffsetsAndBlur = new RegExp('(?:\\s|^)' + shadowOffsetRegex + shadowOffsetRegex + '(' + reNum + '?(?:px)?)?(?:\\s?|$)(?:$|\\s)'); +const shadowDefaultValues = { + color: 'rgb(0,0,0)', + blur: 0, + offsetX: 0, + offsetY: 0, + affectStroke: false, + includeDefaultValues: true, + nonScaling: false +}; +class Shadow { + /** + * @see {@link http://fabricjs.com/shadows|Shadow demo} + * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. "rgba(0,0,0,0.2) 2px 2px 10px") + */ + + constructor(arg0) { + const options = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0; + Object.assign(this, Shadow.ownDefaults, options); + this.id = uid(); + } + + /** + * @param {String} value Shadow value to parse + * @return {Object} Shadow object with color, offsetX, offsetY and blur + */ + static parseShadow(value) { + const shadowStr = value.trim(), + [, offsetX = 0, offsetY = 0, blur = 0] = (reOffsetsAndBlur.exec(shadowStr) || []).map(value => parseFloat(value) || 0), + color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim(); + return { + color, + offsetX, + offsetY, + blur + }; + } + + /** + * Returns a string representation of an instance + * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow + * @return {String} Returns CSS3 text-shadow declaration + */ + toString() { + return [this.offsetX, this.offsetY, this.blur, this.color].join('px '); + } + + /** + * Returns SVG representation of a shadow + * @param {FabricObject} object + * @return {String} SVG representation of a shadow + */ + toSVG(object) { + const offset = rotateVector(new Point(this.offsetX, this.offsetY), degreesToRadians(-object.angle)), + BLUR_BOX = 20, + color = new Color(this.color); + let fBoxX = 40, + fBoxY = 40; + if (object.width && object.height) { + //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion + // we add some extra space to filter box to contain the blur ( 20 ) + fBoxX = toFixed((Math.abs(offset.x) + this.blur) / object.width, config.NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; + fBoxY = toFixed((Math.abs(offset.y) + this.blur) / object.height, config.NUM_FRACTION_DIGITS) * 100 + BLUR_BOX; + } + if (object.flipX) { + offset.x *= -1; + } + if (object.flipY) { + offset.y *= -1; + } + return "\n\t\n\t\n\t\n\t\n\t\n\t\t\n\t\t\n\t\n\n"); + } + + /** + * Returns object representation of a shadow + * @return {Object} Object representation of a shadow instance + */ + toObject() { + const data = { + color: this.color, + blur: this.blur, + offsetX: this.offsetX, + offsetY: this.offsetY, + affectStroke: this.affectStroke, + nonScaling: this.nonScaling, + type: this.constructor.type + }; + const defaults = Shadow.ownDefaults; + return !this.includeDefaultValues ? pickBy(data, (value, key) => value !== defaults[key]) : data; + } + static async fromObject(options) { + return new this(options); + } +} +/** + * Shadow color + * @type String + * @default + */ +/** + * Shadow blur + * @type Number + */ +/** + * Shadow horizontal offset + * @type Number + * @default + */ +/** + * Shadow vertical offset + * @type Number + * @default + */ +/** + * Whether the shadow should affect stroke operations + * @type Boolean + * @default + */ +/** + * Indicates whether toObject should include default values + * @type Boolean + * @default + */ +/** + * When `false`, the shadow will scale with the object. + * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale. + * default to false + * @type Boolean + * @default + */ +_defineProperty(Shadow, "ownDefaults", shadowDefaultValues); +_defineProperty(Shadow, "type", 'shadow'); +classRegistry.setClass(Shadow, 'shadow'); + +const capValue = (min, value, max) => Math.max(min, Math.min(value, max)); + +const stateProperties = [TOP, LEFT, SCALE_X, SCALE_Y, 'flipX', 'flipY', 'originX', 'originY', 'angle', 'opacity', 'globalCompositeOperation', 'shadow', 'visible', SKEW_X, SKEW_Y]; +const cacheProperties = [FILL, STROKE, 'strokeWidth', 'strokeDashArray', 'width', 'height', 'paintFirst', 'strokeUniform', 'strokeLineCap', 'strokeDashOffset', 'strokeLineJoin', 'strokeMiterLimit', 'backgroundColor', 'clipPath']; +const fabricObjectDefaultValues = { + // see composeMatrix() to see order of transforms. First defaults listed based on this + top: 0, + left: 0, + width: 0, + height: 0, + angle: 0, + flipX: false, + flipY: false, + scaleX: 1, + scaleY: 1, + minScaleLimit: 0, + skewX: 0, + skewY: 0, + originX: LEFT, + originY: TOP, + strokeWidth: 1, + strokeUniform: false, + padding: 0, + opacity: 1, + paintFirst: FILL, + fill: 'rgb(0,0,0)', + fillRule: 'nonzero', + stroke: null, + strokeDashArray: null, + strokeDashOffset: 0, + strokeLineCap: 'butt', + strokeLineJoin: 'miter', + strokeMiterLimit: 4, + globalCompositeOperation: 'source-over', + backgroundColor: '', + shadow: null, + visible: true, + includeDefaultValues: true, + excludeFromExport: false, + objectCaching: true, + clipPath: undefined, + inverted: false, + absolutePositioned: false, + centeredRotation: true, + centeredScaling: false, + dirty: true +}; +const interactiveObjectDefaultValues = { + noScaleCache: true, + lockMovementX: false, + lockMovementY: false, + lockRotation: false, + lockScalingX: false, + lockScalingY: false, + lockSkewingX: false, + lockSkewingY: false, + lockScalingFlip: false, + cornerSize: 13, + touchCornerSize: 24, + transparentCorners: true, + cornerColor: 'rgb(178,204,255)', + cornerStrokeColor: '', + cornerStyle: 'rect', + cornerDashArray: null, + hasControls: true, + borderColor: 'rgb(178,204,255)', + borderDashArray: null, + borderOpacityWhenMoving: 0.4, + borderScaleFactor: 1, + hasBorders: true, + selectionBackgroundColor: '', + selectable: true, + evented: true, + perPixelTargetFind: false, + activeOn: 'down', + hoverCursor: null, + moveCursor: null +}; + +/** + * Easing functions + * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner} + */ + +const normalize = (a, c, p, s) => { + if (a < Math.abs(c)) { + a = c; + s = p / 4; + } else { + //handle the 0/0 case: + if (c === 0 && a === 0) { + s = p / twoMathPi * Math.asin(1); + } else { + s = p / twoMathPi * Math.asin(c / a); + } + } + return { + a, + c, + p, + s + }; +}; +const elastic = (a, s, p, t, d) => a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * twoMathPi / p); + +/** + * Default sinusoidal easing + */ +const defaultEasing = (t, b, c, d) => -c * Math.cos(t / d * halfPI) + c + b; + +/** + * Cubic easing in + */ +const easeInCubic = (t, b, c, d) => c * (t / d) ** 3 + b; + +/** + * Cubic easing out + */ +const easeOutCubic = (t, b, c, d) => c * ((t / d - 1) ** 3 + 1) + b; + +/** + * Cubic easing in and out + */ +const easeInOutCubic = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 3 + b; + } + return c / 2 * ((t - 2) ** 3 + 2) + b; +}; + +/** + * Quartic easing in + */ +const easeInQuart = (t, b, c, d) => c * (t /= d) * t ** 3 + b; + +/** + * Quartic easing out + */ +const easeOutQuart = (t, b, c, d) => -c * ((t = t / d - 1) * t ** 3 - 1) + b; + +/** + * Quartic easing in and out + */ +const easeInOutQuart = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 4 + b; + } + return -c / 2 * ((t -= 2) * t ** 3 - 2) + b; +}; + +/** + * Quintic easing in + */ +const easeInQuint = (t, b, c, d) => c * (t / d) ** 5 + b; + +/** + * Quintic easing out + */ +const easeOutQuint = (t, b, c, d) => c * ((t / d - 1) ** 5 + 1) + b; + +/** + * Quintic easing in and out + */ +const easeInOutQuint = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 5 + b; + } + return c / 2 * ((t - 2) ** 5 + 2) + b; +}; + +/** + * Sinusoidal easing in + */ +const easeInSine = (t, b, c, d) => -c * Math.cos(t / d * halfPI) + c + b; + +/** + * Sinusoidal easing out + */ +const easeOutSine = (t, b, c, d) => c * Math.sin(t / d * halfPI) + b; + +/** + * Sinusoidal easing in and out + */ +const easeInOutSine = (t, b, c, d) => -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; + +/** + * Exponential easing in + */ +const easeInExpo = (t, b, c, d) => t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b; + +/** + * Exponential easing out + */ +const easeOutExpo = (t, b, c, d) => t === d ? b + c : c * -(2 ** (-10 * t / d) + 1) + b; + +/** + * Exponential easing in and out + */ +const easeInOutExpo = (t, b, c, d) => { + if (t === 0) { + return b; + } + if (t === d) { + return b + c; + } + t /= d / 2; + if (t < 1) { + return c / 2 * 2 ** (10 * (t - 1)) + b; + } + return c / 2 * -(2 ** (-10 * --t) + 2) + b; +}; + +/** + * Circular easing in + */ +const easeInCirc = (t, b, c, d) => -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; + +/** + * Circular easing out + */ +const easeOutCirc = (t, b, c, d) => c * Math.sqrt(1 - (t = t / d - 1) * t) + b; + +/** + * Circular easing in and out + */ +const easeInOutCirc = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return -c / 2 * (Math.sqrt(1 - t ** 2) - 1) + b; + } + return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; +}; + +/** + * Elastic easing in + */ +const easeInElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + const { + a: normA, + s: normS, + p: normP + } = normalize(a, c, p, s); + return -elastic(normA, normS, normP, t, d) + b; +}; + +/** + * Elastic easing out + */ +const easeOutElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d; + if (t === 1) { + return b + c; + } + if (!p) { + p = d * 0.3; + } + const { + a: normA, + s: normS, + p: normP, + c: normC + } = normalize(a, c, p, s); + return normA * 2 ** (-10 * t) * Math.sin((t * d - normS) * twoMathPi / normP) + normC + b; +}; + +/** + * Elastic easing in and out + */ +const easeInOutElastic = (t, b, c, d) => { + const s = 1.70158, + a = c; + let p = 0; + if (t === 0) { + return b; + } + t /= d / 2; + if (t === 2) { + return b + c; + } + if (!p) { + p = d * (0.3 * 1.5); + } + const { + a: normA, + s: normS, + p: normP, + c: normC + } = normalize(a, c, p, s); + if (t < 1) { + return -0.5 * elastic(normA, normS, normP, t, d) + b; + } + return normA * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - normS) * twoMathPi / normP) * 0.5 + normC + b; +}; + +/** + * Backwards easing in + */ +const easeInBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + return c * (t /= d) * t * ((s + 1) * t - s) + b; +}; + +/** + * Backwards easing out + */ +const easeOutBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; +}; + +/** + * Backwards easing in and out + */ +const easeInOutBack = function (t, b, c, d) { + let s = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1.70158; + t /= d / 2; + if (t < 1) { + return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; + } + return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; +}; + +/** + * Bouncing easing out + */ +const easeOutBounce = (t, b, c, d) => { + if ((t /= d) < 1 / 2.75) { + return c * (7.5625 * t * t) + b; + } else if (t < 2 / 2.75) { + return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b; + } else if (t < 2.5 / 2.75) { + return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b; + } else { + return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b; + } +}; + +/** + * Bouncing easing in + */ +const easeInBounce = (t, b, c, d) => c - easeOutBounce(d - t, 0, c, d) + b; + +/** + * Bouncing easing in and out + */ +const easeInOutBounce = (t, b, c, d) => t < d / 2 ? easeInBounce(t * 2, 0, c, d) * 0.5 + b : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b; + +/** + * Quadratic easing in + */ +const easeInQuad = (t, b, c, d) => c * (t /= d) * t + b; + +/** + * Quadratic easing out + */ +const easeOutQuad = (t, b, c, d) => -c * (t /= d) * (t - 2) + b; + +/** + * Quadratic easing in and out + */ +const easeInOutQuad = (t, b, c, d) => { + t /= d / 2; + if (t < 1) { + return c / 2 * t ** 2 + b; + } + return -c / 2 * (--t * (t - 2) - 1) + b; +}; + +var easing = /*#__PURE__*/Object.freeze({ + __proto__: null, + defaultEasing: defaultEasing, + easeInBack: easeInBack, + easeInBounce: easeInBounce, + easeInCirc: easeInCirc, + easeInCubic: easeInCubic, + easeInElastic: easeInElastic, + easeInExpo: easeInExpo, + easeInOutBack: easeInOutBack, + easeInOutBounce: easeInOutBounce, + easeInOutCirc: easeInOutCirc, + easeInOutCubic: easeInOutCubic, + easeInOutElastic: easeInOutElastic, + easeInOutExpo: easeInOutExpo, + easeInOutQuad: easeInOutQuad, + easeInOutQuart: easeInOutQuart, + easeInOutQuint: easeInOutQuint, + easeInOutSine: easeInOutSine, + easeInQuad: easeInQuad, + easeInQuart: easeInQuart, + easeInQuint: easeInQuint, + easeInSine: easeInSine, + easeOutBack: easeOutBack, + easeOutBounce: easeOutBounce, + easeOutCirc: easeOutCirc, + easeOutCubic: easeOutCubic, + easeOutElastic: easeOutElastic, + easeOutExpo: easeOutExpo, + easeOutQuad: easeOutQuad, + easeOutQuart: easeOutQuart, + easeOutQuint: easeOutQuint, + easeOutSine: easeOutSine +}); + +const defaultAbort = () => false; +class AnimationBase { + /** + * Current value + */ + + /** + * Animation start time ms + */ + + constructor(_ref) { + let { + startValue, + byValue, + duration = 500, + delay = 0, + easing = defaultEasing, + onStart = noop, + onChange = noop, + onComplete = noop, + abort = defaultAbort, + target + } = _ref; + /** + * Used to register the animation to a target object + * so that it can be cancelled within the object context + */ + _defineProperty(this, "_state", 'pending'); + /** + * Time %, or the ratio of `timeElapsed / duration` + * @see tick + */ + _defineProperty(this, "durationProgress", 0); + /** + * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)` + */ + _defineProperty(this, "valueProgress", 0); + this.tick = this.tick.bind(this); + this.duration = duration; + this.delay = delay; + this.easing = easing; + this._onStart = onStart; + this._onChange = onChange; + this._onComplete = onComplete; + this._abort = abort; + this.target = target; + this.startValue = startValue; + this.byValue = byValue; + this.value = this.startValue; + this.endValue = Object.freeze(this.calculate(this.duration).value); + } + get state() { + return this._state; + } + isDone() { + return this._state === 'aborted' || this._state === 'completed'; + } + + /** + * Calculate the current value based on the easing parameters + * @param timeElapsed in ms + * @protected + */ + + start() { + const firstTick = timestamp => { + if (this._state !== 'pending') return; + this.startTime = timestamp || +new Date(); + this._state = 'running'; + this._onStart(); + this.tick(this.startTime); + }; + this.register(); + + // setTimeout(cb, 0) will run cb on the next frame, causing a delay + // we don't want that + if (this.delay > 0) { + setTimeout(() => requestAnimFrame(firstTick), this.delay); + } else { + requestAnimFrame(firstTick); + } + } + tick(t) { + const durationMs = (t || +new Date()) - this.startTime; + const boundDurationMs = Math.min(durationMs, this.duration); + this.durationProgress = boundDurationMs / this.duration; + const { + value, + valueProgress + } = this.calculate(boundDurationMs); + this.value = Object.freeze(value); + this.valueProgress = valueProgress; + if (this._state === 'aborted') { + return; + } else if (this._abort(this.value, this.valueProgress, this.durationProgress)) { + this._state = 'aborted'; + this.unregister(); + } else if (durationMs >= this.duration) { + this.durationProgress = this.valueProgress = 1; + this._onChange(this.endValue, this.valueProgress, this.durationProgress); + this._state = 'completed'; + this._onComplete(this.endValue, this.valueProgress, this.durationProgress); + this.unregister(); + } else { + this._onChange(this.value, this.valueProgress, this.durationProgress); + requestAnimFrame(this.tick); + } + } + register() { + runningAnimations.push(this); + } + unregister() { + runningAnimations.remove(this); + } + abort() { + this._state = 'aborted'; + this.unregister(); + } +} + +const _excluded$h = ["startValue", "endValue"]; +class ValueAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue = 0, + endValue = 100 + } = _ref, + otherOptions = _objectWithoutProperties(_ref, _excluded$h); + super(_objectSpread2(_objectSpread2({}, otherOptions), {}, { + startValue, + byValue: endValue - startValue + })); + } + calculate(timeElapsed) { + const value = this.easing(timeElapsed, this.startValue, this.byValue, this.duration); + return { + value, + valueProgress: Math.abs((value - this.startValue) / this.byValue) + }; + } +} + +const _excluded$g = ["startValue", "endValue"]; +class ArrayAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue = [0], + endValue = [100] + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$g); + super(_objectSpread2(_objectSpread2({}, options), {}, { + startValue, + byValue: endValue.map((value, i) => value - startValue[i]) + })); + } + calculate(timeElapsed) { + const values = this.startValue.map((value, i) => this.easing(timeElapsed, value, this.byValue[i], this.duration, i)); + return { + value: values, + valueProgress: Math.abs((values[0] - this.startValue[0]) / this.byValue[0]) + }; + } +} + +const _excluded$f = ["startValue", "endValue", "easing", "onChange", "onComplete", "abort"]; +const defaultColorEasing = (timeElapsed, startValue, byValue, duration) => { + const durationProgress = 1 - Math.cos(timeElapsed / duration * halfPI); + return startValue + byValue * durationProgress; +}; +const wrapColorCallback = callback => callback && ((rgba, valueProgress, durationProgress) => callback(new Color(rgba).toRgba(), valueProgress, durationProgress)); +class ColorAnimation extends AnimationBase { + constructor(_ref) { + let { + startValue, + endValue, + easing = defaultColorEasing, + onChange, + onComplete, + abort + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$f); + const startColor = new Color(startValue).getSource(); + const endColor = new Color(endValue).getSource(); + super(_objectSpread2(_objectSpread2({}, options), {}, { + startValue: startColor, + byValue: endColor.map((value, i) => value - startColor[i]), + easing, + onChange: wrapColorCallback(onChange), + onComplete: wrapColorCallback(onComplete), + abort: wrapColorCallback(abort) + })); + } + calculate(timeElapsed) { + const [r, g, b, a] = this.startValue.map((value, i) => this.easing(timeElapsed, value, this.byValue[i], this.duration, i)); + const value = [...[r, g, b].map(Math.round), capValue(0, a, 1)]; + return { + value, + valueProgress: + // to correctly calculate the change ratio we must find a changed value + value.map((p, i) => this.byValue[i] !== 0 ? Math.abs((p - this.startValue[i]) / this.byValue[i]) : 0).find(p => p !== 0) || 0 + }; + } +} + +const isArrayAnimation = options => { + return Array.isArray(options.startValue) || Array.isArray(options.endValue); +}; + +/** + * Changes value(s) from startValue to endValue within a certain period of time, + * invoking callbacks as the value(s) change. + * + * @example + * animate({ + * startValue: 1, + * endValue: 0, + * onChange: (v) => { + * obj.set('opacity', v); + * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll` + * canvas.renderAll(); + * } + * }); + * + * @example Using lists: + * animate({ + * startValue: [1, 2, 3], + * endValue: [2, 4, 6], + * onChange: ([x, y, zoom]) => { + * canvas.zoomToPoint(new Point(x, y), zoom); + * canvas.renderAll(); + * } + * }); + * + */ + +function animate(options) { + const animation = isArrayAnimation(options) ? new ArrayAnimation(options) : new ValueAnimation(options); + animation.start(); + return animation; +} +function animateColor(options) { + const animation = new ColorAnimation(options); + animation.start(); + return animation; +} + +/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */ + +class Intersection { + constructor(status) { + this.status = status; + this.points = []; + } + + /** + * Used to verify if a point is alredy in the collection + * @param {Point} point + * @returns {boolean} + */ + includes(point) { + return this.points.some(p => p.eq(point)); + } + + /** + * Appends points of intersection + * @param {...Point[]} points + * @return {Intersection} thisArg + * @chainable + */ + append() { + for (var _len = arguments.length, points = new Array(_len), _key = 0; _key < _len; _key++) { + points[_key] = arguments[_key]; + } + this.points = this.points.concat(points.filter(point => { + return !this.includes(point); + })); + return this; + } + + /** + * check if point T is on the segment or line defined between A and B + * + * @param {Point} T the point we are checking for + * @param {Point} A one extremity of the segment + * @param {Point} B the other extremity of the segment + * @param [infinite] if true checks if `T` is on the line defined by `A` and `B` + * @returns true if `T` is contained + */ + static isPointContained(T, A, B) { + let infinite = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + if (A.eq(B)) { + // Edge case: the segment is a point, we check for coincidence, + // infinite param has no meaning because there are infinite lines to consider + return T.eq(A); + } else if (A.x === B.x) { + // Edge case: horizontal line. + // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y + return T.x === A.x && (infinite || T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)); + } else if (A.y === B.y) { + // Edge case: vertical line. + // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x + return T.y === A.y && (infinite || T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)); + } else { + // Generic case: sloped line. + // we check that AT has the same slope as AB + // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size + // for the infinite case we check the absolute value of the slope, since direction is meaningless + const AB = createVector(A, B); + const AT = createVector(A, T); + const s = AT.divide(AB); + return infinite ? Math.abs(s.x) === Math.abs(s.y) : s.x === s.y && s.x >= 0 && s.x <= 1; + } + } + + /** + * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points} + * @see https://en.wikipedia.org/wiki/Point_in_polygon + * @param point + * @param points polygon points + * @returns + */ + static isPointInPolygon(point, points) { + const other = new Point(point).setX(Math.min(point.x - 1, ...points.map(p => p.x))); + let hits = 0; + for (let index = 0; index < points.length; index++) { + const inter = this.intersectSegmentSegment( + // polygon side + points[index], points[(index + 1) % points.length], + // ray + point, other); + if (inter.includes(point)) { + // point is on the polygon side + return true; + } + hits += Number(inter.status === 'Intersection'); + } + return hits % 2 === 1; + } + + /** + * Checks if a line intersects another + * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection} + * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule} + * @static + * @param {Point} a1 + * @param {Point} a2 + * @param {Point} b1 + * @param {Point} b2 + * @param {boolean} [aInfinite=true] check segment intersection by passing `false` + * @param {boolean} [bInfinite=true] check segment intersection by passing `false` + * @return {Intersection} + */ + static intersectLineLine(a1, a2, b1, b2) { + let aInfinite = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + let bInfinite = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + const a2xa1x = a2.x - a1.x, + a2ya1y = a2.y - a1.y, + b2xb1x = b2.x - b1.x, + b2yb1y = b2.y - b1.y, + a1xb1x = a1.x - b1.x, + a1yb1y = a1.y - b1.y, + uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x, + ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x, + uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y; + if (uB !== 0) { + const ua = uaT / uB, + ub = ubT / uB; + if ((aInfinite || 0 <= ua && ua <= 1) && (bInfinite || 0 <= ub && ub <= 1)) { + return new Intersection('Intersection').append(new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y)); + } else { + return new Intersection(); + } + } else { + if (uaT === 0 || ubT === 0) { + const segmentsCoincide = aInfinite || bInfinite || Intersection.isPointContained(a1, b1, b2) || Intersection.isPointContained(a2, b1, b2) || Intersection.isPointContained(b1, a1, a2) || Intersection.isPointContained(b2, a1, a2); + return new Intersection(segmentsCoincide ? 'Coincident' : undefined); + } else { + return new Intersection('Parallel'); + } + } + } + + /** + * Checks if a segment intersects a line + * @see {@link intersectLineLine} for line intersection + * @static + * @param {Point} s1 boundary point of segment + * @param {Point} s2 other boundary point of segment + * @param {Point} l1 point on line + * @param {Point} l2 other point on line + * @return {Intersection} + */ + static intersectSegmentLine(s1, s2, l1, l2) { + return Intersection.intersectLineLine(s1, s2, l1, l2, false, true); + } + + /** + * Checks if a segment intersects another + * @see {@link intersectLineLine} for line intersection + * @static + * @param {Point} a1 boundary point of segment + * @param {Point} a2 other boundary point of segment + * @param {Point} b1 boundary point of segment + * @param {Point} b2 other boundary point of segment + * @return {Intersection} + */ + static intersectSegmentSegment(a1, a2, b1, b2) { + return Intersection.intersectLineLine(a1, a2, b1, b2, false, false); + } + + /** + * Checks if line intersects polygon + * + * @todo account for stroke + * + * @static + * @see {@link intersectSegmentPolygon} for segment intersection + * @param {Point} a1 point on line + * @param {Point} a2 other point on line + * @param {Point[]} points polygon points + * @param {boolean} [infinite=true] check segment intersection by passing `false` + * @return {Intersection} + */ + static intersectLinePolygon(a1, a2, points) { + let infinite = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + const result = new Intersection(); + const length = points.length; + for (let i = 0, b1, b2, inter; i < length; i++) { + b1 = points[i]; + b2 = points[(i + 1) % length]; + inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false); + if (inter.status === 'Coincident') { + return inter; + } + result.append(...inter.points); + } + if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + } + + /** + * Checks if segment intersects polygon + * @static + * @see {@link intersectLinePolygon} for line intersection + * @param {Point} a1 boundary point of segment + * @param {Point} a2 other boundary point of segment + * @param {Point[]} points polygon points + * @return {Intersection} + */ + static intersectSegmentPolygon(a1, a2, points) { + return Intersection.intersectLinePolygon(a1, a2, points, false); + } + + /** + * Checks if polygon intersects another polygon + * + * @todo account for stroke + * + * @static + * @param {Point[]} points1 + * @param {Point[]} points2 + * @return {Intersection} + */ + static intersectPolygonPolygon(points1, points2) { + const result = new Intersection(), + length = points1.length; + const coincidences = []; + for (let i = 0; i < length; i++) { + const a1 = points1[i], + a2 = points1[(i + 1) % length], + inter = Intersection.intersectSegmentPolygon(a1, a2, points2); + if (inter.status === 'Coincident') { + coincidences.push(inter); + result.append(a1, a2); + } else { + result.append(...inter.points); + } + } + if (coincidences.length > 0 && coincidences.length === points1.length) { + return new Intersection('Coincident'); + } else if (result.points.length > 0) { + result.status = 'Intersection'; + } + return result; + } + + /** + * Checks if polygon intersects rectangle + * @static + * @see {@link intersectPolygonPolygon} for polygon intersection + * @param {Point[]} points polygon points + * @param {Point} r1 top left point of rect + * @param {Point} r2 bottom right point of rect + * @return {Intersection} + */ + static intersectPolygonRectangle(points, r1, r2) { + const min = r1.min(r2), + max = r1.max(r2), + topRight = new Point(max.x, min.y), + bottomLeft = new Point(min.x, max.y); + return Intersection.intersectPolygonPolygon(points, [min, topRight, max, bottomLeft]); + } +} + +class ObjectGeometry extends CommonMethods { + // #region Geometry + + /** + * Describe object's corner position in scene coordinates. + * The coordinates are derived from the following: + * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth. + * The coordinates do not depend on viewport changes. + * The coordinates get updated with {@link setCoords}. + * You can calculate them without updating with {@link calcACoords()} + */ + + /** + * storage cache for object transform matrix + */ + + /** + * storage cache for object full transform matrix + */ + + /** + * A Reference of the Canvas where the object is actually added + * @type StaticCanvas | Canvas; + * @default undefined + * @private + */ + + /** + * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane + */ + getX() { + return this.getXY().x; + } + + /** + * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane + */ + setX(value) { + this.setXY(this.getXY().setX(value)); + } + + /** + * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane + */ + getY() { + return this.getXY().y; + } + + /** + * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane + */ + setY(value) { + this.setXY(this.getXY().setY(value)); + } + + /** + * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link getX} + */ + getRelativeX() { + return this.left; + } + + /** + * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\ + * if parent is canvas then this method is identical to {@link setX} + */ + setRelativeX(value) { + this.left = value; + } + + /** + * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link getY} + */ + getRelativeY() { + return this.top; + } + + /** + * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\ + * if parent is canvas then this property is identical to {@link setY} + */ + setRelativeY(value) { + this.top = value; + } + + /** + * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane + */ + getXY() { + const relativePosition = this.getRelativeXY(); + return this.group ? transformPoint(relativePosition, this.group.calcTransformMatrix()) : relativePosition; + } + + /** + * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate. + * You can specify {@link originX} and {@link originY} values, + * that otherwise are the object's current values. + * @example Set object's bottom left corner to point (5,5) on canvas + * object.setXY(new Point(5, 5), 'left', 'bottom'). + * @param {Point} point position in scene coordinate plane + * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom' + */ + setXY(point, originX, originY) { + if (this.group) { + point = transformPoint(point, invertTransform(this.group.calcTransformMatrix())); + } + this.setRelativeXY(point, originX, originY); + } + + /** + * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane + */ + getRelativeXY() { + return new Point(this.left, this.top); + } + + /** + * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas) + * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane + * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom' + */ + setRelativeXY(point) { + let originX = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.originX; + let originY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.originY; + this.setPositionByOrigin(point, originX, originY); + } + + /** + * @deprecated intermidiate method to be removed, do not use + */ + isStrokeAccountedForInDimensions() { + return false; + } + + /** + * @return {Point[]} [tl, tr, br, bl] in the scene plane + */ + getCoords() { + const { + tl, + tr, + br, + bl + } = this.aCoords || (this.aCoords = this.calcACoords()); + const coords = [tl, tr, br, bl]; + if (this.group) { + const t = this.group.calcTransformMatrix(); + return coords.map(p => transformPoint(p, t)); + } + return coords; + } + + /** + * Checks if object intersects with the scene rect formed by {@link tl} and {@link br} + */ + intersectsWithRect(tl, br) { + const intersection = Intersection.intersectPolygonRectangle(this.getCoords(), tl, br); + return intersection.status === 'Intersection'; + } + + /** + * Checks if object intersects with another object + * @param {Object} other Object to test + * @return {Boolean} true if object intersects with another object + */ + intersectsWithObject(other) { + const intersection = Intersection.intersectPolygonPolygon(this.getCoords(), other.getCoords()); + return intersection.status === 'Intersection' || intersection.status === 'Coincident' || other.isContainedWithinObject(this) || this.isContainedWithinObject(other); + } + + /** + * Checks if object is fully contained within area of another object + * @param {Object} other Object to test + * @return {Boolean} true if object is fully contained within area of another object + */ + isContainedWithinObject(other) { + const points = this.getCoords(); + return points.every(point => other.containsPoint(point)); + } + + /** + * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br} + */ + isContainedWithinRect(tl, br) { + const { + left, + top, + width, + height + } = this.getBoundingRect(); + return left >= tl.x && left + width <= br.x && top >= tl.y && top + height <= br.y; + } + isOverlapping(other) { + return this.intersectsWithObject(other) || this.isContainedWithinObject(other) || other.isContainedWithinObject(this); + } + + /** + * Checks if point is inside the object + * @param {Point} point Point to check against + * @return {Boolean} true if point is inside the object + */ + containsPoint(point) { + return Intersection.isPointInPolygon(point, this.getCoords()); + } + + /** + * Checks if object is contained within the canvas with current viewportTransform + * the check is done stopping at first point that appears on screen + * @return {Boolean} true if object is fully or partially contained within canvas + */ + isOnScreen() { + if (!this.canvas) { + return false; + } + const { + tl, + br + } = this.canvas.vptCoords; + const points = this.getCoords(); + // if some point is on screen, the object is on screen. + if (points.some(point => point.x <= br.x && point.x >= tl.x && point.y <= br.y && point.y >= tl.y)) { + return true; + } + // no points on screen, check intersection with absolute coordinates + if (this.intersectsWithRect(tl, br)) { + return true; + } + // check if the object is so big that it contains the entire viewport + return this.containsPoint(tl.midPointFrom(br)); + } + + /** + * Checks if object is partially contained within the canvas with current viewportTransform + * @return {Boolean} true if object is partially contained within canvas + */ + isPartiallyOnScreen() { + if (!this.canvas) { + return false; + } + const { + tl, + br + } = this.canvas.vptCoords; + if (this.intersectsWithRect(tl, br)) { + return true; + } + const allPointsAreOutside = this.getCoords().every(point => (point.x >= br.x || point.x <= tl.x) && (point.y >= br.y || point.y <= tl.y)); + // check if the object is so big that it contains the entire viewport + return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br)); + } + + /** + * Returns coordinates of object's bounding rectangle (left, top, width, height) + * the box is intended as aligned to axis of canvas. + * @return {Object} Object with left, top, width, height properties + */ + getBoundingRect() { + return makeBoundingBoxFromPoints(this.getCoords()); + } + + /** + * Returns width of an object's bounding box counting transformations + * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane? + * @return {Number} width value + */ + getScaledWidth() { + return this._getTransformedDimensions().x; + } + + /** + * Returns height of an object bounding box counting transformations + * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane? + * @return {Number} height value + */ + getScaledHeight() { + return this._getTransformedDimensions().y; + } + + /** + * Scales an object (equally by x and y) + * @param {Number} value Scale factor + * @return {void} + */ + scale(value) { + this._set(SCALE_X, value); + this._set(SCALE_Y, value); + this.setCoords(); + } + + /** + * Scales an object to a given width, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New width value + * @return {void} + */ + scaleToWidth(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + const boundingRectFactor = this.getBoundingRect().width / this.getScaledWidth(); + return this.scale(value / this.width / boundingRectFactor); + } + + /** + * Scales an object to a given height, with respect to bounding box (scaling by x/y equally) + * @param {Number} value New height value + * @return {void} + */ + scaleToHeight(value) { + // adjust to bounding rect factor so that rotated shapes would fit as well + const boundingRectFactor = this.getBoundingRect().height / this.getScaledHeight(); + return this.scale(value / this.height / boundingRectFactor); + } + getCanvasRetinaScaling() { + var _this$canvas; + return ((_this$canvas = this.canvas) === null || _this$canvas === void 0 ? void 0 : _this$canvas.getRetinaScaling()) || 1; + } + + /** + * Returns the object angle relative to canvas counting also the group property + * @returns {TDegree} + */ + getTotalAngle() { + return this.group ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix())) : this.angle; + } + + /** + * Retrieves viewportTransform from Object's canvas if available + * @return {TMat2D} + */ + getViewportTransform() { + var _this$canvas2; + return ((_this$canvas2 = this.canvas) === null || _this$canvas2 === void 0 ? void 0 : _this$canvas2.viewportTransform) || iMatrix.concat(); + } + + /** + * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates. + * those never change with zoom or viewport changes. + * @return {TCornerPoint} + */ + calcACoords() { + const rotateMatrix = createRotateMatrix({ + angle: this.angle + }), + { + x, + y + } = this.getRelativeCenterPoint(), + tMatrix = createTranslateMatrix(x, y), + finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix), + dim = this._getTransformedDimensions(), + w = dim.x / 2, + h = dim.y / 2; + return { + // corners + tl: transformPoint({ + x: -w, + y: -h + }, finalMatrix), + tr: transformPoint({ + x: w, + y: -h + }, finalMatrix), + bl: transformPoint({ + x: -w, + y: h + }, finalMatrix), + br: transformPoint({ + x: w, + y: h + }, finalMatrix) + }; + } + + /** + * Sets corner and controls position coordinates based on current angle, width and height, left and top. + * aCoords are used to quickly find an object on the canvas. + * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas} + */ + setCoords() { + this.aCoords = this.calcACoords(); + } + transformMatrixKey() { + let skipGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + let prefix = []; + if (!skipGroup && this.group) { + prefix = this.group.transformMatrixKey(skipGroup); + } + prefix.push(this.top, this.left, this.width, this.height, this.scaleX, this.scaleY, this.angle, this.strokeWidth, this.skewX, this.skewY, +this.flipX, +this.flipY, resolveOrigin(this.originX), resolveOrigin(this.originY)); + return prefix; + } + + /** + * calculate transform matrix that represents the current transformations from the + * object's properties. + * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations + * There are some situation in which this is useful to avoid the fake rotation. + * @return {TMat2D} transform matrix for the object + */ + calcTransformMatrix() { + let skipGroup = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + let matrix = this.calcOwnMatrix(); + if (skipGroup || !this.group) { + return matrix; + } + const key = this.transformMatrixKey(skipGroup), + cache = this.matrixCache; + if (cache && cache.key.every((x, i) => x === key[i])) { + return cache.value; + } + if (this.group) { + matrix = multiplyTransformMatrices(this.group.calcTransformMatrix(false), matrix); + } + this.matrixCache = { + key, + value: matrix + }; + return matrix; + } + + /** + * calculate transform matrix that represents the current transformations from the + * object's properties, this matrix does not include the group transformation + * @return {TMat2D} transform matrix for the object + */ + calcOwnMatrix() { + const key = this.transformMatrixKey(true), + cache = this.ownMatrixCache; + if (cache && cache.key === key) { + return cache.value; + } + const center = this.getRelativeCenterPoint(), + options = { + angle: this.angle, + translateX: center.x, + translateY: center.y, + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + flipX: this.flipX, + flipY: this.flipY + }, + value = composeMatrix(options); + this.ownMatrixCache = { + key, + value + }; + return value; + } + + /** + * Calculate object dimensions from its properties + * @private + * @returns {Point} dimensions + */ + _getNonTransformedDimensions() { + return new Point(this.width, this.height).scalarAdd(this.strokeWidth); + } + + /** + * Calculate object dimensions for controls box, including padding and canvas zoom. + * and active selection + * @private + * @param {object} [options] transform options + * @returns {Point} dimensions + */ + _calculateCurrentDimensions(options) { + return this._getTransformedDimensions(options).transform(this.getViewportTransform(), true).scalarAdd(2 * this.padding); + } + + // #region Origin + + /** + * @deprecated please use 'center' as value in new projects + * */ + + /** + * @deprecated please use 'center' as value in new projects + * */ + + /** + * Object containing this object. + * can influence its size and position + */ + + /** + * Calculate object bounding box dimensions from its properties scale, skew. + * This bounding box is aligned with object angle and not with canvas axis or screen. + * @param {Object} [options] + * @param {Number} [options.scaleX] + * @param {Number} [options.scaleY] + * @param {Number} [options.skewX] + * @param {Number} [options.skewY] + * @private + * @returns {Point} dimensions + */ + _getTransformedDimensions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const dimOptions = _objectSpread2({ + // if scaleX or scaleY are negative numbers, + // this will return dimensions that are negative. + // and this will break assumptions around the codebase + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + width: this.width, + height: this.height, + strokeWidth: this.strokeWidth + }, options); + // stroke is applied before/after transformations are applied according to `strokeUniform` + const strokeWidth = dimOptions.strokeWidth; + let preScalingStrokeValue = strokeWidth, + postScalingStrokeValue = 0; + if (this.strokeUniform) { + preScalingStrokeValue = 0; + postScalingStrokeValue = strokeWidth; + } + const dimX = dimOptions.width + preScalingStrokeValue, + dimY = dimOptions.height + preScalingStrokeValue, + noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0; + let finalDimensions; + if (noSkew) { + finalDimensions = new Point(dimX * dimOptions.scaleX, dimY * dimOptions.scaleY); + } else { + finalDimensions = sizeAfterTransform(dimX, dimY, calcDimensionsMatrix(dimOptions)); + } + return finalDimensions.scalarAdd(postScalingStrokeValue); + } + + /** + * Translates the coordinates from a set of origin to another (based on the object's dimensions) + * @param {Point} point The point which corresponds to the originX and originY params + * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom' + * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToGivenOrigin(point, fromOriginX, fromOriginY, toOriginX, toOriginY) { + let x = point.x, + y = point.y; + const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX), + offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY); + if (offsetX || offsetY) { + const dim = this._getTransformedDimensions(); + x += offsetX * dim.x; + y += offsetY * dim.y; + } + return new Point(x, y); + } + + /** + * Translates the coordinates from origin to center coordinates (based on the object's dimensions) + * @param {Point} point The point which corresponds to the originX and originY params + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToCenterPoint(point, originX, originY) { + if (originX === CENTER && originY === CENTER) { + return point; + } + const p = this.translateToGivenOrigin(point, originX, originY, CENTER, CENTER); + if (this.angle) { + return p.rotate(degreesToRadians(this.angle), point); + } + return p; + } + + /** + * Translates the coordinates from center to origin coordinates (based on the object's dimensions) + * @param {Point} center The point which corresponds to center of the object + * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + translateToOriginPoint(center, originX, originY) { + const p = this.translateToGivenOrigin(center, CENTER, CENTER, originX, originY); + if (this.angle) { + return p.rotate(degreesToRadians(this.angle), center); + } + return p; + } + + /** + * Returns the center coordinates of the object relative to canvas + * @return {Point} + */ + getCenterPoint() { + const relCenter = this.getRelativeCenterPoint(); + return this.group ? transformPoint(relCenter, this.group.calcTransformMatrix()) : relCenter; + } + + /** + * Returns the center coordinates of the object relative to it's parent + * @return {Point} + */ + getRelativeCenterPoint() { + return this.translateToCenterPoint(new Point(this.left, this.top), this.originX, this.originY); + } + + /** + * Returns the position of the object as if it has a different origin. + * Take an object that has left, top set to 100, 100 with origin 'left', 'top'. + * Return the values of left top ( wrapped in a point ) that you would need to keep + * the same position if origin where different. + * Alternatively you can use this to also find which point in the parent plane is a specific origin + * ( where is the bottom right corner of my object? ) + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {Point} + */ + getPointByOrigin(originX, originY) { + return this.translateToOriginPoint(this.getRelativeCenterPoint(), originX, originY); + } + + /** + * Sets the position of the object taking into consideration the object's origin + * @param {Point} pos The new position of the object + * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right' + * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom' + * @return {void} + */ + setPositionByOrigin(pos, originX, originY) { + const center = this.translateToCenterPoint(pos, originX, originY), + position = this.translateToOriginPoint(center, this.originX, this.originY); + this.set({ + left: position.x, + top: position.y + }); + } + + /** + * @private + */ + _getLeftTopCoords() { + return this.translateToOriginPoint(this.getRelativeCenterPoint(), LEFT, TOP); + } +} + +const _excluded$e = ["type"], + _excluded2$4 = ["extraParam"]; +/** + * Root object class from which all 2d shape classes inherit from + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects} + * + * @fires added + * @fires removed + * + * @fires selected + * @fires deselected + * + * @fires rotating + * @fires scaling + * @fires moving + * @fires skewing + * @fires modified + * + * @fires mousedown + * @fires mouseup + * @fires mouseover + * @fires mouseout + * @fires mousewheel + * @fires mousedblclick + * + * @fires dragover + * @fires dragenter + * @fires dragleave + * @fires drop + */ +let FabricObject$1 = class FabricObject extends ObjectGeometry { + static getDefaults() { + return FabricObject.ownDefaults; + } + + /** + * The class type. + * This is used for serialization and deserialization purposes and internally it can be used + * to identify classes. + * When we transform a class in a plain JS object we need a way to recognize which class it was, + * and the type is the way we do that. It has no other purposes and you should not give one. + * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type). + * To idenfity a class use instanceof class ( instanceof Rect ). + * We do not do that in fabricJS code because we want to try to have code splitting possible. + */ + + /** + * Legacy identifier of the class. Prefer using utils like isType or instanceOf + * Will be removed in fabric 7 or 8. + * The setter exists to avoid type errors in old code and possibly current deserialization code. + * @TODO add sustainable warning message + * @type string + * @deprecated + */ + get type() { + const name = this.constructor.type; + if (name === 'FabricObject') { + return 'object'; + } + return name.toLowerCase(); + } + set type(value) { + log('warn', 'Setting type has no effect', value); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + /** + * Quick access for the _cacheCanvas rendering context + * This is part of the objectCaching feature + * since 1.7.0 + * @type boolean + * @default undefined + * @private + */ + _defineProperty(this, "_cacheContext", null); + Object.assign(this, FabricObject.ownDefaults); + this.setOptions(options); + } + + /** + * Create a the canvas used to keep the cached copy of the object + * @private + */ + _createCacheCanvas() { + this._cacheCanvas = createCanvasElement(); + this._cacheContext = this._cacheCanvas.getContext('2d'); + this._updateCacheCanvas(); + // if canvas gets created, is empty, so dirty. + this.dirty = true; + } + + /** + * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal + * and each side do not cross fabric.cacheSideLimit + * those numbers are configurable so that you can get as much detail as you want + * making bargain with performances. + * @param {Object} dims + * @param {Object} dims.width width of canvas + * @param {Object} dims.height height of canvas + * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _limitCacheSize(dims) { + const width = dims.width, + height = dims.height, + max = config.maxCacheSideLimit, + min = config.minCacheSideLimit; + if (width <= max && height <= max && width * height <= config.perfLimitSizeTotal) { + if (width < min) { + dims.width = min; + } + if (height < min) { + dims.height = min; + } + return dims; + } + const ar = width / height, + [limX, limY] = cache.limitDimsByArea(ar), + x = capValue(min, limX, max), + y = capValue(min, limY, max); + if (width > x) { + dims.zoomX /= width / x; + dims.width = x; + dims.capped = true; + } + if (height > y) { + dims.zoomY /= height / y; + dims.height = y; + dims.capped = true; + } + return dims; + } + + /** + * Return the dimension and the zoom level needed to create a cache canvas + * big enough to host the object to be cached. + * @private + * @return {Object}.x width of object to be cached + * @return {Object}.y height of object to be cached + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _getCacheCanvasDimensions() { + const objectScale = this.getTotalObjectScaling(), + // calculate dimensions without skewing + dim = this._getTransformedDimensions({ + skewX: 0, + skewY: 0 + }), + neededX = dim.x * objectScale.x / this.scaleX, + neededY = dim.y * objectScale.y / this.scaleY; + return { + // for sure this ALIASING_LIMIT is slightly creating problem + // in situation in which the cache canvas gets an upper limit + // also objectScale contains already scaleX and scaleY + width: neededX + ALIASING_LIMIT, + height: neededY + ALIASING_LIMIT, + zoomX: objectScale.x, + zoomY: objectScale.y, + x: neededX, + y: neededY + }; + } + + /** + * Update width and height of the canvas for cache + * returns true or false if canvas needed resize. + * @private + * @return {Boolean} true if the canvas has been resized + */ + _updateCacheCanvas() { + const canvas = this._cacheCanvas, + context = this._cacheContext, + dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + minCacheSize = config.minCacheSideLimit, + width = dims.width, + height = dims.height, + zoomX = dims.zoomX, + zoomY = dims.zoomY, + dimensionsChanged = width !== canvas.width || height !== canvas.height, + zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY; + if (!canvas || !context) { + return false; + } + let drawingWidth, + drawingHeight, + shouldRedraw = dimensionsChanged || zoomChanged, + additionalWidth = 0, + additionalHeight = 0, + shouldResizeCanvas = false; + if (dimensionsChanged) { + const canvasWidth = this._cacheCanvas.width, + canvasHeight = this._cacheCanvas.height, + sizeGrowing = width > canvasWidth || height > canvasHeight, + sizeShrinking = (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) && canvasWidth > minCacheSize && canvasHeight > minCacheSize; + shouldResizeCanvas = sizeGrowing || sizeShrinking; + if (sizeGrowing && !dims.capped && (width > minCacheSize || height > minCacheSize)) { + additionalWidth = width * 0.1; + additionalHeight = height * 0.1; + } + } + if (isTextObject(this) && this.path) { + shouldRedraw = true; + shouldResizeCanvas = true; + // IMHO in those lines we are using zoomX and zoomY not the this version. + additionalWidth += this.getHeightOfLine(0) * this.zoomX; + additionalHeight += this.getHeightOfLine(0) * this.zoomY; + } + if (shouldRedraw) { + if (shouldResizeCanvas) { + canvas.width = Math.ceil(width + additionalWidth); + canvas.height = Math.ceil(height + additionalHeight); + } else { + context.setTransform(1, 0, 0, 1, 0, 0); + context.clearRect(0, 0, canvas.width, canvas.height); + } + drawingWidth = dims.x / 2; + drawingHeight = dims.y / 2; + this.cacheTranslationX = Math.round(canvas.width / 2 - drawingWidth) + drawingWidth; + this.cacheTranslationY = Math.round(canvas.height / 2 - drawingHeight) + drawingHeight; + context.translate(this.cacheTranslationX, this.cacheTranslationY); + context.scale(zoomX, zoomY); + this.zoomX = zoomX; + this.zoomY = zoomY; + return true; + } + return false; + } + + /** + * Sets object's properties from options, for class constructor only. + * Needs to be overridden for different defaults. + * @protected + * @param {Object} [options] Options object + */ + setOptions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this._setOptions(options); + } + + /** + * Transforms context when rendering an object + * @param {CanvasRenderingContext2D} ctx Context + */ + transform(ctx) { + const needFullTransform = this.group && !this.group._transformDone || this.group && this.canvas && ctx === this.canvas.contextTop; + const m = this.calcTransformMatrix(!needFullTransform); + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + + /** + * Return the object scale factor counting also the group scaling + * @return {Point} + */ + getObjectScaling() { + // if the object is a top level one, on the canvas, we go for simple aritmetic + // otherwise the complex method with angles will return approximations and decimals + // and will likely kill the cache when not needed + // https://github.com/fabricjs/fabric.js/issues/7157 + if (!this.group) { + return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY)); + } + // if we are inside a group total zoom calculation is complex, we defer to generic matrices + const options = qrDecompose(this.calcTransformMatrix()); + return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY)); + } + + /** + * Return the object scale factor counting also the group scaling, zoom and retina + * @return {Object} object with scaleX and scaleY properties + */ + getTotalObjectScaling() { + const scale = this.getObjectScaling(); + if (this.canvas) { + const zoom = this.canvas.getZoom(); + const retina = this.getCanvasRetinaScaling(); + return scale.scalarMultiply(zoom * retina); + } + return scale; + } + + /** + * Return the object opacity counting also the group property + * @return {Number} + */ + getObjectOpacity() { + let opacity = this.opacity; + if (this.group) { + opacity *= this.group.getObjectOpacity(); + } + return opacity; + } + + /** + * Makes sure the scale is valid and modifies it if necessary + * @todo: this is a control action issue, not a geometry one + * @private + * @param {Number} value, unconstrained + * @return {Number} constrained value; + */ + _constrainScale(value) { + if (Math.abs(value) < this.minScaleLimit) { + if (value < 0) { + return -this.minScaleLimit; + } else { + return this.minScaleLimit; + } + } else if (value === 0) { + return 0.0001; + } + return value; + } + + /** + * Handles setting values on the instance and handling internal side effects + * @protected + * @param {String} key + * @param {*} value + */ + _set(key, value) { + if (key === SCALE_X || key === SCALE_Y) { + value = this._constrainScale(value); + } + if (key === SCALE_X && value < 0) { + this.flipX = !this.flipX; + value *= -1; + } else if (key === 'scaleY' && value < 0) { + this.flipY = !this.flipY; + value *= -1; + // i don't like this automatic initialization here + } else if (key === 'shadow' && value && !(value instanceof Shadow)) { + value = new Shadow(value); + } + const isChanged = this[key] !== value; + this[key] = value; + + // invalidate caches + if (isChanged && this.constructor.cacheProperties.includes(key)) { + this.dirty = true; + } + // a dirty child makes the parent dirty. + // but a non dirty child does not make the parent not dirty. + // the parent could be dirty for some other reason. + this.parent && (this.dirty || isChanged && this.constructor.stateProperties.includes(key)) && this.parent._set('dirty', true); + return this; + } + + /* + * @private + * return if the object would be visible in rendering + * @memberOf FabricObject.prototype + * @return {Boolean} + */ + isNotVisible() { + return this.opacity === 0 || !this.width && !this.height && this.strokeWidth === 0 || !this.visible; + } + + /** + * Renders an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + // do not render if width/height are zeros or object is not visible + if (this.isNotVisible()) { + return; + } + if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { + return; + } + ctx.save(); + this._setupCompositeOperation(ctx); + this.drawSelectionBackground(ctx); + this.transform(ctx); + this._setOpacity(ctx); + this._setShadow(ctx); + if (this.shouldCache()) { + this.renderCache(); + this.drawCacheOnCanvas(ctx); + } else { + this._removeCacheCanvas(); + this.drawObject(ctx); + this.dirty = false; + } + ctx.restore(); + } + drawSelectionBackground(_ctx) { + /* no op */ + } + renderCache(options) { + options = options || {}; + if (!this._cacheCanvas || !this._cacheContext) { + this._createCacheCanvas(); + } + if (this.isCacheDirty() && this._cacheContext) { + this.drawObject(this._cacheContext, options.forClipping); + this.dirty = false; + } + } + + /** + * Remove cacheCanvas and its dimensions from the objects + */ + _removeCacheCanvas() { + this._cacheCanvas = undefined; + this._cacheContext = null; + } + + /** + * return true if the object will draw a stroke + * Does not consider text styles. This is just a shortcut used at rendering time + * We want it to be an approximation and be fast. + * wrote to avoid extra caching, it has to return true when stroke happens, + * can guess when it will not happen at 100% chance, does not matter if it misses + * some use case where the stroke is invisible. + * @since 3.0.0 + * @returns Boolean + */ + hasStroke() { + return this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0; + } + + /** + * return true if the object will draw a fill + * Does not consider text styles. This is just a shortcut used at rendering time + * We want it to be an approximation and be fast. + * wrote to avoid extra caching, it has to return true when fill happens, + * can guess when it will not happen at 100% chance, does not matter if it misses + * some use case where the fill is invisible. + * @since 3.0.0 + * @returns Boolean + */ + hasFill() { + return this.fill && this.fill !== 'transparent'; + } + + /** + * When set to `true`, force the object to have its own cache, even if it is inside a group + * it may be needed when your object behave in a particular way on the cache and always needs + * its own isolated canvas to render correctly. + * Created to be overridden + * since 1.7.12 + * @returns Boolean + */ + needsItsOwnCache() { + if (this.paintFirst === STROKE && this.hasFill() && this.hasStroke() && !!this.shadow) { + return true; + } + if (this.clipPath) { + return true; + } + return false; + } + + /** + * Decide if the object should cache or not. Create its own cache level + * objectCaching is a global flag, wins over everything + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * Read as: cache if is needed, or if the feature is enabled but we are not already caching. + * @return {Boolean} + */ + shouldCache() { + this.ownCaching = this.needsItsOwnCache() || this.objectCaching && (!this.parent || !this.parent.isOnACache()); + return this.ownCaching; + } + + /** + * Check if this object will cast a shadow with an offset. + * used by Group.shouldCache to know if child has a shadow recursively + * @return {Boolean} + * @deprecated + */ + willDrawShadow() { + return !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0); + } + + /** + * Execute the drawing operation for an object clipPath + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {FabricObject} clipPath + */ + drawClipPathOnCache(ctx, clipPath) { + ctx.save(); + // DEBUG: uncomment this line, comment the following + // ctx.globalAlpha = 0.4 + if (clipPath.inverted) { + ctx.globalCompositeOperation = 'destination-out'; + } else { + ctx.globalCompositeOperation = 'destination-in'; + } + //ctx.scale(1 / 2, 1 / 2); + if (clipPath.absolutePositioned) { + const m = invertTransform(this.calcTransformMatrix()); + ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]); + } + clipPath.transform(ctx); + ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY); + ctx.drawImage(clipPath._cacheCanvas, -clipPath.cacheTranslationX, -clipPath.cacheTranslationY); + ctx.restore(); + } + + /** + * Execute the drawing operation for an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {boolean} forClipping apply clipping styles + */ + drawObject(ctx, forClipping) { + const originalFill = this.fill, + originalStroke = this.stroke; + if (forClipping) { + this.fill = 'black'; + this.stroke = ''; + this._setClippingProperties(ctx); + } else { + this._renderBackground(ctx); + } + this._render(ctx); + this._drawClipPath(ctx, this.clipPath); + this.fill = originalFill; + this.stroke = originalStroke; + } + + /** + * Prepare clipPath state and cache and draw it on instance's cache + * @param {CanvasRenderingContext2D} ctx + * @param {FabricObject} clipPath + */ + _drawClipPath(ctx, clipPath) { + if (!clipPath) { + return; + } + // needed to setup a couple of variables + // path canvas gets overridden with this one. + // TODO find a better solution? + clipPath._set('canvas', this.canvas); + clipPath.shouldCache(); + clipPath._transformDone = true; + clipPath.renderCache({ + forClipping: true + }); + this.drawClipPathOnCache(ctx, clipPath); + } + + /** + * Paint the cached copy of the object on the target context. + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawCacheOnCanvas(ctx) { + ctx.scale(1 / this.zoomX, 1 / this.zoomY); + ctx.drawImage(this._cacheCanvas, -this.cacheTranslationX, -this.cacheTranslationY); + } + + /** + * Check if cache is dirty + * @param {Boolean} skipCanvas skip canvas checks because this object is painted + * on parent canvas. + */ + isCacheDirty() { + let skipCanvas = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + if (this.isNotVisible()) { + return false; + } + const canvas = this._cacheCanvas; + const ctx = this._cacheContext; + if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) { + // in this case the context is already cleared. + return true; + } else { + if (this.dirty || this.clipPath && this.clipPath.absolutePositioned) { + if (canvas && ctx && !skipCanvas) { + ctx.save(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.restore(); + } + return true; + } + } + return false; + } + + /** + * Draws a background for the object big as its untransformed dimensions + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderBackground(ctx) { + if (!this.backgroundColor) { + return; + } + const dim = this._getNonTransformedDimensions(); + ctx.fillStyle = this.backgroundColor; + ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y); + // if there is background color no other shadows + // should be casted + this._removeShadow(ctx); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setOpacity(ctx) { + if (this.group && !this.group._transformDone) { + ctx.globalAlpha = this.getObjectOpacity(); + } else { + ctx.globalAlpha *= this.opacity; + } + } + _setStrokeStyles(ctx, decl) { + const stroke = decl.stroke; + if (stroke) { + ctx.lineWidth = decl.strokeWidth; + ctx.lineCap = decl.strokeLineCap; + ctx.lineDashOffset = decl.strokeDashOffset; + ctx.lineJoin = decl.strokeLineJoin; + ctx.miterLimit = decl.strokeMiterLimit; + if (isFiller(stroke)) { + if (stroke.gradientUnits === 'percentage' || stroke.gradientTransform || stroke.patternTransform) { + // need to transform gradient in a pattern. + // this is a slow process. If you are hitting this codepath, and the object + // is not using caching, you should consider switching it on. + // we need a canvas as big as the current object caching canvas. + this._applyPatternForTransformedGradient(ctx, stroke); + } else { + // is a simple gradient or pattern + ctx.strokeStyle = stroke.toLive(ctx); + this._applyPatternGradientTransform(ctx, stroke); + } + } else { + // is a color + ctx.strokeStyle = decl.stroke; + } + } + } + _setFillStyles(ctx, _ref) { + let { + fill + } = _ref; + if (fill) { + if (isFiller(fill)) { + ctx.fillStyle = fill.toLive(ctx); + this._applyPatternGradientTransform(ctx, fill); + } else { + ctx.fillStyle = fill; + } + } + } + _setClippingProperties(ctx) { + ctx.globalAlpha = 1; + ctx.strokeStyle = 'transparent'; + ctx.fillStyle = '#000000'; + } + + /** + * @private + * Sets line dash + * @param {CanvasRenderingContext2D} ctx Context to set the dash line on + * @param {Array} dashArray array representing dashes + */ + _setLineDash(ctx, dashArray) { + if (!dashArray || dashArray.length === 0) { + return; + } + // Spec requires the concatenation of two copies of the dash array when the number of elements is odd + if (1 & dashArray.length) { + dashArray.push(...dashArray); + } + ctx.setLineDash(dashArray); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _setShadow(ctx) { + if (!this.shadow) { + return; + } + const shadow = this.shadow, + canvas = this.canvas, + retinaScaling = this.getCanvasRetinaScaling(), + [sx,,, sy] = (canvas === null || canvas === void 0 ? void 0 : canvas.viewportTransform) || iMatrix, + multX = sx * retinaScaling, + multY = sy * retinaScaling, + scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling(); + ctx.shadowColor = shadow.color; + ctx.shadowBlur = shadow.blur * config.browserShadowBlurConstant * (multX + multY) * (scaling.x + scaling.y) / 4; + ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x; + ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _removeShadow(ctx) { + if (!this.shadow) { + return; + } + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {TFiller} filler {@link Pattern} or {@link Gradient} + */ + _applyPatternGradientTransform(ctx, filler) { + if (!isFiller(filler)) { + return { + offsetX: 0, + offsetY: 0 + }; + } + const t = filler.gradientTransform || filler.patternTransform; + const offsetX = -this.width / 2 + filler.offsetX || 0, + offsetY = -this.height / 2 + filler.offsetY || 0; + if (filler.gradientUnits === 'percentage') { + ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY); + } else { + ctx.transform(1, 0, 0, 1, offsetX, offsetY); + } + if (t) { + ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]); + } + return { + offsetX: offsetX, + offsetY: offsetY + }; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderPaintInOrder(ctx) { + if (this.paintFirst === STROKE) { + this._renderStroke(ctx); + this._renderFill(ctx); + } else { + this._renderFill(ctx); + this._renderStroke(ctx); + } + } + + /** + * @private + * function that actually render something on the context. + * empty here to allow Obects to work on tests to benchmark fabric functionalites + * not related to rendering + * @param {CanvasRenderingContext2D} _ctx Context to render on + */ + _render(_ctx) { + // placeholder to be overridden + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderFill(ctx) { + if (!this.fill) { + return; + } + ctx.save(); + this._setFillStyles(ctx, this); + if (this.fillRule === 'evenodd') { + ctx.fill('evenodd'); + } else { + ctx.fill(); + } + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderStroke(ctx) { + if (!this.stroke || this.strokeWidth === 0) { + return; + } + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + ctx.save(); + if (this.strokeUniform) { + const scaling = this.getObjectScaling(); + ctx.scale(1 / scaling.x, 1 / scaling.y); + } + this._setLineDash(ctx, this.strokeDashArray); + this._setStrokeStyles(ctx, this); + ctx.stroke(); + ctx.restore(); + } + + /** + * This function try to patch the missing gradientTransform on canvas gradients. + * transforming a context to transform the gradient, is going to transform the stroke too. + * we want to transform the gradient but not the stroke operation, so we create + * a transformed gradient on a pattern and then we use the pattern instead of the gradient. + * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size + * is limited. + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Gradient} filler + */ + _applyPatternForTransformedGradient(ctx, filler) { + var _pCtx$createPattern; + const dims = this._limitCacheSize(this._getCacheCanvasDimensions()), + pCanvas = createCanvasElement(), + retinaScaling = this.getCanvasRetinaScaling(), + width = dims.x / this.scaleX / retinaScaling, + height = dims.y / this.scaleY / retinaScaling; + // in case width and height are less than 1px, we have to round up. + // since the pattern is no-repeat, this is fine + pCanvas.width = Math.ceil(width); + pCanvas.height = Math.ceil(height); + const pCtx = pCanvas.getContext('2d'); + if (!pCtx) { + return; + } + pCtx.beginPath(); + pCtx.moveTo(0, 0); + pCtx.lineTo(width, 0); + pCtx.lineTo(width, height); + pCtx.lineTo(0, height); + pCtx.closePath(); + pCtx.translate(width / 2, height / 2); + pCtx.scale(dims.zoomX / this.scaleX / retinaScaling, dims.zoomY / this.scaleY / retinaScaling); + this._applyPatternGradientTransform(pCtx, filler); + pCtx.fillStyle = filler.toLive(ctx); + pCtx.fill(); + ctx.translate(-this.width / 2 - this.strokeWidth / 2, -this.height / 2 - this.strokeWidth / 2); + ctx.scale(retinaScaling * this.scaleX / dims.zoomX, retinaScaling * this.scaleY / dims.zoomY); + ctx.strokeStyle = (_pCtx$createPattern = pCtx.createPattern(pCanvas, 'no-repeat')) !== null && _pCtx$createPattern !== void 0 ? _pCtx$createPattern : ''; + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + return new Point(this.left + this.width / 2, this.top + this.height / 2); + } + + /** + * Clones an instance. + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @returns {Promise} + */ + clone(propertiesToInclude) { + const objectForm = this.toObject(propertiesToInclude); + return this.constructor.fromObject(objectForm); + } + + /** + * Creates an instance of Image out of an object + * makes use of toCanvasElement. + * Once this method was based on toDataUrl and loadImage, so it also had a quality + * and format option. toCanvasElement is faster and produce no loss of quality. + * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it. + * toCanvasElement and then toBlob from the obtained canvas is also a good option. + * @todo fix the export type, it could not be Image but the type that getClass return for 'image'. + * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @return {FabricImage} Object cloned as image. + */ + cloneAsImage(options) { + const canvasEl = this.toCanvasElement(options); + // TODO: how to import Image w/o an import cycle? + const ImageClass = classRegistry.getClass('image'); + return new ImageClass(canvasEl); + } + + /** + * Converts an object into a HTMLCanvas element + * @param {ObjectToCanvasElementOptions} options Options object + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform + * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas + * @return {HTMLCanvasElement} Returns DOM element with the FabricObject + */ + toCanvasElement() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const origParams = saveObjectTransform(this), + originalGroup = this.group, + originalShadow = this.shadow, + abs = Math.abs, + retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1, + multiplier = (options.multiplier || 1) * retinaScaling, + canvasProvider = options.canvasProvider || (el => new StaticCanvas$1(el, { + enableRetinaScaling: false, + renderOnAddRemove: false, + skipOffscreen: false + })); + delete this.group; + if (options.withoutTransform) { + resetObjectTransform(this); + } + if (options.withoutShadow) { + this.shadow = null; + } + if (options.viewportTransform) { + sendObjectToPlane(this, this.getViewportTransform()); + } + this.setCoords(); + const el = createCanvasElement(), + boundingRect = this.getBoundingRect(), + shadow = this.shadow, + shadowOffset = new Point(); + if (shadow) { + const shadowBlur = shadow.blur; + const scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling(); + // consider non scaling shadow. + shadowOffset.x = 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x); + shadowOffset.y = 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y); + } + const width = boundingRect.width + shadowOffset.x, + height = boundingRect.height + shadowOffset.y; + // if the current width/height is not an integer + // we need to make it so. + el.width = Math.ceil(width); + el.height = Math.ceil(height); + const canvas = canvasProvider(el); + if (options.format === 'jpeg') { + canvas.backgroundColor = '#fff'; + } + this.setPositionByOrigin(new Point(canvas.width / 2, canvas.height / 2), CENTER, CENTER); + const originalCanvas = this.canvas; + // static canvas and canvas have both an array of InteractiveObjects + // @ts-expect-error this needs to be fixed somehow, or ignored globally + canvas._objects = [this]; + this.set('canvas', canvas); + this.setCoords(); + const canvasEl = canvas.toCanvasElement(multiplier || 1, options); + this.set('canvas', originalCanvas); + this.shadow = originalShadow; + if (originalGroup) { + this.group = originalGroup; + } + this.set(origParams); + this.setCoords(); + // canvas.dispose will call image.dispose that will nullify the elements + // since this canvas is a simple element for the process, we remove references + // to objects in this way in order to avoid object trashing. + canvas._objects = []; + // since render has settled it is safe to destroy canvas + canvas.destroy(); + return canvasEl; + } + + /** + * Converts an object into a data-url-like string + * @param {Object} options Options object + * @param {String} [options.format=png] The format of the output image. Either "jpeg" or "png" + * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg. + * @param {Number} [options.multiplier=1] Multiplier to scale by + * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14 + * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14 + * @param {Number} [options.width] Cropping width. Introduced in v1.2.14 + * @param {Number} [options.height] Cropping height. Introduced in v1.2.14 + * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4 + * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 + * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2 + * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format + */ + toDataURL() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + return toDataURL(this.toCanvasElement(options), options.format || 'png', options.quality || 1); + } + + /** + * Returns true if any of the specified types is identical to the type of an instance + * @param {String} type Type to check against + * @return {Boolean} + */ + isType() { + for (var _len = arguments.length, types = new Array(_len), _key = 0; _key < _len; _key++) { + types[_key] = arguments[_key]; + } + return types.includes(this.constructor.type) || types.includes(this.type); + } + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance (is 1 unless subclassed) + */ + complexity() { + return 1; + } + + /** + * Returns a JSON representation of an instance + * @return {Object} JSON + */ + toJSON() { + // delegate, not alias + return this.toObject(); + } + + /** + * Sets "angle" of an instance with centered rotation + * @param {TDegree} angle Angle value (in degrees) + */ + rotate(angle) { + const { + centeredRotation, + originX, + originY + } = this; + if (centeredRotation) { + const { + x, + y + } = this.getRelativeCenterPoint(); + this.originX = CENTER; + this.originY = CENTER; + this.left = x; + this.top = y; + } + this.set('angle', angle); + if (centeredRotation) { + const { + x, + y + } = this.translateToOriginPoint(this.getRelativeCenterPoint(), originX, originY); + this.left = x; + this.top = y; + this.originX = originX; + this.originY = originY; + } + } + + /** + * This callback function is called by the parent group of an object every + * time a non-delegated property changes on the group. It is passed the key + * and value as parameters. Not adding in this function's signature to avoid + * Travis build error about unused variables. + */ + setOnGroup() { + // implemented by sub-classes, as needed. + } + + /** + * Sets canvas globalCompositeOperation for specific object + * custom composition operation for the particular object can be specified using globalCompositeOperation property + * @param {CanvasRenderingContext2D} ctx Rendering canvas context + */ + _setupCompositeOperation(ctx) { + if (this.globalCompositeOperation) { + ctx.globalCompositeOperation = this.globalCompositeOperation; + } + } + + /** + * cancel instance's running animations + * override if necessary to dispose artifacts such as `clipPath` + */ + dispose() { + runningAnimations.cancelByTarget(this); + this.off(); + this._set('canvas', undefined); + // clear caches + this._cacheCanvas && getEnv$1().dispose(this._cacheCanvas); + this._cacheCanvas = undefined; + this._cacheContext = null; + } + + // #region Animation methods + /** + * List of properties to consider for animating colors. + * @type String[] + */ + + /** + * Animates object's properties + * @param {Record} animatable map of keys and end values + * @param {Partial>} options + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation} + * @return {Record>} map of animation contexts + * + * As object — multiple properties + * + * object.animate({ left: ..., top: ... }); + * object.animate({ left: ..., top: ... }, { duration: ... }); + */ + animate(animatable, options) { + return Object.entries(animatable).reduce((acc, _ref2) => { + let [key, endValue] = _ref2; + acc[key] = this._animate(key, endValue, options); + return acc; + }, {}); + } + + /** + * @private + * @param {String} key Property to animate + * @param {String} to Value to animate to + * @param {Object} [options] Options object + */ + _animate(key, endValue) { + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const path = key.split('.'); + const propIsColor = this.constructor.colorProperties.includes(path[path.length - 1]); + const { + abort, + startValue, + onChange, + onComplete + } = options; + const animationOptions = _objectSpread2(_objectSpread2({}, options), {}, { + target: this, + // path.reduce... is the current value in case start value isn't provided + startValue: startValue !== null && startValue !== void 0 ? startValue : path.reduce((deep, key) => deep[key], this), + endValue, + abort: abort === null || abort === void 0 ? void 0 : abort.bind(this), + onChange: (value, valueProgress, durationProgress) => { + path.reduce((deep, key, index) => { + if (index === path.length - 1) { + deep[key] = value; + } + return deep[key]; + }, this); + onChange && + // @ts-expect-error generic callback arg0 is wrong + onChange(value, valueProgress, durationProgress); + }, + onComplete: (value, valueProgress, durationProgress) => { + this.setCoords(); + onComplete && + // @ts-expect-error generic callback arg0 is wrong + onComplete(value, valueProgress, durationProgress); + } + }); + return propIsColor ? animateColor(animationOptions) : animate(animationOptions); + } + + // #region Object stacking methods + + /** + * A reference to the parent of the object + * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref + */ + + /** + * Checks if object is descendant of target + * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons + * @param {TAncestor} target + * @returns {boolean} + */ + isDescendantOf(target) { + const { + parent, + group + } = this; + return parent === target || group === target || + // walk up + !!parent && parent.isDescendantOf(target) || !!group && group !== parent && group.isDescendantOf(target); + } + + /** + * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top + */ + getAncestors() { + const ancestors = []; + // eslint-disable-next-line @typescript-eslint/no-this-alias + let parent = this; + do { + parent = parent.parent; + parent && ancestors.push(parent); + } while (parent); + return ancestors; + } + + /** + * Compare ancestors + * + * @param {StackedObject} other + * @returns {AncestryComparison} an object that represent the ancestry situation. + */ + findCommonAncestors(other) { + if (this === other) { + return { + fork: [], + otherFork: [], + common: [this, ...this.getAncestors()] + }; + } + const ancestors = this.getAncestors(); + const otherAncestors = other.getAncestors(); + // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case + if (ancestors.length === 0 && otherAncestors.length > 0 && this === otherAncestors[otherAncestors.length - 1]) { + return { + fork: [], + otherFork: [other, ...otherAncestors.slice(0, otherAncestors.length - 1)], + common: [this] + }; + } + // compare ancestors + for (let i = 0, ancestor; i < ancestors.length; i++) { + ancestor = ancestors[i]; + if (ancestor === other) { + return { + fork: [this, ...ancestors.slice(0, i)], + otherFork: [], + common: ancestors.slice(i) + }; + } + for (let j = 0; j < otherAncestors.length; j++) { + if (this === otherAncestors[j]) { + return { + fork: [], + otherFork: [other, ...otherAncestors.slice(0, j)], + common: [this, ...ancestors] + }; + } + if (ancestor === otherAncestors[j]) { + return { + fork: [this, ...ancestors.slice(0, i)], + otherFork: [other, ...otherAncestors.slice(0, j)], + common: ancestors.slice(i) + }; + } + } + } + // nothing shared + return { + fork: [this, ...ancestors], + otherFork: [other, ...otherAncestors], + common: [] + }; + } + + /** + * + * @param {StackedObject} other + * @returns {boolean} + */ + hasCommonAncestors(other) { + const commonAncestors = this.findCommonAncestors(other); + return commonAncestors && !!commonAncestors.common.length; + } + + /** + * + * @param {FabricObject} other object to compare against + * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined` + */ + isInFrontOf(other) { + if (this === other) { + return undefined; + } + const ancestorData = this.findCommonAncestors(other); + if (ancestorData.fork.includes(other)) { + return true; + } + if (ancestorData.otherFork.includes(this)) { + return false; + } + // if there isn't a common ancestor, we take the canvas. + // if there is no canvas, there is nothing to compare + const firstCommonAncestor = ancestorData.common[0] || this.canvas; + if (!firstCommonAncestor) { + return undefined; + } + const headOfFork = ancestorData.fork.pop(), + headOfOtherFork = ancestorData.otherFork.pop(), + thisIndex = firstCommonAncestor._objects.indexOf(headOfFork), + otherIndex = firstCommonAncestor._objects.indexOf(headOfOtherFork); + return thisIndex > -1 && thisIndex > otherIndex; + } + + // #region Serialization + /** + * Define a list of custom properties that will be serialized when + * instance.toObject() gets called + */ + + /** + * Returns an object representation of an instance + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const propertiesToSerialize = propertiesToInclude.concat(FabricObject.customProperties, this.constructor.customProperties || []); + let clipPathData; + const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS; + const { + clipPath, + fill, + stroke, + shadow, + strokeDashArray, + left, + top, + originX, + originY, + width, + height, + strokeWidth, + strokeLineCap, + strokeDashOffset, + strokeLineJoin, + strokeUniform, + strokeMiterLimit, + scaleX, + scaleY, + angle, + flipX, + flipY, + opacity, + visible, + backgroundColor, + fillRule, + paintFirst, + globalCompositeOperation, + skewX, + skewY + } = this; + if (clipPath && !clipPath.excludeFromExport) { + clipPathData = clipPath.toObject(propertiesToSerialize.concat('inverted', 'absolutePositioned')); + } + const toFixedBound = val => toFixed(val, NUM_FRACTION_DIGITS); + const object = _objectSpread2(_objectSpread2({}, pick(this, propertiesToSerialize)), {}, { + type: this.constructor.type, + version: VERSION, + originX, + originY, + left: toFixedBound(left), + top: toFixedBound(top), + width: toFixedBound(width), + height: toFixedBound(height), + fill: isSerializableFiller(fill) ? fill.toObject() : fill, + stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke, + strokeWidth: toFixedBound(strokeWidth), + strokeDashArray: strokeDashArray ? strokeDashArray.concat() : strokeDashArray, + strokeLineCap, + strokeDashOffset, + strokeLineJoin, + strokeUniform, + strokeMiterLimit: toFixedBound(strokeMiterLimit), + scaleX: toFixedBound(scaleX), + scaleY: toFixedBound(scaleY), + angle: toFixedBound(angle), + flipX, + flipY, + opacity: toFixedBound(opacity), + shadow: shadow ? shadow.toObject() : shadow, + visible, + backgroundColor, + fillRule, + paintFirst, + globalCompositeOperation, + skewX: toFixedBound(skewX), + skewY: toFixedBound(skewY) + }, clipPathData ? { + clipPath: clipPathData + } : null); + return !this.includeDefaultValues ? this._removeDefaultValues(object) : object; + } + + /** + * Returns (dataless) object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toDatalessObject(propertiesToInclude) { + // will be overwritten by subclasses + return this.toObject(propertiesToInclude); + } + + /** + * @private + * @param {Object} object + */ + _removeDefaultValues(object) { + // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance + // ownDefault vs prototype is swappable only if you change all the fabric objects consistently. + const defaults = this.constructor.getDefaults(); + const hasStaticDefaultValues = Object.keys(defaults).length > 0; + const baseValues = hasStaticDefaultValues ? defaults : Object.getPrototypeOf(this); + return pickBy(object, (value, key) => { + if (key === LEFT || key === TOP || key === 'type') { + return true; + } + const baseValue = baseValues[key]; + return value !== baseValue && + // basically a check for [] === [] + !(Array.isArray(value) && Array.isArray(baseValue) && value.length === 0 && baseValue.length === 0); + }); + } + + /** + * Returns a string representation of an instance + * @return {String} + */ + toString() { + return "#<".concat(this.constructor.type, ">"); + } + + /** + * + * @param {Function} klass + * @param {object} object + * @param {object} [options] + * @param {string} [options.extraParam] property to pass as first argument to the constructor + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static _fromObject(_ref3) { + let serializedObjectOptions = _objectWithoutProperties(_ref3, _excluded$e); + let _ref4 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + { + extraParam + } = _ref4, + options = _objectWithoutProperties(_ref4, _excluded2$4); + return enlivenObjectEnlivables(serializedObjectOptions, options).then(enlivedObjectOptions => { + // from the resulting enlived options, extract options.extraParam to arg0 + // to avoid accidental overrides later + if (extraParam) { + delete enlivedObjectOptions[extraParam]; + return new this(serializedObjectOptions[extraParam], + // @ts-expect-error different signature + enlivedObjectOptions); + } else { + return new this(enlivedObjectOptions); + } + }); + } + + /** + * + * @param {object} object + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(object, options) { + return this._fromObject(object, options); + } +}; +/** + * This list of properties is used to check if the state of an object is changed. + * This state change now is only used for children of groups to understand if a group + * needs its cache regenerated during a .set call + * @type Array + */ +_defineProperty(FabricObject$1, "stateProperties", stateProperties); +/** + * List of properties to consider when checking if cache needs refresh + * Those properties are checked by + * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty + * and refreshed at the next render + * @type Array + */ +_defineProperty(FabricObject$1, "cacheProperties", cacheProperties); +_defineProperty(FabricObject$1, "ownDefaults", fabricObjectDefaultValues); +_defineProperty(FabricObject$1, "type", 'FabricObject'); +_defineProperty(FabricObject$1, "colorProperties", [FILL, STROKE, 'backgroundColor']); +_defineProperty(FabricObject$1, "customProperties", []); +classRegistry.setClass(FabricObject$1); +classRegistry.setClass(FabricObject$1, 'object'); + +/** + * Wrap an action handler with firing an event if the action is performed + * @param {TModificationEvents} eventName the event we want to fire + * @param {TransformActionHandler} actionHandler the function to wrap + * @param {object} extraEventInfo extra information to pas to the event handler + * @return {TransformActionHandler} a function with an action handler signature + */ +const wrapWithFireEvent = (eventName, actionHandler, extraEventInfo) => { + return (eventData, transform, x, y) => { + const actionPerformed = actionHandler(eventData, transform, x, y); + if (actionPerformed) { + fireEvent(eventName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), extraEventInfo)); + } + return actionPerformed; + }; +}; + +/** + * Wrap an action handler with saving/restoring object position on the transform. + * this is the code that permits to objects to keep their position while transforming. + * @param {Function} actionHandler the function to wrap + * @return {Function} a function with an action handler signature + */ +function wrapWithFixedAnchor(actionHandler) { + return (eventData, transform, x, y) => { + const { + target, + originX, + originY + } = transform, + centerPoint = target.getRelativeCenterPoint(), + constraint = target.translateToOriginPoint(centerPoint, originX, originY), + actionPerformed = actionHandler(eventData, transform, x, y); + // flipping requires to change the transform origin, so we read from the mutated transform + // instead of leveraging the one destructured before + target.setPositionByOrigin(constraint, transform.originX, transform.originY); + return actionPerformed; + }; +} + +/** + * Action handler to change object's width + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const changeObjectWidth = (eventData, transform, x, y) => { + const localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); + // make sure the control changes width ONLY from it's side of target + if (resolveOrigin(transform.originX) === resolveOrigin(CENTER) || resolveOrigin(transform.originX) === resolveOrigin(RIGHT) && localPoint.x < 0 || resolveOrigin(transform.originX) === resolveOrigin(LEFT) && localPoint.x > 0) { + const { + target + } = transform, + strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1), + multiplier = isTransformCentered(transform) ? 2 : 1, + oldWidth = target.width, + newWidth = Math.ceil(Math.abs(localPoint.x * multiplier / target.scaleX) - strokePadding); + target.set('width', Math.max(newWidth, 0)); + // check against actual target width in case `newWidth` was rejected + return oldWidth !== target.width; + } + return false; +}; +const changeWidth = wrapWithFireEvent(RESIZING, wrapWithFixedAnchor(changeObjectWidth)); + +/** + * Render a round control, as per fabric features. + * This function is written to respect object properties like transparentCorners, cornerSize + * cornerColor, cornerStrokeColor + * plus the addition of offsetY and offsetX. + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Number} left x coordinate where the control center should be + * @param {Number} top y coordinate where the control center should be + * @param {Object} styleOverride override for FabricObject controls style + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + */ +function renderCircleControl(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + const xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, + ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, + transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners, + methodName = transparentCorners ? STROKE : FILL, + stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor); + let myLeft = left, + myTop = top, + size; + ctx.save(); + ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || ''; + ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || ''; + // TODO: use proper ellipse code. + if (xSize > ySize) { + size = xSize; + ctx.scale(1.0, ySize / xSize); + myTop = top * xSize / ySize; + } else if (ySize > xSize) { + size = ySize; + ctx.scale(xSize / ySize, 1.0); + myLeft = left * ySize / xSize; + } else { + size = xSize; + } + // this is still wrong + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false); + ctx[methodName](); + if (stroke) { + ctx.stroke(); + } + ctx.restore(); +} + +/** + * Render a square control, as per fabric features. + * This function is written to respect object properties like transparentCorners, cornerSize + * cornerColor, cornerStrokeColor + * plus the addition of offsetY and offsetX. + * @param {CanvasRenderingContext2D} ctx context to render on + * @param {Number} left x coordinate where the control center should be + * @param {Number} top y coordinate where the control center should be + * @param {Object} styleOverride override for FabricObject controls style + * @param {FabricObject} fabricObject the fabric object for which we are rendering controls + */ +function renderSquareControl(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + const xSize = this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize, + ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize, + transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ? styleOverride.transparentCorners : fabricObject.transparentCorners, + methodName = transparentCorners ? STROKE : FILL, + stroke = !transparentCorners && (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor), + xSizeBy2 = xSize / 2, + ySizeBy2 = ySize / 2; + ctx.save(); + ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || ''; + ctx.strokeStyle = styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || ''; + // this is still wrong + ctx.lineWidth = 1; + ctx.translate(left, top); + // angle is relative to canvas plane + const angle = fabricObject.getTotalAngle(); + ctx.rotate(degreesToRadians(angle)); + // this does not work, and fixed with ( && ) does not make sense. + // to have real transparent corners we need the controls on upperCanvas + // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize); + ctx["".concat(methodName, "Rect")](-xSizeBy2, -ySizeBy2, xSize, ySize); + if (stroke) { + ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize); + } + ctx.restore(); +} + +class Control { + constructor(options) { + /** + * keep track of control visibility. + * mainly for backward compatibility. + * if you do not want to see a control, you can remove it + * from the control set. + * @type {Boolean} + * @default true + */ + _defineProperty(this, "visible", true); + /** + * Name of the action that the control will likely execute. + * This is optional. FabricJS uses to identify what the user is doing for some + * extra optimizations. If you are writing a custom control and you want to know + * somewhere else in the code what is going on, you can use this string here. + * you can also provide a custom getActionName if your control run multiple actions + * depending on some external state. + * default to scale since is the most common, used on 4 corners by default + * @type {String} + * @default 'scale' + */ + _defineProperty(this, "actionName", SCALE); + /** + * Drawing angle of the control. + * NOT used for now, but name marked as needed for internal logic + * example: to reuse the same drawing function for different rotated controls + * @type {Number} + * @default 0 + */ + _defineProperty(this, "angle", 0); + /** + * Relative position of the control. X + * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "x", 0); + /** + * Relative position of the control. Y + * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "y", 0); + /** + * Horizontal offset of the control from the defined position. In pixels + * Positive offset moves the control to the right, negative to the left. + * It used when you want to have position of control that does not scale with + * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on + * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will + * stay 30 pixels no matter how the object is big. Another example is having 2 + * controls in the corner, that stay in the same position when the object scale. + * of the bounding box. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "offsetX", 0); + /** + * Vertical offset of the control from the defined position. In pixels + * Positive offset moves the control to the bottom, negative to the top. + * @type {Number} + * @default 0 + */ + _defineProperty(this, "offsetY", 0); + /** + * Sets the length of the control. If null, defaults to object's cornerSize. + * Expects both sizeX and sizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "sizeX", 0); + /** + * Sets the height of the control. If null, defaults to object's cornerSize. + * Expects both sizeX and sizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "sizeY", 0); + /** + * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize. + * Expects both touchSizeX and touchSizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "touchSizeX", 0); + /** + * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize. + * Expects both touchSizeX and touchSizeY to be set when set. + * @type {?Number} + * @default null + */ + _defineProperty(this, "touchSizeY", 0); + /** + * Css cursor style to display when the control is hovered. + * if the method `cursorStyleHandler` is provided, this property is ignored. + * @type {String} + * @default 'crosshair' + */ + _defineProperty(this, "cursorStyle", 'crosshair'); + /** + * If controls has an offsetY or offsetX, draw a line that connects + * the control to the bounding box + * @type {Boolean} + * @default false + */ + _defineProperty(this, "withConnection", false); + Object.assign(this, options); + } + + /** + * The control actionHandler, provide one to handle action ( control being moved ) + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + /** + * The control handler for mouse down, provide one to handle mouse down on control + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + /** + * The control mouseUpHandler, provide one to handle an effect on mouse up. + * @param {Event} eventData the native mouse event + * @param {Transform} transformData properties of the current transform + * @param {Number} x x position of the cursor + * @param {Number} y y position of the cursor + * @return {Boolean} true if the action/event modified the object + */ + + shouldActivate(controlKey, fabricObject, pointer, _ref) { + var _fabricObject$canvas; + let { + tl, + tr, + br, + bl + } = _ref; + // TODO: locking logic can be handled here instead of in the control handler logic + return ((_fabricObject$canvas = fabricObject.canvas) === null || _fabricObject$canvas === void 0 ? void 0 : _fabricObject$canvas.getActiveObject()) === fabricObject && fabricObject.isControlVisible(controlKey) && Intersection.isPointInPolygon(pointer, [tl, tr, br, bl]); + } + + /** + * Returns control actionHandler + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getActionHandler(eventData, fabricObject, control) { + return this.actionHandler; + } + + /** + * Returns control mouseDown handler + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getMouseDownHandler(eventData, fabricObject, control) { + return this.mouseDownHandler; + } + + /** + * Returns control mouseUp handler. + * During actions the fabricObject or the control can be of different obj + * @param {Event} eventData the native mouse event + * @param {FabricObject} fabricObject on which the control is displayed + * @param {Control} control control for which the action handler is being asked + * @return {Function} the action handler + */ + getMouseUpHandler(eventData, fabricObject, control) { + return this.mouseUpHandler; + } + + /** + * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate + * function you can pass one in the constructor + * the cursorStyle property + * @param {Event} eventData the native mouse event + * @param {Control} control the current control ( likely this) + * @param {FabricObject} object on which the control is displayed + * @return {String} + */ + cursorStyleHandler(eventData, control, fabricObject) { + return control.cursorStyle; + } + + /** + * Returns the action name. The basic implementation just return the actionName property. + * @param {Event} eventData the native mouse event + * @param {Control} control the current control ( likely this) + * @param {FabricObject} object on which the control is displayed + * @return {String} + */ + getActionName(eventData, control, fabricObject) { + return control.actionName; + } + + /** + * Returns controls visibility + * @param {FabricObject} object on which the control is displayed + * @param {String} controlKey key where the control is memorized on the + * @return {Boolean} + */ + getVisibility(fabricObject, controlKey) { + var _fabricObject$_contro, _fabricObject$_contro2; + return (_fabricObject$_contro = (_fabricObject$_contro2 = fabricObject._controlsVisibility) === null || _fabricObject$_contro2 === void 0 ? void 0 : _fabricObject$_contro2[controlKey]) !== null && _fabricObject$_contro !== void 0 ? _fabricObject$_contro : this.visible; + } + + /** + * Sets controls visibility + * @param {Boolean} visibility for the object + * @return {Void} + */ + setVisibility(visibility, name, fabricObject) { + this.visible = visibility; + } + positionHandler(dim, finalMatrix, fabricObject, currentControl) { + return new Point(this.x * dim.x + this.offsetX, this.y * dim.y + this.offsetY).transform(finalMatrix); + } + + /** + * Returns the coords for this control based on object values. + * @param {Number} objectAngle angle from the fabric object holding the control + * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if + * isTouch is true) + * @param {Number} centerX x coordinate where the control center should be + * @param {Number} centerY y coordinate where the control center should be + * @param {boolean} isTouch true if touch corner, false if normal corner + */ + calcCornerCoords(angle, objectCornerSize, centerX, centerY, isTouch, fabricObject) { + const t = multiplyTransformMatrixArray([createTranslateMatrix(centerX, centerY), createRotateMatrix({ + angle + }), createScaleMatrix((isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize, (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize)]); + return { + tl: new Point(-0.5, -0.5).transform(t), + tr: new Point(0.5, -0.5).transform(t), + br: new Point(0.5, 0.5).transform(t), + bl: new Point(-0.5, 0.5).transform(t) + }; + } + + /** + * Render function for the control. + * When this function runs the context is unscaled. unrotate. Just retina scaled. + * all the functions will have to translate to the point left,top before starting Drawing + * if they want to draw a control where the position is detected. + * left and top are the result of the positionHandler function + * @param {RenderingContext2D} ctx the context where the control will be drawn + * @param {Number} left position of the canvas where we are about to render the control. + * @param {Number} top position of the canvas where we are about to render the control. + * @param {Object} styleOverride + * @param {FabricObject} fabricObject the object where the control is about to be rendered + */ + render(ctx, left, top, styleOverride, fabricObject) { + styleOverride = styleOverride || {}; + switch (styleOverride.cornerStyle || fabricObject.cornerStyle) { + case 'circle': + renderCircleControl.call(this, ctx, left, top, styleOverride, fabricObject); + break; + default: + renderSquareControl.call(this, ctx, left, top, styleOverride, fabricObject); + } + } +} + +/** + * Find the correct style for the control that is used for rotation. + * this function is very simple and it just take care of not-allowed or standard cursor + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const rotationStyleHandler = (eventData, control, fabricObject) => { + if (fabricObject.lockRotation) { + return NOT_ALLOWED_CURSOR; + } + return control.cursorStyle; +}; + +/** + * Action handler for rotation and snapping, without anchor point. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + * @private + */ +const rotateObjectWithSnapping = (eventData, _ref, x, y) => { + let { + target, + ex, + ey, + theta, + originX, + originY + } = _ref; + const pivotPoint = target.translateToOriginPoint(target.getRelativeCenterPoint(), originX, originY); + if (isLocked(target, 'lockRotation')) { + return false; + } + const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x), + curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x); + let angle = radiansToDegrees(curAngle - lastAngle + theta); + if (target.snapAngle && target.snapAngle > 0) { + const snapAngle = target.snapAngle, + snapThreshold = target.snapThreshold || snapAngle, + rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle, + leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle; + if (Math.abs(angle - leftAngleLocked) < snapThreshold) { + angle = leftAngleLocked; + } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) { + angle = rightAngleLocked; + } + } + + // normalize angle to positive value + if (angle < 0) { + angle = 360 + angle; + } + angle %= 360; + const hasRotated = target.angle !== angle; + // TODO: why aren't we using set? + target.angle = angle; + return hasRotated; +}; +const rotationWithSnapping = wrapWithFireEvent(ROTATING, wrapWithFixedAnchor(rotateObjectWithSnapping)); + +/** + * Inspect event and fabricObject properties to understand if the scaling action + * @param {Event} eventData from the user action + * @param {FabricObject} fabricObject the fabric object about to scale + * @return {Boolean} true if scale is proportional + */ +function scaleIsProportional(eventData, fabricObject) { + const canvas = fabricObject.canvas, + uniformIsToggled = eventData[canvas.uniScaleKey]; + return canvas.uniformScaling && !uniformIsToggled || !canvas.uniformScaling && uniformIsToggled; +} + +/** + * Inspect fabricObject to understand if the current scaling action is allowed + * @param {FabricObject} fabricObject the fabric object about to scale + * @param {String} by 'x' or 'y' or '' + * @param {Boolean} scaleProportionally true if we are trying to scale proportionally + * @return {Boolean} true if scaling is not allowed at current conditions + */ +function scalingIsForbidden(fabricObject, by, scaleProportionally) { + const lockX = isLocked(fabricObject, 'lockScalingX'), + lockY = isLocked(fabricObject, 'lockScalingY'); + if (lockX && lockY) { + return true; + } + if (!by && (lockX || lockY) && scaleProportionally) { + return true; + } + if (lockX && by === 'x') { + return true; + } + if (lockY && by === 'y') { + return true; + } + // code crashes because of a division by 0 if a 0 sized object is scaled + // forbid to prevent scaling to happen. ISSUE-9475 + const { + width, + height, + strokeWidth + } = fabricObject; + if (width === 0 && strokeWidth === 0 && by !== 'y') { + return true; + } + if (height === 0 && strokeWidth === 0 && by !== 'x') { + return true; + } + return false; +} +const scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; + +/** + * return the correct cursor style for the scale action + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const scaleCursorStyleHandler = (eventData, control, fabricObject) => { + const scaleProportionally = scaleIsProportional(eventData, fabricObject), + by = control.x !== 0 && control.y === 0 ? 'x' : control.x === 0 && control.y !== 0 ? 'y' : ''; + if (scalingIsForbidden(fabricObject, by, scaleProportionally)) { + return NOT_ALLOWED_CURSOR; + } + const n = findCornerQuadrant(fabricObject, control); + return "".concat(scaleMap[n], "-resize"); +}; + +/** + * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @param {Object} options additional information for scaling + * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling + * @return {Boolean} true if some change happened + * @private + */ +function scaleObject(eventData, transform, x, y) { + let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + const target = transform.target, + by = options.by, + scaleProportionally = scaleIsProportional(eventData, target), + forbidScaling = scalingIsForbidden(target, by, scaleProportionally); + let newPoint, scaleX, scaleY, dim, signX, signY; + if (forbidScaling) { + return false; + } + if (transform.gestureScale) { + scaleX = transform.scaleX * transform.gestureScale; + scaleY = transform.scaleY * transform.gestureScale; + } else { + newPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y); + // use of sign: We use sign to detect change of direction of an action. sign usually change when + // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling + // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily + // cross many time the origin point and flip the object. so we need a way to filter out the noise. + // This ternary here should be ok to filter out X scaling when we want Y only and vice versa. + signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1; + signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1; + if (!transform.signX) { + transform.signX = signX; + } + if (!transform.signY) { + transform.signY = signY; + } + if (isLocked(target, 'lockScalingFlip') && (transform.signX !== signX || transform.signY !== signY)) { + return false; + } + dim = target._getTransformedDimensions(); + // missing detection of flip and logic to switch the origin + if (scaleProportionally && !by) { + // uniform scaling + const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y), + { + original + } = transform, + originalDistance = Math.abs(dim.x * original.scaleX / target.scaleX) + Math.abs(dim.y * original.scaleY / target.scaleY), + scale = distance / originalDistance; + scaleX = original.scaleX * scale; + scaleY = original.scaleY * scale; + } else { + scaleX = Math.abs(newPoint.x * target.scaleX / dim.x); + scaleY = Math.abs(newPoint.y * target.scaleY / dim.y); + } + // if we are scaling by center, we need to double the scale + if (isTransformCentered(transform)) { + scaleX *= 2; + scaleY *= 2; + } + if (transform.signX !== signX && by !== 'y') { + transform.originX = invertOrigin(transform.originX); + scaleX *= -1; + transform.signX = signX; + } + if (transform.signY !== signY && by !== 'x') { + transform.originY = invertOrigin(transform.originY); + scaleY *= -1; + transform.signY = signY; + } + } + // minScale is taken care of in the setter. + const oldScaleX = target.scaleX, + oldScaleY = target.scaleY; + if (!by) { + !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX); + !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY); + } else { + // forbidden cases already handled on top here. + by === 'x' && target.set(SCALE_X, scaleX); + by === 'y' && target.set(SCALE_Y, scaleY); + } + return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY; +} + +/** + * Generic scaling logic, to scale from corners either equally or freely. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectFromCorner = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y); +}; + +/** + * Scaling logic for the X axis. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectX = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y, { + by: 'x' + }); +}; + +/** + * Scaling logic for the Y axis. + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scaleObjectY = (eventData, transform, x, y) => { + return scaleObject(eventData, transform, x, y, { + by: 'y' + }); +}; +const scalingEqually = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectFromCorner)); +const scalingX = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectX)); +const scalingY = wrapWithFireEvent(SCALING, wrapWithFixedAnchor(scaleObjectY)); + +const _excluded$d = ["target", "ex", "ey", "skewingSide"]; +const AXIS_KEYS = { + x: { + counterAxis: 'y', + scale: SCALE_X, + skew: SKEW_X, + lockSkewing: 'lockSkewingX', + origin: 'originX', + flip: 'flipX' + }, + y: { + counterAxis: 'x', + scale: SCALE_Y, + skew: SKEW_Y, + lockSkewing: 'lockSkewingY', + origin: 'originY', + flip: 'flipY' + } +}; +const skewMap = ['ns', 'nesw', 'ew', 'nwse']; + +/** + * return the correct cursor style for the skew action + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const skewCursorStyleHandler = (eventData, control, fabricObject) => { + if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) { + return NOT_ALLOWED_CURSOR; + } + if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) { + return NOT_ALLOWED_CURSOR; + } + const n = findCornerQuadrant(fabricObject, control) % 4; + return "".concat(skewMap[n], "-resize"); +}; + +/** + * Since skewing is applied before scaling, calculations are done in a scaleless plane + * @see https://github.com/fabricjs/fabric.js/pull/8380 + */ +function skewObject(axis, _ref, pointer) { + let { + target, + ex, + ey, + skewingSide + } = _ref, + transform = _objectWithoutProperties(_ref, _excluded$d); + const { + skew: skewKey + } = AXIS_KEYS[axis], + offset = pointer.subtract(new Point(ex, ey)).divide(new Point(target.scaleX, target.scaleY))[axis], + skewingBefore = target[skewKey], + skewingStart = transform[skewKey], + shearingStart = Math.tan(degreesToRadians(skewingStart)), + // let a, b be the size of target + // let a' be the value of a after applying skewing + // then: + // a' = a + b * skewA => skewA = (a' - a) / b + // the value b is tricky since skewY is applied before skewX + b = axis === 'y' ? target._getTransformedDimensions({ + scaleX: 1, + scaleY: 1, + // since skewY is applied before skewX, b (=width) is not affected by skewX + skewX: 0 + }).x : target._getTransformedDimensions({ + scaleX: 1, + scaleY: 1 + }).y; + const shearing = 2 * offset * skewingSide / + // we max out fractions to safeguard from asymptotic behavior + Math.max(b, 1) + + // add starting state + shearingStart; + const skewing = radiansToDegrees(Math.atan(shearing)); + target.set(skewKey, skewing); + const changed = skewingBefore !== target[skewKey]; + if (changed && axis === 'y') { + // we don't want skewing to affect scaleX + // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer + const { + skewX, + scaleX + } = target, + dimBefore = target._getTransformedDimensions({ + skewY: skewingBefore + }), + dimAfter = target._getTransformedDimensions(), + compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1; + compensationFactor !== 1 && target.set(SCALE_X, compensationFactor * scaleX); + } + return changed; +} + +/** + * Wrapped Action handler for skewing on a given axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +function skewHandler(axis, eventData, transform, x, y) { + const { + target + } = transform, + { + counterAxis, + origin: originKey, + lockSkewing: lockSkewingKey, + skew: skewKey, + flip: flipKey + } = AXIS_KEYS[axis]; + if (isLocked(target, lockSkewingKey)) { + return false; + } + const { + origin: counterOriginKey, + flip: counterFlipKey + } = AXIS_KEYS[counterAxis], + counterOriginFactor = resolveOrigin(transform[counterOriginKey]) * (target[counterFlipKey] ? -1 : 1), + // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively. + // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively. + // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer, + // so we factor skewing direction by this value. + skewingSide = -Math.sign(counterOriginFactor) * (target[flipKey] ? -1 : 1), + skewingDirection = (target[skewKey] === 0 && + // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing + getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0 || + // in case target has skewing we use that as the direction + target[skewKey] > 0 ? 1 : -1) * skewingSide, + // anchor to the opposite side of the skewing direction + // normalize value from [-1, 1] to origin value [0, 1] + origin = -skewingDirection * 0.5 + 0.5; + const finalHandler = wrapWithFireEvent(SKEWING, wrapWithFixedAnchor((eventData, transform, x, y) => skewObject(axis, transform, new Point(x, y)))); + return finalHandler(eventData, _objectSpread2(_objectSpread2({}, transform), {}, { + [originKey]: origin, + skewingSide + }), x, y); +} + +/** + * Wrapped Action handler for skewing on the X axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const skewHandlerX = (eventData, transform, x, y) => { + return skewHandler('x', eventData, transform, x, y); +}; + +/** + * Wrapped Action handler for skewing on the Y axis, takes care of the + * skew direction and determines the correct transform origin for the anchor point + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const skewHandlerY = (eventData, transform, x, y) => { + return skewHandler('y', eventData, transform, x, y); +}; + +function isAltAction(eventData, target) { + return eventData[target.canvas.altActionKey]; +} + +/** + * Inspect event, control and fabricObject to return the correct action name + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} an action name + */ +const scaleOrSkewActionName = (eventData, control, fabricObject) => { + const isAlternative = isAltAction(eventData, fabricObject); + if (control.x === 0) { + // then is scaleY or skewX + return isAlternative ? SKEW_X : SCALE_Y; + } + if (control.y === 0) { + // then is scaleY or skewX + return isAlternative ? SKEW_Y : SCALE_X; + } + return ''; +}; + +/** + * Combine skew and scale style handlers to cover fabric standard use case + * @param {Event} eventData the javascript event that is causing the scale + * @param {Control} control the control that is interested in the action + * @param {FabricObject} fabricObject the fabric object that is interested in the action + * @return {String} a valid css string for the cursor + */ +const scaleSkewCursorStyleHandler = (eventData, control, fabricObject) => { + return isAltAction(eventData, fabricObject) ? skewCursorStyleHandler(eventData, control, fabricObject) : scaleCursorStyleHandler(eventData, control, fabricObject); +}; +/** + * Composed action handler to either scale X or skew Y + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scalingXOrSkewingY = (eventData, transform, x, y) => { + return isAltAction(eventData, transform.target) ? skewHandlerY(eventData, transform, x, y) : scalingX(eventData, transform, x, y); +}; + +/** + * Composed action handler to either scale Y or skew X + * Needs to be wrapped with `wrapWithFixedAnchor` to be effective + * @param {Event} eventData javascript event that is doing the transform + * @param {Object} transform javascript object containing a series of information around the current transform + * @param {number} x current mouse x position, canvas normalized + * @param {number} y current mouse y position, canvas normalized + * @return {Boolean} true if some change happened + */ +const scalingYOrSkewingX = (eventData, transform, x, y) => { + return isAltAction(eventData, transform.target) ? skewHandlerX(eventData, transform, x, y) : scalingY(eventData, transform, x, y); +}; + +// use this function if you want to generate new controls for every instance +const createObjectDefaultControls = () => ({ + ml: new Control({ + x: -0.5, + y: 0, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingXOrSkewingY, + getActionName: scaleOrSkewActionName + }), + mr: new Control({ + x: 0.5, + y: 0, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingXOrSkewingY, + getActionName: scaleOrSkewActionName + }), + mb: new Control({ + x: 0, + y: 0.5, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingYOrSkewingX, + getActionName: scaleOrSkewActionName + }), + mt: new Control({ + x: 0, + y: -0.5, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionHandler: scalingYOrSkewingX, + getActionName: scaleOrSkewActionName + }), + tl: new Control({ + x: -0.5, + y: -0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + tr: new Control({ + x: 0.5, + y: -0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + bl: new Control({ + x: -0.5, + y: 0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + br: new Control({ + x: 0.5, + y: 0.5, + cursorStyleHandler: scaleCursorStyleHandler, + actionHandler: scalingEqually + }), + mtr: new Control({ + x: 0, + y: -0.5, + actionHandler: rotationWithSnapping, + cursorStyleHandler: rotationStyleHandler, + offsetY: -40, + withConnection: true, + actionName: ROTATE + }) +}); +const createResizeControls = () => ({ + mr: new Control({ + x: 0.5, + y: 0, + actionHandler: changeWidth, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionName: RESIZING + }), + ml: new Control({ + x: -0.5, + y: 0, + actionHandler: changeWidth, + cursorStyleHandler: scaleSkewCursorStyleHandler, + actionName: RESIZING + }) +}); +const createTextboxDefaultControls = () => _objectSpread2(_objectSpread2({}, createObjectDefaultControls()), createResizeControls()); + +class InteractiveFabricObject extends FabricObject$1 { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), InteractiveFabricObject.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, this.constructor.createControls(), InteractiveFabricObject.ownDefaults); + this.setOptions(options); + } + + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults + * @param {Object} [options] Options object + */ + static createControls() { + return { + controls: createObjectDefaultControls() + }; + } + + /** + * Update width and height of the canvas for cache + * returns true or false if canvas needed resize. + * @private + * @return {Boolean} true if the canvas has been resized + */ + _updateCacheCanvas() { + const targetCanvas = this.canvas; + if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) { + const transform = targetCanvas._currentTransform, + target = transform.target, + action = transform.action; + if (this === target && action && action.startsWith(SCALE)) { + return false; + } + } + return super._updateCacheCanvas(); + } + getActiveControl() { + const key = this.__corner; + return key ? { + key, + control: this.controls[key], + coord: this.oCoords[key] + } : undefined; + } + + /** + * Determines which corner is under the mouse cursor, represented by `pointer`. + * This function is return a corner only if the object is the active one. + * This is done to avoid selecting corner of non active object and activating transformations + * rather than drag action. The default behavior of fabricJS is that if you want to transform + * an object, first you select it to show the control set + * @private + * @param {Object} pointer The pointer indicating the mouse position + * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action + * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found. + */ + findControl(pointer) { + let forTouch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + if (!this.hasControls || !this.canvas) { + return undefined; + } + this.__corner = undefined; + const cornerEntries = Object.entries(this.oCoords); + for (let i = cornerEntries.length - 1; i >= 0; i--) { + const [key, corner] = cornerEntries[i]; + const control = this.controls[key]; + if (control.shouldActivate(key, this, pointer, forTouch ? corner.touchCorner : corner.corner)) { + // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2); + this.__corner = key; + return { + key, + control, + coord: this.oCoords[key] + }; + } + } + return undefined; + } + + /** + * Calculates the coordinates of the center of each control plus the corners of the control itself + * This basically just delegates to each control positionHandler + * WARNING: changing what is passed to positionHandler is a breaking change, since position handler + * is a public api and should be done just if extremely necessary + * @return {Record} + */ + calcOCoords() { + const vpt = this.getViewportTransform(), + center = this.getCenterPoint(), + tMatrix = createTranslateMatrix(center.x, center.y), + rMatrix = createRotateMatrix({ + angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0) + }), + positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix), + startMatrix = multiplyTransformMatrices(vpt, positionMatrix), + finalMatrix = multiplyTransformMatrices(startMatrix, [1 / vpt[0], 0, 0, 1 / vpt[3], 0, 0]), + transformOptions = this.group ? qrDecompose(this.calcTransformMatrix()) : undefined; + // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it + if (transformOptions) { + transformOptions.scaleX = Math.abs(transformOptions.scaleX); + transformOptions.scaleY = Math.abs(transformOptions.scaleY); + } + const dim = this._calculateCurrentDimensions(transformOptions), + coords = {}; + this.forEachControl((control, key) => { + const position = control.positionHandler(dim, finalMatrix, this, control); + // coords[key] are sometimes used as points. Those are points to which we add + // the property corner and touchCorner from `_calcCornerCoords`. + // don't remove this assign for an object spread. + coords[key] = Object.assign(position, this._calcCornerCoords(control, position)); + }); + + // debug code + /* + const canvas = this.canvas; + setTimeout(function () { + if (!canvas) return; + canvas.contextTop.clearRect(0, 0, 700, 700); + canvas.contextTop.fillStyle = 'green'; + Object.keys(coords).forEach(function(key) { + const control = coords[key]; + canvas.contextTop.fillRect(control.x, control.y, 3, 3); + }); + } 50); + */ + return coords; + } + + /** + * Sets the coordinates that determine the interaction area of each control + * note: if we would switch to ROUND corner area, all of this would disappear. + * everything would resolve to a single point and a pythagorean theorem for the distance + * @todo evaluate simplification of code switching to circle interaction area at runtime + * @private + */ + _calcCornerCoords(control, position) { + const angle = this.getTotalAngle(); + const corner = control.calcCornerCoords(angle, this.cornerSize, position.x, position.y, false, this); + const touchCorner = control.calcCornerCoords(angle, this.touchCornerSize, position.x, position.y, true, this); + return { + corner, + touchCorner + }; + } + + /** + * @override set controls' coordinates as well + * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas} + * @return {void} + */ + setCoords() { + super.setCoords(); + this.canvas && (this.oCoords = this.calcOCoords()); + } + + /** + * Calls a function for each control. The function gets called, + * with the control, the control's key and the object that is calling the iterator + * @param {Function} fn function to iterate over the controls over + */ + forEachControl(fn) { + for (const i in this.controls) { + fn(this.controls[i], i, this); + } + } + + /** + * Draws a colored layer behind the object, inside its selection borders. + * Requires public options: padding, selectionBackgroundColor + * this function is called when the context is transformed + * has checks to be skipped when the object is on a staticCanvas + * @todo evaluate if make this disappear in favor of a pre-render hook for objects + * this was added by Andrea Bogazzi to make possible some feature for work reasons + * it seemed a good option, now is an edge case + * @param {CanvasRenderingContext2D} ctx Context to draw on + */ + drawSelectionBackground(ctx) { + if (!this.selectionBackgroundColor || this.canvas && this.canvas._activeObject !== this) { + return; + } + ctx.save(); + const center = this.getRelativeCenterPoint(), + wh = this._calculateCurrentDimensions(), + vpt = this.getViewportTransform(); + ctx.translate(center.x, center.y); + ctx.scale(1 / vpt[0], 1 / vpt[3]); + ctx.rotate(degreesToRadians(this.angle)); + ctx.fillStyle = this.selectionBackgroundColor; + ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y); + ctx.restore(); + } + + /** + * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style. + * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center + * @param {Point} size the control box size used + */ + strokeBorders(ctx, size) { + ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {Point} size + * @param {TStyleOverride} styleOverride object to override the object style + */ + _drawBorders(ctx, size) { + let styleOverride = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + const options = _objectSpread2({ + hasControls: this.hasControls, + borderColor: this.borderColor, + borderDashArray: this.borderDashArray + }, styleOverride); + ctx.save(); + ctx.strokeStyle = options.borderColor; + this._setLineDash(ctx, options.borderDashArray); + this.strokeBorders(ctx, size); + options.hasControls && this.drawControlsConnectingLines(ctx, size); + ctx.restore(); + } + + /** + * Renders controls and borders for the object + * the context here is not transformed + * @todo move to interactivity + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {TStyleOverride} [styleOverride] properties to override the object style + */ + _renderControls(ctx) { + let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const { + hasBorders, + hasControls + } = this; + const styleOptions = _objectSpread2({ + hasBorders, + hasControls + }, styleOverride); + const vpt = this.getViewportTransform(), + shouldDrawBorders = styleOptions.hasBorders, + shouldDrawControls = styleOptions.hasControls; + const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix()); + const options = qrDecompose(matrix); + ctx.save(); + ctx.translate(options.translateX, options.translateY); + ctx.lineWidth = 1 * this.borderScaleFactor; + // since interactive groups have been introduced, an object could be inside a group and needing controls + // the following equality check `this.group === this.parent` covers: + // object without a group ( undefined === undefined ) + // object inside a group + // excludes object inside a group but multi selected since group and parent will differ in value + if (this.group === this.parent) { + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + } + if (this.flipX) { + options.angle -= 180; + } + ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle)); + shouldDrawBorders && this.drawBorders(ctx, options, styleOverride); + shouldDrawControls && this.drawControls(ctx, styleOverride); + ctx.restore(); + } + + /** + * Draws borders of an object's bounding box. + * Requires public properties: width, height + * Requires public options: padding, borderColor + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {object} options object representing current object parameters + * @param {TStyleOverride} [styleOverride] object to override the object style + */ + drawBorders(ctx, options, styleOverride) { + let size; + if (styleOverride && styleOverride.forActiveSelection || this.group) { + const bbox = sizeAfterTransform(this.width, this.height, calcDimensionsMatrix(options)), + stroke = !this.isStrokeAccountedForInDimensions() ? (this.strokeUniform ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1) : + // this is extremely confusing. options comes from the upper function + // and is the qrDecompose of a matrix that takes in account zoom too + new Point(options.scaleX, options.scaleY)).scalarMultiply(this.strokeWidth) : ZERO; + size = bbox.add(stroke).scalarAdd(this.borderScaleFactor).scalarAdd(this.padding * 2); + } else { + size = this._calculateCurrentDimensions().scalarAdd(this.borderScaleFactor); + } + this._drawBorders(ctx, size, styleOverride); + } + + /** + * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set. + * Requires public properties: width, height + * Requires public options: padding, borderColor + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {Point} size object size x = width, y = height + */ + drawControlsConnectingLines(ctx, size) { + let shouldStroke = false; + ctx.beginPath(); + this.forEachControl((control, key) => { + // in this moment, the ctx is centered on the object. + // width and height of the above function are the size of the bbox. + if (control.withConnection && control.getVisibility(this, key)) { + // reset movement for each control + shouldStroke = true; + ctx.moveTo(control.x * size.x, control.y * size.y); + ctx.lineTo(control.x * size.x + control.offsetX, control.y * size.y + control.offsetY); + } + }); + shouldStroke && ctx.stroke(); + } + + /** + * Draws corners of an object's bounding box. + * Requires public properties: width, height + * Requires public options: cornerSize, padding + * Be aware that since fabric 6.0 this function does not call setCoords anymore. + * setCoords needs to be called manually if the object of which we are rendering controls + * is outside the standard selection and transform process. + * @param {CanvasRenderingContext2D} ctx Context to draw on + * @param {ControlRenderingStyleOverride} styleOverride object to override the object style + */ + drawControls(ctx) { + let styleOverride = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + ctx.save(); + const retinaScaling = this.getCanvasRetinaScaling(); + const { + cornerStrokeColor, + cornerDashArray, + cornerColor + } = this; + const options = _objectSpread2({ + cornerStrokeColor, + cornerDashArray, + cornerColor + }, styleOverride); + ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0); + ctx.strokeStyle = ctx.fillStyle = options.cornerColor; + if (!this.transparentCorners) { + ctx.strokeStyle = options.cornerStrokeColor; + } + this._setLineDash(ctx, options.cornerDashArray); + this.forEachControl((control, key) => { + if (control.getVisibility(this, key)) { + const p = this.oCoords[key]; + control.render(ctx, p.x, p.y, options, this); + } + }); + ctx.restore(); + } + + /** + * Returns true if the specified control is visible, false otherwise. + * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr', + * but since the control api allow for any control name, can be any string. + * @returns {boolean} true if the specified control is visible, false otherwise + */ + isControlVisible(controlKey) { + return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey); + } + + /** + * Sets the visibility of the specified control. + * please do not use. + * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'. + * but since the control api allow for any control name, can be any string. + * @param {Boolean} visible true to set the specified control visible, false otherwise + * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details + */ + setControlVisible(controlKey, visible) { + if (!this._controlsVisibility) { + this._controlsVisibility = {}; + } + this._controlsVisibility[controlKey] = visible; + } + + /** + * Sets the visibility state of object controls, this is just a bulk option for setControlVisible; + * @param {Record} [options] with an optional key per control + * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it + */ + setControlsVisibility() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + Object.entries(options).forEach(_ref => { + let [controlKey, visibility] = _ref; + return this.setControlVisible(controlKey, visibility); + }); + } + + /** + * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box + * that is in the canvas.contextContainer. + * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object. + * Example: blinking cursor text selection, drag effects. + * @todo discuss swapping restoreManually with a renderCallback, but think of async issues + * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else. + * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed + * with the object transformMatrix, or restored to neutral transform + */ + clearContextTop(restoreManually) { + if (!this.canvas) { + return; + } + const ctx = this.canvas.contextTop; + if (!ctx) { + return; + } + const v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + this.transform(ctx); + // we add 4 pixel, to be sure to do not leave any pixel out + const width = this.width + 4, + height = this.height + 4; + ctx.clearRect(-width / 2, -height / 2, width, height); + restoreManually || ctx.restore(); + return ctx; + } + + /** + * This callback function is called every time _discardActiveObject or _setActiveObject + * try to to deselect this object. If the function returns true, the process is cancelled + * @param {Object} [_options] options sent from the upper functions + * @param {TPointerEvent} [options.e] event if the process is generated by an event + * @param {FabricObject} [options.object] next object we are setting as active, and reason why + * this is being deselected + */ + onDeselect(_options) { + // implemented by sub-classes, as needed. + return false; + } + + /** + * This callback function is called every time _discardActiveObject or _setActiveObject + * try to to select this object. If the function returns true, the process is cancelled + * @param {Object} [_options] options sent from the upper functions + * @param {Event} [_options.e] event if the process is generated by an event + */ + onSelect(_options) { + // implemented by sub-classes, as needed. + return false; + } + + /** + * Override to customize Drag behavior + * Fired from {@link Canvas#_onMouseMove} + * @returns true in order for the window to start a drag session + */ + shouldStartDragging(_e) { + return false; + } + + /** + * Override to customize Drag behavior\ + * Fired once a drag session has started + * @returns true to handle the drag event + */ + onDragStart(_e) { + return false; + } + + /** + * Override to customize drag and drop behavior + * @public + * @param {DragEvent} _e + * @returns {boolean} true if the object currently dragged can be dropped on the target + */ + canDrop(_e) { + return false; + } + + /** + * Override to customize drag and drop behavior + * render a specific effect when an object is the source of a drag event + * example: render the selection status for the part of text that is being dragged from a text object + * @public + * @param {DragEvent} _e + */ + renderDragSourceEffect(_e) { + // for subclasses + } + + /** + * Override to customize drag and drop behavior + * render a specific effect when an object is the target of a drag event + * used to show that the underly object can receive a drop, or to show how the + * object will change when dropping. example: show the cursor where the text is about to be dropped + * @public + * @param {DragEvent} _e + */ + renderDropTargetEffect(_e) { + // for subclasses + } +} +/** + * The object's controls' position in viewport coordinates + * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}. + * `corner/touchCorner` describe the 4 points forming the interactive area of the corner. + * Used to draw and locate controls. + */ +/** + * keeps the value of the last hovered corner during mouse move. + * 0 is no corner, or 'mt', 'ml', 'mtr' etc.. + * It should be private, but there is no harm in using it as + * a read-only property. + * this isn't cleaned automatically. Non selected objects may have wrong values + * @type [string] + */ +/** + * a map of control visibility for this object. + * this was left when controls were introduced to not break the api too much + * this takes priority over the generic control visibility + */ +/** + * holds the controls for the object. + * controls are added by default_controls.js + */ +/** + * internal boolean to signal the code that the object is + * part of the move action. + */ +/** + * A boolean used from the gesture module to keep tracking of a scaling + * action when there is no scaling transform in place. + * This is an edge case and is used twice in all codebase. + * Probably added to keep track of some performance issues + * @TODO use git blame to investigate why it was added + * DON'T USE IT. WE WILL TRY TO REMOVE IT + */ +_defineProperty(InteractiveFabricObject, "ownDefaults", interactiveObjectDefaultValues); + +/*** + * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern + */ +function applyMixins(derivedCtor, constructors) { + constructors.forEach(baseCtor => { + Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { + name !== 'constructor' && Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name) || Object.create(null)); + }); + }); + return derivedCtor; +} + +// TODO somehow we have to make a tree-shakeable import + +// eslint-disable-next-line @typescript-eslint/no-empty-object-type + +// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging +class FabricObject extends InteractiveFabricObject {} +applyMixins(FabricObject, [FabricObjectSVGExportMixin]); +classRegistry.setClass(FabricObject); +classRegistry.setClass(FabricObject, 'object'); + +/** + * Returns true if context has transparent pixel + * at specified location (taking tolerance into account) + * @param {CanvasRenderingContext2D} ctx context + * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer + * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer + * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer + * @return {boolean} true if transparent + */ +const isTransparent = (ctx, x, y, tolerance) => { + tolerance = Math.round(tolerance); + const size = tolerance * 2 + 1; + const { + data + } = ctx.getImageData(x - tolerance, y - tolerance, size, size); + + // Split image data - for tolerance > 1, pixelDataSize = 4; + for (let i = 3; i < data.length; i += 4) { + const alphaChannel = data[i]; + if (alphaChannel > 0) { + return false; + } + } + return true; +}; + +/** + * Rotates `point` around `origin` with `radians` + * @deprecated use the Point.rotate + * @param {Point} origin The origin of the rotation + * @param {Point} origin The origin of the rotation + * @param {TRadian} radians The radians of the angle for the rotation + * @return {Point} The new rotated point + */ +const rotatePoint = (point, origin, radians) => point.rotate(radians, origin); + +const findIndexRight = (array, predicate) => { + for (let index = array.length - 1; index >= 0; index--) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +}; + +/** + * @see https://github.com/fabricjs/fabric.js/pull/8344 + * @todo consider removing skewing from points before calculating stroke projection, + * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537 + */ +class StrokeProjectionsBase { + constructor(options) { + this.options = options; + this.strokeProjectionMagnitude = this.options.strokeWidth / 2; + this.scale = new Point(this.options.scaleX, this.options.scaleY); + this.strokeUniformScalar = this.options.strokeUniform ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY) : new Point(1, 1); + } + + /** + * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account. + */ + createSideVector(from, to) { + const v = createVector(from, to); + return this.options.strokeUniform ? v.multiply(this.scale) : v; + } + projectOrthogonally(from, to, magnitude) { + return this.applySkew(from.add(this.calcOrthogonalProjection(from, to, magnitude))); + } + isSkewed() { + return this.options.skewX !== 0 || this.options.skewY !== 0; + } + applySkew(point) { + const p = new Point(point); + // skewY must be applied before skewX as this distortion affects skewX calculation + p.y += p.x * Math.tan(degreesToRadians(this.options.skewY)); + p.x += p.y * Math.tan(degreesToRadians(this.options.skewX)); + return p; + } + scaleUnitVector(unitVector, scalar) { + return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar); + } +} + +const zeroVector = new Point(); + +/** + * class in charge of finding projections for each type of line join + * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)} + * + * - MDN: + * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin + * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin + * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty + * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html + * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js + * + */ +class StrokeLineJoinProjections extends StrokeProjectionsBase { + static getOrthogonalRotationFactor(vector1, vector2) { + const angle = vector2 ? calcAngleBetweenVectors(vector1, vector2) : calcVectorRotation(vector1); + return Math.abs(angle) < halfPI ? -1 : 1; + } + constructor(A, B, C, options) { + super(options); + /** + * The point being projected (the angle ∠BAC) + */ + /** + * The point before A + */ + /** + * The point after A + */ + /** + * The AB vector + */ + _defineProperty(this, "AB", void 0); + /** + * The AC vector + */ + _defineProperty(this, "AC", void 0); + /** + * The angle of A (∠BAC) + */ + _defineProperty(this, "alpha", void 0); + /** + * The bisector of A (∠BAC) + */ + _defineProperty(this, "bisector", void 0); + this.A = new Point(A); + this.B = new Point(B); + this.C = new Point(C); + this.AB = this.createSideVector(this.A, this.B); + this.AC = this.createSideVector(this.A, this.C); + this.alpha = calcAngleBetweenVectors(this.AB, this.AC); + this.bisector = getUnitVector( + // if AC is also the zero vector nothing will be projected + // in that case the next point will handle the projection + rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2)); + } + calcOrthogonalProjection(from, to) { + let magnitude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.strokeProjectionMagnitude; + const vector = this.createSideVector(from, to); + const orthogonalProjection = getOrthonormalVector(vector); + const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(orthogonalProjection, this.bisector); + return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide); + } + + /** + * BEVEL + * Calculation: the projection points are formed by the vector orthogonal to the vertex. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel + */ + projectBevel() { + const projections = []; + // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C` + (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(to => { + projections.push(this.projectOrthogonally(this.A, to)); + projections.push(this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude)); + }); + return projections; + } + + /** + * MITER + * Calculation: the corner is formed by extending the outer edges of the stroke + * at the tangents of the path segments until they intersect. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter + */ + projectMiter() { + const projections = [], + alpha = Math.abs(this.alpha), + hypotUnitScalar = 1 / Math.sin(alpha / 2), + miterVector = this.scaleUnitVector(this.bisector, -this.strokeProjectionMagnitude * hypotUnitScalar); + + // When two line segments meet at a sharp angle, it is possible for the join to extend, + // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes + // a limit on the extent of the line join. + // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit + // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit + const strokeMiterLimit = this.options.strokeUniform ? magnitude(this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit)) : this.options.strokeMiterLimit; + if (magnitude(miterVector) / this.strokeProjectionMagnitude <= strokeMiterLimit) { + projections.push(this.applySkew(this.A.add(miterVector))); + } + /* when the miter-limit is reached, the stroke line join becomes of type bevel. + We always need two orthogonal projections which are basically bevel-type projections, + so regardless of whether the miter-limit was reached or not, we include these projections. + */ + projections.push(...this.projectBevel()); + return projections; + } + + /** + * ROUND (without skew) + * Calculation: the projections are the two vectors parallel to X and Y axes + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew + */ + projectRoundNoSkew(startCircle, endCircle) { + const projections = [], + // correctSide is used to only consider projecting for the outer side + correctSide = new Point(StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector), StrokeLineJoinProjections.getOrthogonalRotationFactor(new Point(this.bisector.y, this.bisector.x))), + radiusOnAxisX = new Point(1, 0).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(correctSide), + radiusOnAxisY = new Point(0, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar).multiply(correctSide); + [radiusOnAxisX, radiusOnAxisY].forEach(vector => { + if (isBetweenVectors(vector, startCircle, endCircle)) { + projections.push(this.A.add(vector)); + } + }); + return projections; + } + + /** + * ROUND (with skew) + * Calculation: the projections are the points furthest from the vertex in + * the direction of the X and Y axes after distortion. + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew + */ + projectRoundWithSkew(startCircle, endCircle) { + const projections = []; + const { + skewX, + skewY, + scaleX, + scaleY, + strokeUniform + } = this.options, + shearing = new Point(Math.tan(degreesToRadians(skewX)), Math.tan(degreesToRadians(skewY))); + // The points furthest from the vertex in the direction of the X and Y axes after distortion + const circleRadius = this.strokeProjectionMagnitude, + newY = strokeUniform ? circleRadius / scaleY / Math.sqrt(1 / scaleY ** 2 + 1 / scaleX ** 2 * shearing.y ** 2) : circleRadius / Math.sqrt(1 + shearing.y ** 2), + furthestY = new Point( + // Safe guard due to floating point precision. In some situations the square root + // was returning NaN because of a negative number close to zero. + Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)), newY), + newX = strokeUniform ? circleRadius / Math.sqrt(1 + shearing.x ** 2 * (1 / scaleY) ** 2 / (1 / scaleX + 1 / scaleX * shearing.x * shearing.y) ** 2) : circleRadius / Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2), + furthestX = new Point(newX, Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0))); + [furthestX, furthestX.scalarMultiply(-1), furthestY, furthestY.scalarMultiply(-1)] + // We need to skew the vector here as this information is used to check if + // it is between the start and end of the circle segment + .map(vector => this.applySkew(strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector)).forEach(vector => { + if (isBetweenVectors(vector, startCircle, endCircle)) { + projections.push(this.applySkew(this.A).add(vector)); + } + }); + return projections; + } + projectRound() { + const projections = []; + /* Include the start and end points of the circle segment, so that only + the projections contained within it are included */ + // add the orthogonal projections (start and end points of circle segment) + projections.push(...this.projectBevel()); + // let's determines which one of the orthogonal projection is the beginning and end of the circle segment. + // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different. + const isStraightLine = this.alpha % twoMathPi === 0, + // change the origin of the projections to point A + // so that the cross product calculation is correct + newOrigin = this.applySkew(this.A), + proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin), + proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin), + // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector. + comparisonVector = isStraightLine ? this.applySkew(this.AB.scalarMultiply(-1)) : this.applySkew(this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1)), + // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0) + isProj0Start = crossProduct(proj0, comparisonVector) > 0, + startCircle = isProj0Start ? proj0 : proj1, + endCircle = isProj0Start ? proj1 : proj0; + if (!this.isSkewed()) { + projections.push(...this.projectRoundNoSkew(startCircle, endCircle)); + } else { + projections.push(...this.projectRoundWithSkew(startCircle, endCircle)); + } + return projections; + } + + /** + * Project stroke width on points returning projections for each point as follows: + * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel) + * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke. + * - `round`: same as `bevel` when it has no skew, with skew are 4 points. + */ + projectPoints() { + switch (this.options.strokeLineJoin) { + case 'miter': + return this.projectMiter(); + case 'round': + return this.projectRound(); + default: + return this.projectBevel(); + } + } + project() { + return this.projectPoints().map(point => ({ + originPoint: this.A, + projectedPoint: point, + angle: this.alpha, + bisector: this.bisector + })); + } +} + +/** + * class in charge of finding projections for each type of line cap for start/end of an open path + * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)} + * + * Reference: + * - MDN: + * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap + * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap + * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev + * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html + * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js + */ +class StrokeLineCapProjections extends StrokeProjectionsBase { + /** + * edge point + */ + + /** + * point next to edge point + */ + + constructor(A, T, options) { + super(options); + this.A = new Point(A); + this.T = new Point(T); + } + calcOrthogonalProjection(from, to) { + let magnitude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.strokeProjectionMagnitude; + const vector = this.createSideVector(from, to); + return this.scaleUnitVector(getOrthonormalVector(vector), magnitude); + } + + /** + * OPEN PATH START/END - Line cap: Butt + * Calculation: to find the projections, just find the points orthogonal to the stroke + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt + */ + projectButt() { + return [this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude), this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude)]; + } + + /** + * OPEN PATH START/END - Line cap: Round + * Calculation: same as stroke line join `round` + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round + */ + projectRound() { + const projections = []; + if (!this.isSkewed() && this.A.eq(this.T)) { + /* 1 point case without `skew` + When `strokeUniform` is true, scaling has no effect. + So we divide by scale, to remove its effect. + */ + const projection = new Point(1, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar); + projections.push(this.applySkew(this.A.add(projection)), this.applySkew(this.A.subtract(projection))); + } else { + projections.push(...new StrokeLineJoinProjections(this.A, this.T, this.T, this.options).projectRound()); + } + return projections; + } + + /** + * OPEN PATH START/END - Line cap: Square + * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT` + * + * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square + */ + projectSquare() { + const projections = []; + if (this.A.eq(this.T)) { + /* 1 point case without `skew` + When `strokeUniform` is true, scaling has no effect. + So we divide by scale, to remove its effect. + */ + const projection = new Point(1, 1).scalarMultiply(this.strokeProjectionMagnitude).multiply(this.strokeUniformScalar); + projections.push(this.A.add(projection), this.A.subtract(projection)); + } else { + const orthogonalProjection = this.calcOrthogonalProjection(this.A, this.T, this.strokeProjectionMagnitude); + const strokePointingOut = this.scaleUnitVector(getUnitVector(this.createSideVector(this.A, this.T)), -this.strokeProjectionMagnitude); + const projectedA = this.A.add(strokePointingOut); + projections.push(projectedA.add(orthogonalProjection), projectedA.subtract(orthogonalProjection)); + } + return projections.map(p => this.applySkew(p)); + } + projectPoints() { + switch (this.options.strokeLineCap) { + case 'round': + return this.projectRound(); + case 'square': + return this.projectSquare(); + default: + return this.projectButt(); + } + } + project() { + return this.projectPoints().map(point => ({ + originPoint: this.A, + projectedPoint: point + })); + } +} + +/** + * + * Used to calculate object's bounding box + * + * @see https://github.com/fabricjs/fabric.js/pull/8344 + * + */ +const projectStrokeOnPoints = function (points, options) { + let openPath = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + const projections = []; + if (points.length === 0) { + return projections; + } + + // first we remove duplicate neighboring points + const reduced = points.reduce((reduced, point) => { + if (!reduced[reduced.length - 1].eq(point)) { + reduced.push(new Point(point)); + } + return reduced; + }, [new Point(points[0])]); + if (reduced.length === 1) { + openPath = true; + } else if (!openPath) { + // remove points from end in case they equal the first point + // in order to correctly project the first point + const start = reduced[0]; + const index = findIndexRight(reduced, point => !point.eq(start)); + reduced.splice(index + 1); + } + reduced.forEach((A, index, points) => { + let B, C; + if (index === 0) { + C = points[1]; + B = openPath ? A : points[points.length - 1]; + } else if (index === points.length - 1) { + B = points[index - 1]; + C = openPath ? A : points[0]; + } else { + B = points[index - 1]; + C = points[index + 1]; + } + if (openPath && points.length === 1) { + projections.push(...new StrokeLineCapProjections(A, A, options).project()); + } else if (openPath && (index === 0 || index === points.length - 1)) { + projections.push(...new StrokeLineCapProjections(A, index === 0 ? C : B, options).project()); + } else { + projections.push(...new StrokeLineJoinProjections(A, B, C, options).project()); + } + }); + return projections; +}; + +const cloneStyles = style => { + const newObj = {}; + Object.keys(style).forEach(key => { + newObj[key] = {}; + Object.keys(style[key]).forEach(keyInner => { + newObj[key][keyInner] = _objectSpread2({}, style[key][keyInner]); + }); + }); + return newObj; +}; + +/** + * Capitalizes a string + * @param {String} string String to capitalize + * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized + * and other letters stay untouched, if false first letter is capitalized + * and other letters are converted to lowercase. + * @return {String} Capitalized version of a string + */ +const capitalize = function (string) { + let firstLetterOnly = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + return "".concat(string.charAt(0).toUpperCase()).concat(firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()); +}; + +/** + * Escapes XML in a string + * @param {String} string String to escape + * @return {String} Escaped version of a string + */ +const escapeXml = string => string.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, ''').replace(//g, '>'); + +/** + * Divide a string in the user perceived single units + * @param {String} textstring String to escape + * @return {Array} array containing the graphemes + */ +const graphemeSplit = textstring => { + const graphemes = []; + for (let i = 0, chr; i < textstring.length; i++) { + if ((chr = getWholeChar(textstring, i)) === false) { + continue; + } + graphemes.push(chr); + } + return graphemes; +}; + +// taken from mdn in the charAt doc page. +const getWholeChar = (str, i) => { + const code = str.charCodeAt(i); + if (isNaN(code)) { + return ''; // Position not found + } + if (code < 0xd800 || code > 0xdfff) { + return str.charAt(i); + } + + // High surrogate (could change last hex to 0xDB7F to treat high private + // surrogates as single characters) + if (0xd800 <= code && code <= 0xdbff) { + if (str.length <= i + 1) { + throw 'High surrogate without following low surrogate'; + } + const next = str.charCodeAt(i + 1); + if (0xdc00 > next || next > 0xdfff) { + throw 'High surrogate without following low surrogate'; + } + return str.charAt(i) + str.charAt(i + 1); + } + // Low surrogate (0xDC00 <= code && code <= 0xDFFF) + if (i === 0) { + throw 'Low surrogate without preceding high surrogate'; + } + const prev = str.charCodeAt(i - 1); + + // (could change last hex to 0xDB7F to treat high private + // surrogates as single characters) + if (0xd800 > prev || prev > 0xdbff) { + throw 'Low surrogate without preceding high surrogate'; + } + // We can pass over low surrogates now as the second component + // in a pair which we have already processed + return false; +}; + +var lang_string = /*#__PURE__*/Object.freeze({ + __proto__: null, + capitalize: capitalize, + escapeXml: escapeXml, + graphemeSplit: graphemeSplit +}); + +/** + * @param {Object} prevStyle first style to compare + * @param {Object} thisStyle second style to compare + * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties + * @return {boolean} true if the style changed + */ +const hasStyleChanged = function (prevStyle, thisStyle) { + let forTextSpans = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + return prevStyle.fill !== thisStyle.fill || prevStyle.stroke !== thisStyle.stroke || prevStyle.strokeWidth !== thisStyle.strokeWidth || prevStyle.fontSize !== thisStyle.fontSize || prevStyle.fontFamily !== thisStyle.fontFamily || prevStyle.fontWeight !== thisStyle.fontWeight || prevStyle.fontStyle !== thisStyle.fontStyle || prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor || prevStyle.deltaY !== thisStyle.deltaY || forTextSpans && (prevStyle.overline !== thisStyle.overline || prevStyle.underline !== thisStyle.underline || prevStyle.linethrough !== thisStyle.linethrough); +}; + +/** + * Returns the array form of a text object's inline styles property with styles grouped in ranges + * rather than per character. This format is less verbose, and is better suited for storage + * so it is used in serialization (not during runtime). + * @param {object} styles per character styles for a text object + * @param {String} text the text string that the styles are applied to + * @return {{start: number, end: number, style: object}[]} + */ +const stylesToArray = (styles, text) => { + const textLines = text.split('\n'), + stylesArray = []; + let charIndex = -1, + prevStyle = {}; + // clone style structure to prevent mutation + styles = cloneStyles(styles); + + //loop through each textLine + for (let i = 0; i < textLines.length; i++) { + const chars = graphemeSplit(textLines[i]); + if (!styles[i]) { + //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle + charIndex += chars.length; + prevStyle = {}; + continue; + } + //loop through each character of the current line + for (let c = 0; c < chars.length; c++) { + charIndex++; + const thisStyle = styles[i][c]; + //check if style exists for this character + if (thisStyle && Object.keys(thisStyle).length > 0) { + if (hasStyleChanged(prevStyle, thisStyle, true)) { + stylesArray.push({ + start: charIndex, + end: charIndex + 1, + style: thisStyle + }); + } else { + //if style is the same as previous character, increase end index + stylesArray[stylesArray.length - 1].end++; + } + } + prevStyle = thisStyle || {}; + } + } + return stylesArray; +}; + +/** + * Returns the object form of the styles property with styles that are assigned per + * character rather than grouped by range. This format is more verbose, and is + * only used during runtime (not for serialization/storage) + * @param {Array} styles the serialized form of a text object's styles + * @param {String} text the text string that the styles are applied to + * @return {Object} + */ +const stylesFromArray = (styles, text) => { + if (!Array.isArray(styles)) { + // clone to prevent mutation + return cloneStyles(styles); + } + const textLines = text.split(reNewline), + stylesObject = {}; + let charIndex = -1, + styleIndex = 0; + //loop through each textLine + for (let i = 0; i < textLines.length; i++) { + const chars = graphemeSplit(textLines[i]); + + //loop through each character of the current line + for (let c = 0; c < chars.length; c++) { + charIndex++; + //check if there's a style collection that includes the current character + if (styles[styleIndex] && styles[styleIndex].start <= charIndex && charIndex < styles[styleIndex].end) { + //create object for line index if it doesn't exist + stylesObject[i] = stylesObject[i] || {}; + //assign a style at this character's index + stylesObject[i][c] = _objectSpread2({}, styles[styleIndex].style); + //if character is at the end of the current style collection, move to the next + if (charIndex === styles[styleIndex].end - 1) { + styleIndex++; + } + } + } + } + return stylesObject; +}; + +/** + * Attributes parsed from all SVG elements + * @type array + */ +const SHARED_ATTRIBUTES = ['display', 'transform', FILL, 'fill-opacity', 'fill-rule', 'opacity', STROKE, 'stroke-dasharray', 'stroke-linecap', 'stroke-dashoffset', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'id', 'paint-order', 'vector-effect', 'instantiated_by_use', 'clip-path']; + +function selectorMatches(element, selector) { + const nodeName = element.nodeName; + const classNames = element.getAttribute('class'); + const id = element.getAttribute('id'); + const azAz = '(?![a-zA-Z\\-]+)'; + let matcher; + // i check if a selector matches slicing away part from it. + // if i get empty string i should match + matcher = new RegExp('^' + nodeName, 'i'); + selector = selector.replace(matcher, ''); + if (id && selector.length) { + matcher = new RegExp('#' + id + azAz, 'i'); + selector = selector.replace(matcher, ''); + } + if (classNames && selector.length) { + const splitClassNames = classNames.split(' '); + for (let i = splitClassNames.length; i--;) { + matcher = new RegExp('\\.' + splitClassNames[i] + azAz, 'i'); + selector = selector.replace(matcher, ''); + } + } + return selector.length === 0; +} + +function doesSomeParentMatch(element, selectors) { + let selector, + parentMatching = true; + while (element.parentElement && element.parentElement.nodeType === 1 && selectors.length) { + if (parentMatching) { + selector = selectors.pop(); + } + element = element.parentElement; + parentMatching = selectorMatches(element, selector); + } + return selectors.length === 0; +} + +/** + * @private + */ + +function elementMatchesRule(element, selectors) { + let parentMatching = true; + // start from rightmost selector. + const firstMatching = selectorMatches(element, selectors.pop()); + if (firstMatching && selectors.length) { + parentMatching = doesSomeParentMatch(element, selectors); + } + return firstMatching && parentMatching && selectors.length === 0; +} + +/** + * @private + */ + +function getGlobalStylesForElement(element) { + let cssRules = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let styles = {}; + for (const rule in cssRules) { + if (elementMatchesRule(element, rule.split(' '))) { + styles = _objectSpread2(_objectSpread2({}, styles), cssRules[rule]); + } + } + return styles; +} + +const normalizeAttr = attr => { + var _attributesMap; + return (_attributesMap = attributesMap[attr]) !== null && _attributesMap !== void 0 ? _attributesMap : attr; +}; + +const regex$1 = new RegExp("(".concat(reNum, ")"), 'gi'); +const cleanupSvgAttribute = attributeValue => attributeValue.replace(regex$1, ' $1 ') +// replace annoying commas and arbitrary whitespace with single spaces +.replace(/,/gi, ' ').replace(/\s+/gi, ' '); + +var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7; + +// == begin transform regexp +const p$1 = "(".concat(reNum, ")"); +const skewX = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1); +const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1); +const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1); +const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1); +const translate = String.raw(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["(translate)(", "(?: ", ")?)"], ["(translate)\\(", "(?: ", ")?\\)"])), p$1, p$1); +const matrix = String.raw(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["(matrix)(", " ", " ", " ", " ", " ", ")"], ["(matrix)\\(", " ", " ", " ", " ", " ", "\\)"])), p$1, p$1, p$1, p$1, p$1, p$1); +const transform = "(?:".concat(matrix, "|").concat(translate, "|").concat(rotate, "|").concat(scale, "|").concat(skewX, "|").concat(skewY, ")"); +const transforms = "(?:".concat(transform, "*)"); +const transformList = String.raw(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["^s*(?:", "?)s*$"], ["^\\s*(?:", "?)\\s*$"])), transforms); +// http://www.w3.org/TR/SVG/coords.html#TransformAttribute +const reTransformList = new RegExp(transformList); +const reTransform = new RegExp(transform); +const reTransformAll = new RegExp(transform, 'g'); +// == end transform regexp + +/** + * Parses "transform" attribute, returning an array of values + * @static + * @function + * @memberOf fabric + * @param {String} attributeValue String containing attribute value + * @return {TTransformMatrix} Array of 6 elements representing transformation matrix + */ +function parseTransformAttribute(attributeValue) { + // first we clean the string + attributeValue = cleanupSvgAttribute(attributeValue) + // remove spaces around front parentheses + .replace(/\s*([()])\s*/gi, '$1'); + + // start with identity matrix + const matrices = []; + + // return if no argument was given or + // an argument does not match transform attribute regexp + if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) { + return [...iMatrix]; + } + for (const match of attributeValue.matchAll(reTransformAll)) { + const transformMatch = reTransform.exec(match[0]); + if (!transformMatch) { + continue; + } + let matrix = iMatrix; + const matchedParams = transformMatch.filter(m => !!m); + const [, operation, ...rawArgs] = matchedParams; + const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map(arg => parseFloat(arg)); + switch (operation) { + case 'translate': + matrix = createTranslateMatrix(arg0, arg1); + break; + case ROTATE: + matrix = createRotateMatrix({ + angle: arg0 + }, { + x: arg1, + y: arg2 + }); + break; + case SCALE: + matrix = createScaleMatrix(arg0, arg1); + break; + case SKEW_X: + matrix = createSkewXMatrix(arg0); + break; + case SKEW_Y: + matrix = createSkewYMatrix(arg0); + break; + case 'matrix': + matrix = [arg0, arg1, arg2, arg3, arg4, arg5]; + break; + } + + // snapshot current matrix into matrices array + matrices.push(matrix); + } + return multiplyTransformMatrixArray(matrices); +} + +function normalizeValue(attr, value, parentAttributes, fontSize) { + const isArray = Array.isArray(value); + let parsed; + let ouputValue = value; + if ((attr === FILL || attr === STROKE) && value === NONE) { + ouputValue = ''; + } else if (attr === 'strokeUniform') { + return value === 'non-scaling-stroke'; + } else if (attr === 'strokeDashArray') { + if (value === NONE) { + ouputValue = null; + } else { + ouputValue = value.replace(/,/g, ' ').split(/\s+/).map(parseFloat); + } + } else if (attr === 'transformMatrix') { + if (parentAttributes && parentAttributes.transformMatrix) { + ouputValue = multiplyTransformMatrices(parentAttributes.transformMatrix, parseTransformAttribute(value)); + } else { + ouputValue = parseTransformAttribute(value); + } + } else if (attr === 'visible') { + ouputValue = value !== NONE && value !== 'hidden'; + // display=none on parent element always takes precedence over child element + if (parentAttributes && parentAttributes.visible === false) { + ouputValue = false; + } + } else if (attr === 'opacity') { + ouputValue = parseFloat(value); + if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') { + ouputValue *= parentAttributes.opacity; + } + } else if (attr === 'textAnchor' /* text-anchor */) { + ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER; + } else if (attr === 'charSpacing') { + // parseUnit returns px and we convert it to em + parsed = parseUnit(value, fontSize) / fontSize * 1000; + } else if (attr === 'paintFirst') { + const fillIndex = value.indexOf(FILL); + const strokeIndex = value.indexOf(STROKE); + ouputValue = FILL; + if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) { + ouputValue = STROKE; + } else if (fillIndex === -1 && strokeIndex > -1) { + ouputValue = STROKE; + } + } else if (attr === 'href' || attr === 'xlink:href' || attr === 'font' || attr === 'id') { + return value; + } else if (attr === 'imageSmoothing') { + return value === 'optimizeQuality'; + } else { + parsed = isArray ? value.map(parseUnit) : parseUnit(value, fontSize); + } + return !isArray && isNaN(parsed) ? ouputValue : parsed; +} + +/** + * Parses a short font declaration, building adding its properties to a style object + * @static + * @function + * @memberOf fabric + * @param {String} value font declaration + * @param {Object} oStyle definition + */ +function parseFontDeclaration(value, oStyle) { + const match = value.match(reFontDeclaration); + if (!match) { + return; + } + const fontStyle = match[1], + // font variant is not used + // fontVariant = match[2], + fontWeight = match[3], + fontSize = match[4], + lineHeight = match[5], + fontFamily = match[6]; + if (fontStyle) { + oStyle.fontStyle = fontStyle; + } + if (fontWeight) { + oStyle.fontWeight = isNaN(parseFloat(fontWeight)) ? fontWeight : parseFloat(fontWeight); + } + if (fontSize) { + oStyle.fontSize = parseUnit(fontSize); + } + if (fontFamily) { + oStyle.fontFamily = fontFamily; + } + if (lineHeight) { + oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight; + } +} + +/** + * Takes a style object and parses it in one that has only defined values + * and lowercases properties + * @param style + * @param oStyle + */ +function parseStyleObject(style, oStyle) { + Object.entries(style).forEach(_ref => { + let [prop, value] = _ref; + if (value === undefined) { + return; + } + oStyle[prop.toLowerCase()] = value; + }); +} + +/** + * Takes a style string and parses it in one that has only defined values + * and lowercases properties + * @param style + * @param oStyle + */ +function parseStyleString(style, oStyle) { + style.replace(/;\s*$/, '').split(';').forEach(chunk => { + if (!chunk) return; + const [attr, value] = chunk.split(':'); + oStyle[attr.trim().toLowerCase()] = value.trim(); + }); +} + +/** + * Parses "style" attribute, retuning an object with values + * @static + * @memberOf fabric + * @param {SVGElement} element Element to parse + * @return {Object} Objects with values parsed from style attribute of an element + */ +function parseStyleAttribute(element) { + const oStyle = {}, + style = element.getAttribute('style'); + if (!style) { + return oStyle; + } + if (typeof style === 'string') { + parseStyleString(style, oStyle); + } else { + parseStyleObject(style, oStyle); + } + return oStyle; +} + +const colorAttributesMap = { + stroke: 'strokeOpacity', + fill: 'fillOpacity' +}; + +/** + * @private + * @param {Object} attributes Array of attributes to parse + */ + +function setStrokeFillOpacity(attributes) { + const defaults = FabricObject.getDefaults(); + Object.entries(colorAttributesMap).forEach(_ref => { + let [attr, colorAttr] = _ref; + if (typeof attributes[colorAttr] === 'undefined' || attributes[attr] === '') { + return; + } + if (typeof attributes[attr] === 'undefined') { + if (!defaults[attr]) { + return; + } + attributes[attr] = defaults[attr]; + } + if (attributes[attr].indexOf('url(') === 0) { + return; + } + const color = new Color(attributes[attr]); + attributes[attr] = color.setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2)).toRgba(); + }); + return attributes; +} + +/** + * Returns an object of attributes' name/value, given element and an array of attribute names; + * Parses parent "g" nodes recursively upwards. + * @param {SVGElement | HTMLElement} element Element to parse + * @param {Array} attributes Array of attributes to parse + * @return {Object} object containing parsed attributes' names/values + */ +function parseAttributes(element, attributes, cssRules) { + if (!element) { + return {}; + } + let parentAttributes = {}, + fontSize, + parentFontSize = DEFAULT_SVG_FONT_SIZE; + + // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards + if (element.parentNode && svgValidParentsRegEx.test(element.parentNode.nodeName)) { + parentAttributes = parseAttributes(element.parentElement, attributes, cssRules); + if (parentAttributes.fontSize) { + fontSize = parentFontSize = parseUnit(parentAttributes.fontSize); + } + } + const ownAttributes = _objectSpread2(_objectSpread2(_objectSpread2({}, attributes.reduce((memo, attr) => { + const value = element.getAttribute(attr); + if (value) { + memo[attr] = value; + } + return memo; + }, {})), getGlobalStylesForElement(element, cssRules)), parseStyleAttribute(element)); + if (ownAttributes[cPath]) { + element.setAttribute(cPath, ownAttributes[cPath]); + } + if (ownAttributes[fSize]) { + // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers. + fontSize = parseUnit(ownAttributes[fSize], parentFontSize); + ownAttributes[fSize] = "".concat(fontSize); + } + + // this should have its own complex type + const normalizedStyle = {}; + for (const attr in ownAttributes) { + const normalizedAttr = normalizeAttr(attr); + const normalizedValue = normalizeValue(normalizedAttr, ownAttributes[attr], parentAttributes, fontSize); + normalizedStyle[normalizedAttr] = normalizedValue; + } + if (normalizedStyle && normalizedStyle.font) { + parseFontDeclaration(normalizedStyle.font, normalizedStyle); + } + const mergedAttrs = _objectSpread2(_objectSpread2({}, parentAttributes), normalizedStyle); + return svgValidParentsRegEx.test(element.nodeName) ? mergedAttrs : setStrokeFillOpacity(mergedAttrs); +} + +const _excluded$c = ["left", "top", "width", "height", "visible"]; +const rectDefaultValues = { + rx: 0, + ry: 0 +}; +const RECT_PROPS = ['rx', 'ry']; +class Rect extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Rect.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Rect.ownDefaults); + this.setOptions(options); + this._initRxRy(); + } + /** + * Initializes rx/ry attributes + * @private + */ + _initRxRy() { + const { + rx, + ry + } = this; + if (rx && !ry) { + this.ry = rx; + } else if (ry && !rx) { + this.rx = ry; + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const { + width: w, + height: h + } = this; + const x = -w / 2; + const y = -h / 2; + const rx = this.rx ? Math.min(this.rx, w / 2) : 0; + const ry = this.ry ? Math.min(this.ry, h / 2) : 0; + const isRounded = rx !== 0 || ry !== 0; + ctx.beginPath(); + ctx.moveTo(x + rx, y); + ctx.lineTo(x + w - rx, y); + isRounded && ctx.bezierCurveTo(x + w - kRect * rx, y, x + w, y + kRect * ry, x + w, y + ry); + ctx.lineTo(x + w, y + h - ry); + isRounded && ctx.bezierCurveTo(x + w, y + h - kRect * ry, x + w - kRect * rx, y + h, x + w - rx, y + h); + ctx.lineTo(x + rx, y + h); + isRounded && ctx.bezierCurveTo(x + kRect * rx, y + h, x, y + h - kRect * ry, x, y + h - ry); + ctx.lineTo(x, y + ry); + isRounded && ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y); + ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...RECT_PROPS, ...propertiesToInclude]); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const { + width, + height, + rx, + ry + } = this; + return ['\n")]; + } + + /** + * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`) + * @static + * @memberOf Rect + * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement + */ + + /* _FROM_SVG_START_ */ + + /** + * Returns {@link Rect} instance from an SVG element + * @static + * @memberOf Rect + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + left = 0, + top = 0, + width = 0, + height = 0, + visible = true + } = _parseAttributes, + restOfparsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$c); + return new this(_objectSpread2(_objectSpread2(_objectSpread2({}, options), restOfparsedAttributes), {}, { + left, + top, + width, + height, + visible: Boolean(visible && width && height) + })); + } + + /* _FROM_SVG_END_ */ +} +/** + * Horizontal border radius + * @type Number + * @default + */ +/** + * Vertical border radius + * @type Number + * @default + */ +_defineProperty(Rect, "type", 'Rect'); +_defineProperty(Rect, "cacheProperties", [...cacheProperties, ...RECT_PROPS]); +_defineProperty(Rect, "ownDefaults", rectDefaultValues); +_defineProperty(Rect, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'x', 'y', 'rx', 'ry', 'width', 'height']); +classRegistry.setClass(Rect); +classRegistry.setSVGClass(Rect); + +const LAYOUT_TYPE_INITIALIZATION = 'initialization'; +const LAYOUT_TYPE_ADDED = 'added'; +const LAYOUT_TYPE_REMOVED = 'removed'; +const LAYOUT_TYPE_IMPERATIVE = 'imperative'; +const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified'; +const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying'; + +/** + * @returns 2 points, the tl and br corners of the non rotated bounding box of an object + * in the {@link group} plane, taking into account objects that {@link group} is their parent + * but also belong to the active selection. + */ +const getObjectBounds = (destinationGroup, object) => { + const { + strokeUniform, + strokeWidth, + width, + height, + group: currentGroup + } = object; + const t = currentGroup && currentGroup !== destinationGroup ? calcPlaneChangeMatrix(currentGroup.calcTransformMatrix(), destinationGroup.calcTransformMatrix()) : null; + const objectCenter = t ? object.getRelativeCenterPoint().transform(t) : object.getRelativeCenterPoint(); + const accountForStroke = !object['isStrokeAccountedForInDimensions'](); + const strokeUniformVector = strokeUniform && accountForStroke ? sendVectorToPlane(new Point(strokeWidth, strokeWidth), undefined, destinationGroup.calcTransformMatrix()) : ZERO; + const scalingStrokeWidth = !strokeUniform && accountForStroke ? strokeWidth : 0; + const sizeVector = sizeAfterTransform(width + scalingStrokeWidth, height + scalingStrokeWidth, multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true)).add(strokeUniformVector).scalarDivide(2); + return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)]; +}; + +/** + * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout. + * Returning `undefined` signals the `LayoutManager` to skip the layout. + * + * In charge of calculating the bounding box of the passed objects. + */ +class LayoutStrategy { + /** + * Used by the `LayoutManager` to perform layout + * @TODO/fix: if this method is calcResult, should calc unconditionally. + * the condition to not calc should be evaluated by the layoutManager. + * @returns layout result **OR** `undefined` to skip layout + */ + calcLayoutResult(context, objects) { + if (this.shouldPerformLayout(context)) { + return this.calcBoundingBox(objects, context); + } + } + shouldPerformLayout(_ref) { + let { + type, + prevStrategy, + strategy + } = _ref; + return type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_IMPERATIVE || !!prevStrategy && strategy !== prevStrategy; + } + shouldLayoutClipPath(_ref2) { + let { + type, + target: { + clipPath + } + } = _ref2; + return type !== LAYOUT_TYPE_INITIALIZATION && clipPath && !clipPath.absolutePositioned; + } + getInitialSize(context, result) { + return result.size; + } + + /** + * Override this method to customize layout. + */ + calcBoundingBox(objects, context) { + const { + type, + target + } = context; + if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) { + return context.overrides; + } + if (objects.length === 0) { + return; + } + const { + left, + top, + width, + height + } = makeBoundingBoxFromPoints(objects.map(object => getObjectBounds(target, object)).reduce((coords, curr) => coords.concat(curr), [])); + const bboxSize = new Point(width, height); + const bboxLeftTop = new Point(left, top); + const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2)); + if (type === LAYOUT_TYPE_INITIALIZATION) { + const actualSize = this.getInitialSize(context, { + size: bboxSize, + center: bboxCenter + }); + return { + // in `initialization` we do not account for target's transformation matrix + center: bboxCenter, + // TODO: investigate if this is still necessary + relativeCorrection: new Point(0, 0), + size: actualSize + }; + } else { + // we send `relativeCenter` up to group's containing plane + const center = bboxCenter.transform(target.calcOwnMatrix()); + return { + center, + size: bboxSize + }; + } + } +} +/** + * override by subclass for persistence (TS does not support `static abstract`) + */ +_defineProperty(LayoutStrategy, "type", 'strategy'); + +/** + * Layout will adjust the bounding box to fit target's objects. + */ +class FitContentLayout extends LayoutStrategy { + /** + * @override layout on all triggers + * Override at will + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + shouldPerformLayout(context) { + return true; + } +} +_defineProperty(FitContentLayout, "type", 'fit-content'); +classRegistry.setClass(FitContentLayout); + +const _excluded$b = ["strategy"], + _excluded2$3 = ["target", "strategy", "bubbles", "prevStrategy"]; +const LAYOUT_MANAGER = 'layoutManager'; +class LayoutManager { + constructor() { + let strategy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new FitContentLayout(); + _defineProperty(this, "strategy", void 0); + this.strategy = strategy; + this._subscriptions = new Map(); + } + performLayout(context) { + const strictContext = _objectSpread2(_objectSpread2({ + bubbles: true, + strategy: this.strategy + }, context), {}, { + prevStrategy: this._prevLayoutStrategy, + stopPropagation() { + this.bubbles = false; + } + }); + this.onBeforeLayout(strictContext); + const layoutResult = this.getLayoutResult(strictContext); + if (layoutResult) { + this.commitLayout(strictContext, layoutResult); + } + this.onAfterLayout(strictContext, layoutResult); + this._prevLayoutStrategy = strictContext.strategy; + } + + /** + * Attach handlers for events that we know will invalidate the layout when + * performed on child objects ( general transforms ). + * Returns the disposers for later unsubscribing and cleanup + * @param {FabricObject} object + * @param {RegistrationContext & Partial} context + * @returns {VoidFunction[]} disposers remove the handlers + */ + attachHandlers(object, context) { + const { + target + } = context; + return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY, MODIFY_PATH].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? { + type: LAYOUT_TYPE_OBJECT_MODIFIED, + trigger: key, + e, + target + } : { + type: LAYOUT_TYPE_OBJECT_MODIFYING, + trigger: key, + e, + target + }))); + } + + /** + * Subscribe an object to transform events that will trigger a layout change on the parent + * This is important only for interactive groups. + * @param object + * @param context + */ + subscribe(object, context) { + this.unsubscribe(object, context); + const disposers = this.attachHandlers(object, context); + this._subscriptions.set(object, disposers); + } + + /** + * unsubscribe object layout triggers + */ + unsubscribe(object, _context) { + (this._subscriptions.get(object) || []).forEach(d => d()); + this._subscriptions.delete(object); + } + unsubscribeTargets(context) { + context.targets.forEach(object => this.unsubscribe(object, context)); + } + subscribeTargets(context) { + context.targets.forEach(object => this.subscribe(object, context)); + } + onBeforeLayout(context) { + const { + target, + type + } = context; + const { + canvas + } = target; + // handle layout triggers subscription + // @TODO: gate the registration when the group is interactive + if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) { + this.subscribeTargets(context); + } else if (type === LAYOUT_TYPE_REMOVED) { + this.unsubscribeTargets(context); + } + // fire layout event (event will fire only for layouts after initialization layout) + target.fire('layout:before', { + context + }); + canvas && canvas.fire('object:layout:before', { + target, + context + }); + if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) { + const tricklingContext = _objectWithoutProperties(context, _excluded$b); + // traverse the tree + target.forEachObject(object => object.layoutManager && object.layoutManager.performLayout(_objectSpread2(_objectSpread2({}, tricklingContext), {}, { + bubbles: false, + target: object + }))); + } + } + getLayoutResult(context) { + const { + target, + strategy, + type + } = context; + const result = strategy.calcLayoutResult(context, target.getObjects()); + if (!result) { + return; + } + const prevCenter = type === LAYOUT_TYPE_INITIALIZATION ? new Point() : target.getRelativeCenterPoint(); + const { + center: nextCenter, + correction = new Point(), + relativeCorrection = new Point() + } = result; + const offset = prevCenter.subtract(nextCenter).add(correction).transform( + // in `initialization` we do not account for target's transformation matrix + type === LAYOUT_TYPE_INITIALIZATION ? iMatrix : invertTransform(target.calcOwnMatrix()), true).add(relativeCorrection); + return { + result, + prevCenter, + nextCenter, + offset + }; + } + commitLayout(context, layoutResult) { + const { + target + } = context; + const { + result: { + size + }, + nextCenter + } = layoutResult; + // set dimensions + target.set({ + width: size.x, + height: size.y + }); + // layout descendants + this.layoutObjects(context, layoutResult); + // set position + // in `initialization` we do not account for target's transformation matrix + if (context.type === LAYOUT_TYPE_INITIALIZATION) { + var _context$x, _context$y; + // TODO: what about strokeWidth? + target.set({ + left: (_context$x = context.x) !== null && _context$x !== void 0 ? _context$x : nextCenter.x + size.x * resolveOrigin(target.originX), + top: (_context$y = context.y) !== null && _context$y !== void 0 ? _context$y : nextCenter.y + size.y * resolveOrigin(target.originY) + }); + } else { + target.setPositionByOrigin(nextCenter, CENTER, CENTER); + // invalidate + target.setCoords(); + target.set('dirty', true); + } + } + layoutObjects(context, layoutResult) { + const { + target + } = context; + // adjust objects to account for new center + target.forEachObject(object => { + object.group === target && this.layoutObject(context, layoutResult, object); + }); + // adjust clip path to account for new center + context.strategy.shouldLayoutClipPath(context) && this.layoutObject(context, layoutResult, target.clipPath); + } + + /** + * @param {FabricObject} object + * @param {Point} offset + */ + layoutObject(context, _ref, object) { + let { + offset + } = _ref; + // TODO: this is here for cache invalidation. + // verify if this is necessary since we have explicit + // cache invalidation at the end of commitLayout + object.set({ + left: object.left + offset.x, + top: object.top + offset.y + }); + } + onAfterLayout(context, layoutResult) { + const { + target, + strategy, + bubbles, + prevStrategy: _ + } = context, + bubblingContext = _objectWithoutProperties(context, _excluded2$3); + const { + canvas + } = target; + + // fire layout event (event will fire only for layouts after initialization layout) + target.fire('layout:after', { + context, + result: layoutResult + }); + canvas && canvas.fire('object:layout:after', { + context, + result: layoutResult, + target + }); + + // bubble + const parent = target.parent; + if (bubbles && parent !== null && parent !== void 0 && parent.layoutManager) { + // add target to context#path + (bubblingContext.path || (bubblingContext.path = [])).push(target); + // all parents should invalidate their layout + parent.layoutManager.performLayout(_objectSpread2(_objectSpread2({}, bubblingContext), {}, { + target: parent + })); + } + target.set('dirty', true); + } + dispose() { + const { + _subscriptions + } = this; + _subscriptions.forEach(disposers => disposers.forEach(d => d())); + _subscriptions.clear(); + } + toObject() { + return { + type: LAYOUT_MANAGER, + strategy: this.strategy.constructor.type + }; + } + toJSON() { + return this.toObject(); + } +} +classRegistry.setClass(LayoutManager, LAYOUT_MANAGER); + +const _excluded$a = ["type", "objects", "layoutManager"]; +/** + * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case. + * We could have used a boolean in the constructor, as we did previously, but we think the boolean + * would stay in the group's constructor interface and create confusion, therefore it was removed. + * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called. + */ +class NoopLayoutManager extends LayoutManager { + // eslint-disable-next-line @typescript-eslint/no-empty-function + performLayout() {} +} +const groupDefaultValues = { + strokeWidth: 0, + subTargetCheck: false, + interactive: false +}; + +/** + * @fires object:added + * @fires object:removed + * @fires layout:before + * @fires layout:after + */ +class Group extends createCollectionMixin(FabricObject) { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Group.ownDefaults); + } + + /** + * Constructor + * + * @param {FabricObject[]} [objects] instance objects + * @param {Object} [options] Options object + */ + constructor() { + let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + /** + * Used to optimize performance + * set to `false` if you don't need contained objects to be targets of events + * @default + * @type boolean + */ + /** + * Used to allow targeting of object inside groups. + * set to true if you want to select an object inside a group.\ + * **REQUIRES** `subTargetCheck` set to true + * This will be not removed but slowly replaced with a method setInteractive + * that will take care of enabling subTargetCheck and necessary object events. + * There is too much attached to group interactivity to just be evaluated by a + * boolean in the code + * @default + * @deprecated + * @type boolean + */ + /** + * Used internally to optimize performance + * Once an object is selected, instance is rendered without the selected object. + * This way instance is cached only once for the entire interaction with the selected object. + * @private + */ + _defineProperty(this, "_activeObjects", []); + _defineProperty(this, "__objectSelectionTracker", void 0); + _defineProperty(this, "__objectSelectionDisposer", void 0); + Object.assign(this, Group.ownDefaults); + this.setOptions(options); + this.groupInit(objects, options); + } + + /** + * Shared code between group and active selection + * Meant to be used by the constructor. + */ + groupInit(objects, options) { + var _options$layoutManage; + this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller + + this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(this, true); + this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(this, false); + this.forEachObject(object => { + this.enterGroup(object, false); + }); + + // perform initial layout + this.layoutManager = (_options$layoutManage = options.layoutManager) !== null && _options$layoutManage !== void 0 ? _options$layoutManage : new LayoutManager(); + this.layoutManager.performLayout({ + type: LAYOUT_TYPE_INITIALIZATION, + target: this, + targets: [...objects], + // @TODO remove this concept from the layout manager. + // Layout manager will calculate the correct position, + // group options can override it later. + x: options.left, + y: options.top + }); + } + + /** + * Checks if object can enter group and logs relevant warnings + * @private + * @param {FabricObject} object + * @returns + */ + canEnterGroup(object) { + if (object === this || this.isDescendantOf(object)) { + // prevent circular object tree + log('error', 'Group: circular object trees are not supported, this call has no effect'); + return false; + } else if (this._objects.indexOf(object) !== -1) { + // is already in the objects array + log('error', 'Group: duplicate objects are not supported inside group, this call has no effect'); + return false; + } + return true; + } + + /** + * Override this method to enhance performance (for groups with a lot of objects). + * If Overriding, be sure not pass illegal objects to group - it will break your app. + * @private + */ + _filterObjectsBeforeEnteringGroup(objects) { + return objects.filter((object, index, array) => { + // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates) + return this.canEnterGroup(object) && array.indexOf(object) === index; + }); + } + + /** + * Add objects + * @param {...FabricObject[]} objects + */ + add() { + for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { + objects[_key] = arguments[_key]; + } + const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects); + const size = super.add(...allowedObjects); + this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects); + return size; + } + + /** + * Inserts an object into collection at specified index + * @param {FabricObject[]} objects Object to insert + * @param {Number} index Index to insert object at + */ + insertAt(index) { + for (var _len2 = arguments.length, objects = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + objects[_key2 - 1] = arguments[_key2]; + } + const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects); + const size = super.insertAt(index, ...allowedObjects); + this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects); + return size; + } + + /** + * Remove objects + * @param {...FabricObject[]} objects + * @returns {FabricObject[]} removed objects + */ + remove() { + const removed = super.remove(...arguments); + this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed); + return removed; + } + _onObjectAdded(object) { + this.enterGroup(object, true); + this.fire('object:added', { + target: object + }); + object.fire('added', { + target: this + }); + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + _onObjectRemoved(object, removeParentTransform) { + this.exitGroup(object, removeParentTransform); + this.fire('object:removed', { + target: object + }); + object.fire('removed', { + target: this + }); + } + + /** + * @private + * @param {'added'|'removed'} type + * @param {FabricObject[]} targets + */ + _onAfterObjectsChange(type, targets) { + this.layoutManager.performLayout({ + type, + targets, + target: this + }); + } + _onStackOrderChanged() { + this._set('dirty', true); + } + + /** + * @private + * @param {string} key + * @param {*} value + */ + _set(key, value) { + const prev = this[key]; + super._set(key, value); + if (key === 'canvas' && prev !== value) { + (this._objects || []).forEach(object => { + object._set(key, value); + }); + } + return this; + } + + /** + * @private + */ + _shouldSetNestedCoords() { + return this.subTargetCheck; + } + + /** + * Remove all objects + * @returns {FabricObject[]} removed objects + */ + removeAll() { + this._activeObjects = []; + return this.remove(...this._objects); + } + + /** + * keeps track of the selected objects + * @private + */ + __objectSelectionMonitor(selected, _ref) { + let { + target: object + } = _ref; + const activeObjects = this._activeObjects; + if (selected) { + activeObjects.push(object); + this._set('dirty', true); + } else if (activeObjects.length > 0) { + const index = activeObjects.indexOf(object); + if (index > -1) { + activeObjects.splice(index, 1); + this._set('dirty', true); + } + } + } + + /** + * @private + * @param {boolean} watch + * @param {FabricObject} object + */ + _watchObject(watch, object) { + // make sure we listen only once + watch && this._watchObject(false, object); + if (watch) { + object.on('selected', this.__objectSelectionTracker); + object.on('deselected', this.__objectSelectionDisposer); + } else { + object.off('selected', this.__objectSelectionTracker); + object.off('deselected', this.__objectSelectionDisposer); + } + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + enterGroup(object, removeParentTransform) { + object.group && object.group.remove(object); + object._set('parent', this); + this._enterGroup(object, removeParentTransform); + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + _enterGroup(object, removeParentTransform) { + if (removeParentTransform) { + // can this be converted to utils (sendObjectToPlane)? + applyTransformToObject(object, multiplyTransformMatrices(invertTransform(this.calcTransformMatrix()), object.calcTransformMatrix())); + } + this._shouldSetNestedCoords() && object.setCoords(); + object._set('group', this); + object._set('canvas', this.canvas); + this._watchObject(true, object); + const activeObject = this.canvas && this.canvas.getActiveObject && this.canvas.getActiveObject(); + // if we are adding the activeObject in a group + if (activeObject && (activeObject === object || object.isDescendantOf(activeObject))) { + this._activeObjects.push(object); + } + } + + /** + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + exitGroup(object, removeParentTransform) { + this._exitGroup(object, removeParentTransform); + object._set('parent', undefined); + object._set('canvas', undefined); + } + + /** + * Executes the inner fabric logic of exiting a group. + * - Stop watching the object + * - Remove the object from the optimization map this._activeObjects + * - unset the group property of the object + * @protected + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + _exitGroup(object, removeParentTransform) { + object._set('group', undefined); + if (!removeParentTransform) { + applyTransformToObject(object, multiplyTransformMatrices(this.calcTransformMatrix(), object.calcTransformMatrix())); + object.setCoords(); + } + this._watchObject(false, object); + const index = this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1; + if (index > -1) { + this._activeObjects.splice(index, 1); + } + } + + /** + * Decide if the object should cache or not. Create its own cache level + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group is already cached. + * @return {Boolean} + */ + shouldCache() { + const ownCache = FabricObject.prototype.shouldCache.call(this); + if (ownCache) { + for (let i = 0; i < this._objects.length; i++) { + if (this._objects[i].willDrawShadow()) { + this.ownCaching = false; + return false; + } + } + } + return ownCache; + } + + /** + * Check if this object or a child object will cast a shadow + * @return {Boolean} + */ + willDrawShadow() { + if (super.willDrawShadow()) { + return true; + } + for (let i = 0; i < this._objects.length; i++) { + if (this._objects[i].willDrawShadow()) { + return true; + } + } + return false; + } + + /** + * Check if instance or its group are caching, recursively up + * @return {Boolean} + */ + isOnACache() { + return this.ownCaching || !!this.parent && this.parent.isOnACache(); + } + + /** + * Execute the drawing operation for an object on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawObject(ctx) { + this._renderBackground(ctx); + for (let i = 0; i < this._objects.length; i++) { + var _this$canvas; + // TODO: handle rendering edge case somehow + if ((_this$canvas = this.canvas) !== null && _this$canvas !== void 0 && _this$canvas.preserveObjectStacking && this._objects[i].group !== this) { + ctx.save(); + ctx.transform(...invertTransform(this.calcTransformMatrix())); + this._objects[i].render(ctx); + ctx.restore(); + } else if (this._objects[i].group === this) { + this._objects[i].render(ctx); + } + } + this._drawClipPath(ctx, this.clipPath); + } + + /** + * @override + * @return {Boolean} + */ + setCoords() { + super.setCoords(); + this._shouldSetNestedCoords() && this.forEachObject(object => object.setCoords()); + } + triggerLayout() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.layoutManager.performLayout(_objectSpread2({ + target: this, + type: LAYOUT_TYPE_IMPERATIVE + }, options)); + } + + /** + * Renders instance on a given context + * @param {CanvasRenderingContext2D} ctx context to render instance on + */ + render(ctx) { + this._transformDone = true; + super.render(ctx); + this._transformDone = false; + } + + /** + * + * @private + * @param {'toObject'|'toDatalessObject'} [method] + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @returns {FabricObject[]} serialized objects + */ + __serializeObjects(method, propertiesToInclude) { + const _includeDefaultValues = this.includeDefaultValues; + return this._objects.filter(function (obj) { + return !obj.excludeFromExport; + }).map(function (obj) { + const originalDefaults = obj.includeDefaultValues; + obj.includeDefaultValues = _includeDefaultValues; + const data = obj[method || 'toObject'](propertiesToInclude); + obj.includeDefaultValues = originalDefaults; + // delete data.version; + return data; + }); + } + + /** + * Returns object representation of an instance + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const layoutManager = this.layoutManager.toObject(); + return _objectSpread2(_objectSpread2(_objectSpread2({}, super.toObject(['subTargetCheck', 'interactive', ...propertiesToInclude])), layoutManager.strategy !== 'fit-content' || this.includeDefaultValues ? { + layoutManager + } : {}), {}, { + objects: this.__serializeObjects('toObject', propertiesToInclude) + }); + } + toString() { + return "#"); + } + dispose() { + this.layoutManager.unsubscribeTargets({ + targets: this.getObjects(), + target: this + }); + this._activeObjects = []; + this.forEachObject(object => { + this._watchObject(false, object); + object.dispose(); + }); + super.dispose(); + } + + /** + * @private + */ + _createSVGBgRect(reviver) { + if (!this.backgroundColor) { + return ''; + } + const fillStroke = Rect.prototype._toSVG.call(this); + const commons = fillStroke.indexOf('COMMON_PARTS'); + fillStroke[commons] = 'for="group" '; + const markup = fillStroke.join(''); + return reviver ? reviver(markup) : markup; + } + + /** + * Returns svg representation of an instance + * @param {TSVGReviver} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + _toSVG(reviver) { + const svgString = ['\n']; + const bg = this._createSVGBgRect(reviver); + bg && svgString.push('\t\t', bg); + for (let i = 0; i < this._objects.length; i++) { + svgString.push('\t\t', this._objects[i].toSVG(reviver)); + } + svgString.push('\n'); + return svgString; + } + + /** + * Returns styles-string for svg-export, specific version for group + * @return {String} + */ + getSvgStyles() { + const opacity = typeof this.opacity !== 'undefined' && this.opacity !== 1 ? "opacity: ".concat(this.opacity, ";") : '', + visibility = this.visible ? '' : ' visibility: hidden;'; + return [opacity, this.getSvgFilter(), visibility].join(''); + } + + /** + * Returns svg clipPath representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {String} svg representation of an instance + */ + toClipPathSVG(reviver) { + const svgString = []; + const bg = this._createSVGBgRect(reviver); + bg && svgString.push('\t', bg); + for (let i = 0; i < this._objects.length; i++) { + svgString.push('\t', this._objects[i].toClipPathSVG(reviver)); + } + return this._createBaseClipPathSVGMarkup(svgString, { + reviver + }); + } + + /** + * @todo support loading from svg + * @private + * @static + * @memberOf Group + * @param {Object} object Object to create a group from + * @returns {Promise} + */ + static fromObject(_ref2, abortable) { + let { + type, + objects = [], + layoutManager + } = _ref2, + options = _objectWithoutProperties(_ref2, _excluded$a); + return Promise.all([enlivenObjects(objects, abortable), enlivenObjectEnlivables(options, abortable)]).then(_ref3 => { + let [objects, hydratedOptions] = _ref3; + const group = new this(objects, _objectSpread2(_objectSpread2(_objectSpread2({}, options), hydratedOptions), {}, { + layoutManager: new NoopLayoutManager() + })); + if (layoutManager) { + const layoutClass = classRegistry.getClass(layoutManager.type); + const strategyClass = classRegistry.getClass(layoutManager.strategy); + group.layoutManager = new layoutClass(new strategyClass()); + } else { + group.layoutManager = new LayoutManager(); + } + group.layoutManager.subscribeTargets({ + type: LAYOUT_TYPE_INITIALIZATION, + target: group, + targets: group.getObjects() + }); + group.setCoords(); + return group; + }); + } +} +_defineProperty(Group, "type", 'Group'); +_defineProperty(Group, "ownDefaults", groupDefaultValues); +classRegistry.setClass(Group); + +/** + * TODO experiment with different layout manager and svg results ( fixed fit content ) + * Groups SVG elements (usually those retrieved from SVG document) + * @static + * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group + * @return {FabricObject | Group} + */ +const groupSVGElements = (elements, options) => { + if (elements && elements.length === 1) { + return elements[0]; + } + return new Group(elements, options); +}; + +/** + * Finds the scale for the object source to fit inside the object destination, + * keeping aspect ratio intact. + * respect the total allowed area for the cache. + * @param {TSize} source natural unscaled size of the object + * @param {TSize} destination natural unscaled size of the object + * @return {Number} scale factor to apply to source to fit into destination + */ +const findScaleToFit = (source, destination) => Math.min(destination.width / source.width, destination.height / source.height); + +/** + * Finds the scale for the object source to cover entirely the object destination, + * keeping aspect ratio intact. + * respect the total allowed area for the cache. + * @param {TSize} source natural unscaled size of the object + * @param {TSize} destination natural unscaled size of the object + * @return {Number} scale factor to apply to source to cover destination + */ +const findScaleToCover = (source, destination) => Math.max(destination.width / source.width, destination.height / source.height); + +const commaWsp = "\\s*,?\\s*"; + +/** + * p for param + * using "bad naming" here because it makes the regex much easier to read + * p is a number that is preceded by an arbitary number of spaces, maybe 0, + * a comma or not, and then possibly more spaces or not. + */ +const p = "".concat(commaWsp, "(").concat(reNum, ")"); + +// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`; + +// const reLineCommand = `(L) ?(?:${p}${p} ?)+`; + +// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`; + +// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`; + +// const reClosePathCommand = String.raw`(Z)\s*`; + +// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`; + +// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`; + +// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`; + +// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`; + +const reArcCommandPoints = "".concat(p).concat(p).concat(p).concat(commaWsp, "([01])").concat(commaWsp, "([01])").concat(p).concat(p); +// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`; + +// export const rePathCommandGroups = +// `(?:(?:${reMoveToCommand})` + +// `|(?:${reLineCommand})` + +// `|(?:${reHorizontalLineCommand})` + +// `|(?:${reVerticalLineCommand})` + +// `|(?:${reClosePathCommand})` + +// `|(?:${reCubicCurveCommand})` + +// `|(?:${reCubicCurveShortcutCommand})` + +// `|(?:${reQuadraticCurveCommand})` + +// `|(?:${reQuadraticCurveShortcutCommand})` + +// `|(?:${reArcCommand}))`; + +const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*'; + +/** + * Commands that may be repeated + */ +const repeatedCommands = { + m: 'l', + M: 'L' +}; + +/** + * Convert an arc of a rotated ellipse to a Bezier Curve + * @param {TRadian} theta1 start of the arc + * @param {TRadian} theta2 end of the arc + * @param cosTh cosine of the angle of rotation + * @param sinTh sine of the angle of rotation + * @param rx x-axis radius (before rotation) + * @param ry y-axis radius (before rotation) + * @param cx1 center x of the ellipse + * @param cy1 center y of the ellipse + * @param mT + * @param fromX starting point of arc x + * @param fromY starting point of arc y + */ +const segmentToBezier = (theta1, theta2, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) => { + const costh1 = cos(theta1), + sinth1 = sin(theta1), + costh2 = cos(theta2), + sinth2 = sin(theta2), + toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1, + toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1, + cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1), + cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1), + cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2), + cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2); + return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY]; +}; + +/** + * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp} + * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here + * http://mozilla.org/MPL/2.0/ + * @param toX + * @param toY + * @param rx + * @param ry + * @param {number} large 0 or 1 flag + * @param {number} sweep 0 or 1 flag + * @param rotateX + */ +const arcToSegments = (toX, toY, rx, ry, large, sweep, rotateX) => { + if (rx === 0 || ry === 0) { + return []; + } + let fromX = 0, + fromY = 0, + root = 0; + const PI = Math.PI, + theta = rotateX * PiBy180, + sinTheta = sin(theta), + cosTh = cos(theta), + px = 0.5 * (-cosTh * toX - sinTheta * toY), + py = 0.5 * (-cosTh * toY + sinTheta * toX), + rx2 = rx ** 2, + ry2 = ry ** 2, + py2 = py ** 2, + px2 = px ** 2, + pl = rx2 * ry2 - rx2 * py2 - ry2 * px2; + let _rx = Math.abs(rx); + let _ry = Math.abs(ry); + if (pl < 0) { + const s = Math.sqrt(1 - pl / (rx2 * ry2)); + _rx *= s; + _ry *= s; + } else { + root = (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2)); + } + const cx = root * _rx * py / _ry, + cy = -root * _ry * px / _rx, + cx1 = cosTh * cx - sinTheta * cy + toX * 0.5, + cy1 = sinTheta * cx + cosTh * cy + toY * 0.5; + let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry); + let dtheta = calcVectorAngle((px - cx) / _rx, (py - cy) / _ry, (-px - cx) / _rx, (-py - cy) / _ry); + if (sweep === 0 && dtheta > 0) { + dtheta -= 2 * PI; + } else if (sweep === 1 && dtheta < 0) { + dtheta += 2 * PI; + } + + // Convert into cubic bezier segments <= 90deg + const segments = Math.ceil(Math.abs(dtheta / PI * 2)), + result = [], + mDelta = dtheta / segments, + mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2); + let th3 = mTheta + mDelta; + for (let i = 0; i < segments; i++) { + result[i] = segmentToBezier(mTheta, th3, cosTh, sinTheta, _rx, _ry, cx1, cy1, mT, fromX, fromY); + fromX = result[i][5]; + fromY = result[i][6]; + mTheta = th3; + th3 += mDelta; + } + return result; +}; + +/** + * @private + * Calculate the angle between two vectors + * @param ux u endpoint x + * @param uy u endpoint y + * @param vx v endpoint x + * @param vy v endpoint y + */ +const calcVectorAngle = (ux, uy, vx, vy) => { + const ta = Math.atan2(uy, ux), + tb = Math.atan2(vy, vx); + if (tb >= ta) { + return tb - ta; + } else { + return 2 * Math.PI - (ta - tb); + } +}; + +// functions for the Cubic beizer +// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350 +const CB1 = t => t ** 3; +const CB2 = t => 3 * t ** 2 * (1 - t); +const CB3 = t => 3 * t * (1 - t) ** 2; +const CB4 = t => (1 - t) ** 3; + +/** + * Calculate bounding box of a cubic Bezier curve + * Taken from http://jsbin.com/ivomiq/56/edit (no credits available) + * TODO: can we normalize this with the starting points set at 0 and then translated the bbox? + * @param {number} begx starting point + * @param {number} begy + * @param {number} cp1x first control point + * @param {number} cp1y + * @param {number} cp2x second control point + * @param {number} cp2y + * @param {number} endx end of bezier + * @param {number} endy + * @return {TRectBounds} the rectangular bounds + */ +function getBoundsOfCurve(begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy) { + let argsString; + if (config.cachesBoundsOfCurve) { + // eslint-disable-next-line + argsString = [...arguments].join(); + if (cache.boundsOfCurveCache[argsString]) { + return cache.boundsOfCurveCache[argsString]; + } + } + const sqrt = Math.sqrt, + abs = Math.abs, + tvalues = [], + bounds = [[0, 0], [0, 0]]; + let b = 6 * begx - 12 * cp1x + 6 * cp2x; + let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx; + let c = 3 * cp1x - 3 * begx; + for (let i = 0; i < 2; ++i) { + if (i > 0) { + b = 6 * begy - 12 * cp1y + 6 * cp2y; + a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy; + c = 3 * cp1y - 3 * begy; + } + if (abs(a) < 1e-12) { + if (abs(b) < 1e-12) { + continue; + } + const t = -c / b; + if (0 < t && t < 1) { + tvalues.push(t); + } + continue; + } + const b2ac = b * b - 4 * c * a; + if (b2ac < 0) { + continue; + } + const sqrtb2ac = sqrt(b2ac); + const t1 = (-b + sqrtb2ac) / (2 * a); + if (0 < t1 && t1 < 1) { + tvalues.push(t1); + } + const t2 = (-b - sqrtb2ac) / (2 * a); + if (0 < t2 && t2 < 1) { + tvalues.push(t2); + } + } + let j = tvalues.length; + const jlen = j; + const iterator = getPointOnCubicBezierIterator(begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy); + while (j--) { + const { + x, + y + } = iterator(tvalues[j]); + bounds[0][j] = x; + bounds[1][j] = y; + } + bounds[0][jlen] = begx; + bounds[1][jlen] = begy; + bounds[0][jlen + 1] = endx; + bounds[1][jlen + 1] = endy; + const result = [new Point(Math.min(...bounds[0]), Math.min(...bounds[1])), new Point(Math.max(...bounds[0]), Math.max(...bounds[1]))]; + if (config.cachesBoundsOfCurve) { + cache.boundsOfCurveCache[argsString] = result; + } + return result; +} + +/** + * Converts arc to a bunch of cubic Bezier curves + * @param {number} fx starting point x + * @param {number} fy starting point y + * @param {TParsedArcCommand} coords Arc command + */ +const fromArcToBeziers = (fx, fy, _ref) => { + let [_, rx, ry, rot, large, sweep, tx, ty] = _ref; + const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); + for (let i = 0, len = segsNorm.length; i < len; i++) { + segsNorm[i][1] += fx; + segsNorm[i][2] += fy; + segsNorm[i][3] += fx; + segsNorm[i][4] += fy; + segsNorm[i][5] += fx; + segsNorm[i][6] += fy; + } + return segsNorm; +}; + +/** + * This function takes a parsed SVG path and makes it simpler for fabricJS logic. + * Simplification consist of: + * - All commands converted to absolute (lowercase to uppercase) + * - S converted to C + * - T converted to Q + * - A converted to C + * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path` + * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path` + * TODO: figure out how to remove the type assertions in a nice way + */ +const makePathSimpler = path => { + // x and y represent the last point of the path, AKA the previous command point. + // we add them to each relative command to make it an absolute comment. + // we also swap the v V h H with L, because are easier to transform. + let x = 0, + y = 0; + // x1 and y1 represent the last point of the subpath. the subpath is started with + // m or M command. When a z or Z command is drawn, x and y need to be resetted to + // the last x1 and y1. + let x1 = 0, + y1 = 0; + // previous will host the letter of the previous command, to handle S and T. + // controlX and controlY will host the previous reflected control point + const destinationPath = []; + let previous, + // placeholders + controlX = 0, + controlY = 0; + for (const parsedCommand of path) { + const current = [...parsedCommand]; + let converted; + switch (current[0] // first letter + ) { + case 'l': + // lineto, relative + current[1] += x; + current[2] += y; + // falls through + case 'L': + x = current[1]; + y = current[2]; + converted = ['L', x, y]; + break; + case 'h': + // horizontal lineto, relative + current[1] += x; + // falls through + case 'H': + x = current[1]; + converted = ['L', x, y]; + break; + case 'v': + // vertical lineto, relative + current[1] += y; + // falls through + case 'V': + y = current[1]; + converted = ['L', x, y]; + break; + case 'm': + // moveTo, relative + current[1] += x; + current[2] += y; + // falls through + case 'M': + x = current[1]; + y = current[2]; + x1 = current[1]; + y1 = current[2]; + converted = ['M', x, y]; + break; + case 'c': + // bezierCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + current[5] += x; + current[6] += y; + // falls through + case 'C': + controlX = current[3]; + controlY = current[4]; + x = current[5]; + y = current[6]; + converted = ['C', current[1], current[2], controlX, controlY, x, y]; + break; + case 's': + // shorthand cubic bezierCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + // falls through + case 'S': + // would be sScC but since we are swapping sSc for C, we check just that. + if (previous === 'C') { + // calculate reflection of previous control points + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } else { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + controlX = x; + controlY = y; + } + x = current[3]; + y = current[4]; + converted = ['C', controlX, controlY, current[1], current[2], x, y]; + // converted[3] and converted[4] are NOW the second control point. + // we keep it for the next reflection. + controlX = converted[3]; + controlY = converted[4]; + break; + case 'q': + // quadraticCurveTo, relative + current[1] += x; + current[2] += y; + current[3] += x; + current[4] += y; + // falls through + case 'Q': + controlX = current[1]; + controlY = current[2]; + x = current[3]; + y = current[4]; + converted = ['Q', controlX, controlY, x, y]; + break; + case 't': + // shorthand quadraticCurveTo, relative + current[1] += x; + current[2] += y; + // falls through + case 'T': + if (previous === 'Q') { + // calculate reflection of previous control point + controlX = 2 * x - controlX; + controlY = 2 * y - controlY; + } else { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + controlX = x; + controlY = y; + } + x = current[1]; + y = current[2]; + converted = ['Q', controlX, controlY, x, y]; + break; + case 'a': + current[6] += x; + current[7] += y; + // falls through + case 'A': + fromArcToBeziers(x, y, current).forEach(b => destinationPath.push(b)); + x = current[6]; + y = current[7]; + break; + case 'z': + case 'Z': + x = x1; + y = y1; + converted = ['Z']; + break; + } + if (converted) { + destinationPath.push(converted); + previous = converted[0]; + } else { + previous = ''; + } + } + return destinationPath; +}; + +// todo verify if we can just use the point class here +/** + * Calc length from point x1,y1 to x2,y2 + * @param {number} x1 starting point x + * @param {number} y1 starting point y + * @param {number} x2 starting point x + * @param {number} y2 starting point y + * @return {number} length of segment + */ +const calcLineLength = (x1, y1, x2, y2) => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); + +/** + * Get an iterator that takes a percentage and returns a point + * @param {number} begx + * @param {number} begy + * @param {number} cp1x + * @param {number} cp1y + * @param {number} cp2x + * @param {number} cp2y + * @param {number} endx + * @param {number} endy + */ +const getPointOnCubicBezierIterator = (begx, begy, cp1x, cp1y, cp2x, cp2y, endx, endy) => pct => { + const c1 = CB1(pct), + c2 = CB2(pct), + c3 = CB3(pct), + c4 = CB4(pct); + return new Point(endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4, endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4); +}; +const QB1 = t => t ** 2; +const QB2 = t => 2 * t * (1 - t); +const QB3 = t => (1 - t) ** 2; +const getTangentCubicIterator = (p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) => pct => { + const qb1 = QB1(pct), + qb2 = QB2(pct), + qb3 = QB3(pct), + tangentX = 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)), + tangentY = 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y)); + return Math.atan2(tangentY, tangentX); +}; +const getPointOnQuadraticBezierIterator = (p1x, p1y, p2x, p2y, p3x, p3y) => pct => { + const c1 = QB1(pct), + c2 = QB2(pct), + c3 = QB3(pct); + return new Point(p3x * c1 + p2x * c2 + p1x * c3, p3y * c1 + p2y * c2 + p1y * c3); +}; +const getTangentQuadraticIterator = (p1x, p1y, p2x, p2y, p3x, p3y) => pct => { + const invT = 1 - pct, + tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)), + tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y)); + return Math.atan2(tangentY, tangentX); +}; + +// this will run over a path segment (a cubic or quadratic segment) and approximate it +// with 100 segments. This will good enough to calculate the length of the curve +const pathIterator = (iterator, x1, y1) => { + let tempP = new Point(x1, y1), + tmpLen = 0; + for (let perc = 1; perc <= 100; perc += 1) { + const p = iterator(perc / 100); + tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y); + tempP = p; + } + return tmpLen; +}; + +/** + * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1 + * that correspond to that pixels run over the path. + * The percentage will be then used to find the correct point on the canvas for the path. + * @param {Array} segInfo fabricJS collection of information on a parsed path + * @param {number} distance from starting point, in pixels. + * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point; + */ +const findPercentageForDistance = (segInfo, distance) => { + let perc = 0, + tmpLen = 0, + tempP = { + x: segInfo.x, + y: segInfo.y + }, + p = _objectSpread2({}, tempP), + nextLen, + nextStep = 0.01, + lastPerc = 0; + // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100 + // the path + const iterator = segInfo.iterator, + angleFinder = segInfo.angleFinder; + while (tmpLen < distance && nextStep > 0.0001) { + p = iterator(perc); + lastPerc = perc; + nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y); + // compare tmpLen each cycle with distance, decide next perc to test. + if (nextLen + tmpLen > distance) { + // we discard this step and we make smaller steps. + perc -= nextStep; + nextStep /= 2; + } else { + tempP = p; + perc += nextStep; + tmpLen += nextLen; + } + } + return _objectSpread2(_objectSpread2({}, p), {}, { + angle: angleFinder(lastPerc) + }); +}; + +/** + * Run over a parsed and simplified path and extract some information (length of each command and starting point) + * @param {TSimplePathData} path parsed path commands + * @return {TPathSegmentInfo[]} path commands information + */ +const getPathSegmentsInfo = path => { + let totalLength = 0, + //x2 and y2 are the coords of segment start + //x1 and y1 are the coords of the current point + x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0, + iterator, + tempInfo; + const info = []; + for (const current of path) { + const basicInfo = { + x: x1, + y: y1, + command: current[0], + length: 0 + }; + switch (current[0] //first letter + ) { + case 'M': + tempInfo = basicInfo; + tempInfo.x = x2 = x1 = current[1]; + tempInfo.y = y2 = y1 = current[2]; + break; + case 'L': + tempInfo = basicInfo; + tempInfo.length = calcLineLength(x1, y1, current[1], current[2]); + x1 = current[1]; + y1 = current[2]; + break; + case 'C': + iterator = getPointOnCubicBezierIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]); + tempInfo = basicInfo; + tempInfo.iterator = iterator; + tempInfo.angleFinder = getTangentCubicIterator(x1, y1, current[1], current[2], current[3], current[4], current[5], current[6]); + tempInfo.length = pathIterator(iterator, x1, y1); + x1 = current[5]; + y1 = current[6]; + break; + case 'Q': + iterator = getPointOnQuadraticBezierIterator(x1, y1, current[1], current[2], current[3], current[4]); + tempInfo = basicInfo; + tempInfo.iterator = iterator; + tempInfo.angleFinder = getTangentQuadraticIterator(x1, y1, current[1], current[2], current[3], current[4]); + tempInfo.length = pathIterator(iterator, x1, y1); + x1 = current[3]; + y1 = current[4]; + break; + case 'Z': + // we add those in order to ease calculations later + tempInfo = basicInfo; + tempInfo.destX = x2; + tempInfo.destY = y2; + tempInfo.length = calcLineLength(x1, y1, x2, y2); + x1 = x2; + y1 = y2; + break; + } + totalLength += tempInfo.length; + info.push(tempInfo); + } + info.push({ + length: totalLength, + x: x1, + y: y1 + }); + return info; +}; + +/** + * Get the point on the path that is distance along the path + * @param path + * @param distance + * @param infos + */ +const getPointOnPath = function (path, distance) { + let infos = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getPathSegmentsInfo(path); + let i = 0; + while (distance - infos[i].length > 0 && i < infos.length - 2) { + distance -= infos[i].length; + i++; + } + const segInfo = infos[i], + segPercent = distance / segInfo.length, + segment = path[i]; + switch (segInfo.command) { + case 'M': + return { + x: segInfo.x, + y: segInfo.y, + angle: 0 + }; + case 'Z': + return _objectSpread2(_objectSpread2({}, new Point(segInfo.x, segInfo.y).lerp(new Point(segInfo.destX, segInfo.destY), segPercent)), {}, { + angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x) + }); + case 'L': + return _objectSpread2(_objectSpread2({}, new Point(segInfo.x, segInfo.y).lerp(new Point(segment[1], segment[2]), segPercent)), {}, { + angle: Math.atan2(segment[2] - segInfo.y, segment[1] - segInfo.x) + }); + case 'C': + return findPercentageForDistance(segInfo, distance); + case 'Q': + return findPercentageForDistance(segInfo, distance); + // throw Error('Invalid command'); + } +}; +const rePathCmdAll = new RegExp(rePathCommand, 'gi'); +const regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g'); +const reMyNum = new RegExp(reNum, 'gi'); +const commandLengths = { + m: 2, + l: 2, + h: 1, + v: 1, + c: 6, + s: 4, + q: 4, + t: 2, + a: 7 +}; +/** + * + * @param {string} pathString + * @return {TComplexPathData} An array of SVG path commands + * @example Usage + * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [ + * ['M', 3, 4], + * ['Q', 3, 5, 2, 1, 4, 0], + * ['Q', 9, 12, 2, 1, 4, 0], + * ]; + */ +const parsePath = pathString => { + var _pathString$match; + const chain = []; + const all = (_pathString$match = pathString.match(rePathCmdAll)) !== null && _pathString$match !== void 0 ? _pathString$match : []; + for (const matchStr of all) { + // take match string and save the first letter as the command + const commandLetter = matchStr[0]; + // in case of Z we have very little to do + if (commandLetter === 'z' || commandLetter === 'Z') { + chain.push([commandLetter]); + continue; + } + const commandLength = commandLengths[commandLetter.toLowerCase()]; + let paramArr = []; + if (commandLetter === 'a' || commandLetter === 'A') { + // the arc command ha some peculariaties that requires a special regex other than numbers + // it is possible to avoid using a space between the sweep and large arc flags, making them either + // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum + // reset the regexp + regExpArcCommandPoints.lastIndex = 0; + for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) { + paramArr.push(...out.slice(1)); + } + } else { + paramArr = matchStr.match(reMyNum) || []; + } + + // inspect the length of paramArr, if is longer than commandLength + // we are dealing with repeated commands + for (let i = 0; i < paramArr.length; i += commandLength) { + const newCommand = new Array(commandLength); + const transformedCommand = repeatedCommands[commandLetter]; + newCommand[0] = i > 0 && transformedCommand ? transformedCommand : commandLetter; + for (let j = 0; j < commandLength; j++) { + newCommand[j + 1] = parseFloat(paramArr[i + j]); + } + chain.push(newCommand); + } + } + return chain; +}; + +/** + * + * Converts points to a smooth SVG path + * @param {XY[]} points Array of points + * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value. + * @return {(string|number)[][]} An array of SVG path commands + */ +const getSmoothPathFromPoints = function (points) { + let correction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + let p1 = new Point(points[0]), + p2 = new Point(points[1]), + multSignX = 1, + multSignY = 0; + const path = [], + len = points.length, + manyPoints = len > 2; + if (manyPoints) { + multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1; + multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1; + } + path.push(['M', p1.x - multSignX * correction, p1.y - multSignY * correction]); + let i; + for (i = 1; i < len; i++) { + if (!p1.eq(p2)) { + const midPoint = p1.midPointFrom(p2); + // p1 is our bezier control point + // midpoint is our endpoint + // start point is p(i-1) value. + path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]); + } + p1 = points[i]; + if (i + 1 < points.length) { + p2 = points[i + 1]; + } + } + if (manyPoints) { + multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1; + multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1; + } + path.push(['L', p1.x + multSignX * correction, p1.y + multSignY * correction]); + return path; +}; + +/** + * Transform a path by transforming each segment. + * it has to be a simplified path or it won't work. + * WARNING: this depends from pathOffset for correct operation + * @param {TSimplePathData} path fabricJS parsed and simplified path commands + * @param {TMat2D} transform matrix that represent the transformation + * @param {Point} [pathOffset] `Path.pathOffset` + * @returns {TSimplePathData} the transformed path + */ +const transformPath = (path, transform, pathOffset) => { + if (pathOffset) { + transform = multiplyTransformMatrices(transform, [1, 0, 0, 1, -pathOffset.x, -pathOffset.y]); + } + return path.map(pathSegment => { + const newSegment = [...pathSegment]; + for (let i = 1; i < pathSegment.length - 1; i += 2) { + // TODO: is there a way to get around casting to any? + const { + x, + y + } = transformPoint({ + x: pathSegment[i], + y: pathSegment[i + 1] + }, transform); + newSegment[i] = x; + newSegment[i + 1] = y; + } + return newSegment; + }); +}; + +/** + * Returns an array of path commands to create a regular polygon + * @param {number} numVertexes + * @param {number} radius + * @returns {TSimplePathData} An array of SVG path commands + */ +const getRegularPolygonPath = (numVertexes, radius) => { + const interiorAngle = Math.PI * 2 / numVertexes; + // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom + // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn + let rotationAdjustment = -halfPI; + if (numVertexes % 2 === 0) { + rotationAdjustment += interiorAngle / 2; + } + const d = new Array(numVertexes + 1); + for (let i = 0; i < numVertexes; i++) { + const rad = i * interiorAngle + rotationAdjustment; + const { + x, + y + } = new Point(cos(rad), sin(rad)).scalarMultiply(radius); + d[i] = [i === 0 ? 'M' : 'L', x, y]; + } + d[numVertexes] = ['Z']; + return d; +}; + +/** + * Join path commands to go back to svg format + * @param {TSimplePathData} pathData fabricJS parsed path commands + * @param {number} fractionDigits number of fraction digits to "leave" + * @return {String} joined path 'M 0 0 L 20 30' + */ +const joinPath = (pathData, fractionDigits) => pathData.map(segment => { + return segment.map((arg, i) => { + if (i === 0) return arg; + return fractionDigits === undefined ? arg : toFixed(arg, fractionDigits); + }).join(' '); +}).join(' '); + +// TODO this file needs to go away, cross browser style support is not fabricjs domain. + +/** + * wrapper for setting element's style + * @param {HTMLElement} element + * @param {Object | string} styles + */ +function setStyle(element, styles) { + const elementStyle = element.style; + if (!elementStyle || !styles) { + return; + } else if (typeof styles === 'string') { + elementStyle.cssText += ';' + styles; + } else { + Object.entries(styles).forEach(_ref => { + let [property, value] = _ref; + return elementStyle.setProperty(property, value); + }); + } +} + +/** + * Merges 2 clip paths into one visually equal clip path + * + * **IMPORTANT**:\ + * Does **NOT** clone the arguments, clone them proir if necessary. + * + * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap. + * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible. + * + * In order to handle the `inverted` property we follow logic described in the following cases:\ + * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\ + * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\ + * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged. + * + * @memberOf fabric.util + * @param {fabric.Object} c1 + * @param {fabric.Object} c2 + * @returns {fabric.Object} merged clip path + */ +const mergeClipPaths = (c1, c2) => { + var _b$group; + let a = c1, + b = c2; + if (a.inverted && !b.inverted) { + // case (2) + a = c2; + b = c1; + } + // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane + sendObjectToPlane(b, (_b$group = b.group) === null || _b$group === void 0 ? void 0 : _b$group.calcTransformMatrix(), a.calcTransformMatrix()); + // assign the `inverted` prop to the wrapping group + const inverted = a.inverted && b.inverted; + if (inverted) { + // case (1) + a.inverted = b.inverted = false; + } + return new Group([a], { + clipPath: b, + inverted + }); +}; + +/** + * Returns random number between 2 specified ones. + * @param {Number} min lower limit + * @param {Number} max upper limit + * @return {Number} random value (between min and max) + */ +const getRandomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; + +/** + * Cross-browser abstraction for sending XMLHttpRequest + * @deprecated this has to go away, we can use a modern browser method to do the same. + * @param {String} url URL to send XMLHttpRequest to + * @param {Object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @param {Function} options.onComplete Callback to invoke when request is completed + * @return {XMLHttpRequest} request + */ + +function request(url) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const onComplete = options.onComplete || noop, + xhr = new (getFabricWindow().XMLHttpRequest)(), + signal = options.signal, + abort = function () { + xhr.abort(); + }, + removeListener = function () { + signal && signal.removeEventListener('abort', abort); + xhr.onerror = xhr.ontimeout = noop; + }; + if (signal && signal.aborted) { + throw new SignalAbortedError('request'); + } else if (signal) { + signal.addEventListener('abort', abort, { + once: true + }); + } + + /** @ignore */ + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + removeListener(); + onComplete(xhr); + xhr.onreadystatechange = noop; + } + }; + xhr.onerror = xhr.ontimeout = removeListener; + xhr.open('get', url, true); + xhr.send(); + return xhr; +} + +/** + * This function is an helper for svg import. it decompose the transformMatrix + * and assign properties to object. + * untransformed coordinates + * @private + */ +const _assignTransformMatrixProps = object => { + if (object.transformMatrix) { + const { + scaleX, + scaleY, + angle, + skewX + } = qrDecompose(object.transformMatrix); + object.flipX = false; + object.flipY = false; + object.set(SCALE_X, scaleX); + object.set(SCALE_Y, scaleY); + object.angle = angle; + object.skewX = skewX; + object.skewY = 0; + } +}; + +/** + * This function is an helper for svg import. it removes the transform matrix + * and set to object properties that fabricjs can handle + * @private + * @param {Object} preserveAspectRatioOptions + */ +const removeTransformMatrixForSvgParsing = (object, preserveAspectRatioOptions) => { + let center = object._findCenterFromElement(); + if (object.transformMatrix) { + _assignTransformMatrixProps(object); + center = center.transform(object.transformMatrix); + } + delete object.transformMatrix; + if (preserveAspectRatioOptions) { + object.scaleX *= preserveAspectRatioOptions.scaleX; + object.scaleY *= preserveAspectRatioOptions.scaleY; + object.cropX = preserveAspectRatioOptions.cropX; + object.cropY = preserveAspectRatioOptions.cropY; + center.x += preserveAspectRatioOptions.offsetLeft; + center.y += preserveAspectRatioOptions.offsetTop; + object.width = preserveAspectRatioOptions.width; + object.height = preserveAspectRatioOptions.height; + } + object.setPositionByOrigin(center, CENTER, CENTER); +}; + +var index$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + addTransformToObject: addTransformToObject, + animate: animate, + animateColor: animateColor, + applyTransformToObject: applyTransformToObject, + calcAngleBetweenVectors: calcAngleBetweenVectors, + calcDimensionsMatrix: calcDimensionsMatrix, + calcPlaneChangeMatrix: calcPlaneChangeMatrix, + calcVectorRotation: calcVectorRotation, + cancelAnimFrame: cancelAnimFrame, + capValue: capValue, + composeMatrix: composeMatrix, + copyCanvasElement: copyCanvasElement, + cos: cos, + createCanvasElement: createCanvasElement, + createImage: createImage, + createRotateMatrix: createRotateMatrix, + createScaleMatrix: createScaleMatrix, + createSkewXMatrix: createSkewXMatrix, + createSkewYMatrix: createSkewYMatrix, + createTranslateMatrix: createTranslateMatrix, + createVector: createVector, + crossProduct: crossProduct, + degreesToRadians: degreesToRadians, + dotProduct: dotProduct, + ease: easing, + enlivenObjectEnlivables: enlivenObjectEnlivables, + enlivenObjects: enlivenObjects, + findScaleToCover: findScaleToCover, + findScaleToFit: findScaleToFit, + getBoundsOfCurve: getBoundsOfCurve, + getOrthonormalVector: getOrthonormalVector, + getPathSegmentsInfo: getPathSegmentsInfo, + getPointOnPath: getPointOnPath, + getPointer: getPointer, + getRandomInt: getRandomInt, + getRegularPolygonPath: getRegularPolygonPath, + getSmoothPathFromPoints: getSmoothPathFromPoints, + getSvgAttributes: getSvgAttributes, + getUnitVector: getUnitVector, + groupSVGElements: groupSVGElements, + hasStyleChanged: hasStyleChanged, + invertTransform: invertTransform, + isBetweenVectors: isBetweenVectors, + isIdentityMatrix: isIdentityMatrix, + isTouchEvent: isTouchEvent, + isTransparent: isTransparent, + joinPath: joinPath, + loadImage: loadImage, + magnitude: magnitude, + makeBoundingBoxFromPoints: makeBoundingBoxFromPoints, + makePathSimpler: makePathSimpler, + matrixToSVG: matrixToSVG, + mergeClipPaths: mergeClipPaths, + multiplyTransformMatrices: multiplyTransformMatrices, + multiplyTransformMatrixArray: multiplyTransformMatrixArray, + parsePath: parsePath, + parsePreserveAspectRatioAttribute: parsePreserveAspectRatioAttribute, + parseUnit: parseUnit, + pick: pick, + projectStrokeOnPoints: projectStrokeOnPoints, + qrDecompose: qrDecompose, + radiansToDegrees: radiansToDegrees, + removeFromArray: removeFromArray, + removeTransformFromObject: removeTransformFromObject, + removeTransformMatrixForSvgParsing: removeTransformMatrixForSvgParsing, + request: request, + requestAnimFrame: requestAnimFrame, + resetObjectTransform: resetObjectTransform, + rotatePoint: rotatePoint, + rotateVector: rotateVector, + saveObjectTransform: saveObjectTransform, + sendObjectToPlane: sendObjectToPlane, + sendPointToPlane: sendPointToPlane, + sendVectorToPlane: sendVectorToPlane, + setStyle: setStyle, + sin: sin, + sizeAfterTransform: sizeAfterTransform, + string: lang_string, + stylesFromArray: stylesFromArray, + stylesToArray: stylesToArray, + toDataURL: toDataURL, + toFixed: toFixed, + transformPath: transformPath, + transformPoint: transformPoint +}); + +class CanvasDOMManager extends StaticCanvasDOMManager { + constructor(arg0) { + let { + allowTouchScrolling = false, + containerClass = '' + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(arg0); + _defineProperty(this, "upper", void 0); + _defineProperty(this, "container", void 0); + const { + el: lowerCanvasEl + } = this.lower; + const upperCanvasEl = this.createUpperCanvas(); + this.upper = { + el: upperCanvasEl, + ctx: upperCanvasEl.getContext('2d') + }; + this.applyCanvasStyle(lowerCanvasEl, { + allowTouchScrolling + }); + this.applyCanvasStyle(upperCanvasEl, { + allowTouchScrolling, + styles: { + position: 'absolute', + left: '0', + top: '0' + } + }); + const container = this.createContainerElement(); + container.classList.add(containerClass); + if (lowerCanvasEl.parentNode) { + lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl); + } + container.append(lowerCanvasEl, upperCanvasEl); + this.container = container; + } + createUpperCanvas() { + const { + el: lowerCanvasEl + } = this.lower; + const el = createCanvasElement(); + // we assign the same classname of the lowerCanvas + el.className = lowerCanvasEl.className; + // but then we remove the lower-canvas specific className + el.classList.remove('lower-canvas'); + // we add the specific upper-canvas class + el.classList.add('upper-canvas'); + el.setAttribute('data-fabric', 'top'); + el.style.cssText = lowerCanvasEl.style.cssText; + el.setAttribute('draggable', 'true'); + return el; + } + createContainerElement() { + const container = getFabricDocument().createElement('div'); + container.setAttribute('data-fabric', 'wrapper'); + setStyle(container, { + position: 'relative' + }); + makeElementUnselectable(container); + return container; + } + + /** + * @private + * @param {HTMLCanvasElement} element canvas element to apply styles on + */ + applyCanvasStyle(element, options) { + const { + styles, + allowTouchScrolling + } = options; + setStyle(element, _objectSpread2(_objectSpread2({}, styles), {}, { + 'touch-action': allowTouchScrolling ? 'manipulation' : NONE + })); + makeElementUnselectable(element); + } + setDimensions(size, retinaScaling) { + super.setDimensions(size, retinaScaling); + const { + el, + ctx + } = this.upper; + setCanvasDimensions(el, ctx, size, retinaScaling); + } + setCSSDimensions(size) { + super.setCSSDimensions(size); + setCSSDimensions(this.upper.el, size); + setCSSDimensions(this.container, size); + } + cleanupDOM(size) { + const container = this.container, + { + el: lowerCanvasEl + } = this.lower, + { + el: upperCanvasEl + } = this.upper; + super.cleanupDOM(size); + container.removeChild(upperCanvasEl); + container.removeChild(lowerCanvasEl); + if (container.parentNode) { + container.parentNode.replaceChild(lowerCanvasEl, container); + } + } + dispose() { + super.dispose(); + getEnv$1().dispose(this.upper.el); + // @ts-expect-error disposing + delete this.upper; + // @ts-expect-error disposing + delete this.container; + } +} + +const canvasDefaults = { + uniformScaling: true, + uniScaleKey: 'shiftKey', + centeredScaling: false, + centeredRotation: false, + centeredKey: 'altKey', + altActionKey: 'shiftKey', + selection: true, + selectionKey: 'shiftKey', + selectionColor: 'rgba(100, 100, 255, 0.3)', + selectionDashArray: [], + selectionBorderColor: 'rgba(255, 255, 255, 0.3)', + selectionLineWidth: 1, + selectionFullyContained: false, + hoverCursor: 'move', + moveCursor: 'move', + defaultCursor: 'default', + freeDrawingCursor: 'crosshair', + notAllowedCursor: 'not-allowed', + perPixelTargetFind: false, + targetFindTolerance: 0, + skipTargetFind: false, + stopContextMenu: false, + fireRightClick: false, + fireMiddleClick: false, + enablePointerEvents: false, + containerClass: 'canvas-container', + preserveObjectStacking: false +}; + +/** + * Canvas class + * @class Canvas + * @extends StaticCanvas + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas} + * + * @fires object:modified at the end of a transform + * @fires object:rotating while an object is being rotated from the control + * @fires object:scaling while an object is being scaled by controls + * @fires object:moving while an object is being dragged + * @fires object:skewing while an object is being skewed from the controls + * + * @fires before:transform before a transform is is started + * @fires before:selection:cleared + * @fires selection:cleared + * @fires selection:updated + * @fires selection:created + * + * @fires path:created after a drawing operation ends and the path is added + * @fires mouse:down + * @fires mouse:move + * @fires mouse:up + * @fires mouse:down:before on mouse down, before the inner fabric logic runs + * @fires mouse:move:before on mouse move, before the inner fabric logic runs + * @fires mouse:up:before on mouse up, before the inner fabric logic runs + * @fires mouse:over + * @fires mouse:out + * @fires mouse:dblclick whenever a native dbl click event fires on the canvas. + * + * @fires dragover + * @fires dragenter + * @fires dragleave + * @fires drag:enter object drag enter + * @fires drag:leave object drag leave + * @fires drop:before before drop event. Prepare for the drop event (same native event). + * @fires drop + * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event). + * @example + * let a: fabric.Object, b: fabric.Object; + * let flag = false; + * canvas.add(a, b); + * a.on('drop:before', opt => { + * // we want a to accept the drop even though it's below b in the stack + * flag = this.canDrop(opt.e); + * }); + * b.canDrop = function(e) { + * !flag && this.draggableTextDelegate.canDrop(e); + * } + * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black')); + * a.on('drop', opt => { + * opt.e.defaultPrevented // drop occurred + * opt.didDrop // drop occurred on canvas + * opt.target // drop target + * opt.target !== a && a.set('text', 'I lost'); + * }); + * canvas.on('drop:after', opt => { + * // inform user who won + * if(!opt.e.defaultPrevented) { + * // no winners + * } + * else if(!opt.didDrop) { + * // my objects didn't win, some other lucky object + * } + * else { + * // we have a winner it's opt.target!! + * } + * }) + * + * @fires after:render at the end of the render process, receives the context in the callback + * @fires before:render at start the render process, receives the context in the callback + * + * @fires contextmenu:before + * @fires contextmenu + * @example + * let handler; + * targets.forEach(target => { + * target.on('contextmenu:before', opt => { + * // decide which target should handle the event before canvas hijacks it + * if (someCaseHappens && opt.targets.includes(target)) { + * handler = target; + * } + * }); + * target.on('contextmenu', opt => { + * // do something fantastic + * }); + * }); + * canvas.on('contextmenu', opt => { + * if (!handler) { + * // no one takes responsibility, it's always left to me + * // let's show them how it's done! + * } + * }); + * + */ +class SelectableCanvas extends StaticCanvas$1 { + constructor() { + super(...arguments); + // transform config + // selection config + // cursors + // target find config + /** + * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing. + * After mousedown, mousemove creates a shape, + * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas. + * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing} + * @type Boolean + * @default + */ + // event config + /** + * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget + * @type FabricObject[] + */ + _defineProperty(this, "targets", []); + /** + * hold the list of nested targets hovered + * @type FabricObject[] + * @private + */ + _defineProperty(this, "_hoveredTargets", []); + /** + * hold the list of objects to render + * @type FabricObject[] + * @private + */ + _defineProperty(this, "_objectsToRender", void 0); + /** + * hold a reference to a data structure that contains information + * on the current on going transform + * @type + * @private + */ + _defineProperty(this, "_currentTransform", null); + /** + * hold a reference to a data structure used to track the selection + * box on canvas drag + * on the current on going transform + * x, y, deltaX and deltaY are in scene plane + * @type + * @private + */ + _defineProperty(this, "_groupSelector", null); + /** + * internal flag used to understand if the context top requires a cleanup + * in case this is true, the contextTop will be cleared at the next render + * @type boolean + * @private + */ + _defineProperty(this, "contextTopDirty", false); + } + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), SelectableCanvas.ownDefaults); + } + get upperCanvasEl() { + var _this$elements$upper; + return (_this$elements$upper = this.elements.upper) === null || _this$elements$upper === void 0 ? void 0 : _this$elements$upper.el; + } + get contextTop() { + var _this$elements$upper2; + return (_this$elements$upper2 = this.elements.upper) === null || _this$elements$upper2 === void 0 ? void 0 : _this$elements$upper2.ctx; + } + get wrapperEl() { + return this.elements.container; + } + initElements(el) { + this.elements = new CanvasDOMManager(el, { + allowTouchScrolling: this.allowTouchScrolling, + containerClass: this.containerClass + }); + this._createCacheCanvas(); + } + + /** + * @private + * @param {FabricObject} obj Object that was added + */ + _onObjectAdded(obj) { + this._objectsToRender = undefined; + super._onObjectAdded(obj); + } + + /** + * @private + * @param {FabricObject} obj Object that was removed + */ + _onObjectRemoved(obj) { + this._objectsToRender = undefined; + // removing active object should fire "selection:cleared" events + if (obj === this._activeObject) { + this.fire('before:selection:cleared', { + deselected: [obj] + }); + this._discardActiveObject(); + this.fire('selection:cleared', { + deselected: [obj] + }); + obj.fire('deselected', { + target: obj + }); + } + if (obj === this._hoveredTarget) { + this._hoveredTarget = undefined; + this._hoveredTargets = []; + } + super._onObjectRemoved(obj); + } + _onStackOrderChanged() { + this._objectsToRender = undefined; + super._onStackOrderChanged(); + } + + /** + * Divides objects in two groups, one to render immediately + * and one to render as activeGroup. + * @return {Array} objects to render immediately and pushes the other in the activeGroup. + */ + _chooseObjectsToRender() { + const activeObject = this._activeObject; + return !this.preserveObjectStacking && activeObject ? this._objects.filter(object => !object.group && object !== activeObject).concat(activeObject) : this._objects; + } + + /** + * Renders both the top canvas and the secondary container canvas. + */ + renderAll() { + this.cancelRequestedRender(); + if (this.destroyed) { + return; + } + if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) { + this.clearContext(this.contextTop); + this.contextTopDirty = false; + } + if (this.hasLostContext) { + this.renderTopLayer(this.contextTop); + this.hasLostContext = false; + } + !this._objectsToRender && (this._objectsToRender = this._chooseObjectsToRender()); + this.renderCanvas(this.getContext(), this._objectsToRender); + } + + /** + * text selection is rendered by the active text instance during the rendering cycle + */ + renderTopLayer(ctx) { + ctx.save(); + if (this.isDrawingMode && this._isCurrentlyDrawing) { + this.freeDrawingBrush && this.freeDrawingBrush._render(); + this.contextTopDirty = true; + } + // we render the top context - last object + if (this.selection && this._groupSelector) { + this._drawSelection(ctx); + this.contextTopDirty = true; + } + ctx.restore(); + } + + /** + * Method to render only the top canvas. + * Also used to render the group selection box. + * Does not render text selection. + */ + renderTop() { + const ctx = this.contextTop; + this.clearContext(ctx); + this.renderTopLayer(ctx); + // todo: how do i know if the after:render is for the top or normal contex? + this.fire('after:render', { + ctx + }); + } + + /** + * Set the canvas tolerance value for pixel taret find. + * Use only integer numbers. + * @private + */ + setTargetFindTolerance(value) { + value = Math.round(value); + this.targetFindTolerance = value; + const retina = this.getRetinaScaling(); + const size = Math.ceil((value * 2 + 1) * retina); + this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size; + this.pixelFindContext.scale(retina, retina); + } + + /** + * Returns true if object is transparent at a certain location + * Clarification: this is `is target transparent at location X or are controls there` + * @TODO this seems dumb that we treat controls with transparency. we can find controls + * programmatically without painting them, the cache canvas optimization is always valid + * @param {FabricObject} target Object to check + * @param {Number} x Left coordinate in viewport space + * @param {Number} y Top coordinate in viewport space + * @return {Boolean} + */ + isTargetTransparent(target, x, y) { + const tolerance = this.targetFindTolerance; + const ctx = this.pixelFindContext; + this.clearContext(ctx); + ctx.save(); + ctx.translate(-x + tolerance, -y + tolerance); + ctx.transform(...this.viewportTransform); + const selectionBgc = target.selectionBackgroundColor; + target.selectionBackgroundColor = ''; + target.render(ctx); + target.selectionBackgroundColor = selectionBgc; + ctx.restore(); + // our canvas is square, and made around tolerance. + // so tolerance in this case also represent the center of the canvas. + const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling()); + return isTransparent(ctx, enhancedTolerance, enhancedTolerance, enhancedTolerance); + } + + /** + * takes an event and determines if selection key has been pressed + * @private + * @param {TPointerEvent} e Event object + */ + _isSelectionKeyPressed(e) { + const sKey = this.selectionKey; + if (!sKey) { + return false; + } + if (Array.isArray(sKey)) { + return !!sKey.find(key => !!key && e[key] === true); + } else { + return e[sKey]; + } + } + + /** + * @private + * @param {TPointerEvent} e Event object + * @param {FabricObject} target + */ + _shouldClearSelection(e, target) { + const activeObjects = this.getActiveObjects(), + activeObject = this._activeObject; + return !!(!target || target && activeObject && activeObjects.length > 1 && activeObjects.indexOf(target) === -1 && activeObject !== target && !this._isSelectionKeyPressed(e) || target && !target.evented || target && !target.selectable && activeObject && activeObject !== target); + } + + /** + * This method will take in consideration a modifier key pressed and the control we are + * about to drag, and try to guess the anchor point ( origin ) of the transormation. + * This should be really in the realm of controls, and we should remove specific code for legacy + * embedded actions. + * @TODO this probably deserve discussion/rediscovery and change/refactor + * @private + * @deprecated + * @param {FabricObject} target + * @param {string} action + * @param {boolean} altKey + * @returns {boolean} true if the transformation should be centered + */ + _shouldCenterTransform(target, action, modifierKeyPressed) { + if (!target) { + return; + } + let centerTransform; + if (action === SCALE || action === SCALE_X || action === SCALE_Y || action === RESIZING) { + centerTransform = this.centeredScaling || target.centeredScaling; + } else if (action === ROTATE) { + centerTransform = this.centeredRotation || target.centeredRotation; + } + return centerTransform ? !modifierKeyPressed : modifierKeyPressed; + } + + /** + * Given the control clicked, determine the origin of the transform. + * This is bad because controls can totally have custom names + * should disappear before release 4.0 + * @private + * @deprecated + */ + _getOriginFromCorner(target, controlName) { + const origin = { + x: target.originX, + y: target.originY + }; + if (!controlName) { + return origin; + } + + // is a left control ? + if (['ml', 'tl', 'bl'].includes(controlName)) { + origin.x = RIGHT; + // is a right control ? + } else if (['mr', 'tr', 'br'].includes(controlName)) { + origin.x = LEFT; + } + // is a top control ? + if (['tl', 'mt', 'tr'].includes(controlName)) { + origin.y = BOTTOM; + // is a bottom control ? + } else if (['bl', 'mb', 'br'].includes(controlName)) { + origin.y = TOP; + } + return origin; + } + + /** + * @private + * @param {Event} e Event object + * @param {FabricObject} target + * @param {boolean} [alreadySelected] pass true to setup the active control + */ + _setupCurrentTransform(e, target, alreadySelected) { + var _control$getActionHan; + const pointer = target.group ? + // transform pointer to target's containing coordinate plane + sendPointToPlane(this.getScenePoint(e), undefined, target.group.calcTransformMatrix()) : this.getScenePoint(e); + const { + key: corner = '', + control + } = target.getActiveControl() || {}, + actionHandler = alreadySelected && control ? (_control$getActionHan = control.getActionHandler(e, target, control)) === null || _control$getActionHan === void 0 ? void 0 : _control$getActionHan.bind(control) : dragHandler, + action = getActionFromCorner(alreadySelected, corner, e, target), + altKey = e[this.centeredKey], + origin = this._shouldCenterTransform(target, action, altKey) ? { + x: CENTER, + y: CENTER + } : this._getOriginFromCorner(target, corner), + /** + * relative to target's containing coordinate plane + * both agree on every point + **/ + transform = { + target: target, + action, + actionHandler, + actionPerformed: false, + corner, + scaleX: target.scaleX, + scaleY: target.scaleY, + skewX: target.skewX, + skewY: target.skewY, + offsetX: pointer.x - target.left, + offsetY: pointer.y - target.top, + originX: origin.x, + originY: origin.y, + ex: pointer.x, + ey: pointer.y, + lastX: pointer.x, + lastY: pointer.y, + theta: degreesToRadians(target.angle), + width: target.width, + height: target.height, + shiftKey: e.shiftKey, + altKey, + original: _objectSpread2(_objectSpread2({}, saveObjectTransform(target)), {}, { + originX: origin.x, + originY: origin.y + }) + }; + this._currentTransform = transform; + this.fire('before:transform', { + e, + transform + }); + } + + /** + * Set the cursor type of the canvas element + * @param {String} value Cursor type of the canvas element. + * @see http://www.w3.org/TR/css3-ui/#cursor + */ + setCursor(value) { + this.upperCanvasEl.style.cursor = value; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx to draw the selection on + */ + _drawSelection(ctx) { + const { + x, + y, + deltaX, + deltaY + } = this._groupSelector, + start = new Point(x, y).transform(this.viewportTransform), + extent = new Point(x + deltaX, y + deltaY).transform(this.viewportTransform), + strokeOffset = this.selectionLineWidth / 2; + let minX = Math.min(start.x, extent.x), + minY = Math.min(start.y, extent.y), + maxX = Math.max(start.x, extent.x), + maxY = Math.max(start.y, extent.y); + if (this.selectionColor) { + ctx.fillStyle = this.selectionColor; + ctx.fillRect(minX, minY, maxX - minX, maxY - minY); + } + if (!this.selectionLineWidth || !this.selectionBorderColor) { + return; + } + ctx.lineWidth = this.selectionLineWidth; + ctx.strokeStyle = this.selectionBorderColor; + minX += strokeOffset; + minY += strokeOffset; + maxX -= strokeOffset; + maxY -= strokeOffset; + // selection border + // @TODO: is _setLineDash still necessary on modern canvas? + FabricObject.prototype._setLineDash.call(this, ctx, this.selectionDashArray); + ctx.strokeRect(minX, minY, maxX - minX, maxY - minY); + } + + /** + * Method that determines what object we are clicking on + * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target + * or the outside part of the corner. + * @param {Event} e mouse event + * @return {FabricObject | null} the target found + */ + findTarget(e) { + if (this.skipTargetFind) { + return undefined; + } + const pointer = this.getViewportPoint(e), + activeObject = this._activeObject, + aObjects = this.getActiveObjects(); + this.targets = []; + if (activeObject && aObjects.length >= 1) { + if (activeObject.findControl(pointer, isTouchEvent(e))) { + // if we hit the corner of the active object, let's return that. + return activeObject; + } else if (aObjects.length > 1 && + // check pointer is over active selection and possibly perform `subTargetCheck` + this.searchPossibleTargets([activeObject], pointer)) { + // active selection does not select sub targets like normal groups + return activeObject; + } else if (activeObject === this.searchPossibleTargets([activeObject], pointer)) { + // active object is not an active selection + if (!this.preserveObjectStacking) { + return activeObject; + } else { + const subTargets = this.targets; + this.targets = []; + const target = this.searchPossibleTargets(this._objects, pointer); + if (e[this.altSelectionKey] && target && target !== activeObject) { + // alt selection: select active object even though it is not the top most target + // restore targets + this.targets = subTargets; + return activeObject; + } + return target; + } + } + } + return this.searchPossibleTargets(this._objects, pointer); + } + + /** + * Checks if the point is inside the object selection area including padding + * @param {FabricObject} obj Object to test against + * @param {Object} [pointer] point in scene coordinates + * @return {Boolean} true if point is contained within an area of given object + * @private + */ + _pointIsInObjectSelectionArea(obj, point) { + // getCoords will already take care of group de-nesting + let coords = obj.getCoords(); + const viewportZoom = this.getZoom(); + const padding = obj.padding / viewportZoom; + if (padding) { + const [tl, tr, br, bl] = coords; + // what is the angle of the object? + // we could use getTotalAngle, but is way easier to look at it + // from how coords are oriented, since if something went wrong + // at least we are consistent. + const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x), + cosP = cos(angleRadians) * padding, + sinP = sin(angleRadians) * padding, + cosPSinP = cosP + sinP, + cosPMinusSinP = cosP - sinP; + coords = [new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP), new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP), new Point(br.x + cosPMinusSinP, br.y + cosPSinP), new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP)]; + // in case of padding we calculate the new coords on the fly. + // otherwise we have to maintain 2 sets of coordinates for everything. + // we can reiterate on storing them. + // if this is slow, for now the semplification is large and doesn't impact + // rendering. + // the idea behind this is that outside target check we don't need ot know + // where those coords are + } + return Intersection.isPointInPolygon(point, coords); + } + + /** + * Checks point is inside the object selection condition. Either area with padding + * or over pixels if perPixelTargetFind is enabled + * @param {FabricObject} obj Object to test against + * @param {Object} [pointer] point from viewport. + * @return {Boolean} true if point is contained within an area of given object + * @private + */ + _checkTarget(obj, pointer) { + if (obj && obj.visible && obj.evented && this._pointIsInObjectSelectionArea(obj, sendPointToPlane(pointer, undefined, this.viewportTransform))) { + if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { + if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) { + return true; + } + } else { + return true; + } + } + return false; + } + + /** + * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted + * @param {Array} [objects] objects array to look into + * @param {Object} [pointer] x,y object of point coordinates we want to check. + * @return {FabricObject} **top most object from given `objects`** that contains pointer + * @private + */ + _searchPossibleTargets(objects, pointer) { + // Cache all targets where their bounding box contains point. + let i = objects.length; + // Do not check for currently grouped objects, since we check the parent group itself. + // until we call this function specifically to search inside the activeGroup + while (i--) { + const target = objects[i]; + if (this._checkTarget(target, pointer)) { + if (isCollection(target) && target.subTargetCheck) { + const subTarget = this._searchPossibleTargets(target._objects, pointer); + subTarget && this.targets.push(subTarget); + } + return target; + } + } + } + + /** + * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted + * @see {@link _searchPossibleTargets} + * @param {FabricObject[]} [objects] objects array to look into + * @param {Point} [pointer] coordinates from viewport to check. + * @return {FabricObject} **top most object on screen** that contains pointer + */ + searchPossibleTargets(objects, pointer) { + const target = this._searchPossibleTargets(objects, pointer); + + // if we found something in this.targets, and the group is interactive, return the innermost subTarget + // that is still interactive + // TODO: reverify why interactive. the target should be returned always, but selected only + // if interactive. + if (target && isCollection(target) && target.interactive && this.targets[0]) { + /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */ + const targets = this.targets; + for (let i = targets.length - 1; i > 0; i--) { + const t = targets[i]; + if (!(isCollection(t) && t.interactive)) { + // one of the subtargets was not interactive. that is the last subtarget we can return. + // we can't dig more deep; + return t; + } + } + return targets[0]; + } + return target; + } + + /** + * @returns point existing in the same plane as the {@link HTMLCanvasElement}, + * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}. + * This means that changes to the {@link viewportTransform} do not change the values of the point + * and it remains unchanged from the viewer's perspective. + * + * @example + * const scenePoint = sendPointToPlane( + * this.getViewportPoint(e), + * undefined, + * canvas.viewportTransform + * ); + * + */ + getViewportPoint(e) { + if (this._pointer) { + return this._pointer; + } + return this.getPointer(e, true); + } + + /** + * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in). + * This means that changes to the {@link viewportTransform} do not change the values of the point, + * however, from the viewer's perspective, the point is changed. + * + * @example + * const viewportPoint = sendPointToPlane( + * this.getScenePoint(e), + * canvas.viewportTransform + * ); + * + */ + getScenePoint(e) { + if (this._absolutePointer) { + return this._absolutePointer; + } + return this.getPointer(e); + } + + /** + * Returns pointer relative to canvas. + * + * @deprecated This method is deprecated since v6 to protect you from misuse. + * Use {@link getViewportPoint} or {@link getScenePoint} instead. + * + * @param {Event} e + * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene + * @return {Point} + */ + getPointer(e) { + let fromViewport = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + const upperCanvasEl = this.upperCanvasEl, + bounds = upperCanvasEl.getBoundingClientRect(); + let pointer = getPointer(e), + boundsWidth = bounds.width || 0, + boundsHeight = bounds.height || 0; + if (!boundsWidth || !boundsHeight) { + if (TOP in bounds && BOTTOM in bounds) { + boundsHeight = Math.abs(bounds.top - bounds.bottom); + } + if (RIGHT in bounds && LEFT in bounds) { + boundsWidth = Math.abs(bounds.right - bounds.left); + } + } + this.calcOffset(); + pointer.x = pointer.x - this._offset.left; + pointer.y = pointer.y - this._offset.top; + if (!fromViewport) { + pointer = sendPointToPlane(pointer, undefined, this.viewportTransform); + } + const retinaScaling = this.getRetinaScaling(); + if (retinaScaling !== 1) { + pointer.x /= retinaScaling; + pointer.y /= retinaScaling; + } + + // If bounds are not available (i.e. not visible), do not apply scale. + const cssScale = boundsWidth === 0 || boundsHeight === 0 ? new Point(1, 1) : new Point(upperCanvasEl.width / boundsWidth, upperCanvasEl.height / boundsHeight); + return pointer.multiply(cssScale); + } + + /** + * Internal use only + * @protected + */ + _setDimensionsImpl(dimensions, options) { + // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract + this._resetTransformEventData(); + super._setDimensionsImpl(dimensions, options); + if (this._isCurrentlyDrawing) { + this.freeDrawingBrush && this.freeDrawingBrush._setBrushStyles(this.contextTop); + } + } + _createCacheCanvas() { + this.pixelFindCanvasEl = createCanvasElement(); + this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', { + willReadFrequently: true + }); + this.setTargetFindTolerance(this.targetFindTolerance); + } + + /** + * Returns context of top canvas where interactions are drawn + * @returns {CanvasRenderingContext2D} + */ + getTopContext() { + return this.elements.upper.ctx; + } + + /** + * Returns context of canvas where object selection is drawn + * @alias + * @return {CanvasRenderingContext2D} + */ + getSelectionContext() { + return this.elements.upper.ctx; + } + + /** + * Returns <canvas> element on which object selection is drawn + * @return {HTMLCanvasElement} + */ + getSelectionElement() { + return this.elements.upper.el; + } + + /** + * Returns currently active object + * @return {FabricObject | null} active object + */ + getActiveObject() { + return this._activeObject; + } + + /** + * Returns an array with the current selected objects + * @return {FabricObject[]} active objects array + */ + getActiveObjects() { + const active = this._activeObject; + return isActiveSelection(active) ? active.getObjects() : active ? [active] : []; + } + + /** + * @private + * Compares the old activeObject with the current one and fires correct events + * @param {FabricObject[]} oldObjects old activeObject + * @param {TPointerEvent} e mouse event triggering the selection events + */ + _fireSelectionEvents(oldObjects, e) { + let somethingChanged = false, + invalidate = false; + const objects = this.getActiveObjects(), + added = [], + removed = []; + oldObjects.forEach(target => { + if (!objects.includes(target)) { + somethingChanged = true; + target.fire('deselected', { + e, + target + }); + removed.push(target); + } + }); + objects.forEach(target => { + if (!oldObjects.includes(target)) { + somethingChanged = true; + target.fire('selected', { + e, + target + }); + added.push(target); + } + }); + if (oldObjects.length > 0 && objects.length > 0) { + invalidate = true; + somethingChanged && this.fire('selection:updated', { + e, + selected: added, + deselected: removed + }); + } else if (objects.length > 0) { + invalidate = true; + this.fire('selection:created', { + e, + selected: added + }); + } else if (oldObjects.length > 0) { + invalidate = true; + this.fire('selection:cleared', { + e, + deselected: removed + }); + } + invalidate && (this._objectsToRender = undefined); + } + + /** + * Sets given object as the only active object on canvas + * @param {FabricObject} object Object to set as an active one + * @param {TPointerEvent} [e] Event (passed along when firing "object:selected") + * @return {Boolean} true if the object has been selected + */ + setActiveObject(object, e) { + // we can't inline this, since _setActiveObject will change what getActiveObjects returns + const currentActives = this.getActiveObjects(); + const selected = this._setActiveObject(object, e); + this._fireSelectionEvents(currentActives, e); + return selected; + } + + /** + * This is supposed to be equivalent to setActiveObject but without firing + * any event. There is commitment to have this stay this way. + * This is the functional part of setActiveObject. + * @param {Object} object to set as active + * @param {Event} [e] Event (passed along when firing "object:selected") + * @return {Boolean} true if the object has been selected + */ + _setActiveObject(object, e) { + const prevActiveObject = this._activeObject; + if (prevActiveObject === object) { + return false; + } + // after calling this._discardActiveObject, this,_activeObject could be undefined + if (!this._discardActiveObject(e, object) && this._activeObject) { + // refused to deselect + return false; + } + if (object.onSelect({ + e + })) { + return false; + } + this._activeObject = object; + if (isActiveSelection(object) && prevActiveObject !== object) { + object.set('canvas', this); + } + object.setCoords(); + return true; + } + + /** + * This is supposed to be equivalent to discardActiveObject but without firing + * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way. + * This is the functional part of discardActiveObject. + * @param {Event} [e] Event (passed along when firing "object:deselected") + * @param {Object} object the next object to set as active, reason why we are discarding this + * @return {Boolean} true if the active object has been discarded + */ + _discardActiveObject(e, object) { + const obj = this._activeObject; + if (obj) { + // onDeselect return TRUE to cancel selection; + if (obj.onDeselect({ + e, + object + })) { + return false; + } + if (this._currentTransform && this._currentTransform.target === obj) { + this.endCurrentTransform(e); + } + if (isActiveSelection(obj) && obj === this._hoveredTarget) { + this._hoveredTarget = undefined; + } + this._activeObject = undefined; + return true; + } + return false; + } + + /** + * Discards currently active object and fire events. If the function is called by fabric + * as a consequence of a mouse event, the event is passed as a parameter and + * sent to the fire function for the custom events. When used as a method the + * e param does not have any application. + * @param {event} e + * @return {Boolean} true if the active object has been discarded + */ + discardActiveObject(e) { + const currentActives = this.getActiveObjects(), + activeObject = this.getActiveObject(); + if (currentActives.length) { + this.fire('before:selection:cleared', { + e, + deselected: [activeObject] + }); + } + const discarded = this._discardActiveObject(e); + this._fireSelectionEvents(currentActives, e); + return discarded; + } + + /** + * End the current transform. + * You don't usually need to call this method unless you are interrupting a user initiated transform + * because of some other event ( a press of key combination, or something that block the user UX ) + * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event + */ + endCurrentTransform(e) { + const transform = this._currentTransform; + this._finalizeCurrentTransform(e); + if (transform && transform.target) { + // this could probably go inside _finalizeCurrentTransform + transform.target.isMoving = false; + } + this._currentTransform = null; + } + + /** + * @private + * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event + */ + _finalizeCurrentTransform(e) { + const transform = this._currentTransform, + target = transform.target, + options = { + e, + target, + transform, + action: transform.action + }; + if (target._scaling) { + target._scaling = false; + } + target.setCoords(); + if (transform.actionPerformed) { + this.fire('object:modified', options); + target.fire(MODIFIED, options); + } + } + + /** + * Sets viewport transformation of this canvas instance + * @param {Array} vpt a Canvas 2D API transform matrix + */ + setViewportTransform(vpt) { + super.setViewportTransform(vpt); + const activeObject = this._activeObject; + if (activeObject) { + activeObject.setCoords(); + } + } + + /** + * @override clears active selection ref and interactive canvas elements and contexts + */ + destroy() { + // dispose of active selection + const activeObject = this._activeObject; + if (isActiveSelection(activeObject)) { + activeObject.removeAll(); + activeObject.dispose(); + } + delete this._activeObject; + super.destroy(); + + // free resources + + // pixel find canvas + // @ts-expect-error disposing + this.pixelFindContext = null; + // @ts-expect-error disposing + this.pixelFindCanvasEl = undefined; + } + + /** + * Clears all contexts (background, main, top) of an instance + */ + clear() { + // discard active object and fire events + this.discardActiveObject(); + // make sure we clear the active object in case it refused to be discarded + this._activeObject = undefined; + this.clearContext(this.contextTop); + super.clear(); + } + + /** + * Draws objects' controls (borders/controls) + * @param {CanvasRenderingContext2D} ctx Context to render controls on + */ + drawControls(ctx) { + const activeObject = this._activeObject; + if (activeObject) { + activeObject._renderControls(ctx); + } + } + + /** + * @private + */ + _toObject(instance, methodName, propertiesToInclude) { + // If the object is part of the current selection group, it should + // be transformed appropriately + // i.e. it should be serialised as it would appear if the selection group + // were to be destroyed. + const originalProperties = this._realizeGroupTransformOnObject(instance), + object = super._toObject(instance, methodName, propertiesToInclude); + //Undo the damage we did by changing all of its properties + instance.set(originalProperties); + return object; + } + + /** + * Realizes an object's group transformation on it + * @private + * @param {FabricObject} [instance] the object to transform (gets mutated) + * @returns the original values of instance which were changed + */ + _realizeGroupTransformOnObject(instance) { + const { + group + } = instance; + if (group && isActiveSelection(group) && this._activeObject === group) { + const layoutProps = ['angle', 'flipX', 'flipY', LEFT, SCALE_X, SCALE_Y, SKEW_X, SKEW_Y, TOP]; + const originalValues = pick(instance, layoutProps); + addTransformToObject(instance, group.calcOwnMatrix()); + return originalValues; + } else { + return {}; + } + } + + /** + * @private + */ + _setSVGObject(markup, instance, reviver) { + // If the object is in a selection group, simulate what would happen to that + // object when the group is deselected + const originalProperties = this._realizeGroupTransformOnObject(instance); + super._setSVGObject(markup, instance, reviver); + instance.set(originalProperties); + } +} +_defineProperty(SelectableCanvas, "ownDefaults", canvasDefaults); + +/** + * In charge of synchronizing all interactive text instances of a canvas + */ +class TextEditingManager { + constructor(canvas) { + _defineProperty(this, "targets", []); + _defineProperty(this, "__disposer", void 0); + const cb = () => { + const { + hiddenTextarea + } = canvas.getActiveObject() || {}; + hiddenTextarea && hiddenTextarea.focus(); + }; + const el = canvas.upperCanvasEl; + el.addEventListener('click', cb); + this.__disposer = () => el.removeEventListener('click', cb); + } + exitTextEditing() { + this.target = undefined; + this.targets.forEach(target => { + if (target.isEditing) { + target.exitEditing(); + } + }); + } + add(target) { + this.targets.push(target); + } + remove(target) { + this.unregister(target); + removeFromArray(this.targets, target); + } + register(target) { + this.target = target; + } + unregister(target) { + if (target === this.target) { + this.target = undefined; + } + } + onMouseMove(e) { + var _this$target; + ((_this$target = this.target) === null || _this$target === void 0 ? void 0 : _this$target.isEditing) && this.target.updateSelectionOnMouseMove(e); + } + clear() { + this.targets = []; + this.target = undefined; + } + dispose() { + this.clear(); + this.__disposer(); + // @ts-expect-error disposing + delete this.__disposer; + } +} + +const _excluded$9 = ["target", "oldTarget", "fireCanvas", "e"]; +const addEventOptions = { + passive: false +}; +const getEventPoints = (canvas, e) => { + const viewportPoint = canvas.getViewportPoint(e); + const scenePoint = canvas.getScenePoint(e); + return { + viewportPoint, + scenePoint, + pointer: viewportPoint, + absolutePointer: scenePoint + }; +}; + +// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers +// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file. +// few bytes but why give it away. +const addListener = function (el) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + return el.addEventListener(...args); +}; +const removeListener = function (el) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + return el.removeEventListener(...args); +}; +const syntheticEventConfig = { + mouse: { + in: 'over', + out: 'out', + targetIn: 'mouseover', + targetOut: 'mouseout', + canvasIn: 'mouse:over', + canvasOut: 'mouse:out' + }, + drag: { + in: 'enter', + out: 'leave', + targetIn: 'dragenter', + targetOut: 'dragleave', + canvasIn: 'drag:enter', + canvasOut: 'drag:leave' + } +}; +let Canvas$1 = class Canvas extends SelectableCanvas { + constructor(el) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(el, options); + // bind event handlers + /** + * Contains the id of the touch event that owns the fabric transform + * @type Number + * @private + */ + /** + * Holds a reference to a setTimeout timer for event synchronization + * @type number + * @private + */ + /** + * Holds a reference to an object on the canvas that is receiving the drag over event. + * @type FabricObject + * @private + */ + /** + * Holds a reference to an object on the canvas from where the drag operation started + * @type FabricObject + * @private + */ + /** + * Holds a reference to an object on the canvas that is the current drop target + * May differ from {@link _draggedoverTarget} + * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow + * @type FabricObject + * @private + */ + _defineProperty(this, "_isClick", void 0); + _defineProperty(this, "textEditingManager", new TextEditingManager(this)); + ['_onMouseDown', '_onTouchStart', '_onMouseMove', '_onMouseUp', '_onTouchEnd', '_onResize', + // '_onGesture', + // '_onDrag', + // '_onShake', + // '_onLongPress', + // '_onOrientationChange', + '_onMouseWheel', '_onMouseOut', '_onMouseEnter', '_onContextMenu', '_onDoubleClick', '_onDragStart', '_onDragEnd', '_onDragProgress', '_onDragOver', '_onDragEnter', '_onDragLeave', '_onDrop'].forEach(eventHandler => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + this[eventHandler] = this[eventHandler].bind(this); + }); + // register event handlers + this.addOrRemove(addListener, 'add'); + } + + /** + * return an event prefix pointer or mouse. + * @private + */ + _getEventPrefix() { + return this.enablePointerEvents ? 'pointer' : 'mouse'; + } + addOrRemove(functor, _eventjsFunctor) { + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + functor(getWindowFromElement(canvasElement), 'resize', this._onResize); + functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown); + functor(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + functor(canvasElement, "".concat(eventTypePrefix, "out"), this._onMouseOut); + functor(canvasElement, "".concat(eventTypePrefix, "enter"), this._onMouseEnter); + functor(canvasElement, 'wheel', this._onMouseWheel); + functor(canvasElement, 'contextmenu', this._onContextMenu); + functor(canvasElement, 'dblclick', this._onDoubleClick); + functor(canvasElement, 'dragstart', this._onDragStart); + functor(canvasElement, 'dragend', this._onDragEnd); + functor(canvasElement, 'dragover', this._onDragOver); + functor(canvasElement, 'dragenter', this._onDragEnter); + functor(canvasElement, 'dragleave', this._onDragLeave); + functor(canvasElement, 'drop', this._onDrop); + if (!this.enablePointerEvents) { + functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions); + } + // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) { + // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture); + // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag); + // eventjs[eventjsFunctor]( + // canvasElement, + // 'orientation', + // this._onOrientationChange + // ); + // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake); + // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress); + // } + } + + /** + * Removes all event listeners + */ + removeListeners() { + this.addOrRemove(removeListener, 'remove'); + // if you dispose on a mouseDown, before mouse up, you need to clean document to... + const eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + removeListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + removeListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + removeListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + } + + /** + * @private + * @param {Event} [e] Event object fired on wheel event + */ + _onMouseWheel(e) { + this.__onMouseWheel(e); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseOut(e) { + const target = this._hoveredTarget; + const shared = _objectSpread2({ + e + }, getEventPoints(this, e)); + this.fire('mouse:out', _objectSpread2(_objectSpread2({}, shared), {}, { + target + })); + this._hoveredTarget = undefined; + target && target.fire('mouseout', _objectSpread2({}, shared)); + this._hoveredTargets.forEach(nestedTarget => { + this.fire('mouse:out', _objectSpread2(_objectSpread2({}, shared), {}, { + target: nestedTarget + })); + nestedTarget && nestedTarget.fire('mouseout', _objectSpread2({}, shared)); + }); + this._hoveredTargets = []; + } + + /** + * @private + * @param {Event} e Event object fired on mouseenter + */ + _onMouseEnter(e) { + // This find target and consequent 'mouse:over' is used to + // clear old instances on hovered target. + // calling findTarget has the side effect of killing target.__corner. + // as a short term fix we are not firing this if we are currently transforming. + // as a long term fix we need to separate the action of finding a target with the + // side effects we added to it. + if (!this._currentTransform && !this.findTarget(e)) { + this.fire('mouse:over', _objectSpread2({ + e + }, getEventPoints(this, e))); + this._hoveredTarget = undefined; + this._hoveredTargets = []; + } + } + + /** + * supports native like text dragging + * @private + * @param {DragEvent} e + */ + _onDragStart(e) { + this._isClick = false; + const activeObject = this.getActiveObject(); + if (activeObject && activeObject.onDragStart(e)) { + this._dragSource = activeObject; + const options = { + e, + target: activeObject + }; + this.fire('dragstart', options); + activeObject.fire('dragstart', options); + addListener(this.upperCanvasEl, 'drag', this._onDragProgress); + return; + } + stopEvent(e); + } + + /** + * First we clear top context where the effects are being rendered. + * Then we render the effects. + * Doing so will render the correct effect for all cases including an overlap between `source` and `target`. + * @private + */ + _renderDragEffects(e, source, target) { + let dirty = false; + // clear top context + const dropTarget = this._dropTarget; + if (dropTarget && dropTarget !== source && dropTarget !== target) { + dropTarget.clearContextTop(); + dirty = true; + } + source === null || source === void 0 || source.clearContextTop(); + target !== source && (target === null || target === void 0 ? void 0 : target.clearContextTop()); + // render effects + const ctx = this.contextTop; + ctx.save(); + ctx.transform(...this.viewportTransform); + if (source) { + ctx.save(); + source.transform(ctx); + source.renderDragSourceEffect(e); + ctx.restore(); + dirty = true; + } + if (target) { + ctx.save(); + target.transform(ctx); + target.renderDropTargetEffect(e); + ctx.restore(); + dirty = true; + } + ctx.restore(); + dirty && (this.contextTopDirty = true); + } + + /** + * supports native like text dragging + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag + * @private + * @param {DragEvent} e + */ + _onDragEnd(e) { + const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE, + dropTarget = didDrop ? this._activeObject : undefined, + options = { + e, + target: this._dragSource, + subTargets: this.targets, + dragSource: this._dragSource, + didDrop, + dropTarget: dropTarget + }; + removeListener(this.upperCanvasEl, 'drag', this._onDragProgress); + this.fire('dragend', options); + this._dragSource && this._dragSource.fire('dragend', options); + delete this._dragSource; + // we need to call mouse up synthetically because the browser won't + this._onMouseUp(e); + } + + /** + * fire `drag` event on canvas and drag source + * @private + * @param {DragEvent} e + */ + _onDragProgress(e) { + const options = { + e, + target: this._dragSource, + dragSource: this._dragSource, + dropTarget: this._draggedoverTarget + }; + this.fire('drag', options); + this._dragSource && this._dragSource.fire('drag', options); + } + + /** + * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line. + * Override at will + */ + findDragTargets(e) { + this.targets = []; + const target = this._searchPossibleTargets(this._objects, this.getViewportPoint(e)); + return { + target, + targets: [...this.targets] + }; + } + + /** + * prevent default to allow drop event to be fired + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets + * @private + * @param {DragEvent} [e] Event object fired on Event.js shake + */ + _onDragOver(e) { + const eventType = 'dragover'; + const { + target, + targets + } = this.findDragTargets(e); + const dragSource = this._dragSource; + const options = { + e, + target, + subTargets: targets, + dragSource, + canDrop: false, + dropTarget: undefined + }; + let dropTarget; + // fire on canvas + this.fire(eventType, options); + // make sure we fire dragenter events before dragover + // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it + this._fireEnterLeaveEvents(target, options); + if (target) { + if (target.canDrop(e)) { + dropTarget = target; + } + target.fire(eventType, options); + } + // propagate the event to subtargets + for (let i = 0; i < targets.length; i++) { + const subTarget = targets[i]; + // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken) + // TODO: verify if those should loop in inverse order then? + // what is the order of subtargets? + if (subTarget.canDrop(e)) { + dropTarget = subTarget; + } + subTarget.fire(eventType, options); + } + // render drag effects now that relations between source and target is clear + this._renderDragEffects(e, dragSource, dropTarget); + this._dropTarget = dropTarget; + } + + /** + * fire `dragleave` on `dragover` targets + * @private + * @param {Event} [e] Event object fired on Event.js shake + */ + _onDragEnter(e) { + const { + target, + targets + } = this.findDragTargets(e); + const options = { + e, + target, + subTargets: targets, + dragSource: this._dragSource + }; + this.fire('dragenter', options); + // fire dragenter on targets + this._fireEnterLeaveEvents(target, options); + } + + /** + * fire `dragleave` on `dragover` targets + * @private + * @param {Event} [e] Event object fired on Event.js shake + */ + _onDragLeave(e) { + const options = { + e, + target: this._draggedoverTarget, + subTargets: this.targets, + dragSource: this._dragSource + }; + this.fire('dragleave', options); + + // fire dragleave on targets + this._fireEnterLeaveEvents(undefined, options); + this._renderDragEffects(e, this._dragSource); + this._dropTarget = undefined; + // clear targets + this.targets = []; + this._hoveredTargets = []; + } + + /** + * `drop:before` is a an event that allows you to schedule logic + * before the `drop` event. Prefer `drop` event always, but if you need + * to run some drop-disabling logic on an event, since there is no way + * to handle event handlers ordering, use `drop:before` + * @private + * @param {Event} e + */ + _onDrop(e) { + const { + target, + targets + } = this.findDragTargets(e); + const options = this._basicEventHandler('drop:before', _objectSpread2({ + e, + target, + subTargets: targets, + dragSource: this._dragSource + }, getEventPoints(this, e))); + // will be set by the drop target + options.didDrop = false; + // will be set by the drop target, used in case options.target refuses the drop + options.dropTarget = undefined; + // fire `drop` + this._basicEventHandler('drop', options); + // inform canvas of the drop + // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it + // use for side effects + this.fire('drop:after', options); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onContextMenu(e) { + const target = this.findTarget(e), + subTargets = this.targets || []; + const options = this._basicEventHandler('contextmenu:before', { + e, + target, + subTargets + }); + // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves + this.stopContextMenu && stopEvent(e); + this._basicEventHandler('contextmenu', options); + return false; + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onDoubleClick(e) { + this._cacheTransformEventData(e); + this._handleEvent(e, 'dblclick'); + this._resetTransformEventData(); + } + + /** + * Return a the id of an event. + * returns either the pointerId or the identifier or 0 for the mouse event + * @private + * @param {Event} evt Event object + */ + getPointerId(evt) { + const changedTouches = evt.changedTouches; + if (changedTouches) { + return changedTouches[0] && changedTouches[0].identifier; + } + if (this.enablePointerEvents) { + return evt.pointerId; + } + return -1; + } + + /** + * Determines if an event has the id of the event that is considered main + * @private + * @param {evt} event Event object + */ + _isMainEvent(evt) { + if (evt.isPrimary === true) { + return true; + } + if (evt.isPrimary === false) { + return false; + } + if (evt.type === 'touchend' && evt.touches.length === 0) { + return true; + } + if (evt.changedTouches) { + return evt.changedTouches[0].identifier === this.mainTouchId; + } + return true; + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onTouchStart(e) { + e.preventDefault(); + if (this.mainTouchId === undefined) { + this.mainTouchId = this.getPointerId(e); + } + this.__onMouseDown(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(canvasElement); + addListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + addListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + // Unbind mousedown to prevent double triggers from touch devices + removeListener(canvasElement, "".concat(eventTypePrefix, "down"), this._onMouseDown); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDown(e) { + this.__onMouseDown(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + removeListener(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + const doc = getDocumentFromElement(canvasElement); + addListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + addListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onTouchEnd(e) { + if (e.touches.length > 0) { + // if there are still touches stop here + return; + } + this.__onMouseUp(e); + this._resetTransformEventData(); + delete this.mainTouchId; + const eventTypePrefix = this._getEventPrefix(); + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, 'touchend', this._onTouchEnd, addEventOptions); + removeListener(doc, 'touchmove', this._onMouseMove, addEventOptions); + if (this._willAddMouseDown) { + clearTimeout(this._willAddMouseDown); + } + this._willAddMouseDown = setTimeout(() => { + // Wait 400ms before rebinding mousedown to prevent double triggers + // from touch devices + addListener(this.upperCanvasEl, "".concat(eventTypePrefix, "down"), this._onMouseDown); + this._willAddMouseDown = 0; + }, 400); + } + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUp(e) { + this.__onMouseUp(e); + this._resetTransformEventData(); + const canvasElement = this.upperCanvasEl, + eventTypePrefix = this._getEventPrefix(); + if (this._isMainEvent(e)) { + const doc = getDocumentFromElement(this.upperCanvasEl); + removeListener(doc, "".concat(eventTypePrefix, "up"), this._onMouseUp); + removeListener(doc, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + addListener(canvasElement, "".concat(eventTypePrefix, "move"), this._onMouseMove, addEventOptions); + } + } + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMove(e) { + const activeObject = this.getActiveObject(); + !this.allowTouchScrolling && (!activeObject || + // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before + // we must not prevent the event's default behavior in order for the window to start dragging + !activeObject.shouldStartDragging(e)) && e.preventDefault && e.preventDefault(); + this.__onMouseMove(e); + } + + /** + * @private + */ + _onResize() { + this.calcOffset(); + this._resetTransformEventData(); + } + + /** + * Decides whether the canvas should be redrawn in mouseup and mousedown events. + * @private + * @param {Object} target + */ + _shouldRender(target) { + const activeObject = this.getActiveObject(); + // if just one of them is available or if they are both but are different objects + // this covers: switch of target, from target to no target, selection of target + // multiSelection with key and mouse + return !!activeObject !== !!target || activeObject && target && activeObject !== target; + } + + /** + * Method that defines the actions when mouse is released on canvas. + * The method resets the currentTransform parameters, store the image corner + * position in the image object and render the canvas on top. + * @private + * @param {Event} e Event object fired on mouseup + */ + __onMouseUp(e) { + var _this$_activeObject; + this._cacheTransformEventData(e); + this._handleEvent(e, 'up:before'); + const transform = this._currentTransform; + const isClick = this._isClick; + const target = this._target; + + // if right/middle click just fire events and return + // target undefined will make the _handleEvent search the target + const { + button + } = e; + if (button) { + (this.fireMiddleClick && button === 1 || this.fireRightClick && button === 2) && this._handleEvent(e, 'up'); + this._resetTransformEventData(); + return; + } + if (this.isDrawingMode && this._isCurrentlyDrawing) { + this._onMouseUpInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + let shouldRender = false; + if (transform) { + this._finalizeCurrentTransform(e); + shouldRender = transform.actionPerformed; + } + if (!isClick) { + const targetWasActive = target === this._activeObject; + this.handleSelection(e); + if (!shouldRender) { + shouldRender = this._shouldRender(target) || !targetWasActive && target === this._activeObject; + } + } + let pointer, corner; + if (target) { + const found = target.findControl(this.getViewportPoint(e), isTouchEvent(e)); + const { + key, + control + } = found || {}; + corner = key; + if (target.selectable && target !== this._activeObject && target.activeOn === 'up') { + this.setActiveObject(target, e); + shouldRender = true; + } else if (control) { + const mouseUpHandler = control.getMouseUpHandler(e, target, control); + if (mouseUpHandler) { + pointer = this.getScenePoint(e); + mouseUpHandler.call(control, e, transform, pointer.x, pointer.y); + } + } + target.isMoving = false; + } + // if we are ending up a transform on a different control or a new object + // fire the original mouse up from the corner that started the transform + if (transform && (transform.target !== target || transform.corner !== corner)) { + const originalControl = transform.target && transform.target.controls[transform.corner], + originalMouseUpHandler = originalControl && originalControl.getMouseUpHandler(e, transform.target, originalControl); + pointer = pointer || this.getScenePoint(e); + originalMouseUpHandler && originalMouseUpHandler.call(originalControl, e, transform, pointer.x, pointer.y); + } + this._setCursorFromEvent(e, target); + this._handleEvent(e, 'up'); + this._groupSelector = null; + this._currentTransform = null; + // reset the target information about which corner is selected + target && (target.__corner = undefined); + if (shouldRender) { + this.requestRenderAll(); + } else if (!isClick && !((_this$_activeObject = this._activeObject) !== null && _this$_activeObject !== void 0 && _this$_activeObject.isEditing)) { + this.renderTop(); + } + } + _basicEventHandler(eventType, options) { + const { + target, + subTargets = [] + } = options; + this.fire(eventType, options); + target && target.fire(eventType, options); + for (let i = 0; i < subTargets.length; i++) { + subTargets[i] !== target && subTargets[i].fire(eventType, options); + } + return options; + } + + /** + * @private + * Handle event firing for target and subtargets + * @param {TPointerEvent} e event from mouse + * @param {TPointerEventNames} eventType + */ + _handleEvent(e, eventType) { + const target = this._target, + targets = this.targets || [], + options = _objectSpread2(_objectSpread2({ + e, + target, + subTargets: targets + }, getEventPoints(this, e)), {}, { + transform: this._currentTransform + }, eventType === 'up:before' || eventType === 'up' ? { + isClick: this._isClick, + currentTarget: this.findTarget(e), + // set by the preceding `findTarget` call + currentSubTargets: this.targets + } : {}); + this.fire("mouse:".concat(eventType), options); + // this may be a little be more complicated of what we want to handle + target && target.fire("mouse".concat(eventType), options); + for (let i = 0; i < targets.length; i++) { + targets[i] !== target && targets[i].fire("mouse".concat(eventType), options); + } + } + + /** + * @private + * @param {Event} e Event object fired on mousedown + */ + _onMouseDownInDrawingMode(e) { + this._isCurrentlyDrawing = true; + if (this.getActiveObject()) { + this.discardActiveObject(e); + this.requestRenderAll(); + } + // TODO: this is a scene point so it should be renamed + const pointer = this.getScenePoint(e); + this.freeDrawingBrush && this.freeDrawingBrush.onMouseDown(pointer, { + e, + pointer + }); + this._handleEvent(e, 'down'); + } + + /** + * @private + * @param {Event} e Event object fired on mousemove + */ + _onMouseMoveInDrawingMode(e) { + if (this._isCurrentlyDrawing) { + const pointer = this.getScenePoint(e); + this.freeDrawingBrush && this.freeDrawingBrush.onMouseMove(pointer, { + e, + // this is an absolute pointer, the naming is wrong + pointer + }); + } + this.setCursor(this.freeDrawingCursor); + this._handleEvent(e, 'move'); + } + + /** + * @private + * @param {Event} e Event object fired on mouseup + */ + _onMouseUpInDrawingMode(e) { + const pointer = this.getScenePoint(e); + if (this.freeDrawingBrush) { + this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({ + e: e, + // this is an absolute pointer, the naming is wrong + pointer + }); + } else { + this._isCurrentlyDrawing = false; + } + this._handleEvent(e, 'up'); + } + + /** + * Method that defines the actions when mouse is clicked on canvas. + * The method inits the currentTransform parameters and renders all the + * canvas so the current image can be placed on the top canvas and the rest + * in on the container one. + * @private + * @param {Event} e Event object fired on mousedown + */ + __onMouseDown(e) { + this._isClick = true; + this._cacheTransformEventData(e); + this._handleEvent(e, 'down:before'); + let target = this._target; + + // if right/middle click just fire events + const { + button + } = e; + if (button) { + (this.fireMiddleClick && button === 1 || this.fireRightClick && button === 2) && this._handleEvent(e, 'down'); + this._resetTransformEventData(); + return; + } + if (this.isDrawingMode) { + this._onMouseDownInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + + // ignore if some object is being transformed at this moment + if (this._currentTransform) { + return; + } + let shouldRender = this._shouldRender(target); + let grouped = false; + if (this.handleMultiSelection(e, target)) { + // active object might have changed while grouping + target = this._activeObject; + grouped = true; + shouldRender = true; + } else if (this._shouldClearSelection(e, target)) { + this.discardActiveObject(e); + } + // we start a group selector rectangle if + // selection is enabled + // and there is no target, or the following 3 conditions are satisfied: + // target is not selectable ( otherwise we selected it ) + // target is not editing + // target is not already selected ( otherwise we drag ) + if (this.selection && (!target || !target.selectable && !target.isEditing && target !== this._activeObject)) { + const p = this.getScenePoint(e); + this._groupSelector = { + x: p.x, + y: p.y, + deltaY: 0, + deltaX: 0 + }; + } + if (target) { + const alreadySelected = target === this._activeObject; + if (target.selectable && target.activeOn === 'down') { + this.setActiveObject(target, e); + } + const handle = target.findControl(this.getViewportPoint(e), isTouchEvent(e)); + if (target === this._activeObject && (handle || !grouped)) { + this._setupCurrentTransform(e, target, alreadySelected); + const control = handle ? handle.control : undefined, + pointer = this.getScenePoint(e), + mouseDownHandler = control && control.getMouseDownHandler(e, target, control); + mouseDownHandler && mouseDownHandler.call(control, e, this._currentTransform, pointer.x, pointer.y); + } + } + // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering + // run before firing the `down` event to give the dev a chance to populate it themselves + shouldRender && (this._objectsToRender = undefined); + this._handleEvent(e, 'down'); + // we must renderAll so that we update the visuals + shouldRender && this.requestRenderAll(); + } + + /** + * reset cache form common information needed during event processing + * @private + */ + _resetTransformEventData() { + this._target = undefined; + this._pointer = undefined; + this._absolutePointer = undefined; + } + + /** + * Cache common information needed during event processing + * @private + * @param {Event} e Event object fired on event + */ + _cacheTransformEventData(e) { + // reset in order to avoid stale caching + this._resetTransformEventData(); + this._pointer = this.getViewportPoint(e); + this._absolutePointer = sendPointToPlane(this._pointer, undefined, this.viewportTransform); + this._target = this._currentTransform ? this._currentTransform.target : this.findTarget(e); + } + + /** + * Method that defines the actions when mouse is hovering the canvas. + * The currentTransform parameter will define whether the user is rotating/scaling/translating + * an image or neither of them (only hovering). A group selection is also possible and would cancel + * all any other type of action. + * In case of an image transformation only the top canvas will be rendered. + * @private + * @param {Event} e Event object fired on mousemove + */ + __onMouseMove(e) { + this._isClick = false; + this._cacheTransformEventData(e); + this._handleEvent(e, 'move:before'); + if (this.isDrawingMode) { + this._onMouseMoveInDrawingMode(e); + return; + } + if (!this._isMainEvent(e)) { + return; + } + const groupSelector = this._groupSelector; + + // We initially clicked in an empty area, so we draw a box for multiple selection + if (groupSelector) { + const pointer = this.getScenePoint(e); + groupSelector.deltaX = pointer.x - groupSelector.x; + groupSelector.deltaY = pointer.y - groupSelector.y; + this.renderTop(); + } else if (!this._currentTransform) { + const target = this.findTarget(e); + this._setCursorFromEvent(e, target); + this._fireOverOutEvents(e, target); + } else { + this._transformObject(e); + } + this.textEditingManager.onMouseMove(e); + this._handleEvent(e, 'move'); + this._resetTransformEventData(); + } + + /** + * Manage the mouseout, mouseover events for the fabric object on the canvas + * @param {Fabric.Object} target the target where the target from the mousemove event + * @param {Event} e Event object fired on mousemove + * @private + */ + _fireOverOutEvents(e, target) { + const _hoveredTarget = this._hoveredTarget, + _hoveredTargets = this._hoveredTargets, + targets = this.targets, + length = Math.max(_hoveredTargets.length, targets.length); + this.fireSyntheticInOutEvents('mouse', { + e, + target, + oldTarget: _hoveredTarget, + fireCanvas: true + }); + for (let i = 0; i < length; i++) { + this.fireSyntheticInOutEvents('mouse', { + e, + target: targets[i], + oldTarget: _hoveredTargets[i] + }); + } + this._hoveredTarget = target; + this._hoveredTargets = this.targets.concat(); + } + + /** + * Manage the dragEnter, dragLeave events for the fabric objects on the canvas + * @param {Fabric.Object} target the target where the target from the onDrag event + * @param {Object} data Event object fired on dragover + * @private + */ + _fireEnterLeaveEvents(target, data) { + const draggedoverTarget = this._draggedoverTarget, + _hoveredTargets = this._hoveredTargets, + targets = this.targets, + length = Math.max(_hoveredTargets.length, targets.length); + this.fireSyntheticInOutEvents('drag', _objectSpread2(_objectSpread2({}, data), {}, { + target, + oldTarget: draggedoverTarget, + fireCanvas: true + })); + for (let i = 0; i < length; i++) { + this.fireSyntheticInOutEvents('drag', _objectSpread2(_objectSpread2({}, data), {}, { + target: targets[i], + oldTarget: _hoveredTargets[i] + })); + } + this._draggedoverTarget = target; + } + + /** + * Manage the synthetic in/out events for the fabric objects on the canvas + * @param {Fabric.Object} target the target where the target from the supported events + * @param {Object} data Event object fired + * @param {Object} config configuration for the function to work + * @param {String} config.targetName property on the canvas where the old target is stored + * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out + * @param {String} config.evtOut name of the event to fire for out + * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in + * @param {String} config.evtIn name of the event to fire for in + * @private + */ + fireSyntheticInOutEvents(type, _ref) { + let { + target, + oldTarget, + fireCanvas, + e + } = _ref, + data = _objectWithoutProperties(_ref, _excluded$9); + const { + targetIn, + targetOut, + canvasIn, + canvasOut + } = syntheticEventConfig[type]; + const targetChanged = oldTarget !== target; + if (oldTarget && targetChanged) { + const outOpt = _objectSpread2(_objectSpread2({}, data), {}, { + e, + target: oldTarget, + nextTarget: target + }, getEventPoints(this, e)); + fireCanvas && this.fire(canvasOut, outOpt); + oldTarget.fire(targetOut, outOpt); + } + if (target && targetChanged) { + const inOpt = _objectSpread2(_objectSpread2({}, data), {}, { + e, + target, + previousTarget: oldTarget + }, getEventPoints(this, e)); + fireCanvas && this.fire(canvasIn, inOpt); + target.fire(targetIn, inOpt); + } + } + + /** + * Method that defines actions when an Event Mouse Wheel + * @param {Event} e Event object fired on mouseup + */ + __onMouseWheel(e) { + this._cacheTransformEventData(e); + this._handleEvent(e, 'wheel'); + this._resetTransformEventData(); + } + + /** + * @private + * @param {Event} e Event fired on mousemove + */ + _transformObject(e) { + const scenePoint = this.getScenePoint(e), + transform = this._currentTransform, + target = transform.target, + // transform pointer to target's containing coordinate plane + // both pointer and object should agree on every point + localPointer = target.group ? sendPointToPlane(scenePoint, undefined, target.group.calcTransformMatrix()) : scenePoint; + transform.shiftKey = e.shiftKey; + transform.altKey = !!this.centeredKey && e[this.centeredKey]; + this._performTransformAction(e, transform, localPointer); + transform.actionPerformed && this.requestRenderAll(); + } + + /** + * @private + */ + _performTransformAction(e, transform, pointer) { + const { + action, + actionHandler, + target + } = transform; + const actionPerformed = !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y); + actionPerformed && target.setCoords(); + + // this object could be created from the function in the control handlers + if (action === 'drag' && actionPerformed) { + transform.target.isMoving = true; + this.setCursor(transform.target.moveCursor || this.moveCursor); + } + transform.actionPerformed = transform.actionPerformed || actionPerformed; + } + + /** + * Sets the cursor depending on where the canvas is being hovered. + * Note: very buggy in Opera + * @param {Event} e Event object + * @param {Object} target Object that the mouse is hovering, if so. + */ + _setCursorFromEvent(e, target) { + if (!target) { + this.setCursor(this.defaultCursor); + return; + } + let hoverCursor = target.hoverCursor || this.hoverCursor; + const activeSelection = isActiveSelection(this._activeObject) ? this._activeObject : null, + // only show proper corner when group selection is not active + corner = (!activeSelection || target.group !== activeSelection) && + // here we call findTargetCorner always with undefined for the touch parameter. + // we assume that if you are using a cursor you do not need to interact with + // the bigger touch area. + target.findControl(this.getViewportPoint(e)); + if (!corner) { + if (target.subTargetCheck) { + // hoverCursor should come from top-most subTarget, + // so we walk the array backwards + this.targets.concat().reverse().map(_target => { + hoverCursor = _target.hoverCursor || hoverCursor; + }); + } + this.setCursor(hoverCursor); + } else { + const control = corner.control; + this.setCursor(control.cursorStyleHandler(e, control, target)); + } + } + + /** + * ## Handles multiple selection + * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively) + * - sets the active object in case it is not set or in case there is a single active object left under active selection. + * --- + * - If the active object is the active selection we add/remove `target` from it + * - If not, add the active object and `target` to the active selection and make it the active object. + * @private + * @param {TPointerEvent} e Event object + * @param {FabricObject} target target of event to select/deselect + * @returns true if grouping occurred + */ + handleMultiSelection(e, target) { + const activeObject = this._activeObject; + const isAS = isActiveSelection(activeObject); + if ( + // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection. + !!activeObject && this._isSelectionKeyPressed(e) && this.selection && + // on top of that the user also has to hit a target that is selectable. + !!target && target.selectable && ( + // group target and active object only if they are different objects + // else we try to find a subtarget of `ActiveSelection` + activeObject !== target || isAS) && ( + // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection` + // if it is then we want to remove `target` from it + isAS || !target.isDescendantOf(activeObject) && !activeObject.isDescendantOf(target)) && + // target accepts selection + !target.onSelect({ + e + }) && + // make sure we are not on top of a control + !activeObject.getActiveControl()) { + if (isAS) { + const prevActiveObjects = activeObject.getObjects(); + if (target === activeObject) { + const pointer = this.getViewportPoint(e); + target = + // first search active objects for a target to remove + this.searchPossibleTargets(prevActiveObjects, pointer) || + // if not found, search under active selection for a target to add + // `prevActiveObjects` will be searched but we already know they will not be found + this.searchPossibleTargets(this._objects, pointer); + // if nothing is found bail out + if (!target || !target.selectable) { + return false; + } + } + if (target.group === activeObject) { + // `target` is part of active selection => remove it + activeObject.remove(target); + this._hoveredTarget = target; + this._hoveredTargets = [...this.targets]; + // if after removing an object we are left with one only... + if (activeObject.size() === 1) { + // activate last remaining object + // deselecting the active selection will remove the remaining object from it + this._setActiveObject(activeObject.item(0), e); + } + } else { + // `target` isn't part of active selection => add it + activeObject.multiSelectAdd(target); + this._hoveredTarget = activeObject; + this._hoveredTargets = [...this.targets]; + } + this._fireSelectionEvents(prevActiveObjects, e); + } else { + activeObject.exitEditing && activeObject.exitEditing(); + // add the active object and the target to the active selection and set it as the active object + const klass = classRegistry.getClass('ActiveSelection'); + const newActiveSelection = new klass([], { + /** + * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd} + * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref + */ + canvas: this + }); + newActiveSelection.multiSelectAdd(activeObject, target); + this._hoveredTarget = newActiveSelection; + // ISSUE 4115: should we consider subTargets here? + // this._hoveredTargets = []; + // this._hoveredTargets = this.targets.concat(); + this._setActiveObject(newActiveSelection, e); + this._fireSelectionEvents([activeObject], e); + } + return true; + } + return false; + } + + /** + * ## Handles selection + * - selects objects that are contained in (and possibly intersecting) the selection bounding box + * - sets the active object + * --- + * runs on mouse up after a mouse move + */ + handleSelection(e) { + if (!this.selection || !this._groupSelector) { + return false; + } + const { + x, + y, + deltaX, + deltaY + } = this._groupSelector, + point1 = new Point(x, y), + point2 = point1.add(new Point(deltaX, deltaY)), + tl = point1.min(point2), + br = point1.max(point2), + size = br.subtract(tl); + const collectedObjects = this.collectObjects({ + left: tl.x, + top: tl.y, + width: size.x, + height: size.y + }, { + includeIntersecting: !this.selectionFullyContained + }); + const objects = + // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down + // should it be handled as is? + point1.eq(point2) ? collectedObjects[0] ? [collectedObjects[0]] : [] : collectedObjects.length > 1 ? collectedObjects.filter(object => !object.onSelect({ + e + })).reverse() : + // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case + collectedObjects; + + // set active object + if (objects.length === 1) { + // set as active object + this.setActiveObject(objects[0], e); + } else if (objects.length > 1) { + // add to active selection and make it the active object + const klass = classRegistry.getClass('ActiveSelection'); + this.setActiveObject(new klass(objects, { + canvas: this + }), e); + } + + // cleanup + this._groupSelector = null; + return true; + } + + /** + * @override clear {@link textEditingManager} + */ + clear() { + this.textEditingManager.clear(); + super.clear(); + } + + /** + * @override clear {@link textEditingManager} + */ + destroy() { + this.removeListeners(); + this.textEditingManager.dispose(); + super.destroy(); + } +}; + +const linearDefaultCoords = { + x1: 0, + y1: 0, + x2: 0, + y2: 0 +}; +const radialDefaultCoords = _objectSpread2(_objectSpread2({}, linearDefaultCoords), {}, { + r1: 0, + r2: 0 +}); + +/** + * + * @param value value to check if NaN + * @param [valueIfNaN] + * @returns `fallback` is `value is NaN + */ +const ifNaN = (value, valueIfNaN) => { + return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value; +}; + +const RE_PERCENT = /^(\d+\.\d+)%|(\d+)%$/; +function isPercent(value) { + return value && RE_PERCENT.test(value); +} + +/** + * + * @param value + * @param valueIfNaN + * @returns ∈ [0, 1] + */ +function parsePercent(value, valueIfNaN) { + const parsed = typeof value === 'number' ? value : typeof value === 'string' ? parseFloat(value) / (isPercent(value) ? 100 : 1) : NaN; + return capValue(0, ifNaN(parsed, valueIfNaN), 1); +} + +const RE_KEY_VALUE_PAIRS = /\s*;\s*/; +const RE_KEY_VALUE = /\s*:\s*/; +function parseColorStop(el, multiplier) { + let colorValue, opacity; + const style = el.getAttribute('style'); + if (style) { + const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS); + if (keyValuePairs[keyValuePairs.length - 1] === '') { + keyValuePairs.pop(); + } + for (let i = keyValuePairs.length; i--;) { + const [key, value] = keyValuePairs[i].split(RE_KEY_VALUE).map(s => s.trim()); + if (key === 'stop-color') { + colorValue = value; + } else if (key === 'stop-opacity') { + opacity = value; + } + } + } + const color = new Color(colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)'); + return { + offset: parsePercent(el.getAttribute('offset'), 0), + color: color.toRgb(), + opacity: ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) * color.getAlpha() * multiplier + }; +} +function parseColorStops(el, opacityAttr) { + const colorStops = [], + colorStopEls = el.getElementsByTagName('stop'), + multiplier = parsePercent(opacityAttr, 1); + for (let i = colorStopEls.length; i--;) { + colorStops.push(parseColorStop(colorStopEls[i], multiplier)); + } + return colorStops; +} + +function parseType(el) { + return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT' ? 'linear' : 'radial'; +} +function parseGradientUnits(el) { + return el.getAttribute('gradientUnits') === 'userSpaceOnUse' ? 'pixels' : 'percentage'; +} + +function convertPercentUnitsToValues(valuesToConvert, _ref) { + let { + width, + height, + gradientUnits + } = _ref; + let finalValue; + return Object.keys(valuesToConvert).reduce((acc, prop) => { + const propValue = valuesToConvert[prop]; + if (propValue === 'Infinity') { + finalValue = 1; + } else if (propValue === '-Infinity') { + finalValue = 0; + } else { + finalValue = typeof propValue === 'string' ? parseFloat(propValue) : propValue; + if (typeof propValue === 'string' && isPercent(propValue)) { + finalValue *= 0.01; + if (gradientUnits === 'pixels') { + // then we need to fix those percentages here in svg parsing + if (prop === 'x1' || prop === 'x2' || prop === 'r2') { + finalValue *= width; + } + if (prop === 'y1' || prop === 'y2') { + finalValue *= height; + } + } + } + } + acc[prop] = finalValue; + return acc; + }, {}); +} +function getValue(el, key) { + return el.getAttribute(key); +} +function parseLinearCoords(el) { + return { + x1: getValue(el, 'x1') || 0, + y1: getValue(el, 'y1') || 0, + x2: getValue(el, 'x2') || '100%', + y2: getValue(el, 'y2') || 0 + }; +} +function parseRadialCoords(el) { + return { + x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%', + y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%', + r1: 0, + x2: getValue(el, 'cx') || '50%', + y2: getValue(el, 'cy') || '50%', + r2: getValue(el, 'r') || '50%' + }; +} +function parseCoords(el, size) { + return convertPercentUnitsToValues(parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el), _objectSpread2(_objectSpread2({}, size), {}, { + gradientUnits: parseGradientUnits(el) + })); +} + +/** + * Gradient class + * @class Gradient + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients} + */ +class Gradient { + constructor(options) { + const { + type = 'linear', + gradientUnits = 'pixels', + coords = {}, + colorStops = [], + offsetX = 0, + offsetY = 0, + gradientTransform, + id + } = options || {}; + Object.assign(this, { + type, + gradientUnits, + coords: _objectSpread2(_objectSpread2({}, type === 'radial' ? radialDefaultCoords : linearDefaultCoords), coords), + colorStops, + offsetX, + offsetY, + gradientTransform, + id: id ? "".concat(id, "_").concat(uid()) : uid() + }); + } + + /** + * Adds another colorStop + * @param {Record} colorStop Object with offset and color + * @return {Gradient} thisArg + */ + addColorStop(colorStops) { + for (const position in colorStops) { + const color = new Color(colorStops[position]); + this.colorStops.push({ + offset: parseFloat(position), + color: color.toRgb(), + opacity: color.getAlpha() + }); + } + return this; + } + + /** + * Returns object representation of a gradient + * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {object} + */ + toObject(propertiesToInclude) { + return _objectSpread2(_objectSpread2({}, pick(this, propertiesToInclude)), {}, { + type: this.type, + coords: _objectSpread2({}, this.coords), + colorStops: this.colorStops.map(colorStop => _objectSpread2({}, colorStop)), + offsetX: this.offsetX, + offsetY: this.offsetY, + gradientUnits: this.gradientUnits, + gradientTransform: this.gradientTransform ? [...this.gradientTransform] : undefined + }); + } + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of an gradient + * @param {FabricObject} object Object to create a gradient for + * @return {String} SVG representation of an gradient (linear/radial) + */ + toSVG(object) { + let { + additionalTransform: preTransform + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const markup = [], + transform = this.gradientTransform ? this.gradientTransform.concat() : iMatrix.concat(), + gradientUnits = this.gradientUnits === 'pixels' ? 'userSpaceOnUse' : 'objectBoundingBox'; + // colorStops must be sorted ascending, and guarded against deep mutations + const colorStops = this.colorStops.map(colorStop => _objectSpread2({}, colorStop)).sort((a, b) => { + return a.offset - b.offset; + }); + let offsetX = -this.offsetX, + offsetY = -this.offsetY; + if (gradientUnits === 'objectBoundingBox') { + offsetX /= object.width; + offsetY /= object.height; + } else { + offsetX += object.width / 2; + offsetY += object.height / 2; + } + // todo what about polygon/polyline? + if (isPath(object) && this.gradientUnits !== 'percentage') { + offsetX -= object.pathOffset.x; + offsetY -= object.pathOffset.y; + } + transform[4] -= offsetX; + transform[5] -= offsetY; + const commonAttributes = ["id=\"SVGID_".concat(this.id, "\""), "gradientUnits=\"".concat(gradientUnits, "\""), "gradientTransform=\"".concat(preTransform ? preTransform + ' ' : '').concat(matrixToSVG(transform), "\""), ''].join(' '); + if (this.type === 'linear') { + const { + x1, + y1, + x2, + y2 + } = this.coords; + markup.push('\n'); + } else if (this.type === 'radial') { + const { + x1, + y1, + x2, + y2, + r1, + r2 + } = this.coords; + const needsSwap = r1 > r2; + // svg radial gradient has just 1 radius. the biggest. + markup.push('\n'); + if (needsSwap) { + // svg goes from internal to external radius. if radius are inverted, swap color stops. + colorStops.reverse(); // mutates array + colorStops.forEach(colorStop => { + colorStop.offset = 1 - colorStop.offset; + }); + } + const minRadius = Math.min(r1, r2); + if (minRadius > 0) { + // i have to shift all colorStops and add new one in 0. + const maxRadius = Math.max(r1, r2), + percentageShift = minRadius / maxRadius; + colorStops.forEach(colorStop => { + colorStop.offset += percentageShift * (1 - colorStop.offset); + }); + } + } + colorStops.forEach(_ref => { + let { + color, + offset, + opacity + } = _ref; + markup.push('\n'); + }); + markup.push(this.type === 'linear' ? '' : '', '\n'); + return markup.join(''); + } + /* _TO_SVG_END_ */ + + /** + * Returns an instance of CanvasGradient + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {CanvasGradient} + */ + toLive(ctx) { + const { + x1, + y1, + x2, + y2, + r1, + r2 + } = this.coords; + const gradient = this.type === 'linear' ? ctx.createLinearGradient(x1, y1, x2, y2) : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2); + this.colorStops.forEach(_ref2 => { + let { + color, + opacity, + offset + } = _ref2; + gradient.addColorStop(offset, typeof opacity !== 'undefined' ? new Color(color).setAlpha(opacity).toRgba() : color); + }); + return gradient; + } + static async fromObject(options) { + const { + colorStops, + gradientTransform + } = options; + return new this(_objectSpread2(_objectSpread2({}, options), {}, { + colorStops: colorStops ? colorStops.map(colorStop => _objectSpread2({}, colorStop)) : undefined, + gradientTransform: gradientTransform ? [...gradientTransform] : undefined + })); + } + + /* _FROM_SVG_START_ */ + /** + * Returns {@link Gradient} instance from an SVG element + * @static + * @memberOf Gradient + * @param {SVGGradientElement} el SVG gradient element + * @param {FabricObject} instance + * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity. + * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients + * that uses gradientUnits as 'userSpaceOnUse' and percentages. + * @return {Gradient} Gradient instance + * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement + * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement + * + * @example + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + * OR + * + * + * + * + * + * + * + */ + static fromElement(el, instance, svgOptions) { + const gradientUnits = parseGradientUnits(el); + const center = instance._findCenterFromElement(); + return new this(_objectSpread2({ + id: el.getAttribute('id') || undefined, + type: parseType(el), + coords: parseCoords(el, { + width: svgOptions.viewBoxWidth || svgOptions.width, + height: svgOptions.viewBoxHeight || svgOptions.height + }), + colorStops: parseColorStops(el, svgOptions.opacity), + gradientUnits, + gradientTransform: parseTransformAttribute(el.getAttribute('gradientTransform') || '') + }, gradientUnits === 'pixels' ? { + offsetX: instance.width / 2 - center.x, + offsetY: instance.height / 2 - center.y + } : { + offsetX: 0, + offsetY: 0 + })); + } + /* _FROM_SVG_END_ */ +} +/** + * Horizontal offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ +/** + * Vertical offset for aligning gradients coming from SVG when outside pathgroups + * @type Number + * @default 0 + */ +/** + * A transform matrix to apply to the gradient before painting. + * Imported from svg gradients, is not applied with the current transform in the center. + * Before this transform is applied, the origin point is at the top left corner of the object + * plus the addition of offsetY and offsetX. + * @type Number[] + * @default null + */ +/** + * coordinates units for coords. + * If `pixels`, the number of coords are in the same unit of width / height. + * If set as `percentage` the coords are still a number, but 1 means 100% of width + * for the X and 100% of the height for the y. It can be bigger than 1 and negative. + * allowed values pixels or percentage. + * @type GradientUnits + * @default 'pixels' + */ +/** + * Gradient type linear or radial + * @type GradientType + * @default 'linear' + */ +/** + * Defines how the gradient is located in space and spread + * @type GradientCoords + */ +/** + * Defines how many colors a gradient has and how they are located on the axis + * defined by coords + * @type GradientCoords + */ +/** + * If true, this object will not be exported during the serialization of a canvas + * @type boolean + */ +/** + * ID used for SVG export functionalities + * @type number | string + */ +_defineProperty(Gradient, "type", 'Gradient'); +classRegistry.setClass(Gradient, 'gradient'); +classRegistry.setClass(Gradient, 'linear'); +classRegistry.setClass(Gradient, 'radial'); + +const _excluded$8 = ["type", "source", "patternTransform"]; + +/** + * @see {@link http://fabricjs.com/patterns demo} + * @see {@link http://fabricjs.com/dynamic-patterns demo} + */ +class Pattern { + /** + * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern' + * or utils like isPattern, or instance of to indentify a pattern in your code. + * Will be removed in future versiones + * @TODO add sustainable warning message + * @type string + * @deprecated + */ + get type() { + return 'pattern'; + } + set type(value) { + log('warn', 'Setting type has no effect', value); + } + + /** + * @type PatternRepeat + * @defaults + */ + + /** + * transform matrix to change the pattern, imported from svgs. + * @todo verify if using the identity matrix as default makes the rest of the code more easy + * @type Array + * @default + */ + + /** + * The actual pixel source of the pattern + */ + + /** + * If true, this object will not be exported during the serialization of a canvas + * @type boolean + */ + + /** + * ID used for SVG export functionalities + * @type number + */ + + /** + * Constructor + * @param {Object} [options] Options object + * @param {option.source} [source] the pattern source, eventually empty or a drawable + */ + constructor(options) { + _defineProperty(this, "repeat", 'repeat'); + /** + * Pattern horizontal offset from object's left/top corner + * @type Number + * @default + */ + _defineProperty(this, "offsetX", 0); + /** + * Pattern vertical offset from object's left/top corner + * @type Number + * @default + */ + _defineProperty(this, "offsetY", 0); + /** + * @type TCrossOrigin + * @default + */ + _defineProperty(this, "crossOrigin", ''); + this.id = uid(); + Object.assign(this, options); + } + + /** + * @returns true if {@link source} is an element + */ + isImageSource() { + return !!this.source && typeof this.source.src === 'string'; + } + + /** + * @returns true if {@link source} is a element + */ + isCanvasSource() { + return !!this.source && !!this.source.toDataURL; + } + sourceToString() { + return this.isImageSource() ? this.source.src : this.isCanvasSource() ? this.source.toDataURL() : ''; + } + + /** + * Returns an instance of CanvasPattern + * @param {CanvasRenderingContext2D} ctx Context to create pattern + * @return {CanvasPattern} + */ + toLive(ctx) { + if ( + // if the image failed to load, return, and allow rest to continue loading + !this.source || + // if an image + this.isImageSource() && (!this.source.complete || this.source.naturalWidth === 0 || this.source.naturalHeight === 0)) { + return null; + } + return ctx.createPattern(this.source, this.repeat); + } + + /** + * Returns object representation of a pattern + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {object} Object representation of a pattern instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const { + repeat, + crossOrigin + } = this; + return _objectSpread2(_objectSpread2({}, pick(this, propertiesToInclude)), {}, { + type: 'pattern', + source: this.sourceToString(), + repeat, + crossOrigin, + offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS), + offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS), + patternTransform: this.patternTransform ? [...this.patternTransform] : null + }); + } + + /* _TO_SVG_START_ */ + /** + * Returns SVG representation of a pattern + */ + toSVG(_ref) { + let { + width, + height + } = _ref; + const { + source: patternSource, + repeat, + id + } = this, + patternOffsetX = ifNaN(this.offsetX / width, 0), + patternOffsetY = ifNaN(this.offsetY / height, 0), + patternWidth = repeat === 'repeat-y' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetX || 0) : ifNaN(patternSource.width / width, 0), + patternHeight = repeat === 'repeat-x' || repeat === 'no-repeat' ? 1 + Math.abs(patternOffsetY || 0) : ifNaN(patternSource.height / height, 0); + return [""), ""), "", ''].join('\n'); + } + /* _TO_SVG_END_ */ + + static async fromObject(_ref2, options) { + let { + type, + source, + patternTransform + } = _ref2, + otherOptions = _objectWithoutProperties(_ref2, _excluded$8); + const img = await loadImage(source, _objectSpread2(_objectSpread2({}, options), {}, { + crossOrigin: otherOptions.crossOrigin + })); + return new this(_objectSpread2(_objectSpread2({}, otherOptions), {}, { + patternTransform: patternTransform && patternTransform.slice(0), + source: img + })); + } +} +_defineProperty(Pattern, "type", 'Pattern'); +classRegistry.setClass(Pattern); +// kept for compatibility reason +classRegistry.setClass(Pattern, 'pattern'); + +/** + * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo} + */ +class BaseBrush { + /** + * @todo add type + */ + + constructor(canvas) { + /** + * Color of a brush + * @type String + * @default + */ + _defineProperty(this, "color", 'rgb(0, 0, 0)'); + /** + * Width of a brush, has to be a Number, no string literals + * @type Number + * @default + */ + _defineProperty(this, "width", 1); + /** + * Shadow object representing shadow of this shape. + * Backwards incompatibility note: This property replaces "shadowColor" (String), "shadowOffsetX" (Number), + * "shadowOffsetY" (Number) and "shadowBlur" (Number) since v1.2.12 + * @type Shadow + * @default + */ + _defineProperty(this, "shadow", null); + /** + * Line endings style of a brush (one of "butt", "round", "square") + * @type String + * @default + */ + _defineProperty(this, "strokeLineCap", 'round'); + /** + * Corner style of a brush (one of "bevel", "round", "miter") + * @type String + * @default + */ + _defineProperty(this, "strokeLineJoin", 'round'); + /** + * Maximum miter length (used for strokeLineJoin = "miter") of a brush's + * @type Number + * @default + */ + _defineProperty(this, "strokeMiterLimit", 10); + /** + * Stroke Dash Array. + * @type Array + * @default + */ + _defineProperty(this, "strokeDashArray", null); + /** + * When `true`, the free drawing is limited to the whiteboard size. Default to false. + * @type Boolean + * @default false + */ + _defineProperty(this, "limitedToCanvasSize", false); + this.canvas = canvas; + } + + /** + * @returns true if brush should continue blocking interaction + */ + + /** + * Sets brush styles + * @private + * @param {CanvasRenderingContext2D} ctx + */ + _setBrushStyles(ctx) { + ctx.strokeStyle = this.color; + ctx.lineWidth = this.width; + ctx.lineCap = this.strokeLineCap; + ctx.miterLimit = this.strokeMiterLimit; + ctx.lineJoin = this.strokeLineJoin; + ctx.setLineDash(this.strokeDashArray || []); + } + + /** + * Sets the transformation on given context + * @param {CanvasRenderingContext2D} ctx context to render on + * @private + */ + _saveAndTransform(ctx) { + const v = this.canvas.viewportTransform; + ctx.save(); + ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]); + } + needsFullRender() { + const color = new Color(this.color); + return color.getAlpha() < 1 || !!this.shadow; + } + + /** + * Sets brush shadow styles + * @private + */ + _setShadow() { + if (!this.shadow || !this.canvas) { + return; + } + const canvas = this.canvas, + shadow = this.shadow, + ctx = canvas.contextTop, + zoom = canvas.getZoom() * canvas.getRetinaScaling(); + ctx.shadowColor = shadow.color; + ctx.shadowBlur = shadow.blur * zoom; + ctx.shadowOffsetX = shadow.offsetX * zoom; + ctx.shadowOffsetY = shadow.offsetY * zoom; + } + + /** + * Removes brush shadow styles + * @private + */ + _resetShadow() { + const ctx = this.canvas.contextTop; + ctx.shadowColor = ''; + ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0; + } + + /** + * Check is pointer is outside canvas boundaries + * @param {Object} pointer + * @private + */ + _isOutSideCanvas(pointer) { + return pointer.x < 0 || pointer.x > this.canvas.getWidth() || pointer.y < 0 || pointer.y > this.canvas.getHeight(); + } +} + +const _excluded$7 = ["path", "left", "top"], + _excluded2$2 = ["d"]; +class Path extends FabricObject { + /** + * Constructor + * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding "command" tokens) + * @param {Partial} [options] Options object + * @return {Path} thisArg + */ + constructor(path) { + let _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + { + path: _, + left, + top + } = _ref, + options = _objectWithoutProperties(_ref, _excluded$7); + super(); + Object.assign(this, Path.ownDefaults); + this.setOptions(options); + this._setPath(path || [], true); + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + + /** + * @private + * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding "command" tokens) + * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box + * @returns {Point} top left position of the bounding box, useful for complementary positioning + */ + _setPath(path, adjustPosition) { + this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path)); + this.setBoundingBox(adjustPosition); + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates, by look at the polyline/polygon points. + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + const bbox = this._calcBoundsFromPath(); + return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render path on + */ + _renderPathCommands(ctx) { + const l = -this.pathOffset.x, + t = -this.pathOffset.y; + ctx.beginPath(); + for (const command of this.path) { + switch (command[0] // first letter + ) { + case 'L': + // lineto, absolute + ctx.lineTo(command[1] + l, command[2] + t); + break; + case 'M': + // moveTo, absolute + ctx.moveTo(command[1] + l, command[2] + t); + break; + case 'C': + // bezierCurveTo, absolute + ctx.bezierCurveTo(command[1] + l, command[2] + t, command[3] + l, command[4] + t, command[5] + l, command[6] + t); + break; + case 'Q': + // quadraticCurveTo, absolute + ctx.quadraticCurveTo(command[1] + l, command[2] + t, command[3] + l, command[4] + t); + break; + case 'Z': + ctx.closePath(); + break; + } + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render path on + */ + _render(ctx) { + this._renderPathCommands(ctx); + this._renderPaintInOrder(ctx); + } + + /** + * Returns string representation of an instance + * @return {string} string representation of an instance + */ + toString() { + return "#"); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), {}, { + path: this.path.map(pathCmd => pathCmd.slice()) + }); + } + + /** + * Returns dataless object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toDatalessObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const o = this.toObject(propertiesToInclude); + if (this.sourcePath) { + delete o.path; + o.sourcePath = this.sourcePath; + } + return o; + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const path = joinPath(this.path, config.NUM_FRACTION_DIGITS); + return ['\n")]; + } + + /** + * @private + * @return the path command's translate transform attribute + */ + _getOffsetTransform() { + const digits = config.NUM_FRACTION_DIGITS; + return " translate(".concat(toFixed(-this.pathOffset.x, digits), ", ").concat(toFixed(-this.pathOffset.y, digits), ")"); + } + + /** + * Returns svg clipPath representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {string} svg representation of an instance + */ + toClipPathSVG(reviver) { + const additionalTransform = this._getOffsetTransform(); + return '\t' + this._createBaseClipPathSVGMarkup(this._toSVG(), { + reviver, + additionalTransform: additionalTransform + }); + } + + /** + * Returns svg representation of an instance + * @param {Function} [reviver] Method for further parsing of svg representation. + * @return {string} svg representation of an instance + */ + toSVG(reviver) { + const additionalTransform = this._getOffsetTransform(); + return this._createBaseSVGMarkup(this._toSVG(), { + reviver, + additionalTransform: additionalTransform + }); + } + + /** + * Returns number representation of an instance complexity + * @return {number} complexity of this instance + */ + complexity() { + return this.path.length; + } + setDimensions() { + this.setBoundingBox(); + } + setBoundingBox(adjustPosition) { + const { + width, + height, + pathOffset + } = this._calcDimensions(); + this.set({ + width, + height, + pathOffset + }); + // using pathOffset because it match the use case. + // if pathOffset change here we need to use left + width/2 , top + height/2 + adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER); + } + _calcBoundsFromPath() { + const bounds = []; + let subpathStartX = 0, + subpathStartY = 0, + x = 0, + // current x + y = 0; // current y + + for (const command of this.path) { + // current instruction + switch (command[0] // first letter + ) { + case 'L': + // lineto, absolute + x = command[1]; + y = command[2]; + bounds.push({ + x: subpathStartX, + y: subpathStartY + }, { + x, + y + }); + break; + case 'M': + // moveTo, absolute + x = command[1]; + y = command[2]; + subpathStartX = x; + subpathStartY = y; + break; + case 'C': + // bezierCurveTo, absolute + bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[3], command[4], command[5], command[6])); + x = command[5]; + y = command[6]; + break; + case 'Q': + // quadraticCurveTo, absolute + bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[1], command[2], command[3], command[4])); + x = command[3]; + y = command[4]; + break; + case 'Z': + x = subpathStartX; + y = subpathStartY; + break; + } + } + return makeBoundingBoxFromPoints(bounds); + } + + /** + * @private + */ + _calcDimensions() { + const bbox = this._calcBoundsFromPath(); + return _objectSpread2(_objectSpread2({}, bbox), {}, { + pathOffset: new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2) + }); + } + + /** + * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`) + * @static + * @memberOf Path + * @see http://www.w3.org/TR/SVG/paths.html#PathElement + */ + + /** + * Creates an instance of Path from an object + * @static + * @memberOf Path + * @param {Object} object + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(object, { + extraParam: 'path' + }); + } + + /** + * Creates an instance of Path from an SVG element + * @static + * @memberOf Path + * @param {HTMLElement} element to parse + * @param {Partial} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + d + } = _parseAttributes, + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded2$2); + return new this(d, _objectSpread2(_objectSpread2(_objectSpread2({}, parsedAttributes), options), {}, { + // we pass undefined to instruct the constructor to position the object using the bbox + left: undefined, + top: undefined + })); + } +} +/** + * Array of path points + * @type Array + * @default + */ +_defineProperty(Path, "type", 'Path'); +_defineProperty(Path, "cacheProperties", [...cacheProperties, 'path', 'fillRule']); +_defineProperty(Path, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'd']); +classRegistry.setClass(Path); +classRegistry.setSVGClass(Path); + +/* _FROM_SVG_START_ */ + +/** + * @private + * @param {TSimplePathData} pathData SVG path commands + * @returns {boolean} + */ +function isEmptySVGPath(pathData) { + return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0'; +} +class PencilBrush extends BaseBrush { + constructor(canvas) { + super(canvas); + /** + * Discard points that are less than `decimate` pixel distant from each other + * @type Number + * @default 0.4 + */ + _defineProperty(this, "decimate", 0.4); + /** + * Draws a straight line between last recorded point to current pointer + * Used for `shift` functionality + * + * @type boolean + * @default false + */ + _defineProperty(this, "drawStraightLine", false); + /** + * The event modifier key that makes the brush draw a straight line. + * If `null` or 'none' or any other string that is not a modifier key the feature is disabled. + * @type {ModifierKey | undefined | null} + */ + _defineProperty(this, "straightLineKey", 'shiftKey'); + this._points = []; + this._hasStraightLine = false; + } + needsFullRender() { + return super.needsFullRender() || this._hasStraightLine; + } + static drawSegment(ctx, p1, p2) { + const midPoint = p1.midPointFrom(p2); + ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); + return midPoint; + } + + /** + * Invoked on mouse down + * @param {Point} pointer + */ + onMouseDown(pointer, _ref) { + let { + e + } = _ref; + if (!this.canvas._isMainEvent(e)) { + return; + } + this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey]; + this._prepareForDrawing(pointer); + // capture coordinates immediately + // this allows to draw dots (when movement never occurs) + this._addPoint(pointer); + this._render(); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer, _ref2) { + let { + e + } = _ref2; + if (!this.canvas._isMainEvent(e)) { + return; + } + this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey]; + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + if (this._addPoint(pointer) && this._points.length > 1) { + if (this.needsFullRender()) { + // redraw curve + // clear top canvas + this.canvas.clearContext(this.canvas.contextTop); + this._render(); + } else { + const points = this._points, + length = points.length, + ctx = this.canvas.contextTop; + // draw the curve update + this._saveAndTransform(ctx); + if (this.oldEnd) { + ctx.beginPath(); + ctx.moveTo(this.oldEnd.x, this.oldEnd.y); + } + this.oldEnd = PencilBrush.drawSegment(ctx, points[length - 2], points[length - 1]); + ctx.stroke(); + ctx.restore(); + } + } + } + + /** + * Invoked on mouse up + */ + onMouseUp(_ref3) { + let { + e + } = _ref3; + if (!this.canvas._isMainEvent(e)) { + return true; + } + this.drawStraightLine = false; + this.oldEnd = undefined; + this._finalizeAndAddPath(); + return false; + } + + /** + * @private + * @param {Point} pointer Actual mouse position related to the canvas. + */ + _prepareForDrawing(pointer) { + this._reset(); + this._addPoint(pointer); + this.canvas.contextTop.moveTo(pointer.x, pointer.y); + } + + /** + * @private + * @param {Point} point Point to be added to points array + */ + _addPoint(point) { + if (this._points.length > 1 && point.eq(this._points[this._points.length - 1])) { + return false; + } + if (this.drawStraightLine && this._points.length > 1) { + this._hasStraightLine = true; + this._points.pop(); + } + this._points.push(point); + return true; + } + + /** + * Clear points array and set contextTop canvas style. + * @private + */ + _reset() { + this._points = []; + this._setBrushStyles(this.canvas.contextTop); + this._setShadow(); + this._hasStraightLine = false; + } + + /** + * Draw a smooth path on the topCanvas using quadraticCurveTo + * @private + * @param {CanvasRenderingContext2D} [ctx] + */ + _render() { + let ctx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.canvas.contextTop; + let p1 = this._points[0], + p2 = this._points[1]; + this._saveAndTransform(ctx); + ctx.beginPath(); + //if we only have 2 points in the path and they are the same + //it means that the user only clicked the canvas without moving the mouse + //then we should be drawing a dot. A path isn't drawn between two identical dots + //that's why we set them apart a bit + if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) { + const width = this.width / 1000; + p1.x -= width; + p2.x += width; + } + ctx.moveTo(p1.x, p1.y); + for (let i = 1; i < this._points.length; i++) { + // we pick the point between pi + 1 & pi + 2 as the + // end point and p1 as our control point. + PencilBrush.drawSegment(ctx, p1, p2); + p1 = this._points[i]; + p2 = this._points[i + 1]; + } + // Draw last line as a straight line while + // we wait for the next point to be able to calculate + // the bezier control point + ctx.lineTo(p1.x, p1.y); + ctx.stroke(); + ctx.restore(); + } + + /** + * Converts points to SVG path + * @param {Point[]} points Array of points + * @return {TSimplePathData} SVG path commands + */ + convertPointsToSVGPath(points) { + const correction = this.width / 1000; + return getSmoothPathFromPoints(points, correction); + } + + /** + * Creates a Path object to add on canvas + * @param {TSimplePathData} pathData Path data + * @return {Path} Path to add on canvas + */ + createPath(pathData) { + const path = new Path(pathData, { + fill: null, + stroke: this.color, + strokeWidth: this.width, + strokeLineCap: this.strokeLineCap, + strokeMiterLimit: this.strokeMiterLimit, + strokeLineJoin: this.strokeLineJoin, + strokeDashArray: this.strokeDashArray + }); + if (this.shadow) { + this.shadow.affectStroke = true; + path.shadow = new Shadow(this.shadow); + } + return path; + } + + /** + * Decimate points array with the decimate value + */ + decimatePoints(points, distance) { + if (points.length <= 2) { + return points; + } + let lastPoint = points[0], + cDistance; + const zoom = this.canvas.getZoom(), + adjustedDistance = Math.pow(distance / zoom, 2), + l = points.length - 1, + newPoints = [lastPoint]; + for (let i = 1; i < l - 1; i++) { + cDistance = Math.pow(lastPoint.x - points[i].x, 2) + Math.pow(lastPoint.y - points[i].y, 2); + if (cDistance >= adjustedDistance) { + lastPoint = points[i]; + newPoints.push(lastPoint); + } + } + // Add the last point from the original line to the end of the array. + // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point. + newPoints.push(points[l]); + return newPoints; + } + + /** + * On mouseup after drawing the path on contextTop canvas + * we use the points captured to create an new Path object + * and add it to the canvas. + */ + _finalizeAndAddPath() { + const ctx = this.canvas.contextTop; + ctx.closePath(); + if (this.decimate) { + this._points = this.decimatePoints(this._points, this.decimate); + } + const pathData = this.convertPointsToSVGPath(this._points); + if (isEmptySVGPath(pathData)) { + // do not create 0 width/height paths, as they are + // rendered inconsistently across browsers + // Firefox 4, for example, renders a dot, + // whereas Chrome 10 renders nothing + this.canvas.requestRenderAll(); + return; + } + const path = this.createPath(pathData); + this.canvas.clearContext(this.canvas.contextTop); + this.canvas.fire('before:path:created', { + path: path + }); + this.canvas.add(path); + this.canvas.requestRenderAll(); + path.setCoords(); + this._resetShadow(); + + // fire event 'path' created + this.canvas.fire('path:created', { + path: path + }); + } +} + +const _excluded$6 = ["left", "top", "radius"]; +const CIRCLE_PROPS = ['radius', 'startAngle', 'endAngle', 'counterClockwise']; +const circleDefaultValues = { + radius: 0, + startAngle: 0, + endAngle: 360, + counterClockwise: false +}; +class Circle extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Circle.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Circle.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {String} key + * @param {*} value + */ + _set(key, value) { + super._set(key, value); + if (key === 'radius') { + this.setRadius(value); + } + return this; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + */ + _render(ctx) { + ctx.beginPath(); + ctx.arc(0, 0, this.radius, degreesToRadians(this.startAngle), degreesToRadians(this.endAngle), this.counterClockwise); + this._renderPaintInOrder(ctx); + } + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusX() { + return this.get('radius') * this.get(SCALE_X); + } + + /** + * Returns vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRadiusY() { + return this.get('radius') * this.get(SCALE_Y); + } + + /** + * Sets radius of an object (and updates width accordingly) + */ + setRadius(value) { + this.radius = value; + this.set({ + width: value * 2, + height: value * 2 + }); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]); + } + + /* _TO_SVG_START_ */ + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const angle = (this.endAngle - this.startAngle) % 360; + if (angle === 0) { + return ['\n']; + } else { + const { + radius + } = this; + const start = degreesToRadians(this.startAngle), + end = degreesToRadians(this.endAngle), + startX = cos(start) * radius, + startY = sin(start) * radius, + endX = cos(end) * radius, + endY = sin(end) * radius, + largeFlag = angle > 180 ? 1 : 0, + sweepFlag = this.counterClockwise ? 0 : 1; + return ["\n']; + } + } + /* _TO_SVG_END_ */ + + /* _FROM_SVG_START_ */ + /** + * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement}) + * @static + * @memberOf Circle + * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement + */ + + /** + * Returns {@link Circle} instance from an SVG element + * @static + * @memberOf Circle + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Partial Circle object to default missing properties on the element. + * @throws {Error} If value of `r` attribute is missing or invalid + */ + static async fromElement(element, options, cssRules) { + const _ref = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + left = 0, + top = 0, + radius = 0 + } = _ref, + otherParsedAttributes = _objectWithoutProperties(_ref, _excluded$6); + + // this probably requires to be fixed for default origins not being top/left. + + return new this(_objectSpread2(_objectSpread2({}, otherParsedAttributes), {}, { + radius, + left: left - radius, + top: top - radius + })); + } + + /* _FROM_SVG_END_ */ + + /** + * @todo how do we declare this?? + */ + static fromObject(object) { + return super._fromObject(object); + } +} +_defineProperty(Circle, "type", 'Circle'); +_defineProperty(Circle, "cacheProperties", [...cacheProperties, ...CIRCLE_PROPS]); +_defineProperty(Circle, "ownDefaults", circleDefaultValues); +_defineProperty(Circle, "ATTRIBUTE_NAMES", ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES]); +classRegistry.setClass(Circle); +classRegistry.setSVGClass(Circle); + +class CircleBrush extends BaseBrush { + constructor(canvas) { + super(canvas); + /** + * Width of a brush + * @type Number + * @default + */ + _defineProperty(this, "width", 10); + this.points = []; + } + + /** + * Invoked inside on mouse down and mouse move + * @param {Point} pointer + */ + drawDot(pointer) { + const point = this.addPoint(pointer), + ctx = this.canvas.contextTop; + this._saveAndTransform(ctx); + this.dot(ctx, point); + ctx.restore(); + } + dot(ctx, point) { + ctx.fillStyle = point.fill; + ctx.beginPath(); + ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false); + ctx.closePath(); + ctx.fill(); + } + + /** + * Invoked on mouse down + */ + onMouseDown(pointer) { + this.points = []; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + this.drawDot(pointer); + } + + /** + * Render the full state of the brush + * @private + */ + _render() { + const ctx = this.canvas.contextTop, + points = this.points; + this._saveAndTransform(ctx); + for (let i = 0; i < points.length; i++) { + this.dot(ctx, points[i]); + } + ctx.restore(); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer) { + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + if (this.needsFullRender()) { + this.canvas.clearContext(this.canvas.contextTop); + this.addPoint(pointer); + this._render(); + } else { + this.drawDot(pointer); + } + } + + /** + * Invoked on mouse up + */ + onMouseUp() { + const originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + const circles = []; + for (let i = 0; i < this.points.length; i++) { + const point = this.points[i], + circle = new Circle({ + radius: point.radius, + left: point.x, + top: point.y, + originX: CENTER, + originY: CENTER, + fill: point.fill + }); + this.shadow && (circle.shadow = new Shadow(this.shadow)); + circles.push(circle); + } + const group = new Group(circles, { + canvas: this.canvas + }); + this.canvas.fire('before:path:created', { + path: group + }); + this.canvas.add(group); + this.canvas.fire('path:created', { + path: group + }); + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.requestRenderAll(); + } + + /** + * @param {Object} pointer + * @return {Point} Just added pointer point + */ + addPoint(_ref) { + let { + x, + y + } = _ref; + const pointerPoint = { + x, + y, + radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2, + fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba() + }; + this.points.push(pointerPoint); + return pointerPoint; + } +} + +/** + * + * @param rects + * @returns + */ +function getUniqueRects(rects) { + const uniqueRects = {}; + const uniqueRectsArray = []; + for (let i = 0, key; i < rects.length; i++) { + key = "".concat(rects[i].left).concat(rects[i].top); + if (!uniqueRects[key]) { + uniqueRects[key] = true; + uniqueRectsArray.push(rects[i]); + } + } + return uniqueRectsArray; +} +class SprayBrush extends BaseBrush { + /** + * Constructor + * @param {Canvas} canvas + * @return {SprayBrush} Instance of a spray brush + */ + constructor(canvas) { + super(canvas); + /** + * Width of a spray + * @type Number + * @default + */ + _defineProperty(this, "width", 10); + /** + * Density of a spray (number of dots per chunk) + * @type Number + * @default + */ + _defineProperty(this, "density", 20); + /** + * Width of spray dots + * @type Number + * @default + */ + _defineProperty(this, "dotWidth", 1); + /** + * Width variance of spray dots + * @type Number + * @default + */ + _defineProperty(this, "dotWidthVariance", 1); + /** + * Whether opacity of a dot should be random + * @type Boolean + * @default + */ + _defineProperty(this, "randomOpacity", false); + /** + * Whether overlapping dots (rectangles) should be removed (for performance reasons) + * @type Boolean + * @default + */ + _defineProperty(this, "optimizeOverlapping", true); + this.sprayChunks = []; + this.sprayChunk = []; + } + + /** + * Invoked on mouse down + * @param {Point} pointer + */ + onMouseDown(pointer) { + this.sprayChunks = []; + this.canvas.clearContext(this.canvas.contextTop); + this._setShadow(); + this.addSprayChunk(pointer); + this.renderChunck(this.sprayChunk); + } + + /** + * Invoked on mouse move + * @param {Point} pointer + */ + onMouseMove(pointer) { + if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) { + return; + } + this.addSprayChunk(pointer); + this.renderChunck(this.sprayChunk); + } + + /** + * Invoked on mouse up + */ + onMouseUp() { + const originalRenderOnAddRemove = this.canvas.renderOnAddRemove; + this.canvas.renderOnAddRemove = false; + const rects = []; + for (let i = 0; i < this.sprayChunks.length; i++) { + const sprayChunk = this.sprayChunks[i]; + for (let j = 0; j < sprayChunk.length; j++) { + const chunck = sprayChunk[j]; + const rect = new Rect({ + width: chunck.width, + height: chunck.width, + left: chunck.x + 1, + top: chunck.y + 1, + originX: CENTER, + originY: CENTER, + fill: this.color + }); + rects.push(rect); + } + } + const group = new Group(this.optimizeOverlapping ? getUniqueRects(rects) : rects, { + objectCaching: true, + subTargetCheck: false, + interactive: false + }); + this.shadow && group.set('shadow', new Shadow(this.shadow)); + this.canvas.fire('before:path:created', { + path: group + }); + this.canvas.add(group); + this.canvas.fire('path:created', { + path: group + }); + this.canvas.clearContext(this.canvas.contextTop); + this._resetShadow(); + this.canvas.renderOnAddRemove = originalRenderOnAddRemove; + this.canvas.requestRenderAll(); + } + renderChunck(sprayChunck) { + const ctx = this.canvas.contextTop; + ctx.fillStyle = this.color; + this._saveAndTransform(ctx); + for (let i = 0; i < sprayChunck.length; i++) { + const point = sprayChunck[i]; + ctx.globalAlpha = point.opacity; + ctx.fillRect(point.x, point.y, point.width, point.width); + } + ctx.restore(); + } + + /** + * Render all spray chunks + */ + _render() { + const ctx = this.canvas.contextTop; + ctx.fillStyle = this.color; + this._saveAndTransform(ctx); + for (let i = 0; i < this.sprayChunks.length; i++) { + this.renderChunck(this.sprayChunks[i]); + } + ctx.restore(); + } + + /** + * @param {Point} pointer + */ + addSprayChunk(pointer) { + this.sprayChunk = []; + const radius = this.width / 2; + for (let i = 0; i < this.density; i++) { + this.sprayChunk.push({ + x: getRandomInt(pointer.x - radius, pointer.x + radius), + y: getRandomInt(pointer.y - radius, pointer.y + radius), + width: this.dotWidthVariance ? getRandomInt( + // bottom clamp width to 1 + Math.max(1, this.dotWidth - this.dotWidthVariance), this.dotWidth + this.dotWidthVariance) : this.dotWidth, + opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1 + }); + } + this.sprayChunks.push(this.sprayChunk); + } +} + +class PatternBrush extends PencilBrush { + constructor(canvas) { + super(canvas); + } + getPatternSrc() { + const dotWidth = 20, + dotDistance = 5, + patternCanvas = createCanvasElement(), + patternCtx = patternCanvas.getContext('2d'); + patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; + if (patternCtx) { + patternCtx.fillStyle = this.color; + patternCtx.beginPath(); + patternCtx.arc(dotWidth / 2, dotWidth / 2, dotWidth / 2, 0, Math.PI * 2, false); + patternCtx.closePath(); + patternCtx.fill(); + } + return patternCanvas; + } + + /** + * Creates "pattern" instance property + * @param {CanvasRenderingContext2D} ctx + */ + getPattern(ctx) { + return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat'); + } + + /** + * Sets brush styles + * @param {CanvasRenderingContext2D} ctx + */ + _setBrushStyles(ctx) { + super._setBrushStyles(ctx); + const pattern = this.getPattern(ctx); + pattern && (ctx.strokeStyle = pattern); + } + + /** + * Creates path + */ + createPath(pathData) { + const path = super.createPath(pathData), + topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2); + path.stroke = new Pattern({ + source: this.source || this.getPatternSrc(), + offsetX: -topLeft.x, + offsetY: -topLeft.y + }); + return path; + } +} + +const _excluded$5 = ["x1", "y1", "x2", "y2"], + _excluded2$1 = ["x1", "y1", "x2", "y2"]; +// @TODO this code is terrible and Line should be a special case of polyline. + +const coordProps = ['x1', 'x2', 'y1', 'y2']; +class Line extends FabricObject { + /** + * Constructor + * @param {Array} [points] Array of points + * @param {Object} [options] Options object + * @return {Line} thisArg + */ + constructor() { + let [x1, y1, x2, y2] = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [0, 0, 0, 0]; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, Line.ownDefaults); + this.setOptions(options); + this.x1 = x1; + this.x2 = x2; + this.y1 = y1; + this.y2 = y2; + this._setWidthHeight(); + const { + left, + top + } = options; + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + + /** + * @private + * @param {Object} [options] Options + */ + _setWidthHeight() { + const { + x1, + y1, + x2, + y2 + } = this; + this.width = Math.abs(x2 - x1); + this.height = Math.abs(y2 - y1); + const { + left, + top, + width, + height + } = makeBoundingBoxFromPoints([{ + x: x1, + y: y1 + }, { + x: x2, + y: y2 + }]); + const position = new Point(left + width / 2, top + height / 2); + this.setPositionByOrigin(position, CENTER, CENTER); + } + + /** + * @private + * @param {String} key + * @param {*} value + */ + _set(key, value) { + super._set(key, value); + if (coordProps.includes(key)) { + // this doesn't make sense very much, since setting x1 when top or left + // are already set, is just going to show a strange result since the + // line will move way more than the developer expect. + // in fabric5 it worked only when the line didn't have extra transformations, + // in fabric6 too. With extra transform they behave bad in different ways. + // This needs probably a good rework or a tutorial if you have to create a dynamic line + this._setWidthHeight(); + } + return this; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + ctx.beginPath(); + const p = this.calcLinePoints(); + ctx.moveTo(p.x1, p.y1); + ctx.lineTo(p.x2, p.y2); + ctx.lineWidth = this.strokeWidth; + + // TODO: test this + // make sure setting "fill" changes color of a line + // (by copying fillStyle to strokeStyle, since line is stroked, not filled) + const origStrokeStyle = ctx.strokeStyle; + if (isFiller(this.stroke)) { + ctx.strokeStyle = this.stroke.toLive(ctx); + } else { + var _this$stroke; + ctx.strokeStyle = (_this$stroke = this.stroke) !== null && _this$stroke !== void 0 ? _this$stroke : ctx.fillStyle; + } + this.stroke && this._renderStroke(ctx); + ctx.strokeStyle = origStrokeStyle; + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2); + } + + /** + * Returns object representation of an instance + * @method toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), this.calcLinePoints()); + } + + /* + * Calculate object dimensions from its properties + * @private + */ + _getNonTransformedDimensions() { + const dim = super._getNonTransformedDimensions(); + if (this.strokeLineCap === 'butt') { + if (this.width === 0) { + dim.y -= this.strokeWidth; + } + if (this.height === 0) { + dim.x -= this.strokeWidth; + } + } + return dim; + } + + /** + * Recalculates line points given width and height + * Those points are simply placed around the center, + * This is not useful outside internal render functions and svg output + * Is not meant to be for the developer. + * @private + */ + calcLinePoints() { + const { + x1: _x1, + x2: _x2, + y1: _y1, + y2: _y2, + width, + height + } = this; + const xMult = _x1 <= _x2 ? -1 : 1, + yMult = _y1 <= _y2 ? -1 : 1, + x1 = xMult * width / 2, + y1 = yMult * height / 2, + x2 = xMult * -width / 2, + y2 = yMult * -height / 2; + return { + x1, + x2, + y1, + y2 + }; + } + + /* _FROM_SVG_START_ */ + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const { + x1, + x2, + y1, + y2 + } = this.calcLinePoints(); + return ['\n")]; + } + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement}) + * @static + * @memberOf Line + * @see http://www.w3.org/TR/SVG/shapes.html#LineElement + */ + + /** + * Returns Line instance from an SVG element + * @static + * @memberOf Line + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + * @param {Function} [callback] callback function invoked after parsing + */ + static async fromElement(element, options, cssRules) { + const _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + { + x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0 + } = _parseAttributes, + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$5); + return new this([x1, y1, x2, y2], parsedAttributes); + } + + /* _FROM_SVG_END_ */ + + /** + * Returns Line instance from an object representation + * @static + * @memberOf Line + * @param {Object} object Object to create an instance from + * @returns {Promise} + */ + static fromObject(_ref) { + let { + x1, + y1, + x2, + y2 + } = _ref, + object = _objectWithoutProperties(_ref, _excluded2$1); + return this._fromObject(_objectSpread2(_objectSpread2({}, object), {}, { + points: [x1, y1, x2, y2] + }), { + extraParam: 'points' + }); + } +} +/** + * x value or first line edge + * @type number + * @default + */ +/** + * y value or first line edge + * @type number + * @default + */ +/** + * x value or second line edge + * @type number + * @default + */ +/** + * y value or second line edge + * @type number + * @default + */ +_defineProperty(Line, "type", 'Line'); +_defineProperty(Line, "cacheProperties", [...cacheProperties, ...coordProps]); +_defineProperty(Line, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat(coordProps)); +classRegistry.setClass(Line); +classRegistry.setSVGClass(Line); + +const triangleDefaultValues = { + width: 100, + height: 100 +}; +class Triangle extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Triangle.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Triangle.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const widthBy2 = this.width / 2, + heightBy2 = this.height / 2; + ctx.beginPath(); + ctx.moveTo(-widthBy2, heightBy2); + ctx.lineTo(0, -heightBy2); + ctx.lineTo(widthBy2, heightBy2); + ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const widthBy2 = this.width / 2, + heightBy2 = this.height / 2, + points = "".concat(-widthBy2, " ").concat(heightBy2, ",0 ").concat(-heightBy2, ",").concat(widthBy2, " ").concat(heightBy2); + return ['']; + } +} +_defineProperty(Triangle, "type", 'Triangle'); +_defineProperty(Triangle, "ownDefaults", triangleDefaultValues); +classRegistry.setClass(Triangle); +classRegistry.setSVGClass(Triangle); + +const ellipseDefaultValues = { + rx: 0, + ry: 0 +}; +const ELLIPSE_PROPS = ['rx', 'ry']; +class Ellipse extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Ellipse.ownDefaults); + } + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor(options) { + super(); + Object.assign(this, Ellipse.ownDefaults); + this.setOptions(options); + } + + /** + * @private + * @param {String} key + * @param {*} value + * @return {Ellipse} thisArg + */ + _set(key, value) { + super._set(key, value); + switch (key) { + case 'rx': + this.rx = value; + this.set('width', value * 2); + break; + case 'ry': + this.ry = value; + this.set('height', value * 2); + break; + } + return this; + } + + /** + * Returns horizontal radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRx() { + return this.get('rx') * this.get(SCALE_X); + } + + /** + * Returns Vertical radius of an object (according to how an object is scaled) + * @return {Number} + */ + getRy() { + return this.get('ry') * this.get(SCALE_Y); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + return ['\n")]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx context to render on + */ + _render(ctx) { + ctx.beginPath(); + ctx.save(); + ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0); + ctx.arc(0, 0, this.rx, 0, twoMathPi, false); + ctx.restore(); + this._renderPaintInOrder(ctx); + } + + /* _FROM_SVG_START_ */ + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement}) + * @static + * @memberOf Ellipse + * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement + */ + + /** + * Returns {@link Ellipse} instance from an SVG element + * @static + * @memberOf Ellipse + * @param {HTMLElement} element Element to parse + * @return {Ellipse} + */ + static async fromElement(element, options, cssRules) { + const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules); + parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx; + parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry; + return new this(parsedAttributes); + } + + /* _FROM_SVG_END_ */ +} +/** + * Horizontal radius + * @type Number + * @default + */ +/** + * Vertical radius + * @type Number + * @default + */ +_defineProperty(Ellipse, "type", 'Ellipse'); +_defineProperty(Ellipse, "cacheProperties", [...cacheProperties, ...ELLIPSE_PROPS]); +_defineProperty(Ellipse, "ownDefaults", ellipseDefaultValues); +_defineProperty(Ellipse, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry']); +classRegistry.setClass(Ellipse); +classRegistry.setSVGClass(Ellipse); + +/** + * Parses "points" attribute, returning an array of values + * @static + * @memberOf fabric + * @param {String} points points attribute string + * @return {Array} array of points + */ +function parsePointsAttribute(points) { + // points attribute is required and must not be empty + if (!points) { + return []; + } + + // replace commas with whitespace and remove bookending whitespace + const pointsSplit = points.replace(/,/g, ' ').trim().split(/\s+/); + const parsedPoints = []; + for (let i = 0; i < pointsSplit.length; i += 2) { + parsedPoints.push({ + x: parseFloat(pointsSplit[i]), + y: parseFloat(pointsSplit[i + 1]) + }); + } + + // odd number of points is an error + // if (parsedPoints.length % 2 !== 0) { + // return null; + // } + return parsedPoints; +} + +const _excluded$4 = ["left", "top"]; +const polylineDefaultValues = { + /** + * @deprecated transient option soon to be removed in favor of a different design + */ + exactBoundingBox: false +}; +class Polyline extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Polyline.ownDefaults); + } + + /** + * A list of properties that if changed trigger a recalculation of dimensions + * @todo check if you really need to recalculate for all cases + */ + + /** + * Constructor + * @param {Array} points Array of points (where each point is an object with x and y) + * @param {Object} [options] Options object + * @return {Polyline} thisArg + * @example + * var poly = new Polyline([ + * { x: 10, y: 10 }, + * { x: 50, y: 30 }, + * { x: 40, y: 70 }, + * { x: 60, y: 50 }, + * { x: 100, y: 150 }, + * { x: 40, y: 100 } + * ], { + * stroke: 'red', + * left: 100, + * top: 100 + * }); + */ + constructor() { + let points = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + _defineProperty(this, "strokeDiff", void 0); + Object.assign(this, Polyline.ownDefaults); + this.setOptions(options); + this.points = points; + const { + left, + top + } = options; + this.initialized = true; + this.setBoundingBox(true); + typeof left === 'number' && this.set(LEFT, left); + typeof top === 'number' && this.set(TOP, top); + } + isOpen() { + return true; + } + _projectStrokeOnPoints(options) { + return projectStrokeOnPoints(this.points, options, this.isOpen()); + } + + /** + * Calculate the polygon bounding box + * @private + */ + _calcDimensions(options) { + options = _objectSpread2({ + scaleX: this.scaleX, + scaleY: this.scaleY, + skewX: this.skewX, + skewY: this.skewY, + strokeLineCap: this.strokeLineCap, + strokeLineJoin: this.strokeLineJoin, + strokeMiterLimit: this.strokeMiterLimit, + strokeUniform: this.strokeUniform, + strokeWidth: this.strokeWidth + }, options || {}); + const points = this.exactBoundingBox ? this._projectStrokeOnPoints(options).map(projection => projection.projectedPoint) : this.points; + if (points.length === 0) { + return { + left: 0, + top: 0, + width: 0, + height: 0, + pathOffset: new Point(), + strokeOffset: new Point(), + strokeDiff: new Point() + }; + } + const bbox = makeBoundingBoxFromPoints(points), + // Remove scale effect, since it's applied after + matrix = calcDimensionsMatrix(_objectSpread2(_objectSpread2({}, options), {}, { + scaleX: 1, + scaleY: 1 + })), + bboxNoStroke = makeBoundingBoxFromPoints(this.points.map(p => transformPoint(p, matrix, true))), + scale = new Point(this.scaleX, this.scaleY); + let offsetX = bbox.left + bbox.width / 2, + offsetY = bbox.top + bbox.height / 2; + if (this.exactBoundingBox) { + offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX)); + // Order of those assignments is important. + // offsetY relies on offsetX being already changed by the line above + offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY)); + } + return _objectSpread2(_objectSpread2({}, bbox), {}, { + pathOffset: new Point(offsetX, offsetY), + strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top).subtract(new Point(bbox.left, bbox.top)).multiply(scale), + strokeDiff: new Point(bbox.width, bbox.height).subtract(new Point(bboxNoStroke.width, bboxNoStroke.height)).multiply(scale) + }); + } + + /** + * This function is an helper for svg import. it returns the center of the object in the svg + * untransformed coordinates, by look at the polyline/polygon points. + * @private + * @return {Point} center point from element coordinates + */ + _findCenterFromElement() { + const bbox = makeBoundingBoxFromPoints(this.points); + return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2); + } + setDimensions() { + this.setBoundingBox(); + } + setBoundingBox(adjustPosition) { + const { + left, + top, + width, + height, + pathOffset, + strokeOffset, + strokeDiff + } = this._calcDimensions(); + this.set({ + width, + height, + pathOffset, + strokeOffset, + strokeDiff + }); + adjustPosition && this.setPositionByOrigin(new Point(left + width / 2, top + height / 2), CENTER, CENTER); + } + + /** + * @deprecated intermidiate method to be removed, do not use + */ + isStrokeAccountedForInDimensions() { + return this.exactBoundingBox; + } + + /** + * @override stroke is taken in account in size + */ + _getNonTransformedDimensions() { + return this.exactBoundingBox ? + // TODO: fix this + new Point(this.width, this.height) : super._getNonTransformedDimensions(); + } + + /** + * @override stroke and skewing are taken into account when projecting stroke on points, + * therefore we don't want the default calculation to account for skewing as well. + * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion. + * + * @private + */ + _getTransformedDimensions() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (this.exactBoundingBox) { + let size; + /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because + the stroke projections are affected. + When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on + projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/ + if (Object.keys(options).some(key => this.strokeUniform || this.constructor.layoutProperties.includes(key))) { + var _options$width, _options$height; + const { + width, + height + } = this._calcDimensions(options); + size = new Point((_options$width = options.width) !== null && _options$width !== void 0 ? _options$width : width, (_options$height = options.height) !== null && _options$height !== void 0 ? _options$height : height); + } else { + var _options$width2, _options$height2; + size = new Point((_options$width2 = options.width) !== null && _options$width2 !== void 0 ? _options$width2 : this.width, (_options$height2 = options.height) !== null && _options$height2 !== void 0 ? _options$height2 : this.height); + } + return size.multiply(new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY)); + } else { + return super._getTransformedDimensions(options); + } + } + + /** + * Recalculates dimensions when changing skew and scale + * @private + */ + _set(key, value) { + const changed = this.initialized && this[key] !== value; + const output = super._set(key, value); + if (this.exactBoundingBox && changed && ((key === SCALE_X || key === SCALE_Y) && this.strokeUniform && this.constructor.layoutProperties.includes('strokeUniform') || this.constructor.layoutProperties.includes(key))) { + this.setDimensions(); + } + return output; + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject(propertiesToInclude)), {}, { + points: this.points.map(_ref => { + let { + x, + y + } = _ref; + return { + x, + y + }; + }) + }); + } + + /** + * Returns svg representation of an instance + * @return {Array} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const points = [], + diffX = this.pathOffset.x, + diffY = this.pathOffset.y, + NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS; + for (let i = 0, len = this.points.length; i < len; i++) { + points.push(toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS), ',', toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS), ' '); + } + return ["<".concat(this.constructor.type.toLowerCase(), " "), 'COMMON_PARTS', "points=\"".concat(points.join(''), "\" />\n")]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const len = this.points.length, + x = this.pathOffset.x, + y = this.pathOffset.y; + if (!len || isNaN(this.points[len - 1].y)) { + // do not draw if no points or odd points + // NaN comes from parseFloat of a empty string in parser + return; + } + ctx.beginPath(); + ctx.moveTo(this.points[0].x - x, this.points[0].y - y); + for (let i = 0; i < len; i++) { + const point = this.points[i]; + ctx.lineTo(point.x - x, point.y - y); + } + !this.isOpen() && ctx.closePath(); + this._renderPaintInOrder(ctx); + } + + /** + * Returns complexity of an instance + * @return {Number} complexity of this instance + */ + complexity() { + return this.points.length; + } + + /* _FROM_SVG_START_ */ + + /** + * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement}) + * @static + * @memberOf Polyline + * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement + */ + + /** + * Returns Polyline instance from an SVG element + * @static + * @memberOf Polyline + * @param {HTMLElement} element Element to parser + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const points = parsePointsAttribute(element.getAttribute('points')), + _parseAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules), + parsedAttributes = _objectWithoutProperties(_parseAttributes, _excluded$4); + return new this(points, _objectSpread2(_objectSpread2({}, parsedAttributes), options)); + } + + /* _FROM_SVG_END_ */ + + /** + * Returns Polyline instance from an object representation + * @static + * @memberOf Polyline + * @param {Object} object Object to create an instance from + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(object, { + extraParam: 'points' + }); + } +} +/** + * Points array + * @type Array + * @default + */ +/** + * WARNING: Feature in progress + * Calculate the exact bounding box taking in account strokeWidth on acute angles + * this will be turned to true by default on fabric 6.0 + * maybe will be left in as an optimization since calculations may be slow + * @deprecated transient option soon to be removed in favor of a different design + * @type Boolean + * @default false + */ +_defineProperty(Polyline, "ownDefaults", polylineDefaultValues); +_defineProperty(Polyline, "type", 'Polyline'); +_defineProperty(Polyline, "layoutProperties", [SKEW_X, SKEW_Y, 'strokeLineCap', 'strokeLineJoin', 'strokeMiterLimit', 'strokeWidth', 'strokeUniform', 'points']); +_defineProperty(Polyline, "cacheProperties", [...cacheProperties, 'points']); +_defineProperty(Polyline, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES]); +classRegistry.setClass(Polyline); +classRegistry.setSVGClass(Polyline); + +class Polygon extends Polyline { + isOpen() { + return false; + } +} +_defineProperty(Polygon, "ownDefaults", polylineDefaultValues); +_defineProperty(Polygon, "type", 'Polygon'); +classRegistry.setClass(Polygon); +classRegistry.setSVGClass(Polygon); + +const fontProperties = ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle']; +const textDecorationProperties = ['underline', 'overline', 'linethrough']; +const textLayoutProperties = [...fontProperties, 'lineHeight', 'text', 'charSpacing', 'textAlign', 'styles', 'path', 'pathStartOffset', 'pathSide', 'pathAlign']; +const additionalProps = [...textLayoutProperties, ...textDecorationProperties, 'textBackgroundColor', 'direction']; +const styleProperties = [...fontProperties, ...textDecorationProperties, STROKE, 'strokeWidth', FILL, 'deltaY', 'textBackgroundColor']; + +// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype +// regexes, list of properties that are not suppose to change by instances, magic consts. +// this will be a separated effort +const textDefaultValues = { + _reNewline: reNewline, + _reSpacesAndTabs: /[ \t\r]/g, + _reSpaceAndTab: /[ \t\r]/, + _reWords: /\S+/g, + fontSize: 40, + fontWeight: 'normal', + fontFamily: 'Times New Roman', + underline: false, + overline: false, + linethrough: false, + textAlign: LEFT, + fontStyle: 'normal', + lineHeight: 1.16, + superscript: { + size: 0.6, + // fontSize factor + baseline: -0.35 // baseline-shift factor (upwards) + }, + subscript: { + size: 0.6, + // fontSize factor + baseline: 0.11 // baseline-shift factor (downwards) + }, + textBackgroundColor: '', + stroke: null, + shadow: null, + path: undefined, + pathStartOffset: 0, + pathSide: LEFT, + pathAlign: 'baseline', + _fontSizeFraction: 0.222, + offsets: { + underline: 0.1, + linethrough: -0.315, + overline: -0.88 + }, + _fontSizeMult: 1.13, + charSpacing: 0, + deltaY: 0, + direction: 'ltr', + CACHE_FONT_SIZE: 400, + MIN_TEXT_WIDTH: 2 +}; +const JUSTIFY = 'justify'; +const JUSTIFY_LEFT = 'justify-left'; +const JUSTIFY_RIGHT = 'justify-right'; +const JUSTIFY_CENTER = 'justify-center'; + +class StyledText extends FabricObject { + /** + * Returns true if object has no styling or no styling in a line + * @param {Number} lineIndex , lineIndex is on wrapped lines. + * @return {Boolean} + */ + isEmptyStyles(lineIndex) { + if (!this.styles) { + return true; + } + if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { + return true; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + line: this.styles[lineIndex] + }; + for (const p1 in obj) { + for (const p2 in obj[p1]) { + // eslint-disable-next-line no-unused-vars + for (const p3 in obj[p1][p2]) { + return false; + } + } + } + return true; + } + + /** + * Returns true if object has a style property or has it ina specified line + * This function is used to detect if a text will use a particular property or not. + * @param {String} property to check for + * @param {Number} lineIndex to check the style on + * @return {Boolean} + */ + styleHas(property, lineIndex) { + if (!this.styles) { + return false; + } + if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) { + return false; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + 0: this.styles[lineIndex] + }; + // eslint-disable-next-line + for (const p1 in obj) { + // eslint-disable-next-line + for (const p2 in obj[p1]) { + if (typeof obj[p1][p2][property] !== 'undefined') { + return true; + } + } + } + return false; + } + + /** + * Check if characters in a text have a value for a property + * whose value matches the textbox's value for that property. If so, + * the character-level property is deleted. If the character + * has no other properties, then it is also deleted. Finally, + * if the line containing that character has no other characters + * then it also is deleted. + * + * @param {string} property The property to compare between characters and text. + */ + cleanStyle(property) { + if (!this.styles) { + return false; + } + const obj = this.styles; + let stylesCount = 0, + letterCount, + stylePropertyValue, + allStyleObjectPropertiesMatch = true, + graphemeCount = 0; + for (const p1 in obj) { + letterCount = 0; + for (const p2 in obj[p1]) { + const styleObject = obj[p1][p2] || {}, + stylePropertyHasBeenSet = styleObject[property] !== undefined; + stylesCount++; + if (stylePropertyHasBeenSet) { + if (!stylePropertyValue) { + stylePropertyValue = styleObject[property]; + } else if (styleObject[property] !== stylePropertyValue) { + allStyleObjectPropertiesMatch = false; + } + if (styleObject[property] === this[property]) { + delete styleObject[property]; + } + } else { + allStyleObjectPropertiesMatch = false; + } + if (Object.keys(styleObject).length !== 0) { + letterCount++; + } else { + delete obj[p1][p2]; + } + } + if (letterCount === 0) { + delete obj[p1]; + } + } + // if every grapheme has the same style set then + // delete those styles and set it on the parent + for (let i = 0; i < this._textLines.length; i++) { + graphemeCount += this._textLines[i].length; + } + if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) { + // @ts-expect-error conspiracy theory of TS + this[property] = stylePropertyValue; + this.removeStyle(property); + } + } + + /** + * Remove a style property or properties from all individual character styles + * in a text object. Deletes the character style object if it contains no other style + * props. Deletes a line style object if it contains no other character styles. + * + * @param {String} props The property to remove from character styles. + */ + removeStyle(property) { + if (!this.styles) { + return; + } + const obj = this.styles; + let line, lineNum, charNum; + for (lineNum in obj) { + line = obj[lineNum]; + for (charNum in line) { + delete line[charNum][property]; + if (Object.keys(line[charNum]).length === 0) { + delete line[charNum]; + } + } + if (Object.keys(line).length === 0) { + delete obj[lineNum]; + } + } + } + _extendStyles(index, style) { + const { + lineIndex, + charIndex + } = this.get2DCursorLocation(index); + if (!this._getLineStyle(lineIndex)) { + this._setLineStyle(lineIndex); + } + const newStyle = pickBy(_objectSpread2(_objectSpread2({}, this._getStyleDeclaration(lineIndex, charIndex)), style), value => value !== undefined); + + // finally assign to the old position the new style + this._setStyleDeclaration(lineIndex, charIndex, newStyle); + } + + /** + * Gets style of a current selection/cursor (at the start position) + * @param {Number} startIndex Start index to get styles at + * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1 + * @param {Boolean} [complete] get full style or not + * @return {Array} styles an array with one, zero or more Style objects + */ + getSelectionStyles(startIndex, endIndex, complete) { + const styles = []; + for (let i = startIndex; i < (endIndex || startIndex); i++) { + styles.push(this.getStyleAtPosition(i, complete)); + } + return styles; + } + + /** + * Gets style of a current selection/cursor position + * @param {Number} position to get styles at + * @param {Boolean} [complete] full style if true + * @return {Object} style Style object at a specified index + * @private + */ + getStyleAtPosition(position, complete) { + const { + lineIndex, + charIndex + } = this.get2DCursorLocation(position); + return complete ? this.getCompleteStyleDeclaration(lineIndex, charIndex) : this._getStyleDeclaration(lineIndex, charIndex); + } + + /** + * Sets style of a current selection, if no selection exist, do not set anything. + * @param {Object} styles Styles object + * @param {Number} startIndex Start index to get styles at + * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1 + */ + setSelectionStyles(styles, startIndex, endIndex) { + for (let i = startIndex; i < (endIndex || startIndex); i++) { + this._extendStyles(i, styles); + } + /* not included in _extendStyles to avoid clearing cache more than once */ + this._forceClearCache = true; + } + + /** + * Get a reference, not a clone, to the style object for a given character, + * if no style is set for a line or char, return a new empty object. + * This is tricky and confusing because when you get an empty object you can't + * determine if it is a reference or a new one. + * @TODO this should always return a reference or always a clone or undefined when necessary. + * @protected + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined + */ + _getStyleDeclaration(lineIndex, charIndex) { + var _lineStyle$charIndex; + const lineStyle = this.styles && this.styles[lineIndex]; + return lineStyle ? (_lineStyle$charIndex = lineStyle[charIndex]) !== null && _lineStyle$charIndex !== void 0 ? _lineStyle$charIndex : {} : {}; + } + + /** + * return a new object that contains all the style property for a character + * the object returned is newly created + * @param {Number} lineIndex of the line where the character is + * @param {Number} charIndex position of the character on the line + * @return {Object} style object + */ + getCompleteStyleDeclaration(lineIndex, charIndex) { + return _objectSpread2(_objectSpread2({}, pick(this, this.constructor._styleProperties)), this._getStyleDeclaration(lineIndex, charIndex)); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {Object} style + * @private + */ + _setStyleDeclaration(lineIndex, charIndex, style) { + this.styles[lineIndex][charIndex] = style; + } + + /** + * + * @param {Number} lineIndex + * @param {Number} charIndex + * @private + */ + _deleteStyleDeclaration(lineIndex, charIndex) { + delete this.styles[lineIndex][charIndex]; + } + + /** + * @param {Number} lineIndex + * @return {Boolean} if the line exists or not + * @private + */ + _getLineStyle(lineIndex) { + return !!this.styles[lineIndex]; + } + + /** + * Set the line style to an empty object so that is initialized + * @param {Number} lineIndex + * @private + */ + _setLineStyle(lineIndex) { + this.styles[lineIndex] = {}; + } + _deleteLineStyle(lineIndex) { + delete this.styles[lineIndex]; + } +} +_defineProperty(StyledText, "_styleProperties", styleProperties); + +const multipleSpacesRegex = / +/g; +const dblQuoteRegex = /"/g; +function createSVGInlineRect(color, left, top, width, height) { + return "\t\t".concat(createSVGRect(color, { + left, + top, + width, + height + }), "\n"); +} +class TextSVGExportMixin extends FabricObjectSVGExportMixin { + _toSVG() { + const offsets = this._getSVGLeftTopOffsets(), + textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft); + return this._wrapSVGTextAndBg(textAndBg); + } + toSVG(reviver) { + return this._createBaseSVGMarkup(this._toSVG(), { + reviver, + noStyle: true, + withShadow: true + }); + } + _getSVGLeftTopOffsets() { + return { + textLeft: -this.width / 2, + textTop: -this.height / 2, + lineTop: this.getHeightOfLine(0) + }; + } + _wrapSVGTextAndBg(_ref) { + let { + textBgRects, + textSpans + } = _ref; + const noShadow = true, + textDecoration = this.getSvgTextDecoration(this); + return [textBgRects.join(''), '\t\t', textSpans.join(''), '\n']; + } + + /** + * @private + * @param {Number} textTopOffset Text top offset + * @param {Number} textLeftOffset Text left offset + * @return {Object} + */ + _getSVGTextAndBg(textTopOffset, textLeftOffset) { + const textSpans = [], + textBgRects = []; + let height = textTopOffset, + lineOffset; + + // bounding-box background + this.backgroundColor && textBgRects.push(...createSVGInlineRect(this.backgroundColor, -this.width / 2, -this.height / 2, this.width, this.height)); + + // text and text-background + for (let i = 0, len = this._textLines.length; i < len; i++) { + lineOffset = this._getLineLeftOffset(i); + if (this.direction === 'rtl') { + lineOffset += this.width; + } + if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) { + this._setSVGTextLineBg(textBgRects, i, textLeftOffset + lineOffset, height); + } + this._setSVGTextLineText(textSpans, i, textLeftOffset + lineOffset, height); + height += this.getHeightOfLine(i); + } + return { + textSpans, + textBgRects + }; + } + _createTextCharSpan(char, styleDecl, left, top) { + const styleProps = this.getSvgSpanStyles(styleDecl, char !== char.trim() || !!char.match(multipleSpacesRegex)), + fillStyles = styleProps ? "style=\"".concat(styleProps, "\"") : '', + dy = styleDecl.deltaY, + dySpan = dy ? " dy=\"".concat(toFixed(dy, config.NUM_FRACTION_DIGITS), "\" ") : ''; + return "").concat(escapeXml(char), ""); + } + _setSVGTextLineText(textSpans, lineIndex, textLeftOffset, textTopOffset) { + const lineHeight = this.getHeightOfLine(lineIndex), + isJustify = this.textAlign.includes(JUSTIFY), + line = this._textLines[lineIndex]; + let actualStyle, + nextStyle, + charsToRender = '', + charBox, + style, + boxWidth = 0, + timeToRender; + textTopOffset += lineHeight * (1 - this._fontSizeFraction) / this.lineHeight; + for (let i = 0, len = line.length - 1; i <= len; i++) { + timeToRender = i === len || this.charSpacing; + charsToRender += line[i]; + charBox = this.__charBounds[lineIndex][i]; + if (boxWidth === 0) { + textLeftOffset += charBox.kernedWidth - charBox.width; + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; + } + if (isJustify && !timeToRender) { + if (this._reSpaceAndTab.test(line[i])) { + timeToRender = true; + } + } + if (!timeToRender) { + // if we have charSpacing, we render char by char + actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); + nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); + timeToRender = hasStyleChanged(actualStyle, nextStyle, true); + } + if (timeToRender) { + style = this._getStyleDeclaration(lineIndex, i); + textSpans.push(this._createTextCharSpan(charsToRender, style, textLeftOffset, textTopOffset)); + charsToRender = ''; + actualStyle = nextStyle; + if (this.direction === 'rtl') { + textLeftOffset -= boxWidth; + } else { + textLeftOffset += boxWidth; + } + boxWidth = 0; + } + } + } + _setSVGTextLineBg(textBgRects, i, leftOffset, textTopOffset) { + const line = this._textLines[i], + heightOfLine = this.getHeightOfLine(i) / this.lineHeight; + let boxWidth = 0, + boxStart = 0, + currentColor, + lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); + for (let j = 0; j < line.length; j++) { + const { + left, + width, + kernedWidth + } = this.__charBounds[i][j]; + currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); + if (currentColor !== lastColor) { + lastColor && textBgRects.push(...createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine)); + boxStart = left; + boxWidth = width; + lastColor = currentColor; + } else { + boxWidth += kernedWidth; + } + } + currentColor && textBgRects.push(...createSVGInlineRect(lastColor, leftOffset + boxStart, textTopOffset, boxWidth, heightOfLine)); + } + + /** + * @deprecated unused + */ + _getSVGLineTopOffset(lineIndex) { + let lineTopOffset = 0, + j; + for (j = 0; j < lineIndex; j++) { + lineTopOffset += this.getHeightOfLine(j); + } + const lastHeight = this.getHeightOfLine(j); + return { + lineTop: lineTopOffset, + offset: (this._fontSizeMult - this._fontSizeFraction) * lastHeight / (this.lineHeight * this._fontSizeMult) + }; + } + + /** + * Returns styles-string for svg-export + * @param {Boolean} skipShadow a boolean to skip shadow filter output + * @return {String} + */ + getSvgStyles(skipShadow) { + return "".concat(super.getSvgStyles(skipShadow), " white-space: pre;"); + } + + /** + * Returns styles-string for svg-export + * @param {Object} style the object from which to retrieve style properties + * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style. + * @return {String} + */ + getSvgSpanStyles(style, useWhiteSpace) { + const { + fontFamily, + strokeWidth, + stroke, + fill, + fontSize, + fontStyle, + fontWeight, + deltaY + } = style; + const textDecoration = this.getSvgTextDecoration(style); + return [stroke ? colorPropToSVG(STROKE, stroke) : '', strokeWidth ? "stroke-width: ".concat(strokeWidth, "; ") : '', fontFamily ? "font-family: ".concat(!fontFamily.includes("'") && !fontFamily.includes('"') ? "'".concat(fontFamily, "'") : fontFamily, "; ") : '', fontSize ? "font-size: ".concat(fontSize, "px; ") : '', fontStyle ? "font-style: ".concat(fontStyle, "; ") : '', fontWeight ? "font-weight: ".concat(fontWeight, "; ") : '', textDecoration ? "text-decoration: ".concat(textDecoration, "; ") : textDecoration, fill ? colorPropToSVG(FILL, fill) : '', deltaY ? "baseline-shift: ".concat(-deltaY, "; ") : '', useWhiteSpace ? 'white-space: pre; ' : ''].join(''); + } + + /** + * Returns text-decoration property for svg-export + * @param {Object} style the object from which to retrieve style properties + * @return {String} + */ + getSvgTextDecoration(style) { + return ['overline', 'underline', 'line-through'].filter(decoration => style[decoration.replace('-', '')]).join(' '); + } +} + +const _excluded$3 = ["textAnchor", "textDecoration", "dx", "dy", "top", "left", "fontSize", "strokeWidth"]; +let measuringContext; + +/** + * Return a context for measurement of text string. + * if created it gets stored for reuse + */ +function getMeasuringContext() { + if (!measuringContext) { + const canvas = createCanvasElement(); + canvas.width = canvas.height = 0; + measuringContext = canvas.getContext('2d'); + } + return measuringContext; +} + +/** + * Measure and return the info of a single grapheme. + * needs the the info of previous graphemes already filled + * Override to customize measuring + */ + +// @TODO this is not complete + +/** + * Text class + * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text} + */ +class FabricText extends StyledText { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), FabricText.ownDefaults); + } + constructor(text, options) { + super(); + /** + * contains characters bounding boxes + * This variable is considered to be protected. + * But for how mixins are implemented right now, we can't leave it private + * @protected + */ + _defineProperty(this, "__charBounds", []); + Object.assign(this, FabricText.ownDefaults); + this.setOptions(options); + if (!this.styles) { + this.styles = {}; + } + this.text = text; + this.initialized = true; + if (this.path) { + this.setPathInfo(); + } + this.initDimensions(); + this.setCoords(); + } + + /** + * If text has a path, it will add the extra information needed + * for path and text calculations + */ + setPathInfo() { + const path = this.path; + if (path) { + path.segmentsInfo = getPathSegmentsInfo(path.path); + } + } + + /** + * @private + * Divides text into lines of text and lines of graphemes. + */ + _splitText() { + const newLines = this._splitTextIntoLines(this.text); + this.textLines = newLines.lines; + this._textLines = newLines.graphemeLines; + this._unwrappedTextLines = newLines._unwrappedLines; + this._text = newLines.graphemeText; + return newLines; + } + + /** + * Initialize or update text dimensions. + * Updates this.width and this.height with the proper values. + * Does not return dimensions. + */ + initDimensions() { + this._splitText(); + this._clearCache(); + this.dirty = true; + if (this.path) { + this.width = this.path.width; + this.height = this.path.height; + } else { + this.width = this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH; + this.height = this.calcTextHeight(); + } + if (this.textAlign.includes(JUSTIFY)) { + // once text is measured we need to make space fatter to make justified text. + this.enlargeSpaces(); + } + } + + /** + * Enlarge space boxes and shift the others + */ + enlargeSpaces() { + let diffSpace, currentLineWidth, numberOfSpaces, accumulatedSpace, line, charBound, spaces; + for (let i = 0, len = this._textLines.length; i < len; i++) { + if (this.textAlign !== JUSTIFY && (i === len - 1 || this.isEndOfWrapping(i))) { + continue; + } + accumulatedSpace = 0; + line = this._textLines[i]; + currentLineWidth = this.getLineWidth(i); + if (currentLineWidth < this.width && (spaces = this.textLines[i].match(this._reSpacesAndTabs))) { + numberOfSpaces = spaces.length; + diffSpace = (this.width - currentLineWidth) / numberOfSpaces; + for (let j = 0; j <= line.length; j++) { + charBound = this.__charBounds[i][j]; + if (this._reSpaceAndTab.test(line[j])) { + charBound.width += diffSpace; + charBound.kernedWidth += diffSpace; + charBound.left += accumulatedSpace; + accumulatedSpace += diffSpace; + } else { + charBound.left += accumulatedSpace; + } + } + } + } + } + + /** + * Detect if the text line is ended with an hard break + * text and itext do not have wrapping, return false + * @return {Boolean} + */ + isEndOfWrapping(lineIndex) { + return lineIndex === this._textLines.length - 1; + } + + /** + * Detect if a line has a linebreak and so we need to account for it when moving + * and counting style. + * It return always 1 for text and Itext. Textbox has its own implementation + * @return Number + */ + + missingNewlineOffset(_lineIndex) { + return 1; + } + + /** + * Returns 2d representation (lineIndex and charIndex) of cursor + * @param {Number} selectionStart + * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. + */ + get2DCursorLocation(selectionStart, skipWrapping) { + const lines = skipWrapping ? this._unwrappedTextLines : this._textLines; + let i; + for (i = 0; i < lines.length; i++) { + if (selectionStart <= lines[i].length) { + return { + lineIndex: i, + charIndex: selectionStart + }; + } + selectionStart -= lines[i].length + this.missingNewlineOffset(i, skipWrapping); + } + return { + lineIndex: i - 1, + charIndex: lines[i - 1].length < selectionStart ? lines[i - 1].length : selectionStart + }; + } + + /** + * Returns string representation of an instance + * @return {String} String representation of text object + */ + toString() { + return "#"); + } + + /** + * Return the dimension and the zoom level needed to create a cache canvas + * big enough to host the object to be cached. + * @private + * @param {Object} dim.x width of object to be cached + * @param {Object} dim.y height of object to be cached + * @return {Object}.width width of canvas + * @return {Object}.height height of canvas + * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache + * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache + */ + _getCacheCanvasDimensions() { + const dims = super._getCacheCanvasDimensions(); + const fontSize = this.fontSize; + dims.width += fontSize * dims.zoomX; + dims.height += fontSize * dims.zoomY; + return dims; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + const path = this.path; + path && !path.isNotVisible() && path._render(ctx); + this._setTextStyles(ctx); + this._renderTextLinesBackground(ctx); + this._renderTextDecoration(ctx, 'underline'); + this._renderText(ctx); + this._renderTextDecoration(ctx, 'overline'); + this._renderTextDecoration(ctx, 'linethrough'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderText(ctx) { + if (this.paintFirst === STROKE) { + this._renderTextStroke(ctx); + this._renderTextFill(ctx); + } else { + this._renderTextFill(ctx); + this._renderTextStroke(ctx); + } + } + + /** + * Set the font parameter of the context with the object properties or with charStyle + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Object} [charStyle] object with font style properties + * @param {String} [charStyle.fontFamily] Font Family + * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix ) + * @param {String} [charStyle.fontWeight] Font weight + * @param {String} [charStyle.fontStyle] Font style (italic|normal) + */ + _setTextStyles(ctx, charStyle, forMeasuring) { + ctx.textBaseline = 'alphabetic'; + if (this.path) { + switch (this.pathAlign) { + case CENTER: + ctx.textBaseline = 'middle'; + break; + case 'ascender': + ctx.textBaseline = TOP; + break; + case 'descender': + ctx.textBaseline = BOTTOM; + break; + } + } + ctx.font = this._getFontDeclaration(charStyle, forMeasuring); + } + + /** + * calculate and return the text Width measuring each line. + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @return {Number} Maximum width of Text object + */ + calcTextWidth() { + let maxWidth = this.getLineWidth(0); + for (let i = 1, len = this._textLines.length; i < len; i++) { + const currentLineWidth = this.getLineWidth(i); + if (currentLineWidth > maxWidth) { + maxWidth = currentLineWidth; + } + } + return maxWidth; + } + + /** + * @private + * @param {String} method Method name ("fillText" or "strokeText") + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} line Text to render + * @param {Number} left Left position of text + * @param {Number} top Top position of text + * @param {Number} lineIndex Index of a line in a text + */ + _renderTextLine(method, ctx, line, left, top, lineIndex) { + this._renderChars(method, ctx, line, left, top, lineIndex); + } + + /** + * Renders the text background for lines, taking care of style + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextLinesBackground(ctx) { + if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) { + return; + } + const originalFill = ctx.fillStyle, + leftOffset = this._getLeftOffset(); + let lineTopOffset = this._getTopOffset(); + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i); + if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor', i)) { + lineTopOffset += heightOfLine; + continue; + } + const jlen = this._textLines[i].length; + const lineLeftOffset = this._getLineLeftOffset(i); + let boxWidth = 0; + let boxStart = 0; + let drawStart; + let currentColor; + let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor'); + for (let j = 0; j < jlen; j++) { + // at this point charbox are either standard or full with pathInfo if there is a path. + const charBox = this.__charBounds[i][j]; + currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor'); + if (this.path) { + ctx.save(); + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + ctx.fillStyle = currentColor; + currentColor && ctx.fillRect(-charBox.width / 2, -heightOfLine / this.lineHeight * (1 - this._fontSizeFraction), charBox.width, heightOfLine / this.lineHeight); + ctx.restore(); + } else if (currentColor !== lastColor) { + drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = lastColor; + lastColor && ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight); + boxStart = charBox.left; + boxWidth = charBox.width; + lastColor = currentColor; + } else { + boxWidth += charBox.kernedWidth; + } + } + if (currentColor && !this.path) { + drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = currentColor; + ctx.fillRect(drawStart, lineTopOffset, boxWidth, heightOfLine / this.lineHeight); + } + lineTopOffset += heightOfLine; + } + ctx.fillStyle = originalFill; + // if there is text background color no + // other shadows should be casted + this._removeShadow(ctx); + } + + /** + * measure and return the width of a single character. + * possibly overridden to accommodate different measure logic or + * to hook some external lib for character measurement + * @private + * @param {String} _char, char to be measured + * @param {Object} charStyle style of char to be measured + * @param {String} [previousChar] previous char + * @param {Object} [prevCharStyle] style of previous char + */ + _measureChar(_char, charStyle, previousChar, prevCharStyle) { + const fontCache = cache.getFontCache(charStyle), + fontDeclaration = this._getFontDeclaration(charStyle), + couple = previousChar + _char, + stylesAreEqual = previousChar && fontDeclaration === this._getFontDeclaration(prevCharStyle), + fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE; + let width, coupleWidth, previousWidth, kernedWidth; + if (previousChar && fontCache[previousChar] !== undefined) { + previousWidth = fontCache[previousChar]; + } + if (fontCache[_char] !== undefined) { + kernedWidth = width = fontCache[_char]; + } + if (stylesAreEqual && fontCache[couple] !== undefined) { + coupleWidth = fontCache[couple]; + kernedWidth = coupleWidth - previousWidth; + } + if (width === undefined || previousWidth === undefined || coupleWidth === undefined) { + const ctx = getMeasuringContext(); + // send a TRUE to specify measuring font size CACHE_FONT_SIZE + this._setTextStyles(ctx, charStyle, true); + if (width === undefined) { + kernedWidth = width = ctx.measureText(_char).width; + fontCache[_char] = width; + } + if (previousWidth === undefined && stylesAreEqual && previousChar) { + previousWidth = ctx.measureText(previousChar).width; + fontCache[previousChar] = previousWidth; + } + if (stylesAreEqual && coupleWidth === undefined) { + // we can measure the kerning couple and subtract the width of the previous character + coupleWidth = ctx.measureText(couple).width; + fontCache[couple] = coupleWidth; + // safe to use the non-null since if undefined we defined it before. + kernedWidth = coupleWidth - previousWidth; + } + } + return { + width: width * fontMultiplier, + kernedWidth: kernedWidth * fontMultiplier + }; + } + + /** + * Computes height of character at given position + * @param {Number} line the line index number + * @param {Number} _char the character index number + * @return {Number} fontSize of the character + */ + getHeightOfChar(line, _char) { + return this.getValueOfPropertyAt(line, _char, 'fontSize'); + } + + /** + * measure a text line measuring all characters. + * @param {Number} lineIndex line number + */ + measureLine(lineIndex) { + const lineInfo = this._measureLine(lineIndex); + if (this.charSpacing !== 0) { + lineInfo.width -= this._getWidthOfCharSpacing(); + } + if (lineInfo.width < 0) { + lineInfo.width = 0; + } + return lineInfo; + } + + /** + * measure every grapheme of a line, populating __charBounds + * @param {Number} lineIndex + * @return {Object} object.width total width of characters + * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs + */ + _measureLine(lineIndex) { + let width = 0, + prevGrapheme, + graphemeInfo; + const reverse = this.pathSide === RIGHT, + path = this.path, + line = this._textLines[lineIndex], + llength = line.length, + lineBounds = new Array(llength); + this.__charBounds[lineIndex] = lineBounds; + for (let i = 0; i < llength; i++) { + const grapheme = line[i]; + graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme); + lineBounds[i] = graphemeInfo; + width += graphemeInfo.kernedWidth; + prevGrapheme = grapheme; + } + // this latest bound box represent the last character of the line + // to simplify cursor handling in interactive mode. + lineBounds[llength] = { + left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0, + width: 0, + kernedWidth: 0, + height: this.fontSize, + deltaY: 0 + }; + if (path && path.segmentsInfo) { + let positionInPath = 0; + const totalPathLength = path.segmentsInfo[path.segmentsInfo.length - 1].length; + switch (this.textAlign) { + case LEFT: + positionInPath = reverse ? totalPathLength - width : 0; + break; + case CENTER: + positionInPath = (totalPathLength - width) / 2; + break; + case RIGHT: + positionInPath = reverse ? 0 : totalPathLength - width; + break; + //todo - add support for justify + } + positionInPath += this.pathStartOffset * (reverse ? -1 : 1); + for (let i = reverse ? llength - 1 : 0; reverse ? i >= 0 : i < llength; reverse ? i-- : i++) { + graphemeInfo = lineBounds[i]; + if (positionInPath > totalPathLength) { + positionInPath %= totalPathLength; + } else if (positionInPath < 0) { + positionInPath += totalPathLength; + } + // it would probably much faster to send all the grapheme position for a line + // and calculate path position/angle at once. + this._setGraphemeOnPath(positionInPath, graphemeInfo); + positionInPath += graphemeInfo.kernedWidth; + } + } + return { + width: width, + numOfSpaces: 0 + }; + } + + /** + * Calculate the angle and the left,top position of the char that follow a path. + * It appends it to graphemeInfo to be reused later at rendering + * @private + * @param {Number} positionInPath to be measured + * @param {GraphemeBBox} graphemeInfo current grapheme box information + * @param {Object} startingPoint position of the point + */ + _setGraphemeOnPath(positionInPath, graphemeInfo) { + const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2, + path = this.path; + + // we are at currentPositionOnPath. we want to know what point on the path is. + const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo); + graphemeInfo.renderLeft = info.x - path.pathOffset.x; + graphemeInfo.renderTop = info.y - path.pathOffset.y; + graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0); + } + + /** + * + * @param {String} grapheme to be measured + * @param {Number} lineIndex index of the line where the char is + * @param {Number} charIndex position in the line + * @param {String} [prevGrapheme] character preceding the one to be measured + * @returns {GraphemeBBox} grapheme bbox + */ + _getGraphemeBox(grapheme, lineIndex, charIndex, prevGrapheme, skipLeft) { + const style = this.getCompleteStyleDeclaration(lineIndex, charIndex), + prevStyle = prevGrapheme ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1) : {}, + info = this._measureChar(grapheme, style, prevGrapheme, prevStyle); + let kernedWidth = info.kernedWidth, + width = info.width, + charSpacing; + if (this.charSpacing !== 0) { + charSpacing = this._getWidthOfCharSpacing(); + width += charSpacing; + kernedWidth += charSpacing; + } + const box = { + width, + left: 0, + height: style.fontSize, + kernedWidth, + deltaY: style.deltaY + }; + if (charIndex > 0 && !skipLeft) { + const previousBox = this.__charBounds[lineIndex][charIndex - 1]; + box.left = previousBox.left + previousBox.width + info.kernedWidth - info.width; + } + return box; + } + + /** + * Calculate height of line at 'lineIndex' + * @param {Number} lineIndex index of line to calculate + * @return {Number} + */ + getHeightOfLine(lineIndex) { + if (this.__lineHeights[lineIndex]) { + return this.__lineHeights[lineIndex]; + } + + // char 0 is measured before the line cycle because it needs to char + // emptylines + let maxHeight = this.getHeightOfChar(lineIndex, 0); + for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) { + maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight); + } + return this.__lineHeights[lineIndex] = maxHeight * this.lineHeight * this._fontSizeMult; + } + + /** + * Calculate text box height + */ + calcTextHeight() { + let lineHeight, + height = 0; + for (let i = 0, len = this._textLines.length; i < len; i++) { + lineHeight = this.getHeightOfLine(i); + height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight; + } + return height; + } + + /** + * @private + * @return {Number} Left offset + */ + _getLeftOffset() { + return this.direction === 'ltr' ? -this.width / 2 : this.width / 2; + } + + /** + * @private + * @return {Number} Top offset + */ + _getTopOffset() { + return -this.height / 2; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {String} method Method name ("fillText" or "strokeText") + */ + _renderTextCommon(ctx, method) { + ctx.save(); + let lineHeights = 0; + const left = this._getLeftOffset(), + top = this._getTopOffset(); + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i), + maxHeight = heightOfLine / this.lineHeight, + leftOffset = this._getLineLeftOffset(i); + this._renderTextLine(method, ctx, this._textLines[i], left + leftOffset, top + lineHeights + maxHeight, i); + lineHeights += heightOfLine; + } + ctx.restore(); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextFill(ctx) { + if (!this.fill && !this.styleHas(FILL)) { + return; + } + this._renderTextCommon(ctx, 'fillText'); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextStroke(ctx) { + if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) { + return; + } + if (this.shadow && !this.shadow.affectStroke) { + this._removeShadow(ctx); + } + ctx.save(); + this._setLineDash(ctx, this.strokeDashArray); + ctx.beginPath(); + this._renderTextCommon(ctx, 'strokeText'); + ctx.closePath(); + ctx.restore(); + } + + /** + * @private + * @param {String} method fillText or strokeText. + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Array} line Content of the line, splitted in an array by grapheme + * @param {Number} left + * @param {Number} top + * @param {Number} lineIndex + */ + _renderChars(method, ctx, line, left, top, lineIndex) { + const lineHeight = this.getHeightOfLine(lineIndex), + isJustify = this.textAlign.includes(JUSTIFY), + path = this.path, + shortCut = !isJustify && this.charSpacing === 0 && this.isEmptyStyles(lineIndex) && !path, + isLtr = this.direction === 'ltr', + sign = this.direction === 'ltr' ? 1 : -1, + // this was changed in the PR #7674 + // currentDirection = ctx.canvas.getAttribute('dir'); + currentDirection = ctx.direction; + let actualStyle, + nextStyle, + charsToRender = '', + charBox, + boxWidth = 0, + timeToRender, + drawingLeft; + ctx.save(); + if (currentDirection !== this.direction) { + ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl'); + ctx.direction = isLtr ? 'ltr' : 'rtl'; + ctx.textAlign = isLtr ? LEFT : RIGHT; + } + top -= lineHeight * this._fontSizeFraction / this.lineHeight; + if (shortCut) { + // render all the line in one pass without checking + // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex); + this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top); + ctx.restore(); + return; + } + for (let i = 0, len = line.length - 1; i <= len; i++) { + timeToRender = i === len || this.charSpacing || path; + charsToRender += line[i]; + charBox = this.__charBounds[lineIndex][i]; + if (boxWidth === 0) { + left += sign * (charBox.kernedWidth - charBox.width); + boxWidth += charBox.width; + } else { + boxWidth += charBox.kernedWidth; + } + if (isJustify && !timeToRender) { + if (this._reSpaceAndTab.test(line[i])) { + timeToRender = true; + } + } + if (!timeToRender) { + // if we have charSpacing, we render char by char + actualStyle = actualStyle || this.getCompleteStyleDeclaration(lineIndex, i); + nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1); + timeToRender = hasStyleChanged(actualStyle, nextStyle, false); + } + if (timeToRender) { + if (path) { + ctx.save(); + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + this._renderChar(method, ctx, lineIndex, i, charsToRender, -boxWidth / 2, 0); + ctx.restore(); + } else { + drawingLeft = left; + this._renderChar(method, ctx, lineIndex, i, charsToRender, drawingLeft, top); + } + charsToRender = ''; + actualStyle = nextStyle; + left += sign * boxWidth; + boxWidth = 0; + } + } + ctx.restore(); + } + + /** + * This function try to patch the missing gradientTransform on canvas gradients. + * transforming a context to transform the gradient, is going to transform the stroke too. + * we want to transform the gradient but not the stroke operation, so we create + * a transformed gradient on a pattern and then we use the pattern instead of the gradient. + * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size + * is limited. + * @private + * @param {TFiller} filler a fabric gradient instance + * @return {CanvasPattern} a pattern to use as fill/stroke style + */ + _applyPatternGradientTransformText(filler) { + const pCanvas = createCanvasElement(), + // TODO: verify compatibility with strokeUniform + width = this.width + this.strokeWidth, + height = this.height + this.strokeWidth, + pCtx = pCanvas.getContext('2d'); + pCanvas.width = width; + pCanvas.height = height; + pCtx.beginPath(); + pCtx.moveTo(0, 0); + pCtx.lineTo(width, 0); + pCtx.lineTo(width, height); + pCtx.lineTo(0, height); + pCtx.closePath(); + pCtx.translate(width / 2, height / 2); + pCtx.fillStyle = filler.toLive(pCtx); + this._applyPatternGradientTransform(pCtx, filler); + pCtx.fill(); + return pCtx.createPattern(pCanvas, 'no-repeat'); + } + handleFiller(ctx, property, filler) { + let offsetX, offsetY; + if (isFiller(filler)) { + if (filler.gradientUnits === 'percentage' || filler.gradientTransform || filler.patternTransform) { + // need to transform gradient in a pattern. + // this is a slow process. If you are hitting this codepath, and the object + // is not using caching, you should consider switching it on. + // we need a canvas as big as the current object caching canvas. + offsetX = -this.width / 2; + offsetY = -this.height / 2; + ctx.translate(offsetX, offsetY); + ctx[property] = this._applyPatternGradientTransformText(filler); + return { + offsetX, + offsetY + }; + } else { + // is a simple gradient or pattern + ctx[property] = filler.toLive(ctx); + return this._applyPatternGradientTransform(ctx, filler); + } + } else { + // is a color + ctx[property] = filler; + } + return { + offsetX: 0, + offsetY: 0 + }; + } + + /** + * This function prepare the canvas for a stroke style, and stroke and strokeWidth + * need to be sent in as defined + * @param {CanvasRenderingContext2D} ctx + * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined + * @returns + */ + _setStrokeStyles(ctx, _ref) { + let { + stroke, + strokeWidth + } = _ref; + ctx.lineWidth = strokeWidth; + ctx.lineCap = this.strokeLineCap; + ctx.lineDashOffset = this.strokeDashOffset; + ctx.lineJoin = this.strokeLineJoin; + ctx.miterLimit = this.strokeMiterLimit; + return this.handleFiller(ctx, 'strokeStyle', stroke); + } + + /** + * This function prepare the canvas for a ill style, and fill + * need to be sent in as defined + * @param {CanvasRenderingContext2D} ctx + * @param {CompleteTextStyleDeclaration} style with ill defined + * @returns + */ + _setFillStyles(ctx, _ref2) { + let { + fill + } = _ref2; + return this.handleFiller(ctx, 'fillStyle', fill); + } + + /** + * @private + * @param {String} method + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {String} _char + * @param {Number} left Left coordinate + * @param {Number} top Top coordinate + * @param {Number} lineHeight Height of the line + */ + _renderChar(method, ctx, lineIndex, charIndex, _char, left, top) { + const decl = this._getStyleDeclaration(lineIndex, charIndex), + fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex), + shouldFill = method === 'fillText' && fullDecl.fill, + shouldStroke = method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth; + if (!shouldStroke && !shouldFill) { + return; + } + ctx.save(); + ctx.font = this._getFontDeclaration(fullDecl); + if (decl.textBackgroundColor) { + this._removeShadow(ctx); + } + if (decl.deltaY) { + top += decl.deltaY; + } + if (shouldFill) { + const fillOffsets = this._setFillStyles(ctx, fullDecl); + ctx.fillText(_char, left - fillOffsets.offsetX, top - fillOffsets.offsetY); + } + if (shouldStroke) { + const strokeOffsets = this._setStrokeStyles(ctx, fullDecl); + ctx.strokeText(_char, left - strokeOffsets.offsetX, top - strokeOffsets.offsetY); + } + ctx.restore(); + } + + /** + * Turns the character into a 'superior figure' (i.e. 'superscript') + * @param {Number} start selection start + * @param {Number} end selection end + */ + setSuperscript(start, end) { + this._setScript(start, end, this.superscript); + } + + /** + * Turns the character into an 'inferior figure' (i.e. 'subscript') + * @param {Number} start selection start + * @param {Number} end selection end + */ + setSubscript(start, end) { + this._setScript(start, end, this.subscript); + } + + /** + * Applies 'schema' at given position + * @private + * @param {Number} start selection start + * @param {Number} end selection end + * @param {Number} schema + */ + _setScript(start, end, schema) { + const loc = this.get2DCursorLocation(start, true), + fontSize = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'fontSize'), + dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'), + style = { + fontSize: fontSize * schema.size, + deltaY: dy + fontSize * schema.baseline + }; + this.setSelectionStyles(style, start, end); + } + + /** + * @private + * @param {Number} lineIndex index text line + * @return {Number} Line left offset + */ + _getLineLeftOffset(lineIndex) { + const lineWidth = this.getLineWidth(lineIndex), + lineDiff = this.width - lineWidth, + textAlign = this.textAlign, + direction = this.direction, + isEndOfWrapping = this.isEndOfWrapping(lineIndex); + let leftOffset = 0; + if (textAlign === JUSTIFY || textAlign === JUSTIFY_CENTER && !isEndOfWrapping || textAlign === JUSTIFY_RIGHT && !isEndOfWrapping || textAlign === JUSTIFY_LEFT && !isEndOfWrapping) { + return 0; + } + if (textAlign === CENTER) { + leftOffset = lineDiff / 2; + } + if (textAlign === RIGHT) { + leftOffset = lineDiff; + } + if (textAlign === JUSTIFY_CENTER) { + leftOffset = lineDiff / 2; + } + if (textAlign === JUSTIFY_RIGHT) { + leftOffset = lineDiff; + } + if (direction === 'rtl') { + if (textAlign === RIGHT || textAlign === JUSTIFY || textAlign === JUSTIFY_RIGHT) { + leftOffset = 0; + } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) { + leftOffset = -lineDiff; + } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) { + leftOffset = -lineDiff / 2; + } + } + return leftOffset; + } + + /** + * @private + */ + _clearCache() { + this._forceClearCache = false; + this.__lineWidths = []; + this.__lineHeights = []; + this.__charBounds = []; + } + + /** + * Measure a single line given its index. Used to calculate the initial + * text bounding box. The values are calculated and stored in __lineWidths cache. + * @private + * @param {Number} lineIndex line number + * @return {Number} Line width + */ + getLineWidth(lineIndex) { + if (this.__lineWidths[lineIndex] !== undefined) { + return this.__lineWidths[lineIndex]; + } + const { + width + } = this.measureLine(lineIndex); + this.__lineWidths[lineIndex] = width; + return width; + } + _getWidthOfCharSpacing() { + if (this.charSpacing !== 0) { + return this.fontSize * this.charSpacing / 1000; + } + return 0; + } + + /** + * Retrieves the value of property at given character position + * @param {Number} lineIndex the line number + * @param {Number} charIndex the character number + * @param {String} property the property name + * @returns the value of 'property' + */ + getValueOfPropertyAt(lineIndex, charIndex, property) { + var _charStyle$property; + const charStyle = this._getStyleDeclaration(lineIndex, charIndex); + return (_charStyle$property = charStyle[property]) !== null && _charStyle$property !== void 0 ? _charStyle$property : this[property]; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _renderTextDecoration(ctx, type) { + if (!this[type] && !this.styleHas(type)) { + return; + } + let topOffset = this._getTopOffset(); + const leftOffset = this._getLeftOffset(), + path = this.path, + charSpacing = this._getWidthOfCharSpacing(), + offsetY = this.offsets[type]; + for (let i = 0, len = this._textLines.length; i < len; i++) { + const heightOfLine = this.getHeightOfLine(i); + if (!this[type] && !this.styleHas(type, i)) { + topOffset += heightOfLine; + continue; + } + const line = this._textLines[i]; + const maxHeight = heightOfLine / this.lineHeight; + const lineLeftOffset = this._getLineLeftOffset(i); + let boxStart = 0; + let boxWidth = 0; + let lastDecoration = this.getValueOfPropertyAt(i, 0, type); + let lastFill = this.getValueOfPropertyAt(i, 0, FILL); + let currentDecoration; + let currentFill; + const top = topOffset + maxHeight * (1 - this._fontSizeFraction); + let size = this.getHeightOfChar(i, 0); + let dy = this.getValueOfPropertyAt(i, 0, 'deltaY'); + for (let j = 0, jlen = line.length; j < jlen; j++) { + const charBox = this.__charBounds[i][j]; + currentDecoration = this.getValueOfPropertyAt(i, j, type); + currentFill = this.getValueOfPropertyAt(i, j, FILL); + const currentSize = this.getHeightOfChar(i, j); + const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY'); + if (path && currentDecoration && currentFill) { + ctx.save(); + // bug? verify lastFill is a valid fill here. + ctx.fillStyle = lastFill; + ctx.translate(charBox.renderLeft, charBox.renderTop); + ctx.rotate(charBox.angle); + ctx.fillRect(-charBox.kernedWidth / 2, offsetY * currentSize + currentDy, charBox.kernedWidth, this.fontSize / 15); + ctx.restore(); + } else if ((currentDecoration !== lastDecoration || currentFill !== lastFill || currentSize !== size || currentDy !== dy) && boxWidth > 0) { + let drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + if (lastDecoration && lastFill) { + // bug? verify lastFill is a valid fill here. + ctx.fillStyle = lastFill; + ctx.fillRect(drawStart, top + offsetY * size + dy, boxWidth, this.fontSize / 15); + } + boxStart = charBox.left; + boxWidth = charBox.width; + lastDecoration = currentDecoration; + lastFill = currentFill; + size = currentSize; + dy = currentDy; + } else { + boxWidth += charBox.kernedWidth; + } + } + let drawStart = leftOffset + lineLeftOffset + boxStart; + if (this.direction === 'rtl') { + drawStart = this.width - drawStart - boxWidth; + } + ctx.fillStyle = currentFill; + currentDecoration && currentFill && ctx.fillRect(drawStart, top + offsetY * size + dy, boxWidth - charSpacing, this.fontSize / 15); + topOffset += heightOfLine; + } + // if there is text background color no + // other shadows should be casted + this._removeShadow(ctx); + } + + /** + * return font declaration string for canvas context + * @param {Object} [styleObject] object + * @returns {String} font declaration formatted for canvas context. + */ + _getFontDeclaration() { + let { + fontFamily = this.fontFamily, + fontStyle = this.fontStyle, + fontWeight = this.fontWeight, + fontSize = this.fontSize + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + let forMeasuring = arguments.length > 1 ? arguments[1] : undefined; + const parsedFontFamily = fontFamily.includes("'") || fontFamily.includes('"') || fontFamily.includes(',') || FabricText.genericFonts.includes(fontFamily.toLowerCase()) ? fontFamily : "\"".concat(fontFamily, "\""); + return [fontStyle, fontWeight, "".concat(forMeasuring ? this.CACHE_FONT_SIZE : fontSize, "px"), parsedFontFamily].join(' '); + } + + /** + * Renders text instance on a specified context + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + if (!this.visible) { + return; + } + if (this.canvas && this.canvas.skipOffscreen && !this.group && !this.isOnScreen()) { + return; + } + if (this._forceClearCache) { + this.initDimensions(); + } + super.render(ctx); + } + + /** + * Override this method to customize grapheme splitting + * @todo the util `graphemeSplit` needs to be injectable in some way. + * is more comfortable to inject the correct util rather than having to override text + * in the middle of the prototype chain + * @param {string} value + * @returns {string[]} array of graphemes + */ + graphemeSplit(value) { + return graphemeSplit(value); + } + + /** + * Returns the text as an array of lines. + * @param {String} text text to split + * @returns Lines in the text + */ + _splitTextIntoLines(text) { + const lines = text.split(this._reNewline), + newLines = new Array(lines.length), + newLine = ['\n']; + let newText = []; + for (let i = 0; i < lines.length; i++) { + newLines[i] = this.graphemeSplit(lines[i]); + newText = newText.concat(newLines[i], newLine); + } + newText.pop(); + return { + _unwrappedLines: newLines, + lines: lines, + graphemeText: newText, + graphemeLines: newLines + }; + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return _objectSpread2(_objectSpread2({}, super.toObject([...additionalProps, ...propertiesToInclude])), {}, { + styles: stylesToArray(this.styles, this.text) + }, this.path ? { + path: this.path.toObject() + } : {}); + } + set(key, value) { + const { + textLayoutProperties + } = this.constructor; + super.set(key, value); + let needsDims = false; + let isAddingPath = false; + if (typeof key === 'object') { + for (const _key in key) { + if (_key === 'path') { + this.setPathInfo(); + } + needsDims = needsDims || textLayoutProperties.includes(_key); + isAddingPath = isAddingPath || _key === 'path'; + } + } else { + needsDims = textLayoutProperties.includes(key); + isAddingPath = key === 'path'; + } + if (isAddingPath) { + this.setPathInfo(); + } + if (needsDims && this.initialized) { + this.initDimensions(); + this.setCoords(); + } + return this; + } + + /** + * Returns complexity of an instance + * @return {Number} complexity + */ + complexity() { + return 1; + } + /** + * Returns FabricText instance from an SVG element (not yet implemented) + * @static + * @memberOf Text + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + */ + static async fromElement(element, options, cssRules) { + const parsedAttributes = parseAttributes(element, FabricText.ATTRIBUTE_NAMES, cssRules); + const _options$parsedAttrib = _objectSpread2(_objectSpread2({}, options), parsedAttributes), + { + textAnchor = LEFT, + textDecoration = '', + dx = 0, + dy = 0, + top = 0, + left = 0, + fontSize = DEFAULT_SVG_FONT_SIZE, + strokeWidth = 1 + } = _options$parsedAttrib, + restOfOptions = _objectWithoutProperties(_options$parsedAttrib, _excluded$3); + const textContent = (element.textContent || '').replace(/^\s+|\s+$|\n+/g, '').replace(/\s+/g, ' '); + + // this code here is probably the usual issue for SVG center find + // this can later looked at again and probably removed. + + const text = new this(textContent, _objectSpread2({ + left: left + dx, + top: top + dy, + underline: textDecoration.includes('underline'), + overline: textDecoration.includes('overline'), + linethrough: textDecoration.includes('line-through'), + // we initialize this as 0 + strokeWidth: 0, + fontSize + }, restOfOptions)), + textHeightScaleFactor = text.getScaledHeight() / text.height, + lineHeightDiff = (text.height + text.strokeWidth) * text.lineHeight - text.height, + scaledDiff = lineHeightDiff * textHeightScaleFactor, + textHeight = text.getScaledHeight() + scaledDiff; + let offX = 0; + /* + Adjust positioning: + x/y attributes in SVG correspond to the bottom-left corner of text bounding box + fabric output by default at top, left. + */ + if (textAnchor === CENTER) { + offX = text.getScaledWidth() / 2; + } + if (textAnchor === RIGHT) { + offX = text.getScaledWidth(); + } + text.set({ + left: text.left - offX, + top: text.top - (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) / text.lineHeight, + strokeWidth + }); + return text; + } + + /* _FROM_SVG_END_ */ + + /** + * Returns FabricText instance from an object representation + * @param {Object} object plain js Object to create an instance from + * @returns {Promise} + */ + static fromObject(object) { + return this._fromObject(_objectSpread2(_objectSpread2({}, object), {}, { + styles: stylesFromArray(object.styles || {}, object.text) + }), { + extraParam: 'text' + }); + } +} +/** + * Properties that requires a text layout recalculation when changed + * @type string[] + * @protected + */ +_defineProperty(FabricText, "textLayoutProperties", textLayoutProperties); +_defineProperty(FabricText, "cacheProperties", [...cacheProperties, ...additionalProps]); +_defineProperty(FabricText, "ownDefaults", textDefaultValues); +_defineProperty(FabricText, "type", 'Text'); +_defineProperty(FabricText, "genericFonts", ['sans-serif', 'serif', 'cursive', 'fantasy', 'monospace']); +/* _FROM_SVG_START_ */ +/** + * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement}) + * @static + * @memberOf Text + * @see: http://www.w3.org/TR/SVG/text.html#TextElement + */ +_defineProperty(FabricText, "ATTRIBUTE_NAMES", SHARED_ATTRIBUTES.concat('x', 'y', 'dx', 'dy', 'font-family', 'font-style', 'font-weight', 'font-size', 'letter-spacing', 'text-decoration', 'text-anchor')); +applyMixins(FabricText, [TextSVGExportMixin]); +classRegistry.setClass(FabricText); +classRegistry.setSVGClass(FabricText); + +/** + * #### Dragging IText/Textbox Lifecycle + * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection} + * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection + * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session + * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur + * - canvas fires relevant drag events that are handled by the handlers defined in this scope + * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior + * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown` + */ +class DraggableTextDelegate { + constructor(target) { + _defineProperty(this, "target", void 0); + _defineProperty(this, "__mouseDownInPlace", false); + _defineProperty(this, "__dragStartFired", false); + _defineProperty(this, "__isDraggingOver", false); + _defineProperty(this, "__dragStartSelection", void 0); + _defineProperty(this, "__dragImageDisposer", void 0); + _defineProperty(this, "_dispose", void 0); + this.target = target; + const disposers = [this.target.on('dragenter', this.dragEnterHandler.bind(this)), this.target.on('dragover', this.dragOverHandler.bind(this)), this.target.on('dragleave', this.dragLeaveHandler.bind(this)), this.target.on('dragend', this.dragEndHandler.bind(this)), this.target.on('drop', this.dropHandler.bind(this))]; + this._dispose = () => { + disposers.forEach(d => d()); + this._dispose = undefined; + }; + } + isPointerOverSelection(e) { + const target = this.target; + const newSelection = target.getSelectionStartFromPointer(e); + return target.isEditing && newSelection >= target.selectionStart && newSelection <= target.selectionEnd && target.selectionStart < target.selectionEnd; + } + + /** + * @public override this method to disable dragging and default to mousedown logic + */ + start(e) { + return this.__mouseDownInPlace = this.isPointerOverSelection(e); + } + + /** + * @public override this method to disable dragging without discarding selection + */ + isActive() { + return this.__mouseDownInPlace; + } + + /** + * Ends interaction and sets cursor in case of a click + * @returns true if was active + */ + end(e) { + const active = this.isActive(); + if (active && !this.__dragStartFired) { + // mousedown has been blocked since `active` is true => cursor has not been set. + // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection. + // meaning this is actually a click, `active` is a false positive. + this.target.setCursorByClick(e); + this.target.initDelayedCursor(true); + } + this.__mouseDownInPlace = false; + this.__dragStartFired = false; + this.__isDraggingOver = false; + return active; + } + getDragStartSelection() { + return this.__dragStartSelection; + } + + /** + * Override to customize the drag image + * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage + */ + setDragImage(e, _ref) { + var _e$dataTransfer; + let { + selectionStart, + selectionEnd + } = _ref; + const target = this.target; + const canvas = target.canvas; + const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1); + const boundaries = target._getCursorBoundaries(selectionStart); + const selectionPosition = new Point(boundaries.left + boundaries.leftOffset, boundaries.top + boundaries.topOffset).multiply(flipFactor); + const pos = selectionPosition.transform(target.calcTransformMatrix()); + const pointer = canvas.getScenePoint(e); + const diff = pointer.subtract(pos); + const retinaScaling = target.getCanvasRetinaScaling(); + const bbox = target.getBoundingRect(); + const correction = pos.subtract(new Point(bbox.left, bbox.top)); + const vpt = canvas.viewportTransform; + const offset = correction.add(diff).transform(vpt, true); + // prepare instance for drag image snapshot by making all non selected text invisible + const bgc = target.backgroundColor; + const styles = cloneStyles(target.styles); + target.backgroundColor = ''; + const styleOverride = { + stroke: 'transparent', + fill: 'transparent', + textBackgroundColor: 'transparent' + }; + target.setSelectionStyles(styleOverride, 0, selectionStart); + target.setSelectionStyles(styleOverride, selectionEnd, target.text.length); + target.dirty = true; + const dragImage = target.toCanvasElement({ + enableRetinaScaling: canvas.enableRetinaScaling, + viewportTransform: true + }); + // restore values + target.backgroundColor = bgc; + target.styles = styles; + target.dirty = true; + // position drag image offscreen + setStyle(dragImage, { + position: 'fixed', + left: "".concat(-dragImage.width, "px"), + border: NONE, + width: "".concat(dragImage.width / retinaScaling, "px"), + height: "".concat(dragImage.height / retinaScaling, "px") + }); + this.__dragImageDisposer && this.__dragImageDisposer(); + this.__dragImageDisposer = () => { + dragImage.remove(); + }; + getDocumentFromElement(e.target || this.target.hiddenTextarea).body.appendChild(dragImage); + (_e$dataTransfer = e.dataTransfer) === null || _e$dataTransfer === void 0 || _e$dataTransfer.setDragImage(dragImage, offset.x, offset.y); + } + + /** + * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source + */ + onDragStart(e) { + this.__dragStartFired = true; + const target = this.target; + const active = this.isActive(); + if (active && e.dataTransfer) { + const selection = this.__dragStartSelection = { + selectionStart: target.selectionStart, + selectionEnd: target.selectionEnd + }; + const value = target._text.slice(selection.selectionStart, selection.selectionEnd).join(''); + const data = _objectSpread2({ + text: target.text, + value + }, selection); + e.dataTransfer.setData('text/plain', value); + e.dataTransfer.setData('application/fabric', JSON.stringify({ + value: value, + styles: target.getSelectionStyles(selection.selectionStart, selection.selectionEnd, true) + })); + e.dataTransfer.effectAllowed = 'copyMove'; + this.setDragImage(e, data); + } + target.abortCursorAnimation(); + return active; + } + + /** + * use {@link targetCanDrop} to respect overriding + * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target + */ + canDrop(e) { + if (this.target.editable && !this.target.getActiveControl() && !e.defaultPrevented) { + if (this.isActive() && this.__dragStartSelection) { + // drag source trying to drop over itself + // allow dropping only outside of drag start selection + const index = this.target.getSelectionStartFromPointer(e); + const dragStartSelection = this.__dragStartSelection; + return index < dragStartSelection.selectionStart || index > dragStartSelection.selectionEnd; + } + return true; + } + return false; + } + + /** + * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly + */ + targetCanDrop(e) { + return this.target.canDrop(e); + } + dragEnterHandler(_ref2) { + let { + e + } = _ref2; + const canDrop = this.targetCanDrop(e); + if (!this.__isDraggingOver && canDrop) { + this.__isDraggingOver = true; + } + } + dragOverHandler(ev) { + const { + e + } = ev; + const canDrop = this.targetCanDrop(e); + if (!this.__isDraggingOver && canDrop) { + this.__isDraggingOver = true; + } else if (this.__isDraggingOver && !canDrop) { + // drop state has changed + this.__isDraggingOver = false; + } + if (this.__isDraggingOver) { + // can be dropped, inform browser + e.preventDefault(); + // inform event subscribers + ev.canDrop = true; + ev.dropTarget = this.target; + } + } + dragLeaveHandler() { + if (this.__isDraggingOver || this.isActive()) { + this.__isDraggingOver = false; + } + } + + /** + * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer} + * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop + */ + dropHandler(ev) { + var _e$dataTransfer2; + const { + e + } = ev; + const didDrop = e.defaultPrevented; + this.__isDraggingOver = false; + // inform browser that the drop has been accepted + e.preventDefault(); + let insert = (_e$dataTransfer2 = e.dataTransfer) === null || _e$dataTransfer2 === void 0 ? void 0 : _e$dataTransfer2.getData('text/plain'); + if (insert && !didDrop) { + const target = this.target; + const canvas = target.canvas; + let insertAt = target.getSelectionStartFromPointer(e); + const { + styles + } = e.dataTransfer.types.includes('application/fabric') ? JSON.parse(e.dataTransfer.getData('application/fabric')) : {}; + const trailing = insert[Math.max(0, insert.length - 1)]; + const selectionStartOffset = 0; + // drag and drop in same instance + if (this.__dragStartSelection) { + const selectionStart = this.__dragStartSelection.selectionStart; + const selectionEnd = this.__dragStartSelection.selectionEnd; + if (insertAt > selectionStart && insertAt <= selectionEnd) { + insertAt = selectionStart; + } else if (insertAt > selectionEnd) { + insertAt -= selectionEnd - selectionStart; + } + target.removeChars(selectionStart, selectionEnd); + // prevent `dragend` from handling event + delete this.__dragStartSelection; + } + // remove redundant line break + if (target._reNewline.test(trailing) && (target._reNewline.test(target._text[insertAt]) || insertAt === target._text.length)) { + insert = insert.trimEnd(); + } + // inform subscribers + ev.didDrop = true; + ev.dropTarget = target; + // finalize + target.insertChars(insert, styles, insertAt); + // can this part be moved in an outside event? andrea to check. + canvas.setActiveObject(target); + target.enterEditing(e); + target.selectionStart = Math.min(insertAt + selectionStartOffset, target._text.length); + target.selectionEnd = Math.min(target.selectionStart + insert.length, target._text.length); + target.hiddenTextarea.value = target.text; + target._updateTextarea(); + target.hiddenTextarea.focus(); + target.fire(CHANGED, { + index: insertAt + selectionStartOffset, + action: 'drop' + }); + canvas.fire('text:changed', { + target + }); + canvas.contextTopDirty = true; + canvas.requestRenderAll(); + } + } + + /** + * fired only on the drag source after drop (if occurred) + * handle changes to the drag source in case of a drop on another object or a cancellation + * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag + */ + dragEndHandler(_ref3) { + let { + e + } = _ref3; + if (this.isActive() && this.__dragStartFired) { + // once the drop event finishes we check if we need to change the drag source + // if the drag source received the drop we bail out since the drop handler has already handled logic + if (this.__dragStartSelection) { + var _e$dataTransfer3; + const target = this.target; + const canvas = this.target.canvas; + const { + selectionStart, + selectionEnd + } = this.__dragStartSelection; + const dropEffect = ((_e$dataTransfer3 = e.dataTransfer) === null || _e$dataTransfer3 === void 0 ? void 0 : _e$dataTransfer3.dropEffect) || NONE; + if (dropEffect === NONE) { + // pointer is back over selection + target.selectionStart = selectionStart; + target.selectionEnd = selectionEnd; + target._updateTextarea(); + target.hiddenTextarea.focus(); + } else { + target.clearContextTop(); + if (dropEffect === 'move') { + target.removeChars(selectionStart, selectionEnd); + target.selectionStart = target.selectionEnd = selectionStart; + target.hiddenTextarea && (target.hiddenTextarea.value = target.text); + target._updateTextarea(); + target.fire(CHANGED, { + index: selectionStart, + action: 'dragend' + }); + canvas.fire('text:changed', { + target + }); + canvas.requestRenderAll(); + } + target.exitEditing(); + } + } + } + this.__dragImageDisposer && this.__dragImageDisposer(); + delete this.__dragImageDisposer; + delete this.__dragStartSelection; + this.__isDraggingOver = false; + } + dispose() { + this._dispose && this._dispose(); + } +} + +/** + * extend this regex to support non english languages + * + * - ` ` Matches a SPACE character (char code 32). + * - `\n` Matches a LINE FEED character (char code 10). + * - `\.` Matches a "." character (char code 46). + * - `,` Matches a "," character (char code 44). + * - `;` Matches a ";" character (char code 59). + * - `!` Matches a "!" character (char code 33). + * - `\?` Matches a "?" character (char code 63). + * - `\-` Matches a "-" character (char code 45). + */ +// eslint-disable-next-line no-useless-escape +const reNonWord = /[ \n\.,;!\?\-]/; +class ITextBehavior extends FabricText { + constructor() { + super(...arguments); + /** + * Helps determining when the text is in composition, so that the cursor + * rendering is altered. + */ + _defineProperty(this, "_currentCursorOpacity", 1); + } + /** + * Initializes all the interactive behavior of IText + */ + initBehavior() { + this._tick = this._tick.bind(this); + this._onTickComplete = this._onTickComplete.bind(this); + this.updateSelectionOnMouseMove = this.updateSelectionOnMouseMove.bind(this); + } + onDeselect(options) { + this.isEditing && this.exitEditing(); + this.selected = false; + return super.onDeselect(options); + } + + /** + * @private + */ + _animateCursor(_ref) { + let { + toValue, + duration, + delay, + onComplete + } = _ref; + return animate({ + startValue: this._currentCursorOpacity, + endValue: toValue, + duration, + delay, + onComplete, + abort: () => !this.canvas || + // we do not want to animate a selection, only cursor + this.selectionStart !== this.selectionEnd, + onChange: value => { + this._currentCursorOpacity = value; + this.renderCursorOrSelection(); + } + }); + } + + /** + * changes the cursor from visible to invisible + */ + _tick(delay) { + this._currentTickState = this._animateCursor({ + toValue: 0, + duration: this.cursorDuration / 2, + delay: Math.max(delay || 0, 100), + onComplete: this._onTickComplete + }); + } + + /** + * Changes the cursor from invisible to visible + */ + _onTickComplete() { + var _this$_currentTickCom; + (_this$_currentTickCom = this._currentTickCompleteState) === null || _this$_currentTickCom === void 0 || _this$_currentTickCom.abort(); + this._currentTickCompleteState = this._animateCursor({ + toValue: 1, + duration: this.cursorDuration, + onComplete: this._tick + }); + } + + /** + * Initializes delayed cursor + */ + initDelayedCursor(restart) { + this.abortCursorAnimation(); + this._tick(restart ? 0 : this.cursorDelay); + } + + /** + * Aborts cursor animation, clears all timeouts and clear textarea context if necessary + */ + abortCursorAnimation() { + let shouldClear = false; + [this._currentTickState, this._currentTickCompleteState].forEach(cursorAnimation => { + if (cursorAnimation && !cursorAnimation.isDone()) { + shouldClear = true; + cursorAnimation.abort(); + } + }); + this._currentCursorOpacity = 1; + + // make sure we clear context even if instance is not editing + if (shouldClear) { + this.clearContextTop(); + } + } + + /** + * Restart tue cursor animation if either is in complete state ( between animations ) + * or if it never started before + */ + restartCursorIfNeeded() { + if ([this._currentTickState, this._currentTickCompleteState].some(cursorAnimation => !cursorAnimation || cursorAnimation.isDone())) { + this.initDelayedCursor(); + } + } + + /** + * Selects entire text + */ + selectAll() { + this.selectionStart = 0; + this.selectionEnd = this._text.length; + this._fireSelectionChanged(); + this._updateTextarea(); + return this; + } + + /** + * Returns selected text + * @return {String} + */ + getSelectedText() { + return this._text.slice(this.selectionStart, this.selectionEnd).join(''); + } + + /** + * Find new selection index representing start of current word according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findWordBoundaryLeft(startFrom) { + let offset = 0, + index = startFrom - 1; + + // remove space before cursor first + if (this._reSpace.test(this._text[index])) { + while (this._reSpace.test(this._text[index])) { + offset++; + index--; + } + } + while (/\S/.test(this._text[index]) && index > -1) { + offset++; + index--; + } + return startFrom - offset; + } + + /** + * Find new selection index representing end of current word according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findWordBoundaryRight(startFrom) { + let offset = 0, + index = startFrom; + + // remove space after cursor first + if (this._reSpace.test(this._text[index])) { + while (this._reSpace.test(this._text[index])) { + offset++; + index++; + } + } + while (/\S/.test(this._text[index]) && index < this._text.length) { + offset++; + index++; + } + return startFrom + offset; + } + + /** + * Find new selection index representing start of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryLeft(startFrom) { + let offset = 0, + index = startFrom - 1; + while (!/\n/.test(this._text[index]) && index > -1) { + offset++; + index--; + } + return startFrom - offset; + } + + /** + * Find new selection index representing end of current line according to current selection index + * @param {Number} startFrom Current selection index + * @return {Number} New selection index + */ + findLineBoundaryRight(startFrom) { + let offset = 0, + index = startFrom; + while (!/\n/.test(this._text[index]) && index < this._text.length) { + offset++; + index++; + } + return startFrom + offset; + } + + /** + * Finds index corresponding to beginning or end of a word + * @param {Number} selectionStart Index of a character + * @param {Number} direction 1 or -1 + * @return {Number} Index of the beginning or end of a word + */ + searchWordBoundary(selectionStart, direction) { + const text = this._text; + // if we land on a space we move the cursor backwards + // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break + let index = selectionStart > 0 && this._reSpace.test(text[selectionStart]) && (direction === -1 || !reNewline.test(text[selectionStart - 1])) ? selectionStart - 1 : selectionStart, + _char = text[index]; + while (index > 0 && index < text.length && !reNonWord.test(_char)) { + index += direction; + _char = text[index]; + } + if (direction === -1 && reNonWord.test(_char)) { + index++; + } + return index; + } + + /** + * TODO fix: selectionStart set as 0 will be ignored? + * Selects a word based on the index + * @param {Number} selectionStart Index of a character + */ + selectWord(selectionStart) { + selectionStart = selectionStart || this.selectionStart; + // search backwards + const newSelectionStart = this.searchWordBoundary(selectionStart, -1), + // search forward + newSelectionEnd = Math.max(newSelectionStart, this.searchWordBoundary(selectionStart, 1)); + this.selectionStart = newSelectionStart; + this.selectionEnd = newSelectionEnd; + this._fireSelectionChanged(); + this._updateTextarea(); + this.renderCursorOrSelection(); + } + + /** + * TODO fix: selectionStart set as 0 will be ignored? + * Selects a line based on the index + * @param {Number} selectionStart Index of a character + */ + selectLine(selectionStart) { + selectionStart = selectionStart || this.selectionStart; + const newSelectionStart = this.findLineBoundaryLeft(selectionStart), + newSelectionEnd = this.findLineBoundaryRight(selectionStart); + this.selectionStart = newSelectionStart; + this.selectionEnd = newSelectionEnd; + this._fireSelectionChanged(); + this._updateTextarea(); + return this; + } + + /** + * Enters editing state + */ + enterEditing(e) { + if (this.isEditing || !this.editable) { + return; + } + if (this.canvas) { + this.canvas.calcOffset(); + this.canvas.textEditingManager.exitTextEditing(); + } + this.isEditing = true; + this.initHiddenTextarea(); + this.hiddenTextarea.focus(); + this.hiddenTextarea.value = this.text; + this._updateTextarea(); + this._saveEditingProps(); + this._setEditingProps(); + this._textBeforeEdit = this.text; + this._tick(); + this.fire('editing:entered', e ? { + e + } : undefined); + this._fireSelectionChanged(); + if (this.canvas) { + this.canvas.fire('text:editing:entered', { + target: this, + e + }); + this.canvas.requestRenderAll(); + } + } + + /** + * called by {@link Canvas#textEditingManager} + */ + updateSelectionOnMouseMove(e) { + if (this.getActiveControl()) { + return; + } + const el = this.hiddenTextarea; + // regain focus + getDocumentFromElement(el).activeElement !== el && el.focus(); + const newSelectionStart = this.getSelectionStartFromPointer(e), + currentStart = this.selectionStart, + currentEnd = this.selectionEnd; + if ((newSelectionStart !== this.__selectionStartOnMouseDown || currentStart === currentEnd) && (currentStart === newSelectionStart || currentEnd === newSelectionStart)) { + return; + } + if (newSelectionStart > this.__selectionStartOnMouseDown) { + this.selectionStart = this.__selectionStartOnMouseDown; + this.selectionEnd = newSelectionStart; + } else { + this.selectionStart = newSelectionStart; + this.selectionEnd = this.__selectionStartOnMouseDown; + } + if (this.selectionStart !== currentStart || this.selectionEnd !== currentEnd) { + this._fireSelectionChanged(); + this._updateTextarea(); + this.renderCursorOrSelection(); + } + } + + /** + * @private + */ + _setEditingProps() { + this.hoverCursor = 'text'; + if (this.canvas) { + this.canvas.defaultCursor = this.canvas.moveCursor = 'text'; + } + this.borderColor = this.editingBorderColor; + this.hasControls = this.selectable = false; + this.lockMovementX = this.lockMovementY = true; + } + + /** + * convert from textarea to grapheme indexes + */ + fromStringToGraphemeSelection(start, end, text) { + const smallerTextStart = text.slice(0, start), + graphemeStart = this.graphemeSplit(smallerTextStart).length; + if (start === end) { + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + }; + } + const smallerTextEnd = text.slice(start, end), + graphemeEnd = this.graphemeSplit(smallerTextEnd).length; + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + graphemeEnd + }; + } + + /** + * convert from fabric to textarea values + */ + fromGraphemeToStringSelection(start, end, graphemes) { + const smallerTextStart = graphemes.slice(0, start), + graphemeStart = smallerTextStart.join('').length; + if (start === end) { + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + }; + } + const smallerTextEnd = graphemes.slice(start, end), + graphemeEnd = smallerTextEnd.join('').length; + return { + selectionStart: graphemeStart, + selectionEnd: graphemeStart + graphemeEnd + }; + } + + /** + * @private + */ + _updateTextarea() { + this.cursorOffsetCache = {}; + if (!this.hiddenTextarea) { + return; + } + if (!this.inCompositionMode) { + const newSelection = this.fromGraphemeToStringSelection(this.selectionStart, this.selectionEnd, this._text); + this.hiddenTextarea.selectionStart = newSelection.selectionStart; + this.hiddenTextarea.selectionEnd = newSelection.selectionEnd; + } + this.updateTextareaPosition(); + } + + /** + * @private + */ + updateFromTextArea() { + if (!this.hiddenTextarea) { + return; + } + this.cursorOffsetCache = {}; + const textarea = this.hiddenTextarea; + this.text = textarea.value; + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + const newSelection = this.fromStringToGraphemeSelection(textarea.selectionStart, textarea.selectionEnd, textarea.value); + this.selectionEnd = this.selectionStart = newSelection.selectionEnd; + if (!this.inCompositionMode) { + this.selectionStart = newSelection.selectionStart; + } + this.updateTextareaPosition(); + } + + /** + * @private + */ + updateTextareaPosition() { + if (this.selectionStart === this.selectionEnd) { + const style = this._calcTextareaPosition(); + this.hiddenTextarea.style.left = style.left; + this.hiddenTextarea.style.top = style.top; + } + } + + /** + * @private + * @return {Object} style contains style for hiddenTextarea + */ + _calcTextareaPosition() { + if (!this.canvas) { + return { + left: '1px', + top: '1px' + }; + } + const desiredPosition = this.inCompositionMode ? this.compositionStart : this.selectionStart, + boundaries = this._getCursorBoundaries(desiredPosition), + cursorLocation = this.get2DCursorLocation(desiredPosition), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex, + charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') * this.lineHeight, + leftOffset = boundaries.leftOffset, + retinaScaling = this.getCanvasRetinaScaling(), + upperCanvas = this.canvas.upperCanvasEl, + upperCanvasWidth = upperCanvas.width / retinaScaling, + upperCanvasHeight = upperCanvas.height / retinaScaling, + maxWidth = upperCanvasWidth - charHeight, + maxHeight = upperCanvasHeight - charHeight; + const p = new Point(boundaries.left + leftOffset, boundaries.top + boundaries.topOffset + charHeight).transform(this.calcTransformMatrix()).transform(this.canvas.viewportTransform).multiply(new Point(upperCanvas.clientWidth / upperCanvasWidth, upperCanvas.clientHeight / upperCanvasHeight)); + if (p.x < 0) { + p.x = 0; + } + if (p.x > maxWidth) { + p.x = maxWidth; + } + if (p.y < 0) { + p.y = 0; + } + if (p.y > maxHeight) { + p.y = maxHeight; + } + + // add canvas offset on document + p.x += this.canvas._offset.left; + p.y += this.canvas._offset.top; + return { + left: "".concat(p.x, "px"), + top: "".concat(p.y, "px"), + fontSize: "".concat(charHeight, "px"), + charHeight: charHeight + }; + } + + /** + * @private + */ + _saveEditingProps() { + this._savedProps = { + hasControls: this.hasControls, + borderColor: this.borderColor, + lockMovementX: this.lockMovementX, + lockMovementY: this.lockMovementY, + hoverCursor: this.hoverCursor, + selectable: this.selectable, + defaultCursor: this.canvas && this.canvas.defaultCursor, + moveCursor: this.canvas && this.canvas.moveCursor + }; + } + + /** + * @private + */ + _restoreEditingProps() { + if (!this._savedProps) { + return; + } + this.hoverCursor = this._savedProps.hoverCursor; + this.hasControls = this._savedProps.hasControls; + this.borderColor = this._savedProps.borderColor; + this.selectable = this._savedProps.selectable; + this.lockMovementX = this._savedProps.lockMovementX; + this.lockMovementY = this._savedProps.lockMovementY; + if (this.canvas) { + this.canvas.defaultCursor = this._savedProps.defaultCursor || this.canvas.defaultCursor; + this.canvas.moveCursor = this._savedProps.moveCursor || this.canvas.moveCursor; + } + delete this._savedProps; + } + + /** + * runs the actual logic that exits from editing state, see {@link exitEditing} + */ + _exitEditing() { + const hiddenTextarea = this.hiddenTextarea; + this.selected = false; + this.isEditing = false; + if (hiddenTextarea) { + hiddenTextarea.blur && hiddenTextarea.blur(); + hiddenTextarea.parentNode && hiddenTextarea.parentNode.removeChild(hiddenTextarea); + } + this.hiddenTextarea = null; + this.abortCursorAnimation(); + this.selectionStart !== this.selectionEnd && this.clearContextTop(); + } + + /** + * Exits from editing state and fires relevant events + */ + exitEditing() { + const isTextChanged = this._textBeforeEdit !== this.text; + this._exitEditing(); + this.selectionEnd = this.selectionStart; + this._restoreEditingProps(); + if (this._forceClearCache) { + this.initDimensions(); + this.setCoords(); + } + this.fire('editing:exited'); + isTextChanged && this.fire(MODIFIED); + if (this.canvas) { + this.canvas.fire('text:editing:exited', { + target: this + }); + // todo: evaluate add an action to this event + isTextChanged && this.canvas.fire('object:modified', { + target: this + }); + } + return this; + } + + /** + * @private + */ + _removeExtraneousStyles() { + for (const prop in this.styles) { + if (!this._textLines[prop]) { + delete this.styles[prop]; + } + } + } + + /** + * remove and reflow a style block from start to end. + * @param {Number} start linear start position for removal (included in removal) + * @param {Number} end linear end position for removal ( excluded from removal ) + */ + removeStyleFromTo(start, end) { + const { + lineIndex: lineStart, + charIndex: charStart + } = this.get2DCursorLocation(start, true), + { + lineIndex: lineEnd, + charIndex: charEnd + } = this.get2DCursorLocation(end, true); + if (lineStart !== lineEnd) { + // step1 remove the trailing of lineStart + if (this.styles[lineStart]) { + for (let i = charStart; i < this._unwrappedTextLines[lineStart].length; i++) { + delete this.styles[lineStart][i]; + } + } + // step2 move the trailing of lineEnd to lineStart if needed + if (this.styles[lineEnd]) { + for (let i = charEnd; i < this._unwrappedTextLines[lineEnd].length; i++) { + const styleObj = this.styles[lineEnd][i]; + if (styleObj) { + this.styles[lineStart] || (this.styles[lineStart] = {}); + this.styles[lineStart][charStart + i - charEnd] = styleObj; + } + } + } + // step3 detects lines will be completely removed. + for (let i = lineStart + 1; i <= lineEnd; i++) { + delete this.styles[i]; + } + // step4 shift remaining lines. + this.shiftLineStyles(lineEnd, lineStart - lineEnd); + } else { + // remove and shift left on the same line + if (this.styles[lineStart]) { + const styleObj = this.styles[lineStart]; + const diff = charEnd - charStart; + for (let i = charStart; i < charEnd; i++) { + delete styleObj[i]; + } + for (const char in this.styles[lineStart]) { + const numericChar = parseInt(char, 10); + if (numericChar >= charEnd) { + styleObj[numericChar - diff] = styleObj[char]; + delete styleObj[char]; + } + } + } + } + } + + /** + * Shifts line styles up or down + * @param {Number} lineIndex Index of a line + * @param {Number} offset Can any number? + */ + shiftLineStyles(lineIndex, offset) { + const clonedStyles = Object.assign({}, this.styles); + for (const line in this.styles) { + const numericLine = parseInt(line, 10); + if (numericLine > lineIndex) { + this.styles[numericLine + offset] = clonedStyles[numericLine]; + if (!clonedStyles[numericLine - offset]) { + delete this.styles[numericLine]; + } + } + } + } + + /** + * Handle insertion of more consecutive style lines for when one or more + * newlines gets added to the text. Since current style needs to be shifted + * first we shift the current style of the number lines needed, then we add + * new lines from the last to the first. + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Number} qty number of lines to add + * @param {Array} copiedStyle Array of objects styles + */ + insertNewlineStyleObject(lineIndex, charIndex, qty, copiedStyle) { + const newLineStyles = {}; + const originalLineLength = this._unwrappedTextLines[lineIndex].length; + const isEndOfLine = originalLineLength === charIndex; + let someStyleIsCarryingOver = false; + qty || (qty = 1); + this.shiftLineStyles(lineIndex, qty); + const currentCharStyle = this.styles[lineIndex] ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1] : undefined; + + // we clone styles of all chars + // after cursor onto the current line + for (const index in this.styles[lineIndex]) { + const numIndex = parseInt(index, 10); + if (numIndex >= charIndex) { + someStyleIsCarryingOver = true; + newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index]; + // remove lines from the previous line since they're on a new line now + if (!(isEndOfLine && charIndex === 0)) { + delete this.styles[lineIndex][index]; + } + } + } + let styleCarriedOver = false; + if (someStyleIsCarryingOver && !isEndOfLine) { + // if is end of line, the extra style we copied + // is probably not something we want + this.styles[lineIndex + qty] = newLineStyles; + styleCarriedOver = true; + } + if (styleCarriedOver || originalLineLength > charIndex) { + // skip the last line of since we already prepared it. + // or contains text without style that we don't want to style + // just because it changed lines + qty--; + } + // for the all the lines or all the other lines + // we clone current char style onto the next (otherwise empty) line + while (qty > 0) { + if (copiedStyle && copiedStyle[qty - 1]) { + this.styles[lineIndex + qty] = { + 0: _objectSpread2({}, copiedStyle[qty - 1]) + }; + } else if (currentCharStyle) { + this.styles[lineIndex + qty] = { + 0: _objectSpread2({}, currentCharStyle) + }; + } else { + delete this.styles[lineIndex + qty]; + } + qty--; + } + this._forceClearCache = true; + } + + /** + * Inserts style object for a given line/char index + * @param {Number} lineIndex Index of a line + * @param {Number} charIndex Index of a char + * @param {Number} quantity number Style object to insert, if given + * @param {Array} copiedStyle array of style objects + */ + insertCharStyleObject(lineIndex, charIndex, quantity, copiedStyle) { + if (!this.styles) { + this.styles = {}; + } + const currentLineStyles = this.styles[lineIndex], + currentLineStylesCloned = currentLineStyles ? _objectSpread2({}, currentLineStyles) : {}; + quantity || (quantity = 1); + // shift all char styles by quantity forward + // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4 + for (const index in currentLineStylesCloned) { + const numericIndex = parseInt(index, 10); + if (numericIndex >= charIndex) { + currentLineStyles[numericIndex + quantity] = currentLineStylesCloned[numericIndex]; + // only delete the style if there was nothing moved there + if (!currentLineStylesCloned[numericIndex - quantity]) { + delete currentLineStyles[numericIndex]; + } + } + } + this._forceClearCache = true; + if (copiedStyle) { + while (quantity--) { + if (!Object.keys(copiedStyle[quantity]).length) { + continue; + } + if (!this.styles[lineIndex]) { + this.styles[lineIndex] = {}; + } + this.styles[lineIndex][charIndex + quantity] = _objectSpread2({}, copiedStyle[quantity]); + } + return; + } + if (!currentLineStyles) { + return; + } + const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1]; + while (newStyle && quantity--) { + this.styles[lineIndex][charIndex + quantity] = _objectSpread2({}, newStyle); + } + } + + /** + * Inserts style object(s) + * @param {Array} insertedText Characters at the location where style is inserted + * @param {Number} start cursor index for inserting style + * @param {Array} [copiedStyle] array of style objects to insert. + */ + insertNewStyleBlock(insertedText, start, copiedStyle) { + const cursorLoc = this.get2DCursorLocation(start, true), + addedLines = [0]; + let linesLength = 0; + // get an array of how many char per lines are being added. + for (let i = 0; i < insertedText.length; i++) { + if (insertedText[i] === '\n') { + linesLength++; + addedLines[linesLength] = 0; + } else { + addedLines[linesLength]++; + } + } + // for the first line copy the style from the current char position. + if (addedLines[0] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex, addedLines[0], copiedStyle); + copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1); + } + linesLength && this.insertNewlineStyleObject(cursorLoc.lineIndex, cursorLoc.charIndex + addedLines[0], linesLength); + let i; + for (i = 1; i < linesLength; i++) { + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } else if (copiedStyle) { + // this test is required in order to close #6841 + // when a pasted buffer begins with a newline then + // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0] + // may be undefined for some reason + if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) { + this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0]; + } + } + copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1); + } + if (addedLines[i] > 0) { + this.insertCharStyleObject(cursorLoc.lineIndex + i, 0, addedLines[i], copiedStyle); + } + } + + /** + * Removes characters from start/end + * start/end ar per grapheme position in _text array. + * + * @param {Number} start + * @param {Number} end default to start + 1 + */ + removeChars(start) { + let end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : start + 1; + this.removeStyleFromTo(start, end); + this._text.splice(start, end - start); + this.text = this._text.join(''); + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + this._removeExtraneousStyles(); + } + + /** + * insert characters at start position, before start position. + * start equal 1 it means the text get inserted between actual grapheme 0 and 1 + * if style array is provided, it must be as the same length of text in graphemes + * if end is provided and is bigger than start, old text is replaced. + * start/end ar per grapheme position in _text array. + * + * @param {String} text text to insert + * @param {Array} style array of style objects + * @param {Number} start + * @param {Number} end default to start + 1 + */ + insertChars(text, style, start) { + let end = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : start; + if (end > start) { + this.removeStyleFromTo(start, end); + } + const graphemes = this.graphemeSplit(text); + this.insertNewStyleBlock(graphemes, start, style); + this._text = [...this._text.slice(0, start), ...graphemes, ...this._text.slice(end)]; + this.text = this._text.join(''); + this.set('dirty', true); + this.initDimensions(); + this.setCoords(); + this._removeExtraneousStyles(); + } + + /** + * Set the selectionStart and selectionEnd according to the new position of cursor + * mimic the key - mouse navigation when shift is pressed. + */ + setSelectionStartEndWithShift(start, end, newSelection) { + if (newSelection <= start) { + if (end === start) { + this._selectionDirection = LEFT; + } else if (this._selectionDirection === RIGHT) { + this._selectionDirection = LEFT; + this.selectionEnd = start; + } + this.selectionStart = newSelection; + } else if (newSelection > start && newSelection < end) { + if (this._selectionDirection === RIGHT) { + this.selectionEnd = newSelection; + } else { + this.selectionStart = newSelection; + } + } else { + // newSelection is > selection start and end + if (end === start) { + this._selectionDirection = RIGHT; + } else if (this._selectionDirection === LEFT) { + this._selectionDirection = RIGHT; + this.selectionStart = end; + } + this.selectionEnd = newSelection; + } + } +} + +class ITextKeyBehavior extends ITextBehavior { + /** + * For functionalities on keyDown + * Map a special key to a function of the instance/prototype + * If you need different behavior for ESC or TAB or arrows, you have to change + * this map setting the name of a function that you build on the IText or + * your prototype. + * the map change will affect all Instances unless you need for only some text Instances + * in that case you have to clone this object and assign your Instance. + * this.keysMap = Object.assign({}, this.keysMap); + * The function must be in IText.prototype.myFunction And will receive event as args[0] + */ + + /** + * For functionalities on keyUp + ctrl || cmd + */ + + /** + * For functionalities on keyDown + ctrl || cmd + */ + + /** + * DOM container to append the hiddenTextarea. + * An alternative to attaching to the document.body. + * Useful to reduce laggish redraw of the full document.body tree and + * also with modals event capturing that won't let the textarea take focus. + * @type HTMLElement + * @default + */ + + /** + * Initializes hidden textarea (needed to bring up keyboard in iOS) + */ + initHiddenTextarea() { + const doc = this.canvas && getDocumentFromElement(this.canvas.getElement()) || getFabricDocument(); + const textarea = doc.createElement('textarea'); + Object.entries({ + autocapitalize: 'off', + autocorrect: 'off', + autocomplete: 'off', + spellcheck: 'false', + 'data-fabric': 'textarea', + wrap: 'off' + }).map(_ref => { + let [attribute, value] = _ref; + return textarea.setAttribute(attribute, value); + }); + const { + top, + left, + fontSize + } = this._calcTextareaPosition(); + // line-height: 1px; was removed from the style to fix this: + // https://bugs.chromium.org/p/chromium/issues/detail?id=870966 + textarea.style.cssText = "position: absolute; top: ".concat(top, "; left: ").concat(left, "; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ").concat(fontSize, ";"); + (this.hiddenTextareaContainer || doc.body).appendChild(textarea); + Object.entries({ + blur: 'blur', + keydown: 'onKeyDown', + keyup: 'onKeyUp', + input: 'onInput', + copy: 'copy', + cut: 'copy', + paste: 'paste', + compositionstart: 'onCompositionStart', + compositionupdate: 'onCompositionUpdate', + compositionend: 'onCompositionEnd' + }).map(_ref2 => { + let [eventName, handler] = _ref2; + return textarea.addEventListener(eventName, this[handler].bind(this)); + }); + this.hiddenTextarea = textarea; + } + + /** + * Override this method to customize cursor behavior on textbox blur + */ + blur() { + this.abortCursorAnimation(); + } + + /** + * Handles keydown event + * only used for arrows and combination of modifier keys. + * @param {KeyboardEvent} e Event object + */ + onKeyDown(e) { + if (!this.isEditing) { + return; + } + const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap; + if (e.keyCode in keyMap) { + // @ts-expect-error legacy method calling pattern + this[keyMap[e.keyCode]](e); + } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) { + // @ts-expect-error legacy method calling pattern + this[this.ctrlKeysMapDown[e.keyCode]](e); + } else { + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + if (e.keyCode >= 33 && e.keyCode <= 40) { + // if i press an arrow key just update selection + this.inCompositionMode = false; + this.clearContextTop(); + this.renderCursorOrSelection(); + } else { + this.canvas && this.canvas.requestRenderAll(); + } + } + + /** + * Handles keyup event + * We handle KeyUp because ie11 and edge have difficulties copy/pasting + * if a copy/cut event fired, keyup is dismissed + * @param {KeyboardEvent} e Event object + */ + onKeyUp(e) { + if (!this.isEditing || this._copyDone || this.inCompositionMode) { + this._copyDone = false; + return; + } + if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) { + // @ts-expect-error legacy method calling pattern + this[this.ctrlKeysMapUp[e.keyCode]](e); + } else { + return; + } + e.stopImmediatePropagation(); + e.preventDefault(); + this.canvas && this.canvas.requestRenderAll(); + } + + /** + * Handles onInput event + * @param {Event} e Event object + */ + onInput(e) { + const fromPaste = this.fromPaste; + this.fromPaste = false; + e && e.stopPropagation(); + if (!this.isEditing) { + return; + } + const updateAndFire = () => { + this.updateFromTextArea(); + this.fire(CHANGED); + if (this.canvas) { + this.canvas.fire('text:changed', { + target: this + }); + this.canvas.requestRenderAll(); + } + }; + if (this.hiddenTextarea.value === '') { + this.styles = {}; + updateAndFire(); + return; + } + // decisions about style changes. + const nextText = this._splitTextIntoLines(this.hiddenTextarea.value).graphemeText, + charCount = this._text.length, + nextCharCount = nextText.length, + selectionStart = this.selectionStart, + selectionEnd = this.selectionEnd, + selection = selectionStart !== selectionEnd; + let copiedStyle, + removedText, + charDiff = nextCharCount - charCount, + removeFrom, + removeTo; + const textareaSelection = this.fromStringToGraphemeSelection(this.hiddenTextarea.selectionStart, this.hiddenTextarea.selectionEnd, this.hiddenTextarea.value); + const backDelete = selectionStart > textareaSelection.selectionStart; + if (selection) { + removedText = this._text.slice(selectionStart, selectionEnd); + charDiff += selectionEnd - selectionStart; + } else if (nextCharCount < charCount) { + if (backDelete) { + removedText = this._text.slice(selectionEnd + charDiff, selectionEnd); + } else { + removedText = this._text.slice(selectionStart, selectionStart - charDiff); + } + } + const insertedText = nextText.slice(textareaSelection.selectionEnd - charDiff, textareaSelection.selectionEnd); + if (removedText && removedText.length) { + if (insertedText.length) { + // let's copy some style before deleting. + // we want to copy the style before the cursor OR the style at the cursor if selection + // is bigger than 0. + copiedStyle = this.getSelectionStyles(selectionStart, selectionStart + 1, false); + // now duplicate the style one for each inserted text. + copiedStyle = insertedText.map(() => + // this return an array of references, but that is fine since we are + // copying the style later. + copiedStyle[0]); + } + if (selection) { + removeFrom = selectionStart; + removeTo = selectionEnd; + } else if (backDelete) { + // detect differences between forwardDelete and backDelete + removeFrom = selectionEnd - removedText.length; + removeTo = selectionEnd; + } else { + removeFrom = selectionEnd; + removeTo = selectionEnd + removedText.length; + } + this.removeStyleFromTo(removeFrom, removeTo); + } + if (insertedText.length) { + const { + copyPasteData + } = getEnv$1(); + if (fromPaste && insertedText.join('') === copyPasteData.copiedText && !config.disableStyleCopyPaste) { + copiedStyle = copyPasteData.copiedTextStyle; + } + this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle); + } + updateAndFire(); + } + + /** + * Composition start + */ + onCompositionStart() { + this.inCompositionMode = true; + } + + /** + * Composition end + */ + onCompositionEnd() { + this.inCompositionMode = false; + } + onCompositionUpdate(_ref3) { + let { + target + } = _ref3; + const { + selectionStart, + selectionEnd + } = target; + this.compositionStart = selectionStart; + this.compositionEnd = selectionEnd; + this.updateTextareaPosition(); + } + + /** + * Copies selected text + */ + copy() { + if (this.selectionStart === this.selectionEnd) { + //do not cut-copy if no selection + return; + } + const { + copyPasteData + } = getEnv$1(); + copyPasteData.copiedText = this.getSelectedText(); + if (!config.disableStyleCopyPaste) { + copyPasteData.copiedTextStyle = this.getSelectionStyles(this.selectionStart, this.selectionEnd, true); + } else { + copyPasteData.copiedTextStyle = undefined; + } + this._copyDone = true; + } + + /** + * Pastes text + */ + paste() { + this.fromPaste = true; + } + + /** + * Finds the width in pixels before the cursor on the same line + * @private + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {Number} widthBeforeCursor width before cursor + */ + _getWidthBeforeCursor(lineIndex, charIndex) { + let widthBeforeCursor = this._getLineLeftOffset(lineIndex), + bound; + if (charIndex > 0) { + bound = this.__charBounds[lineIndex][charIndex - 1]; + widthBeforeCursor += bound.left + bound.width; + } + return widthBeforeCursor; + } + + /** + * Gets start offset of a selection + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getDownCursorOffset(e, isRight) { + const selectionProp = this._getSelectionForOffset(e, isRight), + cursorLocation = this.get2DCursorLocation(selectionProp), + lineIndex = cursorLocation.lineIndex; + // if on last line, down cursor goes to end of line + if (lineIndex === this._textLines.length - 1 || e.metaKey || e.keyCode === 34) { + // move to the end of a text + return this._text.length - selectionProp; + } + const charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor), + textAfterCursor = this._textLines[lineIndex].slice(charIndex); + return textAfterCursor.length + indexOnOtherLine + 1 + this.missingNewlineOffset(lineIndex); + } + + /** + * private + * Helps finding if the offset should be counted from Start or End + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + _getSelectionForOffset(e, isRight) { + if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) { + return this.selectionEnd; + } else { + return this.selectionStart; + } + } + + /** + * @param {KeyboardEvent} e Event object + * @param {Boolean} isRight + * @return {Number} + */ + getUpCursorOffset(e, isRight) { + const selectionProp = this._getSelectionForOffset(e, isRight), + cursorLocation = this.get2DCursorLocation(selectionProp), + lineIndex = cursorLocation.lineIndex; + if (lineIndex === 0 || e.metaKey || e.keyCode === 33) { + // if on first line, up cursor goes to start of line + return -selectionProp; + } + const charIndex = cursorLocation.charIndex, + widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex), + indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor), + textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex), + missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1); + // return a negative offset + return -this._textLines[lineIndex - 1].length + indexOnOtherLine - textBeforeCursor.length + (1 - missingNewlineOffset); + } + + /** + * for a given width it founds the matching character. + * @private + */ + _getIndexOnLine(lineIndex, width) { + const line = this._textLines[lineIndex], + lineLeftOffset = this._getLineLeftOffset(lineIndex); + let widthOfCharsOnLine = lineLeftOffset, + indexOnLine = 0, + charWidth, + foundMatch; + for (let j = 0, jlen = line.length; j < jlen; j++) { + charWidth = this.__charBounds[lineIndex][j].width; + widthOfCharsOnLine += charWidth; + if (widthOfCharsOnLine > width) { + foundMatch = true; + const leftEdge = widthOfCharsOnLine - charWidth, + rightEdge = widthOfCharsOnLine, + offsetFromLeftEdge = Math.abs(leftEdge - width), + offsetFromRightEdge = Math.abs(rightEdge - width); + indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1; + break; + } + } + + // reached end + if (!foundMatch) { + indexOnLine = line.length - 1; + } + return indexOnLine; + } + + /** + * Moves cursor down + * @param {KeyboardEvent} e Event object + */ + moveCursorDown(e) { + if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { + return; + } + this._moveCursorUpOrDown('Down', e); + } + + /** + * Moves cursor up + * @param {KeyboardEvent} e Event object + */ + moveCursorUp(e) { + if (this.selectionStart === 0 && this.selectionEnd === 0) { + return; + } + this._moveCursorUpOrDown('Up', e); + } + + /** + * Moves cursor up or down, fires the events + * @param {String} direction 'Up' or 'Down' + * @param {KeyboardEvent} e Event object + */ + _moveCursorUpOrDown(direction, e) { + const offset = this["get".concat(direction, "CursorOffset")](e, this._selectionDirection === RIGHT); + if (e.shiftKey) { + this.moveCursorWithShift(offset); + } else { + this.moveCursorWithoutShift(offset); + } + if (offset !== 0) { + const max = this.text.length; + this.selectionStart = capValue(0, this.selectionStart, max); + this.selectionEnd = capValue(0, this.selectionEnd, max); + // TODO fix: abort and init should be an alternative depending + // on selectionStart/End being equal or different + this.abortCursorAnimation(); + this.initDelayedCursor(); + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Moves cursor with shift + * @param {Number} offset + */ + moveCursorWithShift(offset) { + const newSelection = this._selectionDirection === LEFT ? this.selectionStart + offset : this.selectionEnd + offset; + this.setSelectionStartEndWithShift(this.selectionStart, this.selectionEnd, newSelection); + return offset !== 0; + } + + /** + * Moves cursor up without shift + * @param {Number} offset + */ + moveCursorWithoutShift(offset) { + if (offset < 0) { + this.selectionStart += offset; + this.selectionEnd = this.selectionStart; + } else { + this.selectionEnd += offset; + this.selectionStart = this.selectionEnd; + } + return offset !== 0; + } + + /** + * Moves cursor left + * @param {KeyboardEvent} e Event object + */ + moveCursorLeft(e) { + if (this.selectionStart === 0 && this.selectionEnd === 0) { + return; + } + this._moveCursorLeftOrRight('Left', e); + } + + /** + * @private + * @return {Boolean} true if a change happened + * + * @todo refactor not to use method name composition + */ + _move(e, prop, direction) { + let newValue; + if (e.altKey) { + newValue = this["findWordBoundary".concat(direction)](this[prop]); + } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) { + newValue = this["findLineBoundary".concat(direction)](this[prop]); + } else { + this[prop] += direction === 'Left' ? -1 : 1; + return true; + } + if (typeof newValue !== 'undefined' && this[prop] !== newValue) { + this[prop] = newValue; + return true; + } + return false; + } + + /** + * @private + */ + _moveLeft(e, prop) { + return this._move(e, prop, 'Left'); + } + + /** + * @private + */ + _moveRight(e, prop) { + return this._move(e, prop, 'Right'); + } + + /** + * Moves cursor left without keeping selection + * @param {KeyboardEvent} e + */ + moveCursorLeftWithoutShift(e) { + let change = true; + this._selectionDirection = LEFT; + + // only move cursor when there is no selection, + // otherwise we discard it, and leave cursor on same place + if (this.selectionEnd === this.selectionStart && this.selectionStart !== 0) { + change = this._moveLeft(e, 'selectionStart'); + } + this.selectionEnd = this.selectionStart; + return change; + } + + /** + * Moves cursor left while keeping selection + * @param {KeyboardEvent} e + */ + moveCursorLeftWithShift(e) { + if (this._selectionDirection === RIGHT && this.selectionStart !== this.selectionEnd) { + return this._moveLeft(e, 'selectionEnd'); + } else if (this.selectionStart !== 0) { + this._selectionDirection = LEFT; + return this._moveLeft(e, 'selectionStart'); + } + } + + /** + * Moves cursor right + * @param {KeyboardEvent} e Event object + */ + moveCursorRight(e) { + if (this.selectionStart >= this._text.length && this.selectionEnd >= this._text.length) { + return; + } + this._moveCursorLeftOrRight('Right', e); + } + + /** + * Moves cursor right or Left, fires event + * @param {String} direction 'Left', 'Right' + * @param {KeyboardEvent} e Event object + */ + _moveCursorLeftOrRight(direction, e) { + const actionName = "moveCursor".concat(direction).concat(e.shiftKey ? 'WithShift' : 'WithoutShift'); + this._currentCursorOpacity = 1; + if (this[actionName](e)) { + // TODO fix: abort and init should be an alternative depending + // on selectionStart/End being equal or different + this.abortCursorAnimation(); + this.initDelayedCursor(); + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Moves cursor right while keeping selection + * @param {KeyboardEvent} e + */ + moveCursorRightWithShift(e) { + if (this._selectionDirection === LEFT && this.selectionStart !== this.selectionEnd) { + return this._moveRight(e, 'selectionStart'); + } else if (this.selectionEnd !== this._text.length) { + this._selectionDirection = RIGHT; + return this._moveRight(e, 'selectionEnd'); + } + } + + /** + * Moves cursor right without keeping selection + * @param {KeyboardEvent} e Event object + */ + moveCursorRightWithoutShift(e) { + let changed = true; + this._selectionDirection = RIGHT; + if (this.selectionStart === this.selectionEnd) { + changed = this._moveRight(e, 'selectionStart'); + this.selectionEnd = this.selectionStart; + } else { + this.selectionStart = this.selectionEnd; + } + return changed; + } +} + +/** + * `LEFT_CLICK === 0` + */ +const notALeftClick = e => !!e.button; +class ITextClickBehavior extends ITextKeyBehavior { + constructor() { + super(...arguments); + _defineProperty(this, "draggableTextDelegate", void 0); + } + initBehavior() { + // Initializes event handlers related to cursor or selection + this.on('mousedown', this._mouseDownHandler); + this.on('mousedown:before', this._mouseDownHandlerBefore); + this.on('mouseup', this.mouseUpHandler); + this.on('mousedblclick', this.doubleClickHandler); + this.on('tripleclick', this.tripleClickHandler); + + // Initializes "dbclick" event handler + this.__lastClickTime = +new Date(); + // for triple click + this.__lastLastClickTime = +new Date(); + this.__lastPointer = {}; + this.on('mousedown', this.onMouseDown); + + // @ts-expect-error in reality it is an IText instance + this.draggableTextDelegate = new DraggableTextDelegate(this); + super.initBehavior(); + } + + /** + * If this method returns true a mouse move operation over a text selection + * will not prevent the native mouse event allowing the browser to start a drag operation. + * shouldStartDragging can be read 'do not prevent default for mouse move event' + * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false + * @returns + */ + shouldStartDragging() { + return this.draggableTextDelegate.isActive(); + } + + /** + * @public override this method to control whether instance should/shouldn't become a drag source, + * @see also {@link DraggableTextDelegate#isActive} + * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false + * @returns {boolean} should handle event + */ + onDragStart(e) { + return this.draggableTextDelegate.onDragStart(e); + } + + /** + * @public override this method to control whether instance should/shouldn't become a drop target + */ + canDrop(e) { + return this.draggableTextDelegate.canDrop(e); + } + + /** + * Default event handler to simulate triple click + * @private + */ + onMouseDown(options) { + if (!this.canvas) { + return; + } + this.__newClickTime = +new Date(); + const newPointer = options.pointer; + if (this.isTripleClick(newPointer)) { + this.fire('tripleclick', options); + stopEvent(options.e); + } + this.__lastLastClickTime = this.__lastClickTime; + this.__lastClickTime = this.__newClickTime; + this.__lastPointer = newPointer; + this.__lastSelected = this.selected && !this.getActiveControl(); + } + isTripleClick(newPointer) { + return this.__newClickTime - this.__lastClickTime < 500 && this.__lastClickTime - this.__lastLastClickTime < 500 && this.__lastPointer.x === newPointer.x && this.__lastPointer.y === newPointer.y; + } + + /** + * Default handler for double click, select a word + */ + doubleClickHandler(options) { + if (!this.isEditing) { + return; + } + this.selectWord(this.getSelectionStartFromPointer(options.e)); + } + + /** + * Default handler for triple click, select a line + */ + tripleClickHandler(options) { + if (!this.isEditing) { + return; + } + this.selectLine(this.getSelectionStartFromPointer(options.e)); + } + + /** + * Default event handler for the basic functionalities needed on _mouseDown + * can be overridden to do something different. + * Scope of this implementation is: find the click position, set selectionStart + * find selectionEnd, initialize the drawing of either cursor or selection area + * initializing a mousedDown on a text area will cancel fabricjs knowledge of + * current compositionMode. It will be set to false. + */ + _mouseDownHandler(_ref) { + let { + e + } = _ref; + if (!this.canvas || !this.editable || notALeftClick(e) || this.getActiveControl()) { + return; + } + if (this.draggableTextDelegate.start(e)) { + return; + } + this.canvas.textEditingManager.register(this); + if (this.selected) { + this.inCompositionMode = false; + this.setCursorByClick(e); + } + if (this.isEditing) { + this.__selectionStartOnMouseDown = this.selectionStart; + if (this.selectionStart === this.selectionEnd) { + this.abortCursorAnimation(); + } + this.renderCursorOrSelection(); + } + } + + /** + * Default event handler for the basic functionalities needed on mousedown:before + * can be overridden to do something different. + * Scope of this implementation is: verify the object is already selected when mousing down + */ + _mouseDownHandlerBefore(_ref2) { + let { + e + } = _ref2; + if (!this.canvas || !this.editable || notALeftClick(e)) { + return; + } + // we want to avoid that an object that was selected and then becomes unselectable, + // may trigger editing mode in some way. + this.selected = this === this.canvas._activeObject; + } + + /** + * standard handler for mouse up, overridable + * @private + */ + mouseUpHandler(_ref3) { + let { + e, + transform + } = _ref3; + const didDrag = this.draggableTextDelegate.end(e); + if (this.canvas) { + this.canvas.textEditingManager.unregister(this); + const activeObject = this.canvas._activeObject; + if (activeObject && activeObject !== this) { + // avoid running this logic when there is an active object + // this because is possible with shift click and fast clicks, + // to rapidly deselect and reselect this object and trigger an enterEdit + return; + } + } + if (!this.editable || this.group && !this.group.interactive || transform && transform.actionPerformed || notALeftClick(e) || didDrag) { + return; + } + if (this.__lastSelected && !this.getActiveControl()) { + this.selected = false; + this.__lastSelected = false; + this.enterEditing(e); + if (this.selectionStart === this.selectionEnd) { + this.initDelayedCursor(true); + } else { + this.renderCursorOrSelection(); + } + } else { + this.selected = true; + } + } + + /** + * Changes cursor location in a text depending on passed pointer (x/y) object + * @param {TPointerEvent} e Event object + */ + setCursorByClick(e) { + const newSelection = this.getSelectionStartFromPointer(e), + start = this.selectionStart, + end = this.selectionEnd; + if (e.shiftKey) { + this.setSelectionStartEndWithShift(start, end, newSelection); + } else { + this.selectionStart = newSelection; + this.selectionEnd = newSelection; + } + if (this.isEditing) { + this._fireSelectionChanged(); + this._updateTextarea(); + } + } + + /** + * Returns index of a character corresponding to where an object was clicked + * @param {TPointerEvent} e Event object + * @return {Number} Index of a character + */ + getSelectionStartFromPointer(e) { + const mouseOffset = this.canvas.getScenePoint(e).transform(invertTransform(this.calcTransformMatrix())).add(new Point(-this._getLeftOffset(), -this._getTopOffset())); + let height = 0, + charIndex = 0, + lineIndex = 0; + for (let i = 0; i < this._textLines.length; i++) { + if (height <= mouseOffset.y) { + height += this.getHeightOfLine(i); + lineIndex = i; + if (i > 0) { + charIndex += this._textLines[i - 1].length + this.missingNewlineOffset(i - 1); + } + } else { + break; + } + } + const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex)); + let width = lineLeftOffset; + const charLength = this._textLines[lineIndex].length; + const chars = this.__charBounds[lineIndex]; + for (let j = 0; j < charLength; j++) { + // i removed something about flipX here, check. + const charWidth = chars[j].kernedWidth; + const widthAfter = width + charWidth; + if (mouseOffset.x <= widthAfter) { + // if the pointer is closer to the end of the char we increment charIndex + // in order to position the cursor after the char + if (Math.abs(mouseOffset.x - widthAfter) <= Math.abs(mouseOffset.x - width)) { + charIndex++; + } + break; + } + width = widthAfter; + charIndex++; + } + return Math.min( + // if object is horizontally flipped, mirror cursor location from the end + this.flipX ? charLength - charIndex : charIndex, this._text.length); + } +} + +const MOVE_CURSOR_UP = 'moveCursorUp'; +const MOVE_CURSOR_DOWN = 'moveCursorDown'; +const MOVE_CURSOR_LEFT = 'moveCursorLeft'; +const MOVE_CURSOR_RIGHT = 'moveCursorRight'; +const EXIT_EDITING = 'exitEditing'; + +// @TODO look into import { Key } from 'ts-key-enum'; +// and transition from keyCode to Key +// also reduce string duplication +const keysMap = { + 9: EXIT_EDITING, + 27: EXIT_EDITING, + 33: MOVE_CURSOR_UP, + 34: MOVE_CURSOR_DOWN, + 35: MOVE_CURSOR_RIGHT, + 36: MOVE_CURSOR_LEFT, + 37: MOVE_CURSOR_LEFT, + 38: MOVE_CURSOR_UP, + 39: MOVE_CURSOR_RIGHT, + 40: MOVE_CURSOR_DOWN +}; +const keysMapRtl = { + 9: EXIT_EDITING, + 27: EXIT_EDITING, + 33: MOVE_CURSOR_UP, + 34: MOVE_CURSOR_DOWN, + 35: MOVE_CURSOR_LEFT, + 36: MOVE_CURSOR_RIGHT, + 37: MOVE_CURSOR_RIGHT, + 38: MOVE_CURSOR_UP, + 39: MOVE_CURSOR_LEFT, + 40: MOVE_CURSOR_DOWN +}; + +/** + * For functionalities on keyUp + ctrl || cmd + */ +const ctrlKeysMapUp = { + 67: 'copy', + // there was a reason this wasn't deleted. for now leave it here + 88: 'cut' +}; + +/** + * For functionalities on keyDown + ctrl || cmd + */ +const ctrlKeysMapDown = { + 65: 'selectAll' +}; + +// Declare IText protected properties to workaround TS +const protectedDefaultValues = { + _selectionDirection: null, + _reSpace: /\s|\r?\n/, + inCompositionMode: false +}; +const iTextDefaultValues = _objectSpread2({ + selectionStart: 0, + selectionEnd: 0, + selectionColor: 'rgba(17,119,255,0.3)', + isEditing: false, + editable: true, + editingBorderColor: 'rgba(102,153,255,0.25)', + cursorWidth: 2, + cursorColor: '', + cursorDelay: 1000, + cursorDuration: 600, + caching: true, + hiddenTextareaContainer: null, + keysMap, + keysMapRtl, + ctrlKeysMapDown, + ctrlKeysMapUp +}, protectedDefaultValues); + +// @TODO this is not complete + +/** + * @fires changed + * @fires selection:changed + * @fires editing:entered + * @fires editing:exited + * @fires dragstart + * @fires drag drag event firing on the drag source + * @fires dragend + * @fires copy + * @fires cut + * @fires paste + * + * #### Supported key combinations + * ``` + * Move cursor: left, right, up, down + * Select character: shift + left, shift + right + * Select text vertically: shift + up, shift + down + * Move cursor by word: alt + left, alt + right + * Select words: shift + alt + left, shift + alt + right + * Move cursor to line start/end: cmd + left, cmd + right or home, end + * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end + * Jump to start/end of text: cmd + up, cmd + down + * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown + * Delete character: backspace + * Delete word: alt + backspace + * Delete line: cmd + backspace + * Forward delete: delete + * Copy text: ctrl/cmd + c + * Paste text: ctrl/cmd + v + * Cut text: ctrl/cmd + x + * Select entire text: ctrl/cmd + a + * Quit editing tab or esc + * ``` + * + * #### Supported mouse/touch combination + * ``` + * Position cursor: click/touch + * Create selection: click/touch & drag + * Create selection: click & shift + click + * Select word: double click + * Select line: triple click + * ``` + */ +class IText extends ITextClickBehavior { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), IText.ownDefaults); + } + get type() { + const type = super.type; + // backward compatibility + return type === 'itext' ? 'i-text' : type; + } + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + */ + constructor(text, options) { + super(text, _objectSpread2(_objectSpread2({}, IText.ownDefaults), options)); + this.initBehavior(); + } + + /** + * While editing handle differently + * @private + * @param {string} key + * @param {*} value + */ + _set(key, value) { + if (this.isEditing && this._savedProps && key in this._savedProps) { + // @ts-expect-error irritating TS + this._savedProps[key] = value; + return this; + } + if (key === 'canvas') { + this.canvas instanceof Canvas$1 && this.canvas.textEditingManager.remove(this); + value instanceof Canvas$1 && value.textEditingManager.add(this); + } + return super._set(key, value); + } + + /** + * Sets selection start (left boundary of a selection) + * @param {Number} index Index to set selection start to + */ + setSelectionStart(index) { + index = Math.max(index, 0); + this._updateAndFire('selectionStart', index); + } + + /** + * Sets selection end (right boundary of a selection) + * @param {Number} index Index to set selection end to + */ + setSelectionEnd(index) { + index = Math.min(index, this.text.length); + this._updateAndFire('selectionEnd', index); + } + + /** + * @private + * @param {String} property 'selectionStart' or 'selectionEnd' + * @param {Number} index new position of property + */ + _updateAndFire(property, index) { + if (this[property] !== index) { + this._fireSelectionChanged(); + this[property] = index; + } + this._updateTextarea(); + } + + /** + * Fires the even of selection changed + * @private + */ + _fireSelectionChanged() { + this.fire('selection:changed'); + this.canvas && this.canvas.fire('text:selection:changed', { + target: this + }); + } + + /** + * Initialize text dimensions. Render all text on given context + * or on a offscreen canvas to get the text width with measureText. + * Updates this.width and this.height with the proper values. + * Does not return dimensions. + * @private + */ + initDimensions() { + this.isEditing && this.initDelayedCursor(); + super.initDimensions(); + } + + /** + * Gets style of a current selection/cursor (at the start position) + * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used. + * @param {Number} startIndex Start index to get styles at + * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1 + * @param {Boolean} [complete] get full style or not + * @return {Array} styles an array with one, zero or more Style objects + */ + getSelectionStyles() { + let startIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart || 0; + let endIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selectionEnd; + let complete = arguments.length > 2 ? arguments[2] : undefined; + return super.getSelectionStyles(startIndex, endIndex, complete); + } + + /** + * Sets style of a current selection, if no selection exist, do not set anything. + * @param {Object} [styles] Styles object + * @param {Number} [startIndex] Start index to get styles at + * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1 + */ + setSelectionStyles(styles) { + let startIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.selectionStart || 0; + let endIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.selectionEnd; + return super.setSelectionStyles(styles, startIndex, endIndex); + } + + /** + * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start) + * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used. + * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles. + */ + get2DCursorLocation() { + let selectionStart = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart; + let skipWrapping = arguments.length > 1 ? arguments[1] : undefined; + return super.get2DCursorLocation(selectionStart, skipWrapping); + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + render(ctx) { + super.render(ctx); + // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor + // the correct position but not at every cursor animation. + this.cursorOffsetCache = {}; + this.renderCursorOrSelection(); + } + + /** + * @override block cursor/selection logic while rendering the exported canvas + * @todo this workaround should be replaced with a more robust solution + */ + toCanvasElement(options) { + const isEditing = this.isEditing; + this.isEditing = false; + const canvas = super.toCanvasElement(options); + this.isEditing = isEditing; + return canvas; + } + + /** + * Renders cursor or selection (depending on what exists) + * it does on the contextTop. If contextTop is not available, do nothing. + */ + renderCursorOrSelection() { + if (!this.isEditing) { + return; + } + const ctx = this.clearContextTop(true); + if (!ctx) { + return; + } + const boundaries = this._getCursorBoundaries(); + if (this.selectionStart === this.selectionEnd) { + this.renderCursor(ctx, boundaries); + } else { + this.renderSelection(ctx, boundaries); + } + this.canvas.contextTopDirty = true; + ctx.restore(); + } + + /** + * Returns cursor boundaries (left, top, leftOffset, topOffset) + * left/top are left/top of entire text box + * leftOffset/topOffset are offset from that left/top point of a text box + * @private + * @param {number} [index] index from start + * @param {boolean} [skipCaching] + */ + _getCursorBoundaries() { + let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.selectionStart; + let skipCaching = arguments.length > 1 ? arguments[1] : undefined; + const left = this._getLeftOffset(), + top = this._getTopOffset(), + offsets = this._getCursorBoundariesOffsets(index, skipCaching); + return { + left: left, + top: top, + leftOffset: offsets.left, + topOffset: offsets.top + }; + } + + /** + * Caches and returns cursor left/top offset relative to instance's center point + * @private + * @param {number} index index from start + * @param {boolean} [skipCaching] + */ + _getCursorBoundariesOffsets(index, skipCaching) { + if (skipCaching) { + return this.__getCursorBoundariesOffsets(index); + } + if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) { + return this.cursorOffsetCache; + } + return this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index); + } + + /** + * Calculates cursor left/top offset relative to instance's center point + * @private + * @param {number} index index from start + */ + __getCursorBoundariesOffsets(index) { + let topOffset = 0, + leftOffset = 0; + const { + charIndex, + lineIndex + } = this.get2DCursorLocation(index); + for (let i = 0; i < lineIndex; i++) { + topOffset += this.getHeightOfLine(i); + } + const lineLeftOffset = this._getLineLeftOffset(lineIndex); + const bound = this.__charBounds[lineIndex][charIndex]; + bound && (leftOffset = bound.left); + if (this.charSpacing !== 0 && charIndex === this._textLines[lineIndex].length) { + leftOffset -= this._getWidthOfCharSpacing(); + } + const boundaries = { + top: topOffset, + left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0) + }; + if (this.direction === 'rtl') { + if (this.textAlign === RIGHT || this.textAlign === JUSTIFY || this.textAlign === JUSTIFY_RIGHT) { + boundaries.left *= -1; + } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) { + boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0); + } else if (this.textAlign === CENTER || this.textAlign === JUSTIFY_CENTER) { + boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0); + } + } + return boundaries; + } + + /** + * Renders cursor on context Top, outside the animation cycle, on request + * Used for the drag/drop effect. + * If contextTop is not available, do nothing. + */ + renderCursorAt(selectionStart) { + const boundaries = this._getCursorBoundaries(selectionStart, true); + this._renderCursor(this.canvas.contextTop, boundaries, selectionStart); + } + + /** + * Renders cursor + * @param {Object} boundaries + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderCursor(ctx, boundaries) { + this._renderCursor(ctx, boundaries, this.selectionStart); + } + _renderCursor(ctx, boundaries, selectionStart) { + const cursorLocation = this.get2DCursorLocation(selectionStart), + lineIndex = cursorLocation.lineIndex, + charIndex = cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0, + charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'), + multiplier = this.getObjectScaling().x * this.canvas.getZoom(), + cursorWidth = this.cursorWidth / multiplier, + dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'), + topOffset = boundaries.topOffset + (1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex) / this.lineHeight - charHeight * (1 - this._fontSizeFraction); + if (this.inCompositionMode) { + // TODO: investigate why there isn't a return inside the if, + // and why can't happen at the top of the function + this.renderSelection(ctx, boundaries); + } + ctx.fillStyle = this.cursorColor || this.getValueOfPropertyAt(lineIndex, charIndex, FILL); + ctx.globalAlpha = this._currentCursorOpacity; + ctx.fillRect(boundaries.left + boundaries.leftOffset - cursorWidth / 2, topOffset + boundaries.top + dy, cursorWidth, charHeight); + } + + /** + * Renders text selection + * @param {Object} boundaries Object with left/top/leftOffset/topOffset + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + renderSelection(ctx, boundaries) { + const selection = { + selectionStart: this.inCompositionMode ? this.hiddenTextarea.selectionStart : this.selectionStart, + selectionEnd: this.inCompositionMode ? this.hiddenTextarea.selectionEnd : this.selectionEnd + }; + this._renderSelection(ctx, selection, boundaries); + } + + /** + * Renders drag start text selection + */ + renderDragSourceEffect() { + const dragStartSelection = this.draggableTextDelegate.getDragStartSelection(); + this._renderSelection(this.canvas.contextTop, dragStartSelection, this._getCursorBoundaries(dragStartSelection.selectionStart, true)); + } + renderDropTargetEffect(e) { + const dragSelection = this.getSelectionStartFromPointer(e); + this.renderCursorAt(dragSelection); + } + + /** + * Renders text selection + * @private + * @param {{ selectionStart: number, selectionEnd: number }} selection + * @param {Object} boundaries Object with left/top/leftOffset/topOffset + * @param {CanvasRenderingContext2D} ctx transformed context to draw on + */ + _renderSelection(ctx, selection, boundaries) { + const selectionStart = selection.selectionStart, + selectionEnd = selection.selectionEnd, + isJustify = this.textAlign.includes(JUSTIFY), + start = this.get2DCursorLocation(selectionStart), + end = this.get2DCursorLocation(selectionEnd), + startLine = start.lineIndex, + endLine = end.lineIndex, + startChar = start.charIndex < 0 ? 0 : start.charIndex, + endChar = end.charIndex < 0 ? 0 : end.charIndex; + for (let i = startLine; i <= endLine; i++) { + const lineOffset = this._getLineLeftOffset(i) || 0; + let lineHeight = this.getHeightOfLine(i), + realLineHeight = 0, + boxStart = 0, + boxEnd = 0; + if (i === startLine) { + boxStart = this.__charBounds[startLine][startChar].left; + } + if (i >= startLine && i < endLine) { + boxEnd = isJustify && !this.isEndOfWrapping(i) ? this.width : this.getLineWidth(i) || 5; // WTF is this 5? + } else if (i === endLine) { + if (endChar === 0) { + boxEnd = this.__charBounds[endLine][endChar].left; + } else { + const charSpacing = this._getWidthOfCharSpacing(); + boxEnd = this.__charBounds[endLine][endChar - 1].left + this.__charBounds[endLine][endChar - 1].width - charSpacing; + } + } + realLineHeight = lineHeight; + if (this.lineHeight < 1 || i === endLine && this.lineHeight > 1) { + lineHeight /= this.lineHeight; + } + let drawStart = boundaries.left + lineOffset + boxStart, + drawHeight = lineHeight, + extraTop = 0; + const drawWidth = boxEnd - boxStart; + if (this.inCompositionMode) { + ctx.fillStyle = this.compositionColor || 'black'; + drawHeight = 1; + extraTop = lineHeight; + } else { + ctx.fillStyle = this.selectionColor; + } + if (this.direction === 'rtl') { + if (this.textAlign === RIGHT || this.textAlign === JUSTIFY || this.textAlign === JUSTIFY_RIGHT) { + drawStart = this.width - drawStart - drawWidth; + } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) { + drawStart = boundaries.left + lineOffset - boxEnd; + } else if (this.textAlign === CENTER || this.textAlign === JUSTIFY_CENTER) { + drawStart = boundaries.left + lineOffset - boxEnd; + } + } + ctx.fillRect(drawStart, boundaries.top + boundaries.topOffset + extraTop, drawWidth, drawHeight); + boundaries.topOffset += realLineHeight; + } + } + + /** + * High level function to know the height of the cursor. + * the currentChar is the one that precedes the cursor + * Returns fontSize of char at the current cursor + * Unused from the library, is for the end user + * @return {Number} Character font size + */ + getCurrentCharFontSize() { + const cp = this._getCurrentCharIndex(); + return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize'); + } + + /** + * High level function to know the color of the cursor. + * the currentChar is the one that precedes the cursor + * Returns color (fill) of char at the current cursor + * if the text object has a pattern or gradient for filler, it will return that. + * Unused by the library, is for the end user + * @return {String | TFiller} Character color (fill) + */ + getCurrentCharColor() { + const cp = this._getCurrentCharIndex(); + return this.getValueOfPropertyAt(cp.l, cp.c, FILL); + } + + /** + * Returns the cursor position for the getCurrent.. functions + * @private + */ + _getCurrentCharIndex() { + const cursorPosition = this.get2DCursorLocation(this.selectionStart, true), + charIndex = cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0; + return { + l: cursorPosition.lineIndex, + c: charIndex + }; + } + dispose() { + this._exitEditing(); + this.draggableTextDelegate.dispose(); + super.dispose(); + } +} +/** + * Index where text selection starts (or where cursor is when there is no selection) + * @type Number + * @default + */ +/** + * Index where text selection ends + * @type Number + * @default + */ +/** + * Color of text selection + * @type String + * @default + */ +/** + * Indicates whether text is in editing mode + * @type Boolean + * @default + */ +/** + * Indicates whether a text can be edited + * @type Boolean + * @default + */ +/** + * Border color of text object while it's in editing mode + * @type String + * @default + */ +/** + * Width of cursor (in px) + * @type Number + * @default + */ +/** + * Color of text cursor color in editing mode. + * if not set (default) will take color from the text. + * if set to a color value that fabric can understand, it will + * be used instead of the color of the text at the current position. + * @type String + * @default + */ +/** + * Delay between cursor blink (in ms) + * @type Number + * @default + */ +/** + * Duration of cursor fade in (in ms) + * @type Number + * @default + */ +/** + * Indicates whether internal text char widths can be cached + * @type Boolean + * @default + */ +_defineProperty(IText, "ownDefaults", iTextDefaultValues); +_defineProperty(IText, "type", 'IText'); +classRegistry.setClass(IText); +// legacy +classRegistry.setClass(IText, 'i-text'); + +// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype +// regexes, list of properties that are not suppose to change by instances, magic consts. +// this will be a separated effort +const textboxDefaultValues = { + minWidth: 20, + dynamicMinWidth: 2, + lockScalingFlip: true, + noScaleCache: false, + _wordJoiners: /[ \t\r]/, + splitByGrapheme: false +}; + +// @TODO this is not complete + +/** + * Textbox class, based on IText, allows the user to resize the text rectangle + * and wraps lines automatically. Textboxes have their Y scaling locked, the + * user can only change width. Height is adjusted automatically based on the + * wrapping of lines. + */ +class Textbox extends IText { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), Textbox.ownDefaults); + } + + /** + * Constructor + * @param {String} text Text string + * @param {Object} [options] Options object + */ + constructor(text, options) { + super(text, _objectSpread2(_objectSpread2({}, Textbox.ownDefaults), options)); + } + + /** + * Creates the default control object. + * If you prefer to have on instance of controls shared among all objects + * make this function return an empty object and add controls to the ownDefaults object + */ + static createControls() { + return { + controls: createTextboxDefaultControls() + }; + } + + /** + * Unlike superclass's version of this function, Textbox does not update + * its width. + * @private + * @override + */ + initDimensions() { + if (!this.initialized) { + return; + } + this.isEditing && this.initDelayedCursor(); + this._clearCache(); + // clear dynamicMinWidth as it will be different after we re-wrap line + this.dynamicMinWidth = 0; + // wrap lines + this._styleMap = this._generateStyleMap(this._splitText()); + // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap + if (this.dynamicMinWidth > this.width) { + this._set('width', this.dynamicMinWidth); + } + if (this.textAlign.includes(JUSTIFY)) { + // once text is measured we need to make space fatter to make justified text. + this.enlargeSpaces(); + } + // clear cache and re-calculate height + this.height = this.calcTextHeight(); + } + + /** + * Generate an object that translates the style object so that it is + * broken up by visual lines (new lines and automatic wrapping). + * The original text styles object is broken up by actual lines (new lines only), + * which is only sufficient for Text / IText + * @private + */ + _generateStyleMap(textInfo) { + let realLineCount = 0, + realLineCharCount = 0, + charCount = 0; + const map = {}; + for (let i = 0; i < textInfo.graphemeLines.length; i++) { + if (textInfo.graphemeText[charCount] === '\n' && i > 0) { + realLineCharCount = 0; + charCount++; + realLineCount++; + } else if (!this.splitByGrapheme && this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) && i > 0) { + // this case deals with space's that are removed from end of lines when wrapping + realLineCharCount++; + charCount++; + } + map[i] = { + line: realLineCount, + offset: realLineCharCount + }; + charCount += textInfo.graphemeLines[i].length; + realLineCharCount += textInfo.graphemeLines[i].length; + } + return map; + } + + /** + * Returns true if object has a style property or has it on a specified line + * @param {Number} lineIndex + * @return {Boolean} + */ + styleHas(property, lineIndex) { + if (this._styleMap && !this.isWrapping) { + const map = this._styleMap[lineIndex]; + if (map) { + lineIndex = map.line; + } + } + return super.styleHas(property, lineIndex); + } + + /** + * Returns true if object has no styling or no styling in a line + * @param {Number} lineIndex , lineIndex is on wrapped lines. + * @return {Boolean} + */ + isEmptyStyles(lineIndex) { + if (!this.styles) { + return true; + } + let offset = 0, + nextLineIndex = lineIndex + 1, + nextOffset, + shouldLimit = false; + const map = this._styleMap[lineIndex], + mapNextLine = this._styleMap[lineIndex + 1]; + if (map) { + lineIndex = map.line; + offset = map.offset; + } + if (mapNextLine) { + nextLineIndex = mapNextLine.line; + shouldLimit = nextLineIndex === lineIndex; + nextOffset = mapNextLine.offset; + } + const obj = typeof lineIndex === 'undefined' ? this.styles : { + line: this.styles[lineIndex] + }; + for (const p1 in obj) { + for (const p2 in obj[p1]) { + const p2Number = parseInt(p2, 10); + if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset)) { + // eslint-disable-next-line no-unused-vars + for (const p3 in obj[p1][p2]) { + return false; + } + } + } + } + return true; + } + + /** + * @protected + * @param {Number} lineIndex + * @param {Number} charIndex + * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined + */ + _getStyleDeclaration(lineIndex, charIndex) { + if (this._styleMap && !this.isWrapping) { + const map = this._styleMap[lineIndex]; + if (!map) { + return {}; + } + lineIndex = map.line; + charIndex = map.offset + charIndex; + } + return super._getStyleDeclaration(lineIndex, charIndex); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @param {Object} style + * @private + */ + _setStyleDeclaration(lineIndex, charIndex, style) { + const map = this._styleMap[lineIndex]; + super._setStyleDeclaration(map.line, map.offset + charIndex, style); + } + + /** + * @param {Number} lineIndex + * @param {Number} charIndex + * @private + */ + _deleteStyleDeclaration(lineIndex, charIndex) { + const map = this._styleMap[lineIndex]; + super._deleteStyleDeclaration(map.line, map.offset + charIndex); + } + + /** + * probably broken need a fix + * Returns the real style line that correspond to the wrapped lineIndex line + * Used just to verify if the line does exist or not. + * @param {Number} lineIndex + * @returns {Boolean} if the line exists or not + * @private + */ + _getLineStyle(lineIndex) { + const map = this._styleMap[lineIndex]; + return !!this.styles[map.line]; + } + + /** + * Set the line style to an empty object so that is initialized + * @param {Number} lineIndex + * @param {Object} style + * @private + */ + _setLineStyle(lineIndex) { + const map = this._styleMap[lineIndex]; + super._setLineStyle(map.line); + } + + /** + * Wraps text using the 'width' property of Textbox. First this function + * splits text on newlines, so we preserve newlines entered by the user. + * Then it wraps each line using the width of the Textbox by calling + * _wrapLine(). + * @param {Array} lines The string array of text that is split into lines + * @param {Number} desiredWidth width you want to wrap to + * @returns {Array} Array of lines + */ + _wrapText(lines, desiredWidth) { + this.isWrapping = true; + // extract all thewords and the widths to optimally wrap lines. + const data = this.getGraphemeDataForRender(lines); + const wrapped = []; + for (let i = 0; i < data.wordsData.length; i++) { + wrapped.push(...this._wrapLine(i, desiredWidth, data)); + } + this.isWrapping = false; + return wrapped; + } + + /** + * For each line of text terminated by an hard line stop, + * measure each word width and extract the largest word from all. + * The returned words here are the one that at the end will be rendered. + * @param {string[]} lines the lines we need to measure + * + */ + getGraphemeDataForRender(lines) { + const splitByGrapheme = this.splitByGrapheme, + infix = splitByGrapheme ? '' : ' '; + let largestWordWidth = 0; + const data = lines.map((line, lineIndex) => { + let offset = 0; + const wordsOrGraphemes = splitByGrapheme ? this.graphemeSplit(line) : this.wordSplit(line); + if (wordsOrGraphemes.length === 0) { + return [{ + word: [], + width: 0 + }]; + } + return wordsOrGraphemes.map(word => { + // if using splitByGrapheme words are already in graphemes. + const graphemeArray = splitByGrapheme ? [word] : this.graphemeSplit(word); + const width = this._measureWord(graphemeArray, lineIndex, offset); + largestWordWidth = Math.max(width, largestWordWidth); + offset += graphemeArray.length + infix.length; + return { + word: graphemeArray, + width + }; + }); + }); + return { + wordsData: data, + largestWordWidth + }; + } + + /** + * Helper function to measure a string of text, given its lineIndex and charIndex offset + * It gets called when charBounds are not available yet. + * Override if necessary + * Use with {@link Textbox#wordSplit} + * + * @param {CanvasRenderingContext2D} ctx + * @param {String} text + * @param {number} lineIndex + * @param {number} charOffset + * @returns {number} + */ + _measureWord(word, lineIndex) { + let charOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + let width = 0, + prevGrapheme; + const skipLeft = true; + for (let i = 0, len = word.length; i < len; i++) { + const box = this._getGraphemeBox(word[i], lineIndex, i + charOffset, prevGrapheme, skipLeft); + width += box.kernedWidth; + prevGrapheme = word[i]; + } + return width; + } + + /** + * Override this method to customize word splitting + * Use with {@link Textbox#_measureWord} + * @param {string} value + * @returns {string[]} array of words + */ + wordSplit(value) { + return value.split(this._wordJoiners); + } + + /** + * Wraps a line of text using the width of the Textbox as desiredWidth + * and leveraging the known width o words from GraphemeData + * @private + * @param {Number} lineIndex + * @param {Number} desiredWidth width you want to wrap the line to + * @param {GraphemeData} graphemeData an object containing all the lines' words width. + * @param {Number} reservedSpace space to remove from wrapping for custom functionalities + * @returns {Array} Array of line(s) into which the given text is wrapped + * to. + */ + _wrapLine(lineIndex, desiredWidth, _ref) { + let { + largestWordWidth, + wordsData + } = _ref; + let reservedSpace = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + const additionalSpace = this._getWidthOfCharSpacing(), + splitByGrapheme = this.splitByGrapheme, + graphemeLines = [], + infix = splitByGrapheme ? '' : ' '; + let lineWidth = 0, + line = [], + // spaces in different languages? + offset = 0, + infixWidth = 0, + lineJustStarted = true; + desiredWidth -= reservedSpace; + const maxWidth = Math.max(desiredWidth, largestWordWidth, this.dynamicMinWidth); + // layout words + const data = wordsData[lineIndex]; + offset = 0; + let i; + for (i = 0; i < data.length; i++) { + const { + word, + width: wordWidth + } = data[i]; + offset += word.length; + lineWidth += infixWidth + wordWidth - additionalSpace; + if (lineWidth > maxWidth && !lineJustStarted) { + graphemeLines.push(line); + line = []; + lineWidth = wordWidth; + lineJustStarted = true; + } else { + lineWidth += additionalSpace; + } + if (!lineJustStarted && !splitByGrapheme) { + line.push(infix); + } + line = line.concat(word); + infixWidth = splitByGrapheme ? 0 : this._measureWord([infix], lineIndex, offset); + offset++; + lineJustStarted = false; + } + i && graphemeLines.push(line); + + // TODO: this code is probably not necessary anymore. + // it can be moved out of this function since largestWordWidth is now + // known in advance + if (largestWordWidth + reservedSpace > this.dynamicMinWidth) { + this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace; + } + return graphemeLines; + } + + /** + * Detect if the text line is ended with an hard break + * text and itext do not have wrapping, return false + * @param {Number} lineIndex text to split + * @return {Boolean} + */ + isEndOfWrapping(lineIndex) { + if (!this._styleMap[lineIndex + 1]) { + // is last line, return true; + return true; + } + if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) { + // this is last line before a line break, return true; + return true; + } + return false; + } + + /** + * Detect if a line has a linebreak and so we need to account for it when moving + * and counting style. + * This is important only for splitByGrapheme at the end of wrapping. + * If we are not wrapping the offset is always 1 + * @return Number + */ + missingNewlineOffset(lineIndex, skipWrapping) { + if (this.splitByGrapheme && !skipWrapping) { + return this.isEndOfWrapping(lineIndex) ? 1 : 0; + } + return 1; + } + + /** + * Gets lines of text to render in the Textbox. This function calculates + * text wrapping on the fly every time it is called. + * @param {String} text text to split + * @returns {Array} Array of lines in the Textbox. + * @override + */ + _splitTextIntoLines(text) { + const newText = super._splitTextIntoLines(text), + graphemeLines = this._wrapText(newText.lines, this.width), + lines = new Array(graphemeLines.length); + for (let i = 0; i < graphemeLines.length; i++) { + lines[i] = graphemeLines[i].join(''); + } + newText.lines = lines; + newText.graphemeLines = graphemeLines; + return newText; + } + getMinWidth() { + return Math.max(this.minWidth, this.dynamicMinWidth); + } + _removeExtraneousStyles() { + const linesToKeep = new Map(); + for (const prop in this._styleMap) { + const propNumber = parseInt(prop, 10); + if (this._textLines[propNumber]) { + const lineIndex = this._styleMap[prop].line; + linesToKeep.set("".concat(lineIndex), true); + } + } + for (const prop in this.styles) { + if (!linesToKeep.has(prop)) { + delete this.styles[prop]; + } + } + } + + /** + * Returns object representation of an instance + * @method toObject + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]); + } +} +/** + * Minimum width of textbox, in pixels. + * @type Number + * @default + */ +/** + * Minimum calculated width of a textbox, in pixels. + * fixed to 2 so that an empty textbox cannot go to 0 + * and is still selectable without text. + * @type Number + * @default + */ +/** + * Use this boolean property in order to split strings that have no white space concept. + * this is a cheap way to help with chinese/japanese + * @type Boolean + * @since 2.6.0 + */ +_defineProperty(Textbox, "type", 'Textbox'); +_defineProperty(Textbox, "textLayoutProperties", [...IText.textLayoutProperties, 'width']); +_defineProperty(Textbox, "ownDefaults", textboxDefaultValues); +classRegistry.setClass(Textbox); + +/** + * Layout will adjust the bounding box to match the clip path bounding box. + */ +class ClipPathLayout extends LayoutStrategy { + shouldPerformLayout(context) { + return !!context.target.clipPath && super.shouldPerformLayout(context); + } + shouldLayoutClipPath() { + return false; + } + calcLayoutResult(context, objects) { + const { + target + } = context; + const { + clipPath, + group + } = target; + if (!clipPath || !this.shouldPerformLayout(context)) { + return; + } + // TODO: remove stroke calculation from this case + const { + width, + height + } = makeBoundingBoxFromPoints(getObjectBounds(target, clipPath)); + const size = new Point(width, height); + if (clipPath.absolutePositioned) { + // we want the center point to exist in group's containing plane + const clipPathCenter = sendPointToPlane(clipPath.getRelativeCenterPoint(), undefined, group ? group.calcTransformMatrix() : undefined); + return { + center: clipPathCenter, + size + }; + } else { + // we want the center point to exist in group's containing plane, so we send it upwards + const clipPathCenter = clipPath.getRelativeCenterPoint().transform(target.calcOwnMatrix(), true); + if (this.shouldPerformLayout(context)) { + // the clip path is positioned relative to the group's center which is affected by the bbox + // so we first calculate the bbox + const { + center = new Point(), + correction = new Point() + } = this.calcBoundingBox(objects, context) || {}; + return { + center: center.add(clipPathCenter), + correction: correction.subtract(clipPathCenter), + size + }; + } else { + return { + center: target.getRelativeCenterPoint().add(clipPathCenter), + size + }; + } + } + } +} +_defineProperty(ClipPathLayout, "type", 'clip-path'); +classRegistry.setClass(ClipPathLayout); + +/** + * Layout will keep target's initial size. + */ +class FixedLayout extends LayoutStrategy { + /** + * @override respect target's initial size + */ + getInitialSize(_ref, _ref2) { + let { + target + } = _ref; + let { + size + } = _ref2; + return new Point(target.width || size.x, target.height || size.y); + } +} +_defineProperty(FixedLayout, "type", 'fixed'); +classRegistry.setClass(FixedLayout); + +/** + * Today the LayoutManager class also takes care of subscribing event handlers + * to update the group layout when the group is interactive and a transform is applied + * to a child object. + * The ActiveSelection is never interactive, but it could contain objects from + * groups that are. + * The standard LayoutManager would subscribe the children of the activeSelection to + * perform layout changes to the active selection itself, what we need instead is that + * the transformation applied to the active selection will trigger changes to the + * original group of the children ( the one referenced under the parent property ) + * This subclass of the LayoutManager has a single duty to fill the gap of this difference.` + */ +class ActiveSelectionLayoutManager extends LayoutManager { + subscribeTargets(context) { + const activeSelection = context.target; + const parents = context.targets.reduce((parents, target) => { + target.parent && parents.add(target.parent); + return parents; + }, new Set()); + parents.forEach(parent => { + parent.layoutManager.subscribeTargets({ + target: parent, + targets: [activeSelection] + }); + }); + } + + /** + * unsubscribe from parent only if all its children were deselected + */ + unsubscribeTargets(context) { + const activeSelection = context.target; + const selectedObjects = activeSelection.getObjects(); + const parents = context.targets.reduce((parents, target) => { + target.parent && parents.add(target.parent); + return parents; + }, new Set()); + parents.forEach(parent => { + !selectedObjects.some(object => object.parent === parent) && parent.layoutManager.unsubscribeTargets({ + target: parent, + targets: [activeSelection] + }); + }); + } +} + +const activeSelectionDefaultValues = { + multiSelectionStacking: 'canvas-stacking' +}; + +/** + * Used by Canvas to manage selection. + * + * @example + * class MyActiveSelection extends ActiveSelection { + * ... + * } + * + * // override the default `ActiveSelection` class + * classRegistry.setClass(MyActiveSelection) + */ +class ActiveSelection extends Group { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), ActiveSelection.ownDefaults); + } + + /** + * The ActiveSelection needs to use the ActiveSelectionLayoutManager + * or selections on interactive groups may be broken + */ + + /** + * controls how selected objects are added during a multiselection event + * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order + * - `selection-order` adds the selected object to the top of the stack, + * meaning that the stack is ordered by the order in which objects were selected + * @default `canvas-stacking` + */ + + constructor() { + let objects = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + super(); + Object.assign(this, ActiveSelection.ownDefaults); + this.setOptions(options); + const { + left, + top, + layoutManager + } = options; + this.groupInit(objects, { + left, + top, + layoutManager: layoutManager !== null && layoutManager !== void 0 ? layoutManager : new ActiveSelectionLayoutManager() + }); + } + + /** + * @private + */ + _shouldSetNestedCoords() { + return true; + } + + /** + * @private + * @override we don't want the selection monitor to be active + */ + __objectSelectionMonitor() { + // noop + } + + /** + * Adds objects with respect to {@link multiSelectionStacking} + * @param targets object to add to selection + */ + multiSelectAdd() { + for (var _len = arguments.length, targets = new Array(_len), _key = 0; _key < _len; _key++) { + targets[_key] = arguments[_key]; + } + if (this.multiSelectionStacking === 'selection-order') { + this.add(...targets); + } else { + // respect object stacking as it is on canvas + // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf` + targets.forEach(target => { + const index = this._objects.findIndex(obj => obj.isInFrontOf(target)); + const insertAt = index === -1 ? + // `target` is in front of all other objects + this.size() : index; + this.insertAt(insertAt, target); + }); + } + } + + /** + * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree + */ + canEnterGroup(object) { + if (this.getObjects().some(o => o.isDescendantOf(object) || object.isDescendantOf(o))) { + // prevent circular object tree + log('error', 'ActiveSelection: circular object trees are not supported, this call has no effect'); + return false; + } + return super.canEnterGroup(object); + } + + /** + * Change an object so that it can be part of an active selection. + * this method is called by multiselectAdd from canvas code. + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane + */ + enterGroup(object, removeParentTransform) { + // This condition check that the object has currently a group, and the group + // is also its parent, meaning that is not in an active selection, but is + // in a normal group. + if (object.parent && object.parent === object.group) { + // Disconnect the object from the group functionalities, but keep the ref parent intact + // for later re-enter + object.parent._exitGroup(object); + // in this case the object is probably inside an active selection. + } else if (object.group && object.parent !== object.group) { + // in this case group.remove will also clear the old parent reference. + object.group.remove(object); + } + // enter the active selection from a render perspective + // the object will be in the objects array of both the ActiveSelection and the Group + // but referenced in the group's _activeObjects so that it won't be rendered twice. + this._enterGroup(object, removeParentTransform); + } + + /** + * we want objects to retain their canvas ref when exiting instance + * @private + * @param {FabricObject} object + * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it + */ + exitGroup(object, removeParentTransform) { + this._exitGroup(object, removeParentTransform); + // return to parent + object.parent && object.parent._enterGroup(object, true); + } + + /** + * @private + * @param {'added'|'removed'} type + * @param {FabricObject[]} targets + */ + _onAfterObjectsChange(type, targets) { + super._onAfterObjectsChange(type, targets); + const groups = new Set(); + targets.forEach(object => { + const { + parent + } = object; + parent && groups.add(parent); + }); + if (type === LAYOUT_TYPE_REMOVED) { + // invalidate groups' layout and mark as dirty + groups.forEach(group => { + group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets); + }); + } else { + // mark groups as dirty + groups.forEach(group => { + group._set('dirty', true); + }); + } + } + + /** + * @override remove all objects + */ + onDeselect() { + this.removeAll(); + return false; + } + + /** + * Returns string representation of a group + * @return {String} + */ + toString() { + return "#"); + } + + /** + * Decide if the object should cache or not. Create its own cache level + * objectCaching is a global flag, wins over everything + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * @return {Boolean} + */ + shouldCache() { + return false; + } + + /** + * Check if this group or its parent group are caching, recursively up + * @return {Boolean} + */ + isOnACache() { + return false; + } + + /** + * Renders controls and borders for the object + * @param {CanvasRenderingContext2D} ctx Context to render on + * @param {Object} [styleOverride] properties to override the object style + * @param {Object} [childrenOverride] properties to override the children overrides + */ + _renderControls(ctx, styleOverride, childrenOverride) { + ctx.save(); + ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1; + const options = _objectSpread2(_objectSpread2({ + hasControls: false + }, childrenOverride), {}, { + forActiveSelection: true + }); + for (let i = 0; i < this._objects.length; i++) { + this._objects[i]._renderControls(ctx, options); + } + super._renderControls(ctx, styleOverride); + ctx.restore(); + } +} +_defineProperty(ActiveSelection, "type", 'ActiveSelection'); +_defineProperty(ActiveSelection, "ownDefaults", activeSelectionDefaultValues); +classRegistry.setClass(ActiveSelection); +classRegistry.setClass(ActiveSelection, 'activeSelection'); + +/** + * Canvas 2D filter backend. + */ + +class Canvas2dFilterBackend { + constructor() { + /** + * Experimental. This object is a sort of repository of help layers used to avoid + * of recreating them during frequent filtering. If you are previewing a filter with + * a slider you probably do not want to create help layers every filter step. + * in this object there will be appended some canvases, created once, resized sometimes + * cleared never. Clearing is left to the developer. + **/ + _defineProperty(this, "resources", {}); + } + /** + * Apply a set of filters against a source image and draw the filtered output + * to the provided destination canvas. + * + * @param {EnhancedFilter} filters The filter to apply. + * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered. + * @param {Number} sourceWidth The width of the source input. + * @param {Number} sourceHeight The height of the source input. + * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. + */ + applyFilters(filters, sourceElement, sourceWidth, sourceHeight, targetCanvas) { + const ctx = targetCanvas.getContext('2d'); + if (!ctx) { + return; + } + ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight); + const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); + const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight); + const pipelineState = { + sourceWidth, + sourceHeight, + imageData, + originalEl: sourceElement, + originalImageData, + canvasEl: targetCanvas, + ctx, + filterBackend: this + }; + filters.forEach(filter => { + filter.applyTo(pipelineState); + }); + const { + imageData: imageDataPostFilter + } = pipelineState; + if (imageDataPostFilter.width !== sourceWidth || imageDataPostFilter.height !== sourceHeight) { + targetCanvas.width = imageDataPostFilter.width; + targetCanvas.height = imageDataPostFilter.height; + } + ctx.putImageData(imageDataPostFilter, 0, 0); + return pipelineState; + } +} + +class WebGLFilterBackend { + constructor() { + let { + tileSize = config.textureSize + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + /** + * Define ... + **/ + _defineProperty(this, "aPosition", new Float32Array([0, 0, 0, 1, 1, 0, 1, 1])); + /** + * Experimental. This object is a sort of repository of help layers used to avoid + * of recreating them during frequent filtering. If you are previewing a filter with + * a slider you probably do not want to create help layers every filter step. + * in this object there will be appended some canvases, created once, resized sometimes + * cleared never. Clearing is left to the developer. + **/ + _defineProperty(this, "resources", {}); + this.tileSize = tileSize; + this.setupGLContext(tileSize, tileSize); + this.captureGPUInfo(); + } + + /** + * Setup a WebGL context suitable for filtering, and bind any needed event handlers. + */ + setupGLContext(width, height) { + this.dispose(); + this.createWebGLCanvas(width, height); + } + + /** + * Create a canvas element and associated WebGL context and attaches them as + * class properties to the GLFilterBackend class. + */ + createWebGLCanvas(width, height) { + const canvas = createCanvasElement(); + canvas.width = width; + canvas.height = height; + const glOptions = { + alpha: true, + premultipliedAlpha: false, + depth: false, + stencil: false, + antialias: false + }, + gl = canvas.getContext('webgl', glOptions); + if (!gl) { + return; + } + gl.clearColor(0, 0, 0, 0); + // this canvas can fire webglcontextlost and webglcontextrestored + this.canvas = canvas; + this.gl = gl; + } + + /** + * Attempts to apply the requested filters to the source provided, drawing the filtered output + * to the provided target canvas. + * + * @param {Array} filters The filters to apply. + * @param {TexImageSource} source The source to be filtered. + * @param {Number} width The width of the source input. + * @param {Number} height The height of the source input. + * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn. + * @param {String|undefined} cacheKey A key used to cache resources related to the source. If + * omitted, caching will be skipped. + */ + applyFilters(filters, source, width, height, targetCanvas, cacheKey) { + const gl = this.gl; + const ctx = targetCanvas.getContext('2d'); + if (!gl || !ctx) { + return; + } + let cachedTexture; + if (cacheKey) { + cachedTexture = this.getCachedTexture(cacheKey, source); + } + const pipelineState = { + originalWidth: source.width || + // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state? + source.originalWidth || 0, + originalHeight: source.height || + // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state? + source.originalHeight || 0, + sourceWidth: width, + sourceHeight: height, + destinationWidth: width, + destinationHeight: height, + context: gl, + sourceTexture: this.createTexture(gl, width, height, !cachedTexture ? source : undefined), + targetTexture: this.createTexture(gl, width, height), + originalTexture: cachedTexture || this.createTexture(gl, width, height, !cachedTexture ? source : undefined), + passes: filters.length, + webgl: true, + aPosition: this.aPosition, + programCache: this.programCache, + pass: 0, + filterBackend: this, + targetCanvas: targetCanvas + }; + const tempFbo = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo); + filters.forEach(filter => { + filter && filter.applyTo(pipelineState); + }); + resizeCanvasIfNeeded(pipelineState); + this.copyGLTo2D(gl, pipelineState); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.deleteTexture(pipelineState.sourceTexture); + gl.deleteTexture(pipelineState.targetTexture); + gl.deleteFramebuffer(tempFbo); + ctx.setTransform(1, 0, 0, 1, 0, 0); + return pipelineState; + } + + /** + * Detach event listeners, remove references, and clean up caches. + */ + dispose() { + if (this.canvas) { + // we are disposing, we don't care about the fact + // that the canvas shouldn't be null. + // @ts-expect-error disposing + this.canvas = null; + // @ts-expect-error disposing + this.gl = null; + } + this.clearWebGLCaches(); + } + + /** + * Wipe out WebGL-related caches. + */ + clearWebGLCaches() { + this.programCache = {}; + this.textureCache = {}; + } + + /** + * Create a WebGL texture object. + * + * Accepts specific dimensions to initialize the texture to or a source image. + * + * @param {WebGLRenderingContext} gl The GL context to use for creating the texture. + * @param {number} width The width to initialize the texture at. + * @param {number} height The height to initialize the texture. + * @param {TexImageSource} textureImageSource A source for the texture data. + * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture. + * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR + * @returns {WebGLTexture} + */ + createTexture(gl, width, height, textureImageSource, filter) { + const { + NEAREST, + TEXTURE_2D, + RGBA, + UNSIGNED_BYTE, + CLAMP_TO_EDGE, + TEXTURE_MAG_FILTER, + TEXTURE_MIN_FILTER, + TEXTURE_WRAP_S, + TEXTURE_WRAP_T + } = gl; + const texture = gl.createTexture(); + gl.bindTexture(TEXTURE_2D, texture); + gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST); + gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST); + gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + if (textureImageSource) { + gl.texImage2D(TEXTURE_2D, 0, RGBA, RGBA, UNSIGNED_BYTE, textureImageSource); + } else { + gl.texImage2D(TEXTURE_2D, 0, RGBA, width, height, 0, RGBA, UNSIGNED_BYTE, null); + } + return texture; + } + + /** + * Can be optionally used to get a texture from the cache array + * + * If an existing texture is not found, a new texture is created and cached. + * + * @param {String} uniqueId A cache key to use to find an existing texture. + * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the + * texture cache entry if one does not already exist. + */ + getCachedTexture(uniqueId, textureImageSource, filter) { + const { + textureCache + } = this; + if (textureCache[uniqueId]) { + return textureCache[uniqueId]; + } else { + const texture = this.createTexture(this.gl, textureImageSource.width, textureImageSource.height, textureImageSource, filter); + if (texture) { + textureCache[uniqueId] = texture; + } + return texture; + } + } + + /** + * Clear out cached resources related to a source image that has been + * filtered previously. + * + * @param {String} cacheKey The cache key provided when the source image was filtered. + */ + evictCachesForKey(cacheKey) { + if (this.textureCache[cacheKey]) { + this.gl.deleteTexture(this.textureCache[cacheKey]); + delete this.textureCache[cacheKey]; + } + } + + /** + * Copy an input WebGL canvas on to an output 2D canvas. + * + * The WebGL canvas is assumed to be upside down, with the top-left pixel of the + * desired output image appearing in the bottom-left corner of the WebGL canvas. + * + * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. + * @param {Object} pipelineState The 2D target canvas to copy on to. + */ + copyGLTo2D(gl, pipelineState) { + const glCanvas = gl.canvas, + targetCanvas = pipelineState.targetCanvas, + ctx = targetCanvas.getContext('2d'); + if (!ctx) { + return; + } + ctx.translate(0, targetCanvas.height); // move it down again + ctx.scale(1, -1); // vertical flip + // where is my image on the big glcanvas? + const sourceY = glCanvas.height - targetCanvas.height; + ctx.drawImage(glCanvas, 0, sourceY, targetCanvas.width, targetCanvas.height, 0, 0, targetCanvas.width, targetCanvas.height); + } + + /** + * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData + * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra). + * + * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from. + * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to. + * @param {Object} pipelineState The 2D target canvas to copy on to. + */ + copyGLTo2DPutImageData(gl, pipelineState) { + const targetCanvas = pipelineState.targetCanvas, + ctx = targetCanvas.getContext('2d'), + dWidth = pipelineState.destinationWidth, + dHeight = pipelineState.destinationHeight, + numBytes = dWidth * dHeight * 4; + if (!ctx) { + return; + } + const u8 = new Uint8Array(this.imageBuffer, 0, numBytes); + const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes); + gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8); + const imgData = new ImageData(u8Clamped, dWidth, dHeight); + ctx.putImageData(imgData, 0, 0); + } + + /** + * Attempt to extract GPU information strings from a WebGL context. + * + * Useful information when debugging or blacklisting specific GPUs. + * + * @returns {Object} A GPU info object with renderer and vendor strings. + */ + captureGPUInfo() { + if (this.gpuInfo) { + return this.gpuInfo; + } + const gl = this.gl, + gpuInfo = { + renderer: '', + vendor: '' + }; + if (!gl) { + return gpuInfo; + } + const ext = gl.getExtension('WEBGL_debug_renderer_info'); + if (ext) { + const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL); + const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL); + if (renderer) { + gpuInfo.renderer = renderer.toLowerCase(); + } + if (vendor) { + gpuInfo.vendor = vendor.toLowerCase(); + } + } + this.gpuInfo = gpuInfo; + return gpuInfo; + } +} +function resizeCanvasIfNeeded(pipelineState) { + const targetCanvas = pipelineState.targetCanvas, + width = targetCanvas.width, + height = targetCanvas.height, + dWidth = pipelineState.destinationWidth, + dHeight = pipelineState.destinationHeight; + if (width !== dWidth || height !== dHeight) { + targetCanvas.width = dWidth; + targetCanvas.height = dHeight; + } +} + +let filterBackend; + +/** + * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend + */ +function initFilterBackend() { + const { + WebGLProbe + } = getEnv$1(); + WebGLProbe.queryWebGL(createCanvasElement()); + if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) { + return new WebGLFilterBackend({ + tileSize: config.textureSize + }); + } else { + return new Canvas2dFilterBackend(); + } +} + +/** + * Get the current fabricJS filter backend or initialize one if not available yet + * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior), + * pass `false` to get the backend ref without mutating it + */ +function getFilterBackend() { + let strict = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + if (!filterBackend && strict) { + filterBackend = initFilterBackend(); + } + return filterBackend; +} +function setFilterBackend(backend) { + filterBackend = backend; +} + +const _excluded$2 = ["filters", "resizeFilter", "src", "crossOrigin", "type"]; + +// @todo Would be nice to have filtering code not imported directly. + +const imageDefaultValues = { + strokeWidth: 0, + srcFromAttribute: false, + minimumScaleTrigger: 0.5, + cropX: 0, + cropY: 0, + imageSmoothing: true +}; +const IMAGE_PROPS = ['cropX', 'cropY']; + +/** + * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images} + */ +class FabricImage extends FabricObject { + static getDefaults() { + return _objectSpread2(_objectSpread2({}, super.getDefaults()), FabricImage.ownDefaults); + } + /** + * Constructor + * Image can be initialized with any canvas drawable or a string. + * The string should be a url and will be loaded as an image. + * Canvas and Image element work out of the box, while videos require extra code to work. + * Please check video element events for seeking. + * @param {ImageSource | string} element Image element + * @param {Object} [options] Options object + */ + + constructor(arg0, options) { + super(); + /** + * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`. + * This allows for relative urls as image src. + * @since 2.7.0 + * @type Boolean + * @default false + */ + /** + * private + * contains last value of scaleX to detect + * if the Image got resized after the last Render + * @type Number + */ + _defineProperty(this, "_lastScaleX", 1); + /** + * private + * contains last value of scaleY to detect + * if the Image got resized after the last Render + * @type Number + */ + _defineProperty(this, "_lastScaleY", 1); + /** + * private + * contains last value of scaling applied by the apply filter chain + * @type Number + */ + _defineProperty(this, "_filterScalingX", 1); + /** + * private + * contains last value of scaling applied by the apply filter chain + * @type Number + */ + _defineProperty(this, "_filterScalingY", 1); + this.filters = []; + Object.assign(this, FabricImage.ownDefaults); + this.setOptions(options); + this.cacheKey = "texture".concat(uid()); + this.setElement(typeof arg0 === 'string' ? (this.canvas && getDocumentFromElement(this.canvas.getElement()) || getFabricDocument()).getElementById(arg0) : arg0, options); + } + + /** + * Returns image element which this instance if based on + */ + getElement() { + return this._element; + } + + /** + * Sets image element for this instance to a specified one. + * If filters defined they are applied to new image. + * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area. + * @param {HTMLImageElement} element + * @param {Partial} [size] Options object + */ + setElement(element) { + let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + this.removeTexture(this.cacheKey); + this.removeTexture("".concat(this.cacheKey, "_filtered")); + this._element = element; + this._originalElement = element; + this._setWidthHeight(size); + element.classList.add(FabricImage.CSS_CANVAS); + if (this.filters.length !== 0) { + this.applyFilters(); + } + // resizeFilters work on the already filtered copy. + // we need to apply resizeFilters AFTER normal filters. + // applyResizeFilters is run more often than normal filters + // and is triggered by user interactions rather than dev code + if (this.resizeFilter) { + this.applyResizeFilters(); + } + } + + /** + * Delete a single texture if in webgl mode + */ + removeTexture(key) { + const backend = getFilterBackend(false); + if (backend instanceof WebGLFilterBackend) { + backend.evictCachesForKey(key); + } + } + + /** + * Delete textures, reference to elements and eventually JSDOM cleanup + */ + dispose() { + super.dispose(); + this.removeTexture(this.cacheKey); + this.removeTexture("".concat(this.cacheKey, "_filtered")); + this._cacheContext = null; + ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'].forEach(elementKey => { + const el = this[elementKey]; + el && getEnv$1().dispose(el); + // @ts-expect-error disposing + this[elementKey] = undefined; + }); + } + + /** + * Get the crossOrigin value (of the corresponding image element) + */ + getCrossOrigin() { + return this._originalElement && (this._originalElement.crossOrigin || null); + } + + /** + * Returns original size of an image + */ + getOriginalSize() { + const element = this.getElement(); + if (!element) { + return { + width: 0, + height: 0 + }; + } + return { + width: element.naturalWidth || element.width, + height: element.naturalHeight || element.height + }; + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _stroke(ctx) { + if (!this.stroke || this.strokeWidth === 0) { + return; + } + const w = this.width / 2, + h = this.height / 2; + ctx.beginPath(); + ctx.moveTo(-w, -h); + ctx.lineTo(w, -h); + ctx.lineTo(w, h); + ctx.lineTo(-w, h); + ctx.lineTo(-w, -h); + ctx.closePath(); + } + + /** + * Returns object representation of an instance + * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output + * @return {Object} Object representation of an instance + */ + toObject() { + let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; + const filters = []; + this.filters.forEach(filterObj => { + filterObj && filters.push(filterObj.toObject()); + }); + return _objectSpread2(_objectSpread2({}, super.toObject([...IMAGE_PROPS, ...propertiesToInclude])), {}, { + src: this.getSrc(), + crossOrigin: this.getCrossOrigin(), + filters + }, this.resizeFilter ? { + resizeFilter: this.resizeFilter.toObject() + } : {}); + } + + /** + * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height. + * @return {Boolean} + */ + hasCrop() { + return !!this.cropX || !!this.cropY || this.width < this._element.width || this.height < this._element.height; + } + + /** + * Returns svg representation of an instance + * @return {string[]} an array of strings with the specific svg representation + * of the instance + */ + _toSVG() { + const imageMarkup = [], + element = this._element, + x = -this.width / 2, + y = -this.height / 2; + let svgString = [], + strokeSvg = [], + clipPath = '', + imageRendering = ''; + if (!element) { + return []; + } + if (this.hasCrop()) { + const clipPathId = uid(); + svgString.push('\n', '\t\n', '\n'); + clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" '; + } + if (!this.imageSmoothing) { + imageRendering = ' image-rendering="optimizeSpeed"'; + } + imageMarkup.push('\t element with actual transformation, then offsetting object to the top/left + // so that object's center aligns with container's left/top + , "\" width=\"").concat(element.width || element.naturalWidth, "\" height=\"").concat(element.height || element.naturalHeight, "\"").concat(imageRendering).concat(clipPath, ">\n")); + if (this.stroke || this.strokeDashArray) { + const origFill = this.fill; + this.fill = null; + strokeSvg = ["\t\n")]; + this.fill = origFill; + } + if (this.paintFirst !== FILL) { + svgString = svgString.concat(strokeSvg, imageMarkup); + } else { + svgString = svgString.concat(imageMarkup, strokeSvg); + } + return svgString; + } + + /** + * Returns source of an image + * @param {Boolean} filtered indicates if the src is needed for svg + * @return {String} Source of an image + */ + getSrc(filtered) { + const element = filtered ? this._element : this._originalElement; + if (element) { + if (element.toDataURL) { + return element.toDataURL(); + } + if (this.srcFromAttribute) { + return element.getAttribute('src') || ''; + } else { + return element.src; + } + } else { + return this.src || ''; + } + } + + /** + * Alias for getSrc + * @param filtered + * @deprecated + */ + getSvgSrc(filtered) { + return this.getSrc(filtered); + } + + /** + * Loads and sets source of an image\ + * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking + * @param {String} src Source string (URL) + * @param {LoadImageOptions} [options] Options object + */ + setSrc(src) { + let { + crossOrigin, + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + return loadImage(src, { + crossOrigin, + signal + }).then(img => { + typeof crossOrigin !== 'undefined' && this.set({ + crossOrigin + }); + this.setElement(img); + }); + } + + /** + * Returns string representation of an instance + * @return {String} String representation of an instance + */ + toString() { + return "#"); + } + applyResizeFilters() { + const filter = this.resizeFilter, + minimumScale = this.minimumScaleTrigger, + objectScale = this.getTotalObjectScaling(), + scaleX = objectScale.x, + scaleY = objectScale.y, + elementToFilter = this._filteredEl || this._originalElement; + if (this.group) { + this.set('dirty', true); + } + if (!filter || scaleX > minimumScale && scaleY > minimumScale) { + this._element = elementToFilter; + this._filterScalingX = 1; + this._filterScalingY = 1; + this._lastScaleX = scaleX; + this._lastScaleY = scaleY; + return; + } + const canvasEl = createCanvasElement(), + sourceWidth = elementToFilter.width, + sourceHeight = elementToFilter.height; + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; + this._element = canvasEl; + this._lastScaleX = filter.scaleX = scaleX; + this._lastScaleY = filter.scaleY = scaleY; + getFilterBackend().applyFilters([filter], elementToFilter, sourceWidth, sourceHeight, this._element); + this._filterScalingX = canvasEl.width / this._originalElement.width; + this._filterScalingY = canvasEl.height / this._originalElement.height; + } + + /** + * Applies filters assigned to this image (from "filters" array) or from filter param + * @method applyFilters + * @param {Array} filters to be applied + * @param {Boolean} forResizing specify if the filter operation is a resize operation + */ + applyFilters() { + let filters = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.filters || []; + filters = filters.filter(filter => filter && !filter.isNeutralState()); + this.set('dirty', true); + + // needs to clear out or WEBGL will not resize correctly + this.removeTexture("".concat(this.cacheKey, "_filtered")); + if (filters.length === 0) { + this._element = this._originalElement; + // this is unsafe and needs to be rethinkend + this._filteredEl = undefined; + this._filterScalingX = 1; + this._filterScalingY = 1; + return; + } + const imgElement = this._originalElement, + sourceWidth = imgElement.naturalWidth || imgElement.width, + sourceHeight = imgElement.naturalHeight || imgElement.height; + if (this._element === this._originalElement) { + // if the _element a reference to _originalElement + // we need to create a new element to host the filtered pixels + const canvasEl = createCanvasElement(); + canvasEl.width = sourceWidth; + canvasEl.height = sourceHeight; + this._element = canvasEl; + this._filteredEl = canvasEl; + } else if (this._filteredEl) { + // if the _element is it own element, + // and we also have a _filteredEl, then we clean up _filteredEl + // and we assign it to _element. + // in this way we invalidate the eventual old resize filtered element + this._element = this._filteredEl; + this._filteredEl.getContext('2d').clearRect(0, 0, sourceWidth, sourceHeight); + // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y + this._lastScaleX = 1; + this._lastScaleY = 1; + } + getFilterBackend().applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element); + if (this._originalElement.width !== this._element.width || this._originalElement.height !== this._element.height) { + this._filterScalingX = this._element.width / this._originalElement.width; + this._filterScalingY = this._element.height / this._originalElement.height; + } + } + + /** + * @private + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + _render(ctx) { + ctx.imageSmoothingEnabled = this.imageSmoothing; + if (this.isMoving !== true && this.resizeFilter && this._needsResize()) { + this.applyResizeFilters(); + } + this._stroke(ctx); + this._renderPaintInOrder(ctx); + } + + /** + * Paint the cached copy of the object on the target context. + * it will set the imageSmoothing for the draw operation + * @param {CanvasRenderingContext2D} ctx Context to render on + */ + drawCacheOnCanvas(ctx) { + ctx.imageSmoothingEnabled = this.imageSmoothing; + super.drawCacheOnCanvas(ctx); + } + + /** + * Decide if the object should cache or not. Create its own cache level + * needsItsOwnCache should be used when the object drawing method requires + * a cache step. None of the fabric classes requires it. + * Generally you do not cache objects in groups because the group outside is cached. + * This is the special image version where we would like to avoid caching where possible. + * Essentially images do not benefit from caching. They may require caching, and in that + * case we do it. Also caching an image usually ends in a loss of details. + * A full performance audit should be done. + * @return {Boolean} + */ + shouldCache() { + return this.needsItsOwnCache(); + } + _renderFill(ctx) { + const elementToDraw = this._element; + if (!elementToDraw) { + return; + } + const scaleX = this._filterScalingX, + scaleY = this._filterScalingY, + w = this.width, + h = this.height, + // crop values cannot be lesser than 0. + cropX = Math.max(this.cropX, 0), + cropY = Math.max(this.cropY, 0), + elWidth = elementToDraw.naturalWidth || elementToDraw.width, + elHeight = elementToDraw.naturalHeight || elementToDraw.height, + sX = cropX * scaleX, + sY = cropY * scaleY, + // the width height cannot exceed element width/height, starting from the crop offset. + sW = Math.min(w * scaleX, elWidth - sX), + sH = Math.min(h * scaleY, elHeight - sY), + x = -w / 2, + y = -h / 2, + maxDestW = Math.min(w, elWidth / scaleX - cropX), + maxDestH = Math.min(h, elHeight / scaleY - cropY); + elementToDraw && ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH); + } + + /** + * needed to check if image needs resize + * @private + */ + _needsResize() { + const scale = this.getTotalObjectScaling(); + return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY; + } + + /** + * @private + * @deprecated unused + */ + _resetWidthHeight() { + this.set(this.getOriginalSize()); + } + + /** + * @private + * Set the width and the height of the image object, using the element or the + * options. + */ + _setWidthHeight() { + let { + width, + height + } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + const size = this.getOriginalSize(); + this.width = width || size.width; + this.height = height || size.height; + } + + /** + * Calculate offset for center and scale factor for the image in order to respect + * the preserveAspectRatio attribute + * @private + */ + parsePreserveAspectRatioAttribute() { + const pAR = parsePreserveAspectRatioAttribute(this.preserveAspectRatio || ''), + pWidth = this.width, + pHeight = this.height, + parsedAttributes = { + width: pWidth, + height: pHeight + }; + let rWidth = this._element.width, + rHeight = this._element.height, + scaleX = 1, + scaleY = 1, + offsetLeft = 0, + offsetTop = 0, + cropX = 0, + cropY = 0, + offset; + if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) { + if (pAR.meetOrSlice === 'meet') { + scaleX = scaleY = findScaleToFit(this._element, parsedAttributes); + offset = (pWidth - rWidth * scaleX) / 2; + if (pAR.alignX === 'Min') { + offsetLeft = -offset; + } + if (pAR.alignX === 'Max') { + offsetLeft = offset; + } + offset = (pHeight - rHeight * scaleY) / 2; + if (pAR.alignY === 'Min') { + offsetTop = -offset; + } + if (pAR.alignY === 'Max') { + offsetTop = offset; + } + } + if (pAR.meetOrSlice === 'slice') { + scaleX = scaleY = findScaleToCover(this._element, parsedAttributes); + offset = rWidth - pWidth / scaleX; + if (pAR.alignX === 'Mid') { + cropX = offset / 2; + } + if (pAR.alignX === 'Max') { + cropX = offset; + } + offset = rHeight - pHeight / scaleY; + if (pAR.alignY === 'Mid') { + cropY = offset / 2; + } + if (pAR.alignY === 'Max') { + cropY = offset; + } + rWidth = pWidth / scaleX; + rHeight = pHeight / scaleY; + } + } else { + scaleX = pWidth / rWidth; + scaleY = pHeight / rHeight; + } + return { + width: rWidth, + height: rHeight, + scaleX, + scaleY, + offsetLeft, + offsetTop, + cropX, + cropY + }; + } + + /** + * Default CSS class name for canvas + * @static + * @type String + * @default + */ + + /** + * Creates an instance of FabricImage from its object representation + * @static + * @param {Object} object Object to create an instance from + * @param {object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(_ref, options) { + let { + filters: f, + resizeFilter: rf, + src, + crossOrigin, + type + } = _ref, + object = _objectWithoutProperties(_ref, _excluded$2); + return Promise.all([loadImage(src, _objectSpread2(_objectSpread2({}, options), {}, { + crossOrigin + })), f && enlivenObjects(f, options), + // TODO: redundant - handled by enlivenObjectEnlivables + rf && enlivenObjects([rf], options), enlivenObjectEnlivables(object, options)]).then(_ref2 => { + let [el, filters = [], [resizeFilter] = [], hydratedProps = {}] = _ref2; + return new this(el, _objectSpread2(_objectSpread2({}, object), {}, { + // TODO: this creates a difference between image creation and restoring from JSON + src, + filters, + resizeFilter + }, hydratedProps)); + }); + } + + /** + * Creates an instance of Image from an URL string + * @static + * @param {String} url URL to create an image from + * @param {LoadImageOptions} [options] Options object + * @returns {Promise} + */ + static fromURL(url) { + let { + crossOrigin = null, + signal + } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let imageOptions = arguments.length > 2 ? arguments[2] : undefined; + return loadImage(url, { + crossOrigin, + signal + }).then(img => new this(img, imageOptions)); + } + + /** + * Returns {@link FabricImage} instance from an SVG element + * @static + * @param {HTMLElement} element Element to parse + * @param {Object} [options] Options object + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @param {Function} callback Callback to execute when Image object is created + */ + static async fromElement(element) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + let cssRules = arguments.length > 2 ? arguments[2] : undefined; + const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules); + return this.fromURL(parsedAttributes['xlink:href'], options, parsedAttributes).catch(err => { + log('log', 'Unable to parse Image', err); + return null; + }); + } +} +_defineProperty(FabricImage, "type", 'Image'); +_defineProperty(FabricImage, "cacheProperties", [...cacheProperties, ...IMAGE_PROPS]); +_defineProperty(FabricImage, "ownDefaults", imageDefaultValues); +_defineProperty(FabricImage, "CSS_CANVAS", 'canvas-img'); +/** + * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement}) + * @static + * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement} + */ +_defineProperty(FabricImage, "ATTRIBUTE_NAMES", [...SHARED_ATTRIBUTES, 'x', 'y', 'width', 'height', 'preserveAspectRatio', 'xlink:href', 'crossOrigin', 'image-rendering']); +classRegistry.setClass(FabricImage); +classRegistry.setSVGClass(FabricImage); + +/** + * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements + */ +function applyViewboxTransform(element) { + if (!svgViewBoxElementsRegEx.test(element.nodeName)) { + return {}; + } + const viewBoxAttr = element.getAttribute('viewBox'); + let scaleX = 1; + let scaleY = 1; + let minX = 0; + let minY = 0; + let matrix; + let el; + const widthAttr = element.getAttribute('width'); + const heightAttr = element.getAttribute('height'); + const x = element.getAttribute('x') || 0; + const y = element.getAttribute('y') || 0; + const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr); + const missingViewBox = !goodViewbox; + const missingDimAttr = !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%'; + let translateMatrix = ''; + let widthDiff = 0; + let heightDiff = 0; + if (missingViewBox) { + if ((x || y) && element.parentNode && element.parentNode.nodeName !== '#document') { + translateMatrix = ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') '; + matrix = (element.getAttribute('transform') || '') + translateMatrix; + element.setAttribute('transform', matrix); + element.removeAttribute('x'); + element.removeAttribute('y'); + } + } + if (missingViewBox && missingDimAttr) { + return { + width: 0, + height: 0 + }; + } + const parsedDim = { + width: 0, + height: 0 + }; + if (missingViewBox) { + parsedDim.width = parseUnit(widthAttr); + parsedDim.height = parseUnit(heightAttr); + // set a transform for elements that have x y and are inner(only) SVGs + return parsedDim; + } + const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue); + minX = -parseFloat(pasedViewBox[1]); + minY = -parseFloat(pasedViewBox[2]); + const viewBoxWidth = parseFloat(pasedViewBox[3]); + const viewBoxHeight = parseFloat(pasedViewBox[4]); + parsedDim.minX = minX; + parsedDim.minY = minY; + parsedDim.viewBoxWidth = viewBoxWidth; + parsedDim.viewBoxHeight = viewBoxHeight; + if (!missingDimAttr) { + parsedDim.width = parseUnit(widthAttr); + parsedDim.height = parseUnit(heightAttr); + scaleX = parsedDim.width / viewBoxWidth; + scaleY = parsedDim.height / viewBoxHeight; + } else { + parsedDim.width = viewBoxWidth; + parsedDim.height = viewBoxHeight; + } + + // default is to preserve aspect ratio + const preserveAspectRatio = parsePreserveAspectRatioAttribute(element.getAttribute('preserveAspectRatio') || ''); + if (preserveAspectRatio.alignX !== NONE) { + //translate all container for the effect of Mid, Min, Max + if (preserveAspectRatio.meetOrSlice === 'meet') { + scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX; + // calculate additional translation to move the viewbox + } + if (preserveAspectRatio.meetOrSlice === 'slice') { + scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY; + // calculate additional translation to move the viewbox + } + widthDiff = parsedDim.width - viewBoxWidth * scaleX; + heightDiff = parsedDim.height - viewBoxHeight * scaleX; + if (preserveAspectRatio.alignX === 'Mid') { + widthDiff /= 2; + } + if (preserveAspectRatio.alignY === 'Mid') { + heightDiff /= 2; + } + if (preserveAspectRatio.alignX === 'Min') { + widthDiff = 0; + } + if (preserveAspectRatio.alignY === 'Min') { + heightDiff = 0; + } + } + if (scaleX === 1 && scaleY === 1 && minX === 0 && minY === 0 && x === 0 && y === 0) { + return parsedDim; + } + if ((x || y) && element.parentNode.nodeName !== '#document') { + translateMatrix = ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') '; + } + matrix = translateMatrix + ' matrix(' + scaleX + ' 0' + ' 0 ' + scaleY + ' ' + (minX * scaleX + widthDiff) + ' ' + (minY * scaleY + heightDiff) + ') '; + // seems unused. + // parsedDim.viewboxTransform = parseTransformAttribute(matrix); + if (element.nodeName === 'svg') { + el = element.ownerDocument.createElementNS(svgNS, 'g'); + // element.firstChild != null + while (element.firstChild) { + el.appendChild(element.firstChild); + } + element.appendChild(el); + } else { + el = element; + el.removeAttribute('x'); + el.removeAttribute('y'); + matrix = el.getAttribute('transform') + matrix; + } + el.setAttribute('transform', matrix); + return parsedDim; +} + +const getTagName = node => node.tagName.replace('svg:', ''); + +const svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors); +function hasInvalidAncestor(element) { + let _element = element; + while (_element && (_element = _element.parentElement)) { + if (_element && _element.nodeName && svgInvalidAncestorsRegEx.test(getTagName(_element)) && !_element.getAttribute('instantiated_by_use')) { + return true; + } + } + return false; +} + +function getMultipleNodes(doc, nodeNames) { + let nodeName, + nodeArray = [], + nodeList, + i, + len; + for (i = 0, len = nodeNames.length; i < len; i++) { + nodeName = nodeNames[i]; + nodeList = doc.getElementsByTagNameNS('http://www.w3.org/2000/svg', nodeName); + nodeArray = nodeArray.concat(Array.from(nodeList)); + } + return nodeArray; +} + +function parseUseDirectives(doc) { + const nodelist = getMultipleNodes(doc, ['use', 'svg:use']); + const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform']; + for (const useElement of nodelist) { + const useAttributes = useElement.attributes; + const useAttrMap = {}; + for (const attr of useAttributes) { + attr.value && (useAttrMap[attr.name] = attr.value); + } + const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1); + if (xlink === '') { + return; + } + const referencedElement = doc.getElementById(xlink); + if (referencedElement === null) { + // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink + return; + } + let clonedOriginal = referencedElement.cloneNode(true); + const originalAttributes = clonedOriginal.attributes; + const originalAttrMap = {}; + for (const attr of originalAttributes) { + attr.value && (originalAttrMap[attr.name] = attr.value); + } + + // Transform attribute needs to be merged in a particular way + const { + x = 0, + y = 0, + transform = '' + } = useAttrMap; + const currentTrans = "".concat(transform, " ").concat(originalAttrMap.transform || '', " translate(").concat(x, ", ").concat(y, ")"); + applyViewboxTransform(clonedOriginal); + if (/^svg$/i.test(clonedOriginal.nodeName)) { + // if is an SVG, create a group and apply all the attributes on top of it + const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g'); + Object.entries(originalAttrMap).forEach(_ref => { + let [name, value] = _ref; + return el3.setAttributeNS(svgNS, name, value); + }); + el3.append(...clonedOriginal.childNodes); + clonedOriginal = el3; + } + for (const attr of useAttributes) { + if (!attr) { + continue; + } + const { + name, + value + } = attr; + if (skipAttributes.includes(name)) { + continue; + } + if (name === 'style') { + // when use has a style, merge the two styles, with the ref being priority (not use) + // priority is by feature. an attribute for fill on the original element + // will overwrite the fill in style or attribute for tha use + const styleRecord = {}; + parseStyleString(value, styleRecord); + // cleanup styleRecord from attributes of original + Object.entries(originalAttrMap).forEach(_ref2 => { + let [name, value] = _ref2; + styleRecord[name] = value; + }); + // now we can put in the style of the original that will overwrite the original attributes + parseStyleString(originalAttrMap.style || '', styleRecord); + const mergedStyles = Object.entries(styleRecord).map(entry => entry.join(':')).join(';'); + clonedOriginal.setAttribute(name, mergedStyles); + } else { + // set the attribute from use element only if the original does not have it already + !originalAttrMap[name] && clonedOriginal.setAttribute(name, value); + } + } + clonedOriginal.setAttribute('transform', currentTrans); + clonedOriginal.setAttribute('instantiated_by_use', '1'); + clonedOriginal.removeAttribute('id'); + useElement.parentNode.replaceChild(clonedOriginal, useElement); + } +} + +const gradientsAttrs = ['gradientTransform', 'x1', 'x2', 'y1', 'y2', 'gradientUnits', 'cx', 'cy', 'r', 'fx', 'fy']; +const xlinkAttr = 'xlink:href'; +function recursivelyParseGradientsXlink(doc, gradient) { + var _gradient$getAttribut; + const xLink = ((_gradient$getAttribut = gradient.getAttribute(xlinkAttr)) === null || _gradient$getAttribut === void 0 ? void 0 : _gradient$getAttribut.slice(1)) || '', + referencedGradient = doc.getElementById(xLink); + if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) { + recursivelyParseGradientsXlink(doc, referencedGradient); + } + if (referencedGradient) { + gradientsAttrs.forEach(attr => { + const value = referencedGradient.getAttribute(attr); + if (!gradient.hasAttribute(attr) && value) { + gradient.setAttribute(attr, value); + } + }); + if (!gradient.children.length) { + const referenceClone = referencedGradient.cloneNode(true); + while (referenceClone.firstChild) { + gradient.appendChild(referenceClone.firstChild); + } + } + } + gradient.removeAttribute(xlinkAttr); +} + +const tagArray = ['linearGradient', 'radialGradient', 'svg:linearGradient', 'svg:radialGradient']; + +/** + * Parses an SVG document, returning all of the gradient declarations found in it + * @param {SVGDocument} doc SVG document to parse + * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element + */ +function getGradientDefs(doc) { + const elList = getMultipleNodes(doc, tagArray); + const gradientDefs = {}; + let j = elList.length; + while (j--) { + const el = elList[j]; + if (el.getAttribute('xlink:href')) { + recursivelyParseGradientsXlink(doc, el); + } + const id = el.getAttribute('id'); + if (id) { + gradientDefs[id] = el; + } + } + return gradientDefs; +} + +/** + * Returns CSS rules for a given SVG document + * @param {HTMLElement} doc SVG document to parse + * @return {Object} CSS rules of this document + */ +function getCSSRules(doc) { + const styles = doc.getElementsByTagName('style'); + let i; + let len; + const allRules = {}; + + // very crude parsing of style contents + for (i = 0, len = styles.length; i < len; i++) { + const styleContents = (styles[i].textContent || '').replace( + // remove comments + /\/\*[\s\S]*?\*\//g, ''); + if (styleContents.trim() === '') { + continue; + } + // recovers all the rule in this form `body { style code... }` + // rules = styleContents.match(/[^{]*\{[\s\S]*?\}/g); + styleContents.split('}') + // remove empty rules and remove everything if we didn't split in at least 2 pieces + .filter((rule, index, array) => array.length > 1 && rule.trim()) + // at this point we have hopefully an array of rules `body { style code... ` + .forEach(rule => { + // if there is more than one opening bracket and the rule starts with '@', it is likely + // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below + // can not handle it. + if ((rule.match(/{/g) || []).length > 1 && rule.trim().startsWith('@')) { + return; + } + const match = rule.split('{'), + ruleObj = {}, + declaration = match[1].trim(), + propertyValuePairs = declaration.split(';').filter(function (pair) { + return pair.trim(); + }); + for (i = 0, len = propertyValuePairs.length; i < len; i++) { + const pair = propertyValuePairs[i].split(':'), + property = pair[0].trim(), + value = pair[1].trim(); + ruleObj[property] = value; + } + rule = match[0].trim(); + rule.split(',').forEach(_rule => { + _rule = _rule.replace(/^svg/i, '').trim(); + if (_rule === '') { + return; + } + allRules[_rule] = _objectSpread2(_objectSpread2({}, allRules[_rule] || {}), ruleObj); + }); + }); + } + return allRules; +} + +const findTag = el => classRegistry.getSVGClass(getTagName(el).toLowerCase()); +class ElementsParser { + constructor(elements, options, reviver, doc, clipPaths) { + this.elements = elements; + this.options = options; + this.reviver = reviver; + this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g; + this.doc = doc; + this.clipPaths = clipPaths; + this.gradientDefs = getGradientDefs(doc); + this.cssRules = getCSSRules(doc); + } + parse() { + return Promise.all(this.elements.map(element => this.createObject(element))); + } + async createObject(el) { + const klass = findTag(el); + if (klass) { + const obj = await klass.fromElement(el, this.options, this.cssRules); + this.resolveGradient(obj, el, FILL); + this.resolveGradient(obj, el, STROKE); + if (obj instanceof FabricImage && obj._originalElement) { + removeTransformMatrixForSvgParsing(obj, obj.parsePreserveAspectRatioAttribute()); + } else { + removeTransformMatrixForSvgParsing(obj); + } + await this.resolveClipPath(obj, el); + this.reviver && this.reviver(el, obj); + return obj; + } + return null; + } + extractPropertyDefinition(obj, property, storage) { + const value = obj[property], + regex = this.regexUrl; + if (!regex.test(value)) { + return undefined; + } + // verify: can we remove the 'g' flag? and remove lastIndex changes? + regex.lastIndex = 0; + // we passed the regex test, so we know is not null; + const id = regex.exec(value)[1]; + regex.lastIndex = 0; + // @todo fix this + return storage[id]; + } + resolveGradient(obj, el, property) { + const gradientDef = this.extractPropertyDefinition(obj, property, this.gradientDefs); + if (gradientDef) { + const opacityAttr = el.getAttribute(property + '-opacity'); + const gradient = Gradient.fromElement(gradientDef, obj, _objectSpread2(_objectSpread2({}, this.options), {}, { + opacity: opacityAttr + })); + obj.set(property, gradient); + } + } + + // TODO: resolveClipPath could be run once per clippath with minor work per object. + // is a refactor that i m not sure is worth on this code + async resolveClipPath(obj, usingElement) { + const clipPathElements = this.extractPropertyDefinition(obj, 'clipPath', this.clipPaths); + if (clipPathElements) { + const objTransformInv = invertTransform(obj.calcTransformMatrix()); + const clipPathTag = clipPathElements[0].parentElement; + let clipPathOwner = usingElement; + while (clipPathOwner.parentElement && clipPathOwner.getAttribute('clip-path') !== obj.clipPath) { + clipPathOwner = clipPathOwner.parentElement; + } + // move the clipPath tag as sibling to the real element that is using it + clipPathOwner.parentElement.appendChild(clipPathTag); + + // this multiplication order could be opposite. + // but i don't have an svg to test it + // at the first SVG that has a transform on both places and is misplaced + // try to invert this multiplication order + const finalTransform = parseTransformAttribute("".concat(clipPathOwner.getAttribute('transform') || '', " ").concat(clipPathTag.getAttribute('originalTransform') || '')); + clipPathTag.setAttribute('transform', "matrix(".concat(finalTransform.join(','), ")")); + const container = await Promise.all(clipPathElements.map(clipPathElement => { + return findTag(clipPathElement).fromElement(clipPathElement, this.options, this.cssRules).then(enlivedClippath => { + removeTransformMatrixForSvgParsing(enlivedClippath); + enlivedClippath.fillRule = enlivedClippath.clipRule; + delete enlivedClippath.clipRule; + return enlivedClippath; + }); + })); + const clipPath = container.length === 1 ? container[0] : new Group(container); + const gTransform = multiplyTransformMatrices(objTransformInv, clipPath.calcTransformMatrix()); + if (clipPath.clipPath) { + await this.resolveClipPath(clipPath, clipPathOwner); + } + const { + scaleX, + scaleY, + angle, + skewX, + translateX, + translateY + } = qrDecompose(gTransform); + clipPath.set({ + flipX: false, + flipY: false + }); + clipPath.set({ + scaleX, + scaleY, + angle, + skewX, + skewY: 0 + }); + clipPath.setPositionByOrigin(new Point(translateX, translateY), CENTER, CENTER); + obj.clipPath = clipPath; + } else { + // if clip-path does not resolve to any element, delete the property. + delete obj.clipPath; + return; + } + } +} + +const isValidSvgTag = el => svgValidTagNamesRegEx.test(getTagName(el)); +const createEmptyResponse = () => ({ + objects: [], + elements: [], + options: {}, + allElements: [] +}); + +/** + * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback + * @static + * @function + * @memberOf fabric + * @param {HTMLElement} doc SVG document to parse + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @return {SVGParsingOutput} + * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + */ +async function parseSVGDocument(doc, reviver) { + let { + crossOrigin, + signal + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + if (signal && signal.aborted) { + log('log', new SignalAbortedError('parseSVGDocument')); + // this is an unhappy path, we dont care about speed + return createEmptyResponse(); + } + const documentElement = doc.documentElement; + parseUseDirectives(doc); + const descendants = Array.from(documentElement.getElementsByTagName('*')), + options = _objectSpread2(_objectSpread2({}, applyViewboxTransform(documentElement)), {}, { + crossOrigin, + signal + }); + const elements = descendants.filter(el => { + applyViewboxTransform(el); + return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement + }); + if (!elements || elements && !elements.length) { + return _objectSpread2(_objectSpread2({}, createEmptyResponse()), {}, { + options, + allElements: descendants + }); + } + const localClipPaths = {}; + descendants.filter(el => getTagName(el) === 'clipPath').forEach(el => { + el.setAttribute('originalTransform', el.getAttribute('transform') || ''); + const id = el.getAttribute('id'); + localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(el => isValidSvgTag(el)); + }); + + // Precedence of rules: style > class > attribute + const elementParser = new ElementsParser(elements, options, reviver, doc, localClipPaths); + const instances = await elementParser.parse(); + return { + objects: instances, + elements, + options, + allElements: descendants + }; +} + +/** + * Takes string corresponding to an SVG document, and parses it into a set of fabric objects + * @memberOf fabric + * @param {String} string representing the svg + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + */ +function loadSVGFromString(string, reviver, options) { + const parser = new (getFabricWindow().DOMParser)(), + // should we use `image/svg+xml` here? + doc = parser.parseFromString(string.trim(), 'text/xml'); + return parseSVGDocument(doc, reviver, options); +} + +/** + * Takes url corresponding to an SVG document, and parses it into a set of fabric objects. + * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy) + * @memberOf fabric + * @param {string} url where the SVG is + * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes. + * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document. + * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added ) + * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created. + * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric, + * or extra custom manipulation + * @param {Object} [options] Object containing options for parsing + * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources + * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + */ +function loadSVGFromURL(url, reviver) { + let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // need to handle error properly + return new Promise((resolve, reject) => { + const onComplete = r => { + const xml = r.responseXML; + if (xml) { + resolve(xml); + } + reject(); + }; + request(url.replace(/^\n\s*/, '').trim(), { + onComplete, + signal: options.signal + }); + }).then(parsedDoc => parseSVGDocument(parsedDoc, reviver, options)).catch(() => { + // this is an unhappy path, we dont care about speed + return createEmptyResponse(); + }); +} + +const ACTION_NAME$1 = MODIFY_POLY; +/** + * This function locates the controls. + * It'll be used both for drawing and for interaction. + */ +const createPolyPositionHandler = pointIndex => { + return function (dim, finalMatrix, polyObject) { + const { + points, + pathOffset + } = polyObject; + return new Point(points[pointIndex]).subtract(pathOffset).transform(multiplyTransformMatrices(polyObject.getViewportTransform(), polyObject.calcTransformMatrix())); + }; +}; + +/** + * This function defines what the control does. + * It'll be called on every mouse move after a control has been clicked and is being dragged. + * The function receives as argument the mouse event, the current transform object + * and the current position in canvas coordinate `transform.target` is a reference to the + * current object being transformed. + */ +const polyActionHandler = (eventData, transform, x, y) => { + const { + target, + pointIndex + } = transform; + const poly = target; + const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, poly.calcOwnMatrix()); + poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset); + poly.setDimensions(); + return true; +}; + +/** + * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`. + */ +const factoryPolyActionHandler = (pointIndex, fn) => { + return function (eventData, transform, x, y) { + const poly = transform.target, + anchorPoint = new Point(poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1]), + anchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()), + actionPerformed = fn(eventData, _objectSpread2(_objectSpread2({}, transform), {}, { + pointIndex + }), x, y); + const newAnchorPointInParentPlane = anchorPoint.subtract(poly.pathOffset).transform(poly.calcOwnMatrix()); + const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane); + poly.left -= diff.x; + poly.top -= diff.y; + return actionPerformed; + }; +}; +const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler)); +function createPolyControls(arg0) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const controls = {}; + for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) { + controls["p".concat(idx)] = new Control(_objectSpread2({ + actionName: ACTION_NAME$1, + positionHandler: createPolyPositionHandler(idx), + actionHandler: createPolyActionHandler(idx) + }, options)); + } + return controls; +} + +const ACTION_NAME = 'modifyPath'; +const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => { + const { + path, + pathOffset + } = pathObject; + const command = path[commandIndex]; + return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix())); +}; +const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => { + const { + path, + pathOffset + } = pathObject; + const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1]; + const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]); + const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix()); + const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix()); + path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x; + path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y; + pathObject.setDimensions(); + const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix()); + const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane); + pathObject.left -= diff.x; + pathObject.top -= diff.y; + pathObject.set('dirty', true); + return true; +}; + +/** + * This function locates the controls. + * It'll be used both for drawing and for interaction. + */ +function pathPositionHandler(dim, finalMatrix, pathObject) { + const { + commandIndex, + pointIndex + } = this; + return calcPathPointPosition(pathObject, commandIndex, pointIndex); +} + +/** + * This function defines what the control does. + * It'll be called on every mouse move after a control has been clicked and is being dragged. + * The function receives as argument the mouse event, the current transform object + * and the current position in canvas coordinate `transform.target` is a reference to the + * current object being transformed. + */ +function pathActionHandler(eventData, transform, x, y) { + const { + target + } = transform; + const { + commandIndex, + pointIndex + } = this; + const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex); + { + fireEvent(this.actionName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), {}, { + commandIndex, + pointIndex + })); + } + return actionPerformed; +} +const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1; +class PathPointControl extends Control { + constructor(options) { + super(options); + } + render(ctx, left, top, styleOverride, fabricObject) { + const overrides = _objectSpread2(_objectSpread2({}, styleOverride), {}, { + cornerColor: this.controlFill, + cornerStrokeColor: this.controlStroke, + transparentCorners: !this.controlFill + }); + super.render(ctx, left, top, overrides, fabricObject); + } +} +class PathControlPointControl extends PathPointControl { + constructor(options) { + super(options); + } + render(ctx, left, top, styleOverride, fabricObject) { + const { + path + } = fabricObject; + const { + commandIndex, + pointIndex, + connectToCommandIndex, + connectToPointIndex + } = this; + ctx.save(); + ctx.strokeStyle = this.controlStroke; + if (this.connectionDashArray) { + ctx.setLineDash(this.connectionDashArray); + } + const [commandType] = path[commandIndex]; + const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex); + if (commandType === 'Q') { + // one control point connects to 2 points + const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2); + ctx.moveTo(point2.x, point2.y); + ctx.lineTo(left, top); + } else { + ctx.moveTo(left, top); + } + ctx.lineTo(point.x, point.y); + ctx.stroke(); + ctx.restore(); + super.render(ctx, left, top, styleOverride, fabricObject); + } +} +const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)(_objectSpread2(_objectSpread2({ + commandIndex: commandIndexPos, + pointIndex: pointIndexPos, + actionName: ACTION_NAME, + positionHandler: pathPositionHandler, + actionHandler: pathActionHandler, + connectToCommandIndex, + connectToPointIndex +}, options), isControlPoint ? options.controlPointStyle : options.pointStyle)); +function createPathControls(path) { + let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + const controls = {}; + let previousCommandType = 'M'; + path.path.forEach((command, commandIndex) => { + const commandType = command[0]; + if (commandType !== 'Z') { + controls["c_".concat(commandIndex, "_").concat(commandType)] = createControl(commandIndex, command.length - 2, false, options); + } + switch (commandType) { + case 'C': + controls["c_".concat(commandIndex, "_C_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType)); + controls["c_".concat(commandIndex, "_C_CP_2")] = createControl(commandIndex, 3, true, options, commandIndex, 5); + break; + case 'Q': + controls["c_".concat(commandIndex, "_Q_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex, 3); + break; + } + previousCommandType = commandType; + }); + return controls; +} + +var index = /*#__PURE__*/Object.freeze({ + __proto__: null, + changeWidth: changeWidth, + createObjectDefaultControls: createObjectDefaultControls, + createPathControls: createPathControls, + createPolyActionHandler: createPolyActionHandler, + createPolyControls: createPolyControls, + createPolyPositionHandler: createPolyPositionHandler, + createResizeControls: createResizeControls, + createTextboxDefaultControls: createTextboxDefaultControls, + dragHandler: dragHandler, + factoryPolyActionHandler: factoryPolyActionHandler, + getLocalPoint: getLocalPoint, + polyActionHandler: polyActionHandler, + renderCircleControl: renderCircleControl, + renderSquareControl: renderSquareControl, + rotationStyleHandler: rotationStyleHandler, + rotationWithSnapping: rotationWithSnapping, + scaleCursorStyleHandler: scaleCursorStyleHandler, + scaleOrSkewActionName: scaleOrSkewActionName, + scaleSkewCursorStyleHandler: scaleSkewCursorStyleHandler, + scalingEqually: scalingEqually, + scalingX: scalingX, + scalingXOrSkewingY: scalingXOrSkewingY, + scalingY: scalingY, + scalingYOrSkewingX: scalingYOrSkewingX, + skewCursorStyleHandler: skewCursorStyleHandler, + skewHandlerX: skewHandlerX, + skewHandlerY: skewHandlerY, + wrapWithFireEvent: wrapWithFireEvent, + wrapWithFixedAnchor: wrapWithFixedAnchor +}); + +const isWebGLPipelineState = options => { + return options.webgl !== undefined; +}; + +/** + * Pick a method to copy data from GL context to 2d canvas. In some browsers using + * drawImage should be faster, but is also bugged for a small combination of old hardware + * and drivers. + * putImageData is faster than drawImage for that specific operation. + */ +const isPutImageFaster = (width, height) => { + const targetCanvas = createCanvasElement(); + const sourceCanvas = createCanvasElement(); + const gl = sourceCanvas.getContext('webgl'); + // eslint-disable-next-line no-undef + const imageBuffer = new ArrayBuffer(width * height * 4); + const testContext = { + imageBuffer: imageBuffer + }; + const testPipelineState = { + destinationWidth: width, + destinationHeight: height, + targetCanvas: targetCanvas + }; + let startTime; + targetCanvas.width = width; + targetCanvas.height = height; + startTime = getFabricWindow().performance.now(); + WebGLFilterBackend.prototype.copyGLTo2D.call(testContext, gl, testPipelineState); + const drawImageTime = getFabricWindow().performance.now() - startTime; + startTime = getFabricWindow().performance.now(); + WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(testContext, gl, testPipelineState); + const putImageDataTime = getFabricWindow().performance.now() - startTime; + return drawImageTime > putImageDataTime; +}; + +const highPsourceCode = "precision highp float"; +const identityFragmentShader = "\n ".concat(highPsourceCode, ";\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }"); +const vertexSource$1 = "\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }"; + +const _excluded$1 = ["type"], + _excluded2 = ["type"]; +const regex = new RegExp(highPsourceCode, 'g'); +class BaseFilter { + /** + * Filter type + * @param {String} type + * @default + */ + get type() { + return this.constructor.type; + } + + /** + * The class type. Used to identify which class this is. + * This is used for serialization purposes and internally it can be used + * to identify classes. As a developer you could use `instance of Class` + * but to avoid importing all the code and blocking tree shaking we try + * to avoid doing that. + */ + + /** + * Constructor + * @param {Object} [options] Options object + */ + constructor() { + let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + options = _objectWithoutProperties(_ref, _excluded$1); + Object.assign(this, this.constructor.defaults, options); + } + getFragmentSource() { + return identityFragmentShader; + } + getVertexSource() { + return vertexSource$1; + } + + /** + * Compile this filter's shader program. + * + * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation. + * @param {String} fragmentSource fragmentShader source for compilation + * @param {String} vertexSource vertexShader source for compilation + */ + createProgram(gl) { + let fragmentSource = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getFragmentSource(); + let vertexSource = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getVertexSource(); + const { + WebGLProbe: { + GLPrecision = 'highp' + } + } = getEnv$1(); + if (GLPrecision !== 'highp') { + fragmentSource = fragmentSource.replace(regex, highPsourceCode.replace('highp', GLPrecision)); + } + const vertexShader = gl.createShader(gl.VERTEX_SHADER); + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + const program = gl.createProgram(); + if (!vertexShader || !fragmentShader || !program) { + throw new FabricError('Vertex, fragment shader or program creation error'); + } + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { + throw new FabricError("Vertex shader compile error for ".concat(this.type, ": ").concat(gl.getShaderInfoLog(vertexShader))); + } + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) { + throw new FabricError("Fragment shader compile error for ".concat(this.type, ": ").concat(gl.getShaderInfoLog(fragmentShader))); + } + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + throw new FabricError("Shader link error for \"".concat(this.type, "\" ").concat(gl.getProgramInfoLog(program))); + } + const uniformLocations = this.getUniformLocations(gl, program) || {}; + uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW'); + uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH'); + return { + program, + attributeLocations: this.getAttributeLocations(gl, program), + uniformLocations + }; + } + + /** + * Return a map of attribute names to WebGLAttributeLocation objects. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {WebGLShaderProgram} program The shader program from which to take attribute locations. + * @returns {Object} A map of attribute names to attribute locations. + */ + getAttributeLocations(gl, program) { + return { + aPosition: gl.getAttribLocation(program, 'aPosition') + }; + } + + /** + * Return a map of uniform names to WebGLUniformLocation objects. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {WebGLShaderProgram} program The shader program from which to take uniform locations. + * @returns {Object} A map of uniform names to uniform locations. + */ + getUniformLocations(gl, program) { + const locations = this.constructor.uniformLocations; + const uniformLocations = {}; + for (let i = 0; i < locations.length; i++) { + uniformLocations[locations[i]] = gl.getUniformLocation(program, locations[i]); + } + return uniformLocations; + } + + /** + * Send attribute data from this filter to its shader program on the GPU. + * + * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program. + * @param {Object} attributeLocations A map of shader attribute names to their locations. + */ + sendAttributeData(gl, attributeLocations, aPositionData) { + const attributeLocation = attributeLocations.aPosition; + const buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.enableVertexAttribArray(attributeLocation); + gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0); + gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW); + } + _setupFrameBuffer(options) { + const gl = options.context; + if (options.passes > 1) { + const width = options.destinationWidth; + const height = options.destinationHeight; + if (options.sourceWidth !== width || options.sourceHeight !== height) { + gl.deleteTexture(options.targetTexture); + options.targetTexture = options.filterBackend.createTexture(gl, width, height); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, options.targetTexture, 0); + } else { + // draw last filter on canvas and not to framebuffer. + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.finish(); + } + } + _swapTextures(options) { + options.passes--; + options.pass++; + const temp = options.targetTexture; + options.targetTexture = options.sourceTexture; + options.sourceTexture = temp; + } + + /** + * Generic isNeutral implementation for one parameter based filters. + * Used only in image applyFilters to discard filters that will not have an effect + * on the image + * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter ) + * @param {Object} options + **/ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + isNeutralState(options) { + return false; + } + + /** + * Apply this filter to the input image data provided. + * + * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + this._setupFrameBuffer(options); + this.applyToWebGL(options); + this._swapTextures(options); + } else { + this.applyTo2d(options); + } + } + applyTo2d(_options) { + // override by subclass + } + + /** + * Returns a string that represent the current selected shader code for the filter. + * Used to force recompilation when parameters change or to retrieve the shader from cache + * @type string + **/ + getCacheKey() { + return this.type; + } + + /** + * Retrieves the cached shader. + * @param {Object} options + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + * @return {WebGLProgram} the compiled program shader + */ + retrieveShader(options) { + const key = this.getCacheKey(); + if (!options.programCache[key]) { + options.programCache[key] = this.createProgram(options.context); + } + return options.programCache[key]; + } + + /** + * Apply this filter using webgl. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.originalTexture The texture of the original input image. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyToWebGL(options) { + const gl = options.context; + const shader = this.retrieveShader(options); + if (options.pass === 0 && options.originalTexture) { + gl.bindTexture(gl.TEXTURE_2D, options.originalTexture); + } else { + gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture); + } + gl.useProgram(shader.program); + this.sendAttributeData(gl, shader.attributeLocations, options.aPosition); + gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth); + gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight); + this.sendUniformData(gl, shader.uniformLocations); + gl.viewport(0, 0, options.destinationWidth, options.destinationHeight); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + bindAdditionalTexture(gl, texture, textureUnit) { + gl.activeTexture(textureUnit); + gl.bindTexture(gl.TEXTURE_2D, texture); + // reset active texture to 0 as usual + gl.activeTexture(gl.TEXTURE0); + } + unbindAdditionalTexture(gl, textureUnit) { + gl.activeTexture(textureUnit); + gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0); + } + + /** + * Send uniform data from this filter to its shader program on the GPU. + * + * Intended to be overridden by subclasses. + * + * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program. + * @param {Object} _uniformLocations A map of shader uniform names to their locations. + */ + sendUniformData(_gl, _uniformLocations) { + // override by subclass + } + + /** + * If needed by a 2d filter, this functions can create an helper canvas to be used + * remember that options.targetCanvas is available for use till end of chain. + */ + createHelpLayer(options) { + if (!options.helpLayer) { + const helpLayer = createCanvasElement(); + helpLayer.width = options.sourceWidth; + helpLayer.height = options.sourceHeight; + options.helpLayer = helpLayer; + } + } + + /** + * Returns object representation of an instance + * It will automatically export the default values of a filter, + * stored in the static defaults property. + * @return {Object} Object representation of an instance + */ + toObject() { + const defaultKeys = Object.keys(this.constructor.defaults || {}); + return _objectSpread2({ + type: this.type + }, defaultKeys.reduce((acc, key) => { + acc[key] = this[key]; + return acc; + }, {})); + } + + /** + * Returns a JSON representation of an instance + * @return {Object} JSON + */ + toJSON() { + // delegate, not alias + return this.toObject(); + } + static async fromObject(_ref2, _options) { + let filterOptions = _objectWithoutProperties(_ref2, _excluded2); + return new this(filterOptions); + } +} +_defineProperty(BaseFilter, "type", 'BaseFilter'); +/** + * Contains the uniform locations for the fragment shader. + * uStepW and uStepH are handled by the BaseFilter, each filter class + * needs to specify all the one that are needed + */ +_defineProperty(BaseFilter, "uniformLocations", []); + +const blendColorFragmentSource = { + multiply: 'gl_FragColor.rgb *= uColor.rgb;\n', + screen: 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\n', + add: 'gl_FragColor.rgb += uColor.rgb;\n', + difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\n', + subtract: 'gl_FragColor.rgb -= uColor.rgb;\n', + lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\n', + darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\n', + exclusion: 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\n', + overlay: "\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n ", + tint: "\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n " +}; + +const blendColorDefaultValues = { + color: '#F95C63', + mode: 'multiply', + alpha: 1 +}; + +/** + * Color Blend filter class + * @example + * const filter = new BlendColor({ + * color: '#000', + * mode: 'multiply' + * }); + * + * const filter = new BlendImage({ + * image: fabricImageObject, + * mode: 'multiply' + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class BlendColor extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ".concat(blendColorFragmentSource[this.mode], "\n }\n }\n "); + } + + /** + * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const source = new Color(this.color).getSource(); + const tr = source[0] * this.alpha; + const tg = source[1] * this.alpha; + const tb = source[2] * this.alpha; + const alpha1 = 1 - this.alpha; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + switch (this.mode) { + case 'multiply': + data[i] = r * tr / 255; + data[i + 1] = g * tg / 255; + data[i + 2] = b * tb / 255; + break; + case 'screen': + data[i] = 255 - (255 - r) * (255 - tr) / 255; + data[i + 1] = 255 - (255 - g) * (255 - tg) / 255; + data[i + 2] = 255 - (255 - b) * (255 - tb) / 255; + break; + case 'add': + data[i] = r + tr; + data[i + 1] = g + tg; + data[i + 2] = b + tb; + break; + case 'difference': + data[i] = Math.abs(r - tr); + data[i + 1] = Math.abs(g - tg); + data[i + 2] = Math.abs(b - tb); + break; + case 'subtract': + data[i] = r - tr; + data[i + 1] = g - tg; + data[i + 2] = b - tb; + break; + case 'darken': + data[i] = Math.min(r, tr); + data[i + 1] = Math.min(g, tg); + data[i + 2] = Math.min(b, tb); + break; + case 'lighten': + data[i] = Math.max(r, tr); + data[i + 1] = Math.max(g, tg); + data[i + 2] = Math.max(b, tb); + break; + case 'overlay': + data[i] = tr < 128 ? 2 * r * tr / 255 : 255 - 2 * (255 - r) * (255 - tr) / 255; + data[i + 1] = tg < 128 ? 2 * g * tg / 255 : 255 - 2 * (255 - g) * (255 - tg) / 255; + data[i + 2] = tb < 128 ? 2 * b * tb / 255 : 255 - 2 * (255 - b) * (255 - tb) / 255; + break; + case 'exclusion': + data[i] = tr + r - 2 * tr * r / 255; + data[i + 1] = tg + g - 2 * tg * g / 255; + data[i + 2] = tb + b - 2 * tb * b / 255; + break; + case 'tint': + data[i] = tr + r * alpha1; + data[i + 1] = tg + g * alpha1; + data[i + 2] = tb + b * alpha1; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const source = new Color(this.color).getSource(); + source[0] = this.alpha * source[0] / 255; + source[1] = this.alpha * source[1] / 255; + source[2] = this.alpha * source[2] / 255; + source[3] = this.alpha; + gl.uniform4fv(uniformLocations.uColor, source); + } +} +/** + * Color to make the blend operation with. default to a reddish color since black or white + * gives always strong result. + * @type String + * @default + **/ +/** + * Blend mode for the filter: one of multiply, add, difference, screen, subtract, + * darken, lighten, overlay, exclusion, tint. + * @type String + * @default + **/ +/** + * alpha value. represent the strength of the blend color operation. + * @type Number + * @default + **/ +_defineProperty(BlendColor, "defaults", blendColorDefaultValues); +_defineProperty(BlendColor, "type", 'BlendColor'); +_defineProperty(BlendColor, "uniformLocations", ['uColor']); +classRegistry.setClass(BlendColor); + +const fragmentSource$c = { + multiply: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n ", + mask: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n " +}; +const vertexSource = "\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n "; + +const _excluded = ["type", "image"]; +const blendImageDefaultValues = { + mode: 'multiply', + alpha: 1 +}; + +/** + * Image Blend filter class + * @example + * const filter = new filters.BlendColor({ + * color: '#000', + * mode: 'multiply' + * }); + * + * const filter = new BlendImage({ + * image: fabricImageObject, + * mode: 'multiply' + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class BlendImage extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return fragmentSource$c[this.mode]; + } + getVertexSource() { + return vertexSource; + } + applyToWebGL(options) { + const gl = options.context, + texture = this.createTexture(options.filterBackend, this.image); + this.bindAdditionalTexture(gl, texture, gl.TEXTURE1); + super.applyToWebGL(options); + this.unbindAdditionalTexture(gl, gl.TEXTURE1); + } + createTexture(backend, image) { + return backend.getCachedTexture(image.cacheKey, image.getElement()); + } + + /** + * Calculate a transformMatrix to adapt the image to blend over + * @param {Object} options + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + calculateMatrix() { + const image = this.image, + { + width, + height + } = image.getElement(); + return [1 / image.scaleX, 0, 0, 0, 1 / image.scaleY, 0, -image.left / width, -image.top / height, 1]; + } + + /** + * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data, + width, + height + }, + filterBackend: { + resources + } + } = _ref; + const image = this.image; + if (!resources.blendImage) { + resources.blendImage = createCanvasElement(); + } + const canvas1 = resources.blendImage; + const context = canvas1.getContext('2d'); + if (canvas1.width !== width || canvas1.height !== height) { + canvas1.width = width; + canvas1.height = height; + } else { + context.clearRect(0, 0, width, height); + } + context.setTransform(image.scaleX, 0, 0, image.scaleY, image.left, image.top); + context.drawImage(image.getElement(), 0, 0, width, height); + const blendData = context.getImageData(0, 0, width, height).data; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + const a = data[i + 3]; + const tr = blendData[i]; + const tg = blendData[i + 1]; + const tb = blendData[i + 2]; + const ta = blendData[i + 3]; + switch (this.mode) { + case 'multiply': + data[i] = r * tr / 255; + data[i + 1] = g * tg / 255; + data[i + 2] = b * tb / 255; + data[i + 3] = a * ta / 255; + break; + case 'mask': + data[i + 3] = ta; + break; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const matrix = this.calculateMatrix(); + gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1. + gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix); + } + + /** + * Returns object representation of an instance + * TODO: Handle the possibility of missing image better. + * As of now a BlendImage filter without image can't be used with fromObject + * @return {Object} Object representation of an instance + */ + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + image: this.image && this.image.toObject() + }); + } + + /** + * Create filter instance from an object representation + * @static + * @param {object} object Object to create an instance from + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static async fromObject(_ref2, options) { + let { + type, + image + } = _ref2, + filterOptions = _objectWithoutProperties(_ref2, _excluded); + return FabricImage.fromObject(image, options).then(enlivedImage => new this(_objectSpread2(_objectSpread2({}, filterOptions), {}, { + image: enlivedImage + }))); + } +} +/** + * Image to make the blend operation with. + **/ +/** + * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will + * multiply the values of each channel (R, G, B, and A) of the filter image by + * their corresponding values in the base image. 'mask' will only look at the + * alpha channel of the filter image, and apply those values to the base + * image's alpha channel. + * @type String + * @default + **/ +/** + * alpha value. represent the strength of the blend image operation. + * not implemented. + **/ +_defineProperty(BlendImage, "type", 'BlendImage'); +_defineProperty(BlendImage, "defaults", blendImageDefaultValues); +_defineProperty(BlendImage, "uniformLocations", ['uTransformMatrix', 'uImage']); +classRegistry.setClass(BlendImage); + +const fragmentSource$b = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n "; + +const blurDefaultValues = { + blur: 0 +}; + +/** + * Blur filter class + * @example + * const filter = new Blur({ + * blur: 0.5 + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Blur extends BaseFilter { + getFragmentSource() { + return fragmentSource$b; + } + applyTo(options) { + if (isWebGLPipelineState(options)) { + // this aspectRatio is used to give the same blur to vertical and horizontal + this.aspectRatio = options.sourceWidth / options.sourceHeight; + options.passes++; + this._setupFrameBuffer(options); + this.horizontal = true; + this.applyToWebGL(options); + this._swapTextures(options); + this._setupFrameBuffer(options); + this.horizontal = false; + this.applyToWebGL(options); + this._swapTextures(options); + } else { + this.applyTo2d(options); + } + } + applyTo2d(options) { + options.imageData = this.simpleBlur(options); + } + simpleBlur(_ref) { + let { + ctx, + imageData, + filterBackend: { + resources + } + } = _ref; + const { + width, + height + } = imageData; + if (!resources.blurLayer1) { + resources.blurLayer1 = createCanvasElement(); + resources.blurLayer2 = createCanvasElement(); + } + const canvas1 = resources.blurLayer1; + const canvas2 = resources.blurLayer2; + if (canvas1.width !== width || canvas1.height !== height) { + canvas2.width = canvas1.width = width; + canvas2.height = canvas1.height = height; + } + const ctx1 = canvas1.getContext('2d'), + ctx2 = canvas2.getContext('2d'), + nSamples = 15, + blur = this.blur * 0.06 * 0.5; + let random, percent, j, i; + + // load first canvas + ctx1.putImageData(imageData, 0, 0); + ctx2.clearRect(0, 0, width, height); + for (i = -nSamples; i <= nSamples; i++) { + random = (Math.random() - 0.5) / 4; + percent = i / nSamples; + j = blur * percent * width + random; + ctx2.globalAlpha = 1 - Math.abs(percent); + ctx2.drawImage(canvas1, j, random); + ctx1.drawImage(canvas2, 0, 0); + ctx2.globalAlpha = 1; + ctx2.clearRect(0, 0, canvas2.width, canvas2.height); + } + for (i = -nSamples; i <= nSamples; i++) { + random = (Math.random() - 0.5) / 4; + percent = i / nSamples; + j = blur * percent * height + random; + ctx2.globalAlpha = 1 - Math.abs(percent); + ctx2.drawImage(canvas1, random, j); + ctx1.drawImage(canvas2, 0, 0); + ctx2.globalAlpha = 1; + ctx2.clearRect(0, 0, canvas2.width, canvas2.height); + } + ctx.drawImage(canvas1, 0, 0); + const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height); + ctx1.globalAlpha = 1; + ctx1.clearRect(0, 0, canvas1.width, canvas1.height); + return newImageData; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const delta = this.chooseRightDelta(); + gl.uniform2fv(uniformLocations.uDelta, delta); + } + isNeutralState() { + return this.blur === 0; + } + + /** + * choose right value of image percentage to blur with + * @returns {Array} a numeric array with delta values + */ + chooseRightDelta() { + let blurScale = 1; + const delta = [0, 0]; + if (this.horizontal) { + if (this.aspectRatio > 1) { + // image is wide, i want to shrink radius horizontal + blurScale = 1 / this.aspectRatio; + } + } else { + if (this.aspectRatio < 1) { + // image is tall, i want to shrink radius vertical + blurScale = this.aspectRatio; + } + } + const blur = blurScale * this.blur * 0.12; + if (this.horizontal) { + delta[0] = blur; + } else { + delta[1] = blur; + } + return delta; + } +} +/** + * blur value, in percentage of image dimensions. + * specific to keep the image blur constant at different resolutions + * range between 0 and 1. + * @type Number + * @default + */ +_defineProperty(Blur, "type", 'Blur'); +_defineProperty(Blur, "defaults", blurDefaultValues); +_defineProperty(Blur, "uniformLocations", ['uDelta']); +classRegistry.setClass(Blur); + +const fragmentSource$a = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n"; + +const brightnessDefaultValues = { + brightness: 0 +}; + +/** + * Brightness filter class + * @example + * const filter = new Brightness({ + * brightness: 0.05 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Brightness extends BaseFilter { + getFragmentSource() { + return fragmentSource$a; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const brightness = Math.round(this.brightness * 255); + for (let i = 0; i < data.length; i += 4) { + data[i] = data[i] + brightness; + data[i + 1] = data[i + 1] + brightness; + data[i + 2] = data[i + 2] + brightness; + } + } + isNeutralState() { + return this.brightness === 0; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uBrightness, this.brightness); + } +} +/** + * Brightness value, from -1 to 1. + * translated to -255 to 255 for 2d + * 0.0039215686 is the part of 1 that get translated to 1 in 2d + * @param {Number} brightness + * @default + */ +_defineProperty(Brightness, "type", 'Brightness'); +_defineProperty(Brightness, "defaults", brightnessDefaultValues); +_defineProperty(Brightness, "uniformLocations", ['uBrightness']); +classRegistry.setClass(Brightness); + +const fragmentSource$9 = "\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }"; + +const colorMatrixDefaultValues = { + matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], + colorsOnly: true +}; + +/** + * Color Matrix filter class + * @see {@link http://fabricjs.com/image-filters|ImageFilters demo} + * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo} + * @example Kodachrome filter + * const filter = new ColorMatrix({ + * matrix: [ + 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, + -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, + -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, + 0, 0, 0, 1, 0 + ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class ColorMatrix extends BaseFilter { + getFragmentSource() { + return fragmentSource$9; + } + + /** + * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(options) { + const imageData = options.imageData, + data = imageData.data, + m = this.matrix, + colorsOnly = this.colorsOnly; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + if (colorsOnly) { + data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255; + data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255; + data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255; + } else { + const a = data[i + 3]; + data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255; + data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255; + data[i + 2] = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255; + data[i + 3] = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const m = this.matrix, + matrix = [m[0], m[1], m[2], m[3], m[5], m[6], m[7], m[8], m[10], m[11], m[12], m[13], m[15], m[16], m[17], m[18]], + constants = [m[4], m[9], m[14], m[19]]; + gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix); + gl.uniform4fv(uniformLocations.uConstants, constants); + } + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + matrix: [...this.matrix] + }); + } +} +/** + * Colormatrix for pixels. + * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning + * outside the -1, 1 range. + * 0.0039215686 is the part of 1 that get translated to 1 in 2d + * @param {Array} matrix array of 20 numbers. + * @default + */ +/** + * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario + * to save some calculation + * @type Boolean + * @default true + */ +_defineProperty(ColorMatrix, "type", 'ColorMatrix'); +_defineProperty(ColorMatrix, "defaults", colorMatrixDefaultValues); +_defineProperty(ColorMatrix, "uniformLocations", ['uColorMatrix', 'uConstants']); +classRegistry.setClass(ColorMatrix); + +function createColorMatrixFilter(key, matrix) { + var _Class; + const newClass = (_Class = class newClass extends ColorMatrix { + //@ts-expect-error TS wants matrix to be exported. + toObject() { + return { + type: this.type, + colorsOnly: this.colorsOnly + }; + } + }, _defineProperty(_Class, "type", key), _defineProperty(_Class, "defaults", { + colorsOnly: false, + matrix + }), _Class); + classRegistry.setClass(newClass, key); + return newClass; +} +const Brownie = createColorMatrixFilter('Brownie', [0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449, 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0]); +const Vintage = createColorMatrixFilter('Vintage', [0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0, 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0]); +const Kodachrome = createColorMatrixFilter('Kodachrome', [1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0, 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0]); +const Technicolor = createColorMatrixFilter('Technicolor', [1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0, -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0]); +const Polaroid = createColorMatrixFilter('Polaroid', [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0]); +const Sepia = createColorMatrixFilter('Sepia', [0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131, 0, 0, 0, 0, 0, 1, 0]); +const BlackWhite = createColorMatrixFilter('BlackWhite', [1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0, 1, 0]); + +/** + * A container class that knows how to apply a sequence of filters to an input image. + */ +class Composed extends BaseFilter { + constructor() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + super(options); + this.subFilters = options.subFilters || []; + } + + /** + * Apply this container's filters to the input image provided. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be applied. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + options.passes += this.subFilters.length - 1; + } + this.subFilters.forEach(filter => { + filter.applyTo(options); + }); + } + + /** + * Serialize this filter into JSON. + * @returns {Object} A JSON representation of this filter. + */ + //@ts-expect-error TS doesn't like this toObject + toObject() { + return { + type: this.type, + subFilters: this.subFilters.map(filter => filter.toObject()) + }; + } + isNeutralState() { + return !this.subFilters.some(filter => !filter.isNeutralState()); + } + + /** + * Deserialize a JSON definition of a ComposedFilter into a concrete instance. + * @static + * @param {oject} object Object to create an instance from + * @param {object} [options] + * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal + * @returns {Promise} + */ + static fromObject(object, options) { + return Promise.all((object.subFilters || []).map(filter => classRegistry.getClass(filter.type).fromObject(filter, options))).then(enlivedFilters => new this({ + subFilters: enlivedFilters + })); + } +} +/** + * A non sparse array of filters to apply + */ +_defineProperty(Composed, "type", 'Composed'); +classRegistry.setClass(Composed); + +const fragmentSource$8 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }"; + +const contrastDefaultValues = { + contrast: 0 +}; + +/** + * Contrast filter class + * @example + * const filter = new Contrast({ + * contrast: 0.25 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Contrast extends BaseFilter { + getFragmentSource() { + return fragmentSource$8; + } + isNeutralState() { + return this.contrast === 0; + } + + /** + * Apply the Contrast operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const contrast = Math.floor(this.contrast * 255), + contrastF = 259 * (contrast + 255) / (255 * (259 - contrast)); + for (let i = 0; i < data.length; i += 4) { + data[i] = contrastF * (data[i] - 128) + 128; + data[i + 1] = contrastF * (data[i + 1] - 128) + 128; + data[i + 2] = contrastF * (data[i + 2] - 128) + 128; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uContrast, this.contrast); + } +} +/** + * contrast value, range from -1 to 1. + * @param {Number} contrast + * @default 0 + */ +_defineProperty(Contrast, "type", 'Contrast'); +_defineProperty(Contrast, "defaults", contrastDefaultValues); +_defineProperty(Contrast, "uniformLocations", ['uContrast']); +classRegistry.setClass(Contrast); + +const fragmentSource$7 = { + Convolute_3_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_3_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_5_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_5_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_7_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_7_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n ", + Convolute_9_1: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n ", + Convolute_9_0: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n " +}; + +const convoluteDefaultValues = { + opaque: false, + matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0] +}; + +/** + * Adapted from html5rocks article + * @example Sharpen filter + * const filter = new Convolute({ + * matrix: [ 0, -1, 0, + * -1, 5, -1, + * 0, -1, 0 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Blur filter + * const filter = new Convolute({ + * matrix: [ 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9, + * 1/9, 1/9, 1/9 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Emboss filter + * const filter = new Convolute({ + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + * @example Emboss filter with opaqueness + * const filter = new Convolute({ + * opaque: true, + * matrix: [ 1, 1, 1, + * 1, 0.7, -1, + * -1, -1, -1 ] + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Convolute extends BaseFilter { + getCacheKey() { + return "".concat(this.type, "_").concat(Math.sqrt(this.matrix.length), "_").concat(this.opaque ? 1 : 0); + } + getFragmentSource() { + return fragmentSource$7[this.getCacheKey()]; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(options) { + const imageData = options.imageData, + data = imageData.data, + weights = this.matrix, + side = Math.round(Math.sqrt(weights.length)), + halfSide = Math.floor(side / 2), + sw = imageData.width, + sh = imageData.height, + output = options.ctx.createImageData(sw, sh), + dst = output.data, + // go through the destination image pixels + alphaFac = this.opaque ? 1 : 0; + let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy; + for (y = 0; y < sh; y++) { + for (x = 0; x < sw; x++) { + dstOff = (y * sw + x) * 4; + // calculate the weighed sum of the source image pixels that + // fall under the convolution matrix + r = 0; + g = 0; + b = 0; + a = 0; + for (cy = 0; cy < side; cy++) { + for (cx = 0; cx < side; cx++) { + scy = y + cy - halfSide; + scx = x + cx - halfSide; + + // eslint-disable-next-line max-depth + if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) { + continue; + } + srcOff = (scy * sw + scx) * 4; + wt = weights[cy * side + cx]; + r += data[srcOff] * wt; + g += data[srcOff + 1] * wt; + b += data[srcOff + 2] * wt; + // eslint-disable-next-line max-depth + if (!alphaFac) { + a += data[srcOff + 3] * wt; + } + } + } + dst[dstOff] = r; + dst[dstOff + 1] = g; + dst[dstOff + 2] = b; + if (!alphaFac) { + dst[dstOff + 3] = a; + } else { + dst[dstOff + 3] = data[dstOff + 3]; + } + } + } + options.imageData = output; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1fv(uniformLocations.uMatrix, this.matrix); + } + + /** + * Returns object representation of an instance + * @return {Object} Object representation of an instance + */ + toObject() { + return _objectSpread2(_objectSpread2({}, super.toObject()), {}, { + opaque: this.opaque, + matrix: [...this.matrix] + }); + } +} +/* + * Opaque value (true/false) + */ +/* + * matrix for the filter, max 9x9 + */ +_defineProperty(Convolute, "type", 'Convolute'); +_defineProperty(Convolute, "defaults", convoluteDefaultValues); +_defineProperty(Convolute, "uniformLocations", ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize']); +classRegistry.setClass(Convolute); + +const fragmentSource$6 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n"; + +const GAMMA = 'Gamma'; +const gammaDefaultValues = { + gamma: [1, 1, 1] +}; + +/** + * Gamma filter class + * @example + * const filter = new Gamma({ + * gamma: [1, 0.5, 2.1] + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Gamma extends BaseFilter { + getFragmentSource() { + return fragmentSource$6; + } + constructor() { + let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + super(options); + this.gamma = options.gamma || this.constructor.defaults.gamma.concat(); + } + + /** + * Apply the Gamma operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const gamma = this.gamma, + rInv = 1 / gamma[0], + gInv = 1 / gamma[1], + bInv = 1 / gamma[2]; + if (!this.rgbValues) { + this.rgbValues = { + r: new Uint8Array(256), + g: new Uint8Array(256), + b: new Uint8Array(256) + }; + } + + // This is an optimization - pre-compute a look-up table for each color channel + // instead of performing these pow calls for each pixel in the image. + const rgb = this.rgbValues; + for (let i = 0; i < 256; i++) { + rgb.r[i] = Math.pow(i / 255, rInv) * 255; + rgb.g[i] = Math.pow(i / 255, gInv) * 255; + rgb.b[i] = Math.pow(i / 255, bInv) * 255; + } + for (let i = 0; i < data.length; i += 4) { + data[i] = rgb.r[data[i]]; + data[i + 1] = rgb.g[data[i + 1]]; + data[i + 2] = rgb.b[data[i + 2]]; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform3fv(uniformLocations.uGamma, this.gamma); + } + isNeutralState() { + const { + gamma + } = this; + return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1; + } + toObject() { + return { + type: GAMMA, + gamma: this.gamma.concat() + }; + } +} +/** + * Gamma array value, from 0.01 to 2.2. + * @param {Array} gamma + * @default + */ +_defineProperty(Gamma, "type", GAMMA); +_defineProperty(Gamma, "defaults", gammaDefaultValues); +_defineProperty(Gamma, "uniformLocations", ['uGamma']); +classRegistry.setClass(Gamma); + +const fragmentSource$5 = { + average: "\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n ", + lightness: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n ", + luminosity: "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n " +}; + +const grayscaleDefaultValues = { + mode: 'average' +}; + +/** + * Grayscale image filter class + * @example + * const filter = new Grayscale(); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Grayscale extends BaseFilter { + /** + * Apply the Grayscale operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + for (let i = 0, value; i < data.length; i += 4) { + switch (this.mode) { + case 'average': + value = (data[i] + data[i + 1] + data[i + 2]) / 3; + break; + case 'lightness': + value = (Math.min(data[i], data[i + 1], data[i + 2]) + Math.max(data[i], data[i + 1], data[i + 2])) / 2; + break; + case 'luminosity': + value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2]; + break; + } + data[i] = value; + data[i + 1] = value; + data[i + 2] = value; + } + } + getCacheKey() { + return "".concat(this.type, "_").concat(this.mode); + } + getFragmentSource() { + return fragmentSource$5[this.mode]; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const mode = 1; + gl.uniform1i(uniformLocations.uMode, mode); + } + + /** + * Grayscale filter isNeutralState implementation + * The filter is never neutral + * on the image + **/ + isNeutralState() { + return false; + } +} +_defineProperty(Grayscale, "type", 'Grayscale'); +_defineProperty(Grayscale, "defaults", grayscaleDefaultValues); +_defineProperty(Grayscale, "uniformLocations", ['uMode']); +classRegistry.setClass(Grayscale); + +const hueRotationDefaultValues = { + rotation: 0 +}; + +/** + * HueRotation filter class + * @example + * const filter = new HueRotation({ + * rotation: -0.5 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class HueRotation extends ColorMatrix { + calculateMatrix() { + const rad = this.rotation * Math.PI, + cosine = cos(rad), + sine = sin(rad), + aThird = 1 / 3, + aThirdSqtSin = Math.sqrt(aThird) * sine, + OneMinusCos = 1 - cosine; + this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0]; + this.matrix[0] = cosine + OneMinusCos / 3; + this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[6] = cosine + aThird * OneMinusCos; + this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin; + this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin; + this.matrix[12] = cosine + aThird * OneMinusCos; + } + isNeutralState() { + return this.rotation === 0; + } + applyTo(options) { + this.calculateMatrix(); + super.applyTo(options); + } + + //@ts-expect-error TS and classes with different methods + toObject() { + return { + type: this.type, + rotation: this.rotation + }; + } +} +/** + * HueRotation value, from -1 to 1. + */ +_defineProperty(HueRotation, "type", 'HueRotation'); +_defineProperty(HueRotation, "defaults", hueRotationDefaultValues); +classRegistry.setClass(HueRotation); + +const fragmentSource$4 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n"; + +const invertDefaultValues = { + alpha: false, + invert: true +}; + +/** + * @example + * const filter = new Invert(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ +class Invert extends BaseFilter { + /** + * Apply the Invert operation to a Uint8Array representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8Array to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + for (let i = 0; i < data.length; i += 4) { + data[i] = 255 - data[i]; + data[i + 1] = 255 - data[i + 1]; + data[i + 2] = 255 - data[i + 2]; + if (this.alpha) { + data[i + 3] = 255 - data[i + 3]; + } + } + } + getFragmentSource() { + return fragmentSource$4; + } + + /** + * Invert filter isNeutralState implementation + * Used only in image applyFilters to discard filters that will not have an effect + * on the image + * @param {Object} options + **/ + isNeutralState() { + return !this.invert; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1i(uniformLocations.uInvert, Number(this.invert)); + gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha)); + } +} +/** + * Invert also alpha. + * @param {Boolean} alpha + * @default + **/ +/** + * Filter invert. if false, does nothing + * @param {Boolean} invert + * @default + */ +_defineProperty(Invert, "type", 'Invert'); +_defineProperty(Invert, "defaults", invertDefaultValues); +_defineProperty(Invert, "uniformLocations", ['uInvert', 'uAlpha']); +classRegistry.setClass(Invert); + +const fragmentSource$3 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n"; + +const noiseDefaultValues = { + noise: 0 +}; + +/** + * Noise filter class + * @example + * const filter = new Noise({ + * noise: 700 + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class Noise extends BaseFilter { + getFragmentSource() { + return fragmentSource$3; + } + + /** + * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const noise = this.noise; + for (let i = 0; i < data.length; i += 4) { + const rand = (0.5 - Math.random()) * noise; + data[i] += rand; + data[i + 1] += rand; + data[i + 2] += rand; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uNoise, this.noise / 255); + gl.uniform1f(uniformLocations.uSeed, Math.random()); + } + isNeutralState() { + return this.noise === 0; + } +} +/** + * Noise value, from + * @param {Number} noise + * @default + */ +_defineProperty(Noise, "type", 'Noise'); +_defineProperty(Noise, "defaults", noiseDefaultValues); +_defineProperty(Noise, "uniformLocations", ['uNoise', 'uSeed']); +classRegistry.setClass(Noise); + +const fragmentSource$2 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n"; + +const pixelateDefaultValues = { + blocksize: 4 +}; + +/** + * Pixelate filter class + * @example + * const filter = new Pixelate({ + * blocksize: 8 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Pixelate extends BaseFilter { + /** + * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data, + width, + height + } + } = _ref; + for (let i = 0; i < height; i += this.blocksize) { + for (let j = 0; j < width; j += this.blocksize) { + const index = i * 4 * width + j * 4; + const r = data[index]; + const g = data[index + 1]; + const b = data[index + 2]; + const a = data[index + 3]; + for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) { + for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) { + const index = _i * 4 * width + _j * 4; + data[index] = r; + data[index + 1] = g; + data[index + 2] = b; + data[index + 3] = a; + } + } + } + } + } + + /** + * Indicate when the filter is not gonna apply changes to the image + **/ + isNeutralState() { + return this.blocksize === 1; + } + getFragmentSource() { + return fragmentSource$2; + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uBlocksize, this.blocksize); + } +} +_defineProperty(Pixelate, "type", 'Pixelate'); +_defineProperty(Pixelate, "defaults", pixelateDefaultValues); +_defineProperty(Pixelate, "uniformLocations", ['uBlocksize']); +classRegistry.setClass(Pixelate); + +const fragmentShader = "\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n"; + +const removeColorDefaultValues = { + color: '#FFFFFF', + distance: 0.02, + useAlpha: false +}; + +/** + * Remove white filter class + * @example + * const filter = new RemoveColor({ + * threshold: 0.2, + * }); + * object.filters.push(filter); + * object.applyFilters(); + * canvas.renderAll(); + */ +class RemoveColor extends BaseFilter { + getFragmentSource() { + return fragmentShader; + } + + /** + * Applies filter to canvas element + * @param {Object} canvasEl Canvas element to apply filter to + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const distance = this.distance * 255, + source = new Color(this.color).getSource(), + lowC = [source[0] - distance, source[1] - distance, source[2] - distance], + highC = [source[0] + distance, source[1] + distance, source[2] + distance]; + for (let i = 0; i < data.length; i += 4) { + const r = data[i]; + const g = data[i + 1]; + const b = data[i + 2]; + if (r > lowC[0] && g > lowC[1] && b > lowC[2] && r < highC[0] && g < highC[1] && b < highC[2]) { + data[i + 3] = 0; + } + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + const source = new Color(this.color).getSource(), + distance = this.distance, + lowC = [0 + source[0] / 255 - distance, 0 + source[1] / 255 - distance, 0 + source[2] / 255 - distance, 1], + highC = [source[0] / 255 + distance, source[1] / 255 + distance, source[2] / 255 + distance, 1]; + gl.uniform4fv(uniformLocations.uLow, lowC); + gl.uniform4fv(uniformLocations.uHigh, highC); + } +} +/** + * Color to remove, in any format understood by {@link Color}. + * @param {String} type + * @default + */ +/** + * distance to actual color, as value up or down from each r,g,b + * between 0 and 1 + **/ +/** + * For color to remove inside distance, use alpha channel for a smoother deletion + * NOT IMPLEMENTED YET + **/ +_defineProperty(RemoveColor, "type", 'RemoveColor'); +_defineProperty(RemoveColor, "defaults", removeColorDefaultValues); +_defineProperty(RemoveColor, "uniformLocations", ['uLow', 'uHigh']); +classRegistry.setClass(RemoveColor); + +const resizeDefaultValues = { + resizeType: 'hermite', + scaleX: 1, + scaleY: 1, + lanczosLobes: 3 +}; +/** + * Resize image filter class + * @example + * const filter = new Resize(); + * object.filters.push(filter); + * object.applyFilters(canvas.renderAll.bind(canvas)); + */ +class Resize extends BaseFilter { + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform2fv(uniformLocations.uDelta, this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height]); + gl.uniform1fv(uniformLocations.uTaps, this.taps); + } + getFilterWindow() { + const scale = this.tempScale; + return Math.ceil(this.lanczosLobes / scale); + } + getCacheKey() { + const filterWindow = this.getFilterWindow(); + return "".concat(this.type, "_").concat(filterWindow); + } + getFragmentSource() { + const filterWindow = this.getFilterWindow(); + return this.generateShader(filterWindow); + } + getTaps() { + const lobeFunction = this.lanczosCreate(this.lanczosLobes), + scale = this.tempScale, + filterWindow = this.getFilterWindow(), + taps = new Array(filterWindow); + for (let i = 1; i <= filterWindow; i++) { + taps[i - 1] = lobeFunction(i * scale); + } + return taps; + } + + /** + * Generate vertex and shader sources from the necessary steps numbers + * @param {Number} filterWindow + */ + generateShader(filterWindow) { + const offsets = new Array(filterWindow); + for (let i = 1; i <= filterWindow; i++) { + offsets[i - 1] = "".concat(i, ".0 * uDelta"); + } + return "\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[".concat(filterWindow, "];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ").concat(offsets.map((offset, i) => "\n color += texture2D(uTexture, vTexCoord + ".concat(offset, ") * uTaps[").concat(i, "] + texture2D(uTexture, vTexCoord - ").concat(offset, ") * uTaps[").concat(i, "];\n sum += 2.0 * uTaps[").concat(i, "];\n ")).join('\n'), "\n gl_FragColor = color / sum;\n }\n "); + } + applyToForWebgl(options) { + options.passes++; + this.width = options.sourceWidth; + this.horizontal = true; + this.dW = Math.round(this.width * this.scaleX); + this.dH = options.sourceHeight; + this.tempScale = this.dW / this.width; + this.taps = this.getTaps(); + options.destinationWidth = this.dW; + super.applyTo(options); + options.sourceWidth = options.destinationWidth; + this.height = options.sourceHeight; + this.horizontal = false; + this.dH = Math.round(this.height * this.scaleY); + this.tempScale = this.dH / this.height; + this.taps = this.getTaps(); + options.destinationHeight = this.dH; + super.applyTo(options); + options.sourceHeight = options.destinationHeight; + } + + /** + * Apply the resize filter to the image + * Determines whether to use WebGL or Canvas2D based on the options.webgl flag. + * + * @param {Object} options + * @param {Number} options.passes The number of filters remaining to be executed + * @param {Boolean} options.webgl Whether to use webgl to render the filter. + * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered. + * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn. + * @param {WebGLRenderingContext} options.context The GL context used for rendering. + * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type. + */ + applyTo(options) { + if (isWebGLPipelineState(options)) { + this.applyToForWebgl(options); + } else { + this.applyTo2d(options); + } + } + isNeutralState() { + return this.scaleX === 1 && this.scaleY === 1; + } + lanczosCreate(lobes) { + return x => { + if (x >= lobes || x <= -lobes) { + return 0.0; + } + if (x < 1.1920929e-7 && x > -1.1920929e-7) { + return 1.0; + } + x *= Math.PI; + const xx = x / lobes; + return Math.sin(x) / x * Math.sin(xx) / xx; + }; + } + applyTo2d(options) { + const imageData = options.imageData, + scaleX = this.scaleX, + scaleY = this.scaleY; + this.rcpScaleX = 1 / scaleX; + this.rcpScaleY = 1 / scaleY; + const oW = imageData.width; + const oH = imageData.height; + const dW = Math.round(oW * scaleX); + const dH = Math.round(oH * scaleY); + let newData; + if (this.resizeType === 'sliceHack') { + newData = this.sliceByTwo(options, oW, oH, dW, dH); + } else if (this.resizeType === 'hermite') { + newData = this.hermiteFastResize(options, oW, oH, dW, dH); + } else if (this.resizeType === 'bilinear') { + newData = this.bilinearFiltering(options, oW, oH, dW, dH); + } else if (this.resizeType === 'lanczos') { + newData = this.lanczosResize(options, oW, oH, dW, dH); + } else { + // this should never trigger, is here just for safety net. + newData = new ImageData(dW, dH); + } + options.imageData = newData; + } + + /** + * Filter sliceByTwo + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + sliceByTwo(options, oW, oH, dW, dH) { + const imageData = options.imageData; + const mult = 0.5; + let doneW = false; + let doneH = false; + let stepW = oW * mult; + let stepH = oH * mult; + const resources = options.filterBackend.resources; + let sX = 0; + let sY = 0; + const dX = oW; + let dY = 0; + if (!resources.sliceByTwo) { + resources.sliceByTwo = createCanvasElement(); + } + const tmpCanvas = resources.sliceByTwo; + if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) { + tmpCanvas.width = oW * 1.5; + tmpCanvas.height = oH; + } + const ctx = tmpCanvas.getContext('2d'); + ctx.clearRect(0, 0, oW * 1.5, oH); + ctx.putImageData(imageData, 0, 0); + dW = Math.floor(dW); + dH = Math.floor(dH); + while (!doneW || !doneH) { + oW = stepW; + oH = stepH; + if (dW < Math.floor(stepW * mult)) { + stepW = Math.floor(stepW * mult); + } else { + stepW = dW; + doneW = true; + } + if (dH < Math.floor(stepH * mult)) { + stepH = Math.floor(stepH * mult); + } else { + stepH = dH; + doneH = true; + } + ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH); + sX = dX; + sY = dY; + dY += stepH; + } + return ctx.getImageData(sX, sY, dW, dH); + } + + /** + * Filter lanczosResize + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + lanczosResize(options, oW, oH, dW, dH) { + function process(u) { + let v, i, weight, idx, a, red, green, blue, alpha, fX, fY; + center.x = (u + 0.5) * ratioX; + icenter.x = Math.floor(center.x); + for (v = 0; v < dH; v++) { + center.y = (v + 0.5) * ratioY; + icenter.y = Math.floor(center.y); + a = 0; + red = 0; + green = 0; + blue = 0; + alpha = 0; + for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) { + if (i < 0 || i >= oW) { + continue; + } + fX = Math.floor(1000 * Math.abs(i - center.x)); + if (!cacheLanc[fX]) { + cacheLanc[fX] = {}; + } + for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) { + if (j < 0 || j >= oH) { + continue; + } + fY = Math.floor(1000 * Math.abs(j - center.y)); + if (!cacheLanc[fX][fY]) { + cacheLanc[fX][fY] = lanczos(Math.sqrt(Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2)) / 1000); + } + weight = cacheLanc[fX][fY]; + if (weight > 0) { + idx = (j * oW + i) * 4; + a += weight; + red += weight * srcData[idx]; + green += weight * srcData[idx + 1]; + blue += weight * srcData[idx + 2]; + alpha += weight * srcData[idx + 3]; + } + } + } + idx = (v * dW + u) * 4; + destData[idx] = red / a; + destData[idx + 1] = green / a; + destData[idx + 2] = blue / a; + destData[idx + 3] = alpha / a; + } + if (++u < dW) { + return process(u); + } else { + return destImg; + } + } + const srcData = options.imageData.data, + destImg = options.ctx.createImageData(dW, dH), + destData = destImg.data, + lanczos = this.lanczosCreate(this.lanczosLobes), + ratioX = this.rcpScaleX, + ratioY = this.rcpScaleY, + rcpRatioX = 2 / this.rcpScaleX, + rcpRatioY = 2 / this.rcpScaleY, + range2X = Math.ceil(ratioX * this.lanczosLobes / 2), + range2Y = Math.ceil(ratioY * this.lanczosLobes / 2), + cacheLanc = {}, + center = { + x: 0, + y: 0 + }, + icenter = { + x: 0, + y: 0 + }; + return process(0); + } + + /** + * bilinearFiltering + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + bilinearFiltering(options, oW, oH, dW, dH) { + let a; + let b; + let c; + let d; + let x; + let y; + let i; + let j; + let xDiff; + let yDiff; + let chnl; + let color; + let offset = 0; + let origPix; + const ratioX = this.rcpScaleX; + const ratioY = this.rcpScaleY; + const w4 = 4 * (oW - 1); + const img = options.imageData; + const pixels = img.data; + const destImage = options.ctx.createImageData(dW, dH); + const destPixels = destImage.data; + for (i = 0; i < dH; i++) { + for (j = 0; j < dW; j++) { + x = Math.floor(ratioX * j); + y = Math.floor(ratioY * i); + xDiff = ratioX * j - x; + yDiff = ratioY * i - y; + origPix = 4 * (y * oW + x); + for (chnl = 0; chnl < 4; chnl++) { + a = pixels[origPix + chnl]; + b = pixels[origPix + 4 + chnl]; + c = pixels[origPix + w4 + chnl]; + d = pixels[origPix + w4 + 4 + chnl]; + color = a * (1 - xDiff) * (1 - yDiff) + b * xDiff * (1 - yDiff) + c * yDiff * (1 - xDiff) + d * xDiff * yDiff; + destPixels[offset++] = color; + } + } + } + return destImage; + } + + /** + * hermiteFastResize + * @param {Object} canvasEl Canvas element to apply filter to + * @param {Number} oW Original Width + * @param {Number} oH Original Height + * @param {Number} dW Destination Width + * @param {Number} dH Destination Height + * @returns {ImageData} + */ + hermiteFastResize(options, oW, oH, dW, dH) { + const ratioW = this.rcpScaleX, + ratioH = this.rcpScaleY, + ratioWHalf = Math.ceil(ratioW / 2), + ratioHHalf = Math.ceil(ratioH / 2), + img = options.imageData, + data = img.data, + img2 = options.ctx.createImageData(dW, dH), + data2 = img2.data; + for (let j = 0; j < dH; j++) { + for (let i = 0; i < dW; i++) { + const x2 = (i + j * dW) * 4; + let weight = 0; + let weights = 0; + let weightsAlpha = 0; + let gxR = 0; + let gxG = 0; + let gxB = 0; + let gxA = 0; + const centerY = (j + 0.5) * ratioH; + for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) { + const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf, + centerX = (i + 0.5) * ratioW, + w0 = dy * dy; + for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) { + let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf; + const w = Math.sqrt(w0 + dx * dx); + /* eslint-disable max-depth */ + if (w > 1 && w < -1) { + continue; + } + //hermite filter + weight = 2 * w * w * w - 3 * w * w + 1; + if (weight > 0) { + dx = 4 * (xx + yy * oW); + //alpha + gxA += weight * data[dx + 3]; + weightsAlpha += weight; + //colors + if (data[dx + 3] < 255) { + weight = weight * data[dx + 3] / 250; + } + gxR += weight * data[dx]; + gxG += weight * data[dx + 1]; + gxB += weight * data[dx + 2]; + weights += weight; + } + /* eslint-enable max-depth */ + } + } + data2[x2] = gxR / weights; + data2[x2 + 1] = gxG / weights; + data2[x2 + 2] = gxB / weights; + data2[x2 + 3] = gxA / weightsAlpha; + } + } + return img2; + } +} +/** + * Resize type + * for webgl resizeType is just lanczos, for canvas2d can be: + * bilinear, hermite, sliceHack, lanczos. + * @default + */ +/** + * Scale factor for resizing, x axis + * @param {Number} scaleX + * @default + */ +/** + * Scale factor for resizing, y axis + * @param {Number} scaleY + * @default + */ +/** + * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos + * @param {Number} lanczosLobes + * @default + */ +_defineProperty(Resize, "type", 'Resize'); +_defineProperty(Resize, "defaults", resizeDefaultValues); +_defineProperty(Resize, "uniformLocations", ['uDelta', 'uTaps']); +classRegistry.setClass(Resize); + +const fragmentSource$1 = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n"; + +const saturationDefaultValues = { + saturation: 0 +}; + +/** + * Saturate filter class + * @example + * const filter = new Saturation({ + * saturation: 1 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Saturation extends BaseFilter { + getFragmentSource() { + return fragmentSource$1; + } + + /** + * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const adjust = -this.saturation; + for (let i = 0; i < data.length; i += 4) { + const max = Math.max(data[i], data[i + 1], data[i + 2]); + data[i] += max !== data[i] ? (max - data[i]) * adjust : 0; + data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0; + data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uSaturation, -this.saturation); + } + isNeutralState() { + return this.saturation === 0; + } +} +/** + * Saturation value, from -1 to 1. + * Increases/decreases the color saturation. + * A value of 0 has no effect. + * + * @param {Number} saturation + * @default + */ +_defineProperty(Saturation, "type", 'Saturation'); +_defineProperty(Saturation, "defaults", saturationDefaultValues); +_defineProperty(Saturation, "uniformLocations", ['uSaturation']); +classRegistry.setClass(Saturation); + +const fragmentSource = "\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n"; + +const vibranceDefaultValues = { + vibrance: 0 +}; + +/** + * Vibrance filter class + * @example + * const filter = new Vibrance({ + * vibrance: 1 + * }); + * object.filters.push(filter); + * object.applyFilters(); + */ +class Vibrance extends BaseFilter { + getFragmentSource() { + return fragmentSource; + } + + /** + * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image. + * + * @param {Object} options + * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered. + */ + applyTo2d(_ref) { + let { + imageData: { + data + } + } = _ref; + const adjust = -this.vibrance; + for (let i = 0; i < data.length; i += 4) { + const max = Math.max(data[i], data[i + 1], data[i + 2]); + const avg = (data[i] + data[i + 1] + data[i + 2]) / 3; + const amt = Math.abs(max - avg) * 2 / 255 * adjust; + data[i] += max !== data[i] ? (max - data[i]) * amt : 0; + data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0; + data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0; + } + } + + /** + * Send data from this filter to its shader program's uniforms. + * + * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader. + * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects + */ + sendUniformData(gl, uniformLocations) { + gl.uniform1f(uniformLocations.uVibrance, -this.vibrance); + } + isNeutralState() { + return this.vibrance === 0; + } +} +/** + * Vibrance value, from -1 to 1. + * Increases/decreases the saturation of more muted colors with less effect on saturated colors. + * A value of 0 has no effect. + * + * @param {Number} vibrance + * @default + */ +_defineProperty(Vibrance, "type", 'Vibrance'); +_defineProperty(Vibrance, "defaults", vibranceDefaultValues); +_defineProperty(Vibrance, "uniformLocations", ['uVibrance']); +classRegistry.setClass(Vibrance); + +var filters = /*#__PURE__*/Object.freeze({ + __proto__: null, + BaseFilter: BaseFilter, + BlackWhite: BlackWhite, + BlendColor: BlendColor, + BlendImage: BlendImage, + Blur: Blur, + Brightness: Brightness, + Brownie: Brownie, + ColorMatrix: ColorMatrix, + Composed: Composed, + Contrast: Contrast, + Convolute: Convolute, + Gamma: Gamma, + Grayscale: Grayscale, + HueRotation: HueRotation, + Invert: Invert, + Kodachrome: Kodachrome, + Noise: Noise, + Pixelate: Pixelate, + Polaroid: Polaroid, + RemoveColor: RemoveColor, + Resize: Resize, + Saturation: Saturation, + Sepia: Sepia, + Technicolor: Technicolor, + Vibrance: Vibrance, + Vintage: Vintage +}); + +// First we set the env variable + +setEnv(getEnv()); +FabricObject$1.ownDefaults.objectCaching = false; +class StaticCanvas extends StaticCanvas$1 { + getNodeCanvas() { + return getNodeCanvas(this.getElement()); + } + createPNGStream(opts) { + return this.getNodeCanvas().createPNGStream(opts); + } + createJPEGStream(opts) { + return this.getNodeCanvas().createJPEGStream(opts); + } +} + +/** + * **NOTICE**: + * {@link Canvas} is designed for interactivity. + * Therefore, using it in node has no benefit. + * Use {@link StaticCanvas} instead. + */ +class Canvas extends Canvas$1 { + getNodeCanvas() { + return getNodeCanvas(this.getElement()); + } + createPNGStream(opts) { + return this.getNodeCanvas().createPNGStream(opts); + } + createJPEGStream(opts) { + return this.getNodeCanvas().createJPEGStream(opts); + } +} + +export { ActiveSelection, BaseBrush, FabricObject$1 as BaseFabricObject, Canvas, Canvas2dFilterBackend, CanvasDOMManager, Circle, CircleBrush, ClipPathLayout, Color, Control, Ellipse, FabricImage, FabricObject, FabricText, FitContentLayout, FixedLayout, Gradient, Group, IText, FabricImage as Image, InteractiveFabricObject, Intersection, LayoutManager, LayoutStrategy, Line, FabricObject as Object, Observable, Path, Pattern, PatternBrush, PencilBrush, Point, Polygon, Polyline, Rect, Shadow, SprayBrush, StaticCanvas, StaticCanvasDOMManager, FabricText as Text, Textbox, Triangle, WebGLFilterBackend, cache, classRegistry, config, index as controlsUtils, createCollectionMixin, filters, getCSSRules, getEnv$1 as getEnv, getFabricDocument, getFabricWindow, getFilterBackend, iMatrix, initFilterBackend, isPutImageFaster, isWebGLPipelineState, loadSVGFromString, loadSVGFromURL, parseAttributes, parseFontDeclaration, parsePointsAttribute, parseSVGDocument, parseStyleAttribute, parseTransformAttribute, runningAnimations, setEnv, setFilterBackend, index$1 as util, VERSION as version }; +//# sourceMappingURL=index.node.mjs.map diff --git a/dist/index.node.mjs.map b/dist/index.node.mjs.map new file mode 100644 index 00000000000..eae68fe3543 --- /dev/null +++ b/dist/index.node.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"index.node.mjs","sources":["../src/config.ts","../src/util/internals/console.ts","../src/filters/GLProbes/GLProbe.ts","../src/filters/GLProbes/WebGLProbe.ts","../src/env/browser.ts","../src/env/index.ts","../src/filters/GLProbes/NodeGLProbe.ts","../src/env/node.ts","../src/cache.ts","../src/constants.ts","../src/ClassRegistry.ts","../src/util/animation/AnimationRegistry.ts","../src/Observable.ts","../src/util/internals/removeFromArray.ts","../src/util/misc/cos.ts","../src/util/misc/sin.ts","../src/Point.ts","../src/Collection.ts","../src/CommonMethods.ts","../src/util/animation/AnimationFrameProvider.ts","../src/util/internals/uid.ts","../src/util/misc/dom.ts","../src/util/misc/radiansDegreesConversion.ts","../src/util/misc/matrix.ts","../src/util/misc/objectEnlive.ts","../src/util/misc/pick.ts","../src/color/color_map.ts","../src/color/constants.ts","../src/color/util.ts","../src/color/Color.ts","../src/util/misc/toFixed.ts","../src/util/misc/svgParsing.ts","../src/util/typeAssertions.ts","../src/util/dom_misc.ts","../src/canvas/DOMManagers/util.ts","../src/canvas/DOMManagers/StaticCanvasDOMManager.ts","../src/canvas/StaticCanvasOptions.ts","../src/canvas/StaticCanvas.ts","../src/util/dom_event.ts","../src/util/misc/boundingBoxFromPoints.ts","../src/util/misc/objectTransforms.ts","../src/util/misc/planeChange.ts","../src/controls/fireEvent.ts","../src/util/misc/resolveOrigin.ts","../src/controls/util.ts","../src/controls/drag.ts","../src/shapes/Object/FabricObjectSVGExportMixin.ts","../src/parser/getSvgRegex.ts","../src/parser/constants.ts","../src/util/misc/vectors.ts","../src/Shadow.ts","../src/util/misc/capValue.ts","../src/shapes/Object/defaultValues.ts","../src/util/animation/easing.ts","../src/util/animation/AnimationBase.ts","../src/util/animation/ValueAnimation.ts","../src/util/animation/ArrayAnimation.ts","../src/util/animation/ColorAnimation.ts","../src/util/animation/animate.ts","../src/Intersection.ts","../src/shapes/Object/ObjectGeometry.ts","../src/shapes/Object/Object.ts","../src/controls/wrapWithFireEvent.ts","../src/controls/wrapWithFixedAnchor.ts","../src/controls/changeWidth.ts","../src/controls/controlRendering.ts","../src/controls/Control.ts","../src/controls/rotate.ts","../src/controls/scale.ts","../src/controls/skew.ts","../src/controls/scaleSkew.ts","../src/controls/commonControls.ts","../src/shapes/Object/InteractiveObject.ts","../src/util/applyMixins.ts","../src/shapes/Object/FabricObject.ts","../src/util/misc/isTransparent.ts","../src/util/misc/rotatePoint.ts","../src/util/internals/findRight.ts","../src/util/misc/projectStroke/StrokeProjectionsBase.ts","../src/util/misc/projectStroke/StrokeLineJoinProjections.ts","../src/util/misc/projectStroke/StrokeLineCapProjections.ts","../src/util/misc/projectStroke/index.ts","../src/util/internals/cloneStyles.ts","../src/util/lang_string.ts","../src/util/misc/textStyles.ts","../src/parser/attributes.ts","../src/parser/selectorMatches.ts","../src/parser/doesSomeParentMatch.ts","../src/parser/elementMatchesRule.ts","../src/parser/getGlobalStylesForElement.ts","../src/parser/normalizeAttr.ts","../src/util/internals/cleanupSvgAttribute.ts","../src/parser/parseTransformAttribute.ts","../src/parser/normalizeValue.ts","../src/parser/parseFontDeclaration.ts","../src/parser/parseStyleObject.ts","../src/parser/parseStyleString.ts","../src/parser/parseStyleAttribute.ts","../src/parser/setStrokeFillOpacity.ts","../src/parser/parseAttributes.ts","../src/shapes/Rect.ts","../src/LayoutManager/constants.ts","../src/LayoutManager/LayoutStrategies/utils.ts","../src/LayoutManager/LayoutStrategies/LayoutStrategy.ts","../src/LayoutManager/LayoutStrategies/FitContentLayout.ts","../src/LayoutManager/LayoutManager.ts","../src/shapes/Group.ts","../src/util/misc/groupSVGElements.ts","../src/util/misc/findScaleTo.ts","../src/util/path/regex.ts","../src/util/path/index.ts","../src/util/dom_style.ts","../src/util/misc/mergeClipPaths.ts","../src/util/internals/getRandomInt.ts","../src/util/internals/dom_request.ts","../src/util/transform_matrix_removal.ts","../src/canvas/DOMManagers/CanvasDOMManager.ts","../src/canvas/CanvasOptions.ts","../src/canvas/SelectableCanvas.ts","../src/canvas/TextEditingManager.ts","../src/canvas/Canvas.ts","../src/gradient/constants.ts","../src/util/internals/ifNaN.ts","../src/parser/percent.ts","../src/gradient/parser/parseColorStops.ts","../src/gradient/parser/misc.ts","../src/gradient/parser/parseCoords.ts","../src/gradient/Gradient.ts","../src/Pattern/Pattern.ts","../src/brushes/BaseBrush.ts","../src/shapes/Path.ts","../src/brushes/PencilBrush.ts","../src/shapes/Circle.ts","../src/brushes/CircleBrush.ts","../src/brushes/SprayBrush.ts","../src/brushes/PatternBrush.ts","../src/shapes/Line.ts","../src/shapes/Triangle.ts","../src/shapes/Ellipse.ts","../src/parser/parsePointsAttribute.ts","../src/shapes/Polyline.ts","../src/shapes/Polygon.ts","../src/shapes/Text/constants.ts","../src/shapes/Text/StyledText.ts","../src/shapes/Text/TextSVGExportMixin.ts","../src/shapes/Text/Text.ts","../src/shapes/IText/DraggableTextDelegate.ts","../src/shapes/IText/ITextBehavior.ts","../src/shapes/IText/ITextKeyBehavior.ts","../src/shapes/IText/ITextClickBehavior.ts","../src/shapes/IText/constants.ts","../src/shapes/IText/IText.ts","../src/shapes/Textbox.ts","../src/LayoutManager/LayoutStrategies/ClipPathLayout.ts","../src/LayoutManager/LayoutStrategies/FixedLayout.ts","../src/LayoutManager/ActiveSelectionLayoutManager.ts","../src/shapes/ActiveSelection.ts","../src/filters/Canvas2dFilterBackend.ts","../src/filters/WebGLFilterBackend.ts","../src/filters/FilterBackend.ts","../src/shapes/Image.ts","../src/parser/applyViewboxTransform.ts","../src/parser/getTagName.ts","../src/parser/hasInvalidAncestor.ts","../src/parser/getMultipleNodes.ts","../src/parser/parseUseDirectives.ts","../src/parser/recursivelyParseGradientsXlink.ts","../src/parser/getGradientDefs.ts","../src/parser/getCSSRules.ts","../src/parser/elements_parser.ts","../src/parser/parseSVGDocument.ts","../src/parser/loadSVGFromString.ts","../src/parser/loadSVGFromURL.ts","../src/controls/polyControl.ts","../src/controls/pathControl.ts","../src/filters/utils.ts","../src/filters/shaders/baseFilter.ts","../src/filters/BaseFilter.ts","../src/filters/shaders/blendColor.ts","../src/filters/BlendColor.ts","../src/filters/shaders/blendImage.ts","../src/filters/BlendImage.ts","../src/filters/shaders/blur.ts","../src/filters/Blur.ts","../src/filters/shaders/brightness.ts","../src/filters/Brightness.ts","../src/filters/shaders/colorMatrix.ts","../src/filters/ColorMatrix.ts","../src/filters/ColorMatrixFilters.ts","../src/filters/Composed.ts","../src/filters/shaders/constrast.ts","../src/filters/Contrast.ts","../src/filters/shaders/convolute.ts","../src/filters/Convolute.ts","../src/filters/shaders/gamma.ts","../src/filters/Gamma.ts","../src/filters/shaders/grayscale.ts","../src/filters/Grayscale.ts","../src/filters/HueRotation.ts","../src/filters/shaders/invert.ts","../src/filters/Invert.ts","../src/filters/shaders/noise.ts","../src/filters/Noise.ts","../src/filters/shaders/pixelate.ts","../src/filters/Pixelate.ts","../src/filters/shaders/removeColor.ts","../src/filters/RemoveColor.ts","../src/filters/Resize.ts","../src/filters/shaders/saturation.ts","../src/filters/Saturation.ts","../src/filters/shaders/vibrance.ts","../src/filters/Vibrance.ts","../index.node.ts"],"sourcesContent":["export type TConfiguration = Partial;\n\nclass BaseConfiguration {\n /**\n * Browser-specific constant to adjust CanvasRenderingContext2D.shadowBlur value,\n * which is unitless and not rendered equally across browsers.\n *\n * Values that work quite well (as of October 2017) are:\n * - Chrome: 1.5\n * - Edge: 1.75\n * - Firefox: 0.9\n * - Safari: 0.95\n *\n * @since 2.0.0\n * @type Number\n * @default 1\n */\n browserShadowBlurConstant = 1;\n\n /**\n * Pixel per Inch as a default value set to 96. Can be changed for more realistic conversion.\n */\n DPI = 96;\n\n /**\n * Device Pixel Ratio\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n */\n devicePixelRatio =\n typeof window !== 'undefined' ? window.devicePixelRatio : 1; // eslint-disable-line no-restricted-globals\n\n /**\n * Pixel limit for cache canvases. 1Mpx , 4Mpx should be fine.\n * @since 1.7.14\n * @type Number\n * @default\n */\n perfLimitSizeTotal = 2097152;\n\n /**\n * Pixel limit for cache canvases width or height. IE fixes the maximum at 5000\n * @since 1.7.14\n * @type Number\n * @default\n */\n maxCacheSideLimit = 4096;\n\n /**\n * Lowest pixel limit for cache canvases, set at 256PX\n * @since 1.7.14\n * @type Number\n * @default\n */\n minCacheSideLimit = 256;\n\n /**\n * When 'true', style information is not retained when copy/pasting text, making\n * pasted text use destination style.\n * Defaults to 'false'.\n * @type Boolean\n * @default\n * @deprecated\n */\n disableStyleCopyPaste = false;\n\n /**\n * Enable webgl for filtering picture is available\n * A filtering backend will be initialized, this will both take memory and\n * time since a default 2048x2048 canvas will be created for the gl context\n * @since 2.0.0\n * @type Boolean\n * @default\n */\n enableGLFiltering = true;\n\n /**\n * if webgl is enabled and available, textureSize will determine the size\n * of the canvas backend\n *\n * In order to support old hardware set to `2048` to avoid OOM\n *\n * @since 2.0.0\n * @type Number\n * @default\n */\n textureSize = 4096;\n\n /**\n * Skip performance testing of setupGLContext and force the use of putImageData that seems to be the one that works best on\n * Chrome + old hardware. if your users are experiencing empty images after filtering you may try to force this to true\n * this has to be set before instantiating the filtering backend ( before filtering the first image )\n * @type Boolean\n * @default false\n */\n forceGLPutImageData = false;\n\n /**\n * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better\n * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from\n * the curve is very hard to hit any cache.\n * Enable only if you know why it could be useful.\n * Candidate for removal/simplification\n * @default false\n */\n cachesBoundsOfCurve = false;\n\n /**\n * Map of font files\n * Map of font files\n */\n fontPaths: Record = {};\n\n /**\n * Defines the number of fraction digits to use when serializing object values.\n * Used in exporting methods (`toObject`, `toJSON`, `toSVG`)\n * You can use it to increase/decrease precision of such values like left, top, scaleX, scaleY, etc.\n */\n NUM_FRACTION_DIGITS = 4;\n}\n\nexport class Configuration extends BaseConfiguration {\n constructor(config?: TConfiguration) {\n super();\n this.configure(config);\n }\n\n configure(config: TConfiguration = {}) {\n Object.assign(this, config);\n }\n\n /**\n * Map of font files\n */\n addFonts(\n paths: Record = {},\n ) {\n this.fontPaths = {\n ...this.fontPaths,\n ...paths,\n };\n }\n\n removeFonts(fontFamilys: string[] = []) {\n fontFamilys.forEach((fontFamily) => {\n delete this.fontPaths[fontFamily];\n });\n }\n\n clearFonts() {\n this.fontPaths = {};\n }\n\n restoreDefaults(keys?: (keyof T)[]) {\n const defaults = new BaseConfiguration() as T;\n const config =\n keys?.reduce((acc, key) => {\n acc[key] = defaults[key];\n return acc;\n }, {} as T) || defaults;\n this.configure(config);\n }\n}\n\nexport const config = new Configuration();\n","export const log = (\n severity: 'log' | 'warn' | 'error',\n ...optionalParams: any[]\n) =>\n // eslint-disable-next-line no-restricted-syntax\n console[severity]('fabric', ...optionalParams);\n\nexport class FabricError extends Error {\n constructor(message?: string, options?: ErrorOptions) {\n super(`fabric: ${message}`, options);\n }\n}\n\nexport class SignalAbortedError extends FabricError {\n constructor(context: string) {\n super(`${context} 'options.signal' is in 'aborted' state`);\n }\n}\n","export type GLPrecision = 'lowp' | 'mediump' | 'highp';\n\nexport abstract class GLProbe {\n declare GLPrecision: GLPrecision | undefined;\n abstract queryWebGL(canvas: HTMLCanvasElement): void;\n abstract isSupported(textureSize: number): boolean;\n}\n","import { log } from '../../util/internals/console';\nimport { GLProbe } from './GLProbe';\nimport type { GLPrecision } from './GLProbe';\n\n/**\n * Lazy initialize WebGL constants\n */\nexport class WebGLProbe extends GLProbe {\n declare maxTextureSize?: number;\n\n /**\n * Tests if webgl supports certain precision\n * @param {WebGL} Canvas WebGL context to test on\n * @param {GLPrecision} Precision to test can be any of following\n * @returns {Boolean} Whether the user's browser WebGL supports given precision.\n */\n private testPrecision(\n gl: WebGLRenderingContext,\n precision: GLPrecision,\n ): boolean {\n const fragmentSource = `precision ${precision} float;\\nvoid main(){}`;\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n if (!fragmentShader) {\n return false;\n }\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n return !!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS);\n }\n\n /**\n * query browser for WebGL\n */\n queryWebGL(canvas: HTMLCanvasElement) {\n const gl = canvas.getContext('webgl');\n if (gl) {\n this.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n this.GLPrecision = (['highp', 'mediump', 'lowp'] as const).find(\n (precision) => this.testPrecision(gl, precision),\n );\n gl.getExtension('WEBGL_lose_context')!.loseContext();\n log('log', `WebGL: max texture size ${this.maxTextureSize}`);\n }\n }\n\n isSupported(textureSize: number) {\n return !!this.maxTextureSize && this.maxTextureSize >= textureSize;\n }\n}\n","/* eslint-disable no-restricted-globals */\nimport { WebGLProbe } from '../filters/GLProbes/WebGLProbe';\nimport type { TCopyPasteData, TFabricEnv } from './types';\n\nconst copyPasteData: TCopyPasteData = {};\n\nexport const getEnv = (): TFabricEnv => {\n return {\n document,\n window,\n isTouchSupported:\n 'ontouchstart' in window ||\n 'ontouchstart' in document ||\n (window && window.navigator && window.navigator.maxTouchPoints > 0),\n WebGLProbe: new WebGLProbe(),\n dispose() {\n // noop\n },\n copyPasteData,\n };\n};\n","/**\n * This file is consumed by fabric.\n * The `./node` and `./browser` files define the env variable that is used by this module.\n * The `./browser` module is defined to be the default env and doesn't set the env at all.\n * This is done in order to support isomorphic usage for browser and node applications\n * since window and document aren't defined at time of import in SSR, we can't set env so we avoid it by deferring to the default env.\n */\n\nimport { config } from '../config';\nimport { getEnv as getBrowserEnv } from './browser';\nimport type { TFabricEnv } from './types';\nimport type { DOMWindow } from 'jsdom';\n\nlet env: TFabricEnv;\n\n/**\n * Sets the environment variables used by fabric.\\\n * This is exposed for special cases, such as configuring a test environment, and should be used with care.\n *\n * **CAUTION**: Must be called before using the package.\n *\n * @example\n * Passing `window` and `document` objects to fabric (in case they are mocked or something)\n * import { getEnv, setEnv } from 'fabric';\n * // we want fabric to use the `window` and `document` objects exposed by the environment we are running in.\n * setEnv({ ...getEnv(), window, document });\n * // done with setup, using fabric is now safe\n */\nexport const setEnv = (value: TFabricEnv) => {\n env = value;\n};\n\n/**\n * In order to support SSR we **MUST** access the browser env only after the window has loaded\n */\nexport const getEnv = () => env || (env = getBrowserEnv());\n\nexport const getFabricDocument = (): Document => getEnv().document;\n\nexport const getFabricWindow = (): (Window & typeof globalThis) | DOMWindow =>\n getEnv().window;\n\n/**\n * @returns the config value if defined, fallbacks to the environment value\n */\nexport const getDevicePixelRatio = () =>\n Math.max(config.devicePixelRatio ?? getFabricWindow().devicePixelRatio, 1);\n","import { GLProbe } from './GLProbe';\n\n/**\n * @todo GL rendering in node is possible:\n * - https://github.com/stackgl/headless-gl\n * - https://github.com/akira-cn/node-canvas-webgl\n */\nexport class NodeGLProbe extends GLProbe {\n queryWebGL() {\n // noop\n }\n isSupported() {\n return false;\n }\n}\n","/* eslint-disable no-restricted-globals */\nimport type { Canvas as NodeCanvas } from 'canvas';\nimport { JSDOM } from 'jsdom';\n// @ts-expect-error internal import\nimport utils from 'jsdom/lib/jsdom/living/generated/utils.js';\nimport { NodeGLProbe } from '../filters/GLProbes/NodeGLProbe';\nimport type { TCopyPasteData, TFabricEnv } from './types';\n\nconst { implForWrapper: jsdomImplForWrapper } = utils;\n\nconst copyPasteData: TCopyPasteData = {};\n\nconst { window: JSDOMWindow } = new JSDOM(\n decodeURIComponent(\n '%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E',\n ),\n {\n resources: 'usable',\n // needed for `requestAnimationFrame`\n pretendToBeVisual: true,\n },\n);\n\nexport const getNodeCanvas = (canvasEl: HTMLCanvasElement) => {\n const impl = jsdomImplForWrapper(canvasEl);\n return (impl._canvas || impl._image) as NodeCanvas;\n};\n\nexport const dispose = (element: Element) => {\n const impl = jsdomImplForWrapper(element);\n if (impl) {\n impl._image = null;\n impl._canvas = null;\n // unsure if necessary\n impl._currentSrc = null;\n impl._attributes = null;\n impl._classList = null;\n }\n};\n\nexport const getEnv = (): TFabricEnv => {\n return {\n document: JSDOMWindow.document,\n window: JSDOMWindow,\n isTouchSupported: false,\n WebGLProbe: new NodeGLProbe(),\n dispose,\n copyPasteData,\n };\n};\n","import { config } from './config';\nimport type { TRectBounds } from './typedefs';\n\nexport class Cache {\n /**\n * Cache of widths of chars in text rendering.\n */\n charWidthsCache: Record<\n /** fontFamily */ string,\n Record<\n /** fontStyleCacheKey */ string,\n Record\n >\n > = {};\n\n /**\n * @return {Object} reference to cache\n */\n getFontCache({\n fontFamily,\n fontStyle,\n fontWeight,\n }: {\n fontFamily: string;\n fontStyle: string;\n fontWeight: string | number;\n }) {\n fontFamily = fontFamily.toLowerCase();\n if (!this.charWidthsCache[fontFamily]) {\n this.charWidthsCache[fontFamily] = {};\n }\n const fontCache = this.charWidthsCache[fontFamily];\n const cacheKey = `${fontStyle.toLowerCase()}_${(\n fontWeight + ''\n ).toLowerCase()}`;\n if (!fontCache[cacheKey]) {\n fontCache[cacheKey] = {};\n }\n return fontCache[cacheKey];\n }\n\n /**\n * Clear char widths cache for the given font family or all the cache if no\n * fontFamily is specified.\n * Use it if you know you are loading fonts in a lazy way and you are not waiting\n * for custom fonts to load properly when adding text objects to the canvas.\n * If a text object is added when its own font is not loaded yet, you will get wrong\n * measurement and so wrong bounding boxes.\n * After the font cache is cleared, either change the textObject text content or call\n * initDimensions() to trigger a recalculation\n * @param {String} [fontFamily] font family to clear\n */\n clearFontCache(fontFamily?: string) {\n fontFamily = (fontFamily || '').toLowerCase();\n if (!fontFamily) {\n this.charWidthsCache = {};\n } else if (this.charWidthsCache[fontFamily]) {\n delete this.charWidthsCache[fontFamily];\n }\n }\n\n /**\n * Given current aspect ratio, determines the max width and height that can\n * respect the total allowed area for the cache.\n * @param {number} ar aspect ratio\n * @return {number[]} Limited dimensions X and Y\n */\n limitDimsByArea(ar: number) {\n const { perfLimitSizeTotal } = config;\n const roughWidth = Math.sqrt(perfLimitSizeTotal * ar);\n // we are not returning a point on purpose, to avoid circular dependencies\n // this is an internal utility\n return [\n Math.floor(roughWidth),\n Math.floor(perfLimitSizeTotal / roughWidth),\n ];\n }\n\n /**\n * This object keeps the results of the boundsOfCurve calculation mapped by the joined arguments necessary to calculate it.\n * It does speed up calculation, if you parse and add always the same paths, but in case of heavy usage of freedrawing\n * you do not get any speed benefit and you get a big object in memory.\n * The object was a private variable before, while now is appended to the lib so that you have access to it and you\n * can eventually clear it.\n * It was an internal variable, is accessible since version 2.3.4\n */\n boundsOfCurveCache: Record = {};\n}\n\nexport const cache = new Cache();\n","import type { TMat2D } from './typedefs';\n// use this syntax so babel plugin see this import here\nimport { version } from '../package.json';\n\nexport const VERSION = version;\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport const halfPI = Math.PI / 2;\nexport const twoMathPi = Math.PI * 2;\nexport const PiBy180 = Math.PI / 180;\n\nexport const iMatrix = Object.freeze([1, 0, 0, 1, 0, 0]) as TMat2D;\nexport const DEFAULT_SVG_FONT_SIZE = 16;\nexport const ALIASING_LIMIT = 2;\n\n/* \"magic number\" for bezier approximations of arcs (http://itc.ktu.lt/itc354/Riskus354.pdf) */\nexport const kRect = 1 - 0.5522847498;\n\nexport const CENTER = 'center';\nexport const LEFT = 'left';\nexport const TOP = 'top';\nexport const BOTTOM = 'bottom';\nexport const RIGHT = 'right';\nexport const NONE = 'none';\n\nexport const reNewline = /\\r?\\n/;\n\nexport const MOVING = 'moving';\nexport const SCALING = 'scaling';\nexport const ROTATING = 'rotating';\nexport const ROTATE = 'rotate';\nexport const SKEWING = 'skewing';\nexport const RESIZING = 'resizing';\nexport const MODIFY_POLY = 'modifyPoly';\nexport const MODIFY_PATH = 'modifyPath';\nexport const CHANGED = 'changed';\nexport const SCALE = 'scale';\nexport const SCALE_X = 'scaleX';\nexport const SCALE_Y = 'scaleY';\nexport const SKEW_X = 'skewX';\nexport const SKEW_Y = 'skewY';\nexport const FILL = 'fill';\nexport const STROKE = 'stroke';\nexport const MODIFIED = 'modified';\n","import { FabricError } from './util/internals/console';\n\n/*\n * This Map connects the objects type value with their\n * class implementation. It used from any object to understand which are\n * the classes to enlive when requesting a object.type = 'path' for example.\n * Objects uses it for clipPath, Canvas uses it for everything.\n * This is necessary for generic code to run and enlive instances from serialized representation.\n * You can customize which classes get enlived from SVG parsing using this classRegistry.\n * The Registry start empty and gets filled in depending which files you import.\n * If you want to be able to parse arbitrary SVGs or JSON representation of canvases, coming from\n * different sources you will need to import all fabric because you may need all classes.\n */\n\nexport const JSON = 'json';\nexport const SVG = 'svg';\n\nexport class ClassRegistry {\n declare [JSON]: Map;\n declare [SVG]: Map;\n\n constructor() {\n this[JSON] = new Map();\n this[SVG] = new Map();\n }\n\n has(classType: string): boolean {\n return this[JSON].has(classType);\n }\n\n getClass(classType: string): T {\n const constructor = this[JSON].get(classType);\n if (!constructor) {\n throw new FabricError(`No class registered for ${classType}`);\n }\n return constructor;\n }\n\n setClass(classConstructor: any, classType?: string) {\n if (classType) {\n this[JSON].set(classType, classConstructor);\n } else {\n this[JSON].set(classConstructor.type, classConstructor);\n // legacy\n // @TODO: needs to be removed in fabric 7 or 8\n this[JSON].set(classConstructor.type.toLowerCase(), classConstructor);\n }\n }\n\n getSVGClass(SVGTagName: string): any {\n return this[SVG].get(SVGTagName);\n }\n\n setSVGClass(classConstructor: any, SVGTagName?: string) {\n this[SVG].set(\n SVGTagName ?? classConstructor.type.toLowerCase(),\n classConstructor,\n );\n }\n}\n\nexport const classRegistry = new ClassRegistry();\n","import type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type { AnimationBase } from './AnimationBase';\n\n/**\n * Array holding all running animations\n */\nclass AnimationRegistry extends Array {\n /**\n * Remove a single animation using an animation context\n * @param {AnimationBase} context\n */\n remove(context: AnimationBase) {\n const index = this.indexOf(context);\n index > -1 && this.splice(index, 1);\n }\n\n /**\n * Cancel all running animations on the next frame\n */\n cancelAll() {\n const animations = this.splice(0);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations attached to a canvas on the next frame\n * @param {StaticCanvas} canvas\n */\n cancelByCanvas(canvas: StaticCanvas) {\n if (!canvas) {\n return [];\n }\n const animations = this.filter(\n (animation) =>\n animation.target === canvas ||\n (typeof animation.target === 'object' &&\n (animation.target as FabricObject)?.canvas === canvas),\n );\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n\n /**\n * Cancel all running animations for target on the next frame\n * @param target\n */\n cancelByTarget(target: AnimationBase['target']) {\n if (!target) {\n return [];\n }\n const animations = this.filter((animation) => animation.target === target);\n animations.forEach((animation) => animation.abort());\n return animations;\n }\n}\n\nexport const runningAnimations = new AnimationRegistry();\n","export type TEventCallback = (options: T) => any;\n\ntype EventRegistryObject = {\n [K in keyof E]?: TEventCallback;\n};\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#events}\n * @see {@link http://fabricjs.com/events|Events demo}\n */\nexport class Observable {\n private __eventListeners: Record =\n {} as Record;\n\n /**\n * Observes specified event\n * @alias on\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n on(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n on(handlers: EventRegistryObject): VoidFunction;\n on(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (!this.__eventListeners) {\n this.__eventListeners = {} as Record;\n }\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this.on(eventName as K, handler as TEventCallback);\n });\n return () => this.off(arg0);\n } else if (handler) {\n const eventName = arg0;\n if (!this.__eventListeners[eventName]) {\n this.__eventListeners[eventName] = [];\n }\n this.__eventListeners[eventName].push(handler);\n return () => this.off(eventName, handler);\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * Observes specified event **once**\n * @alias once\n * @param {string} eventName Event name (eg. 'after:render')\n * @param {EventRegistryObject} handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n * @param {Function} handler Function that receives a notification when an event of the specified type occurs\n * @return {Function} disposer\n */\n once(\n eventName: K,\n handler: TEventCallback,\n ): VoidFunction;\n once(handlers: EventRegistryObject): VoidFunction;\n once(\n arg0: K | EventRegistryObject,\n handler?: TEventCallback,\n ): VoidFunction {\n if (typeof arg0 === 'object') {\n // one object with key/value pairs was passed\n const disposers: VoidFunction[] = [];\n Object.entries(arg0).forEach(([eventName, handler]) => {\n disposers.push(this.once(eventName as K, handler as TEventCallback));\n });\n return () => disposers.forEach((d) => d());\n } else if (handler) {\n const disposer = this.on(\n arg0,\n function onceHandler(this: Observable, ...args) {\n handler.call(this, ...args);\n disposer();\n },\n );\n return disposer;\n } else {\n // noop\n return () => false;\n }\n }\n\n /**\n * @private\n * @param {string} eventName\n * @param {Function} [handler]\n */\n private _removeEventListener(\n eventName: K,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners[eventName]) {\n return;\n }\n\n if (handler) {\n const eventListener = this.__eventListeners[eventName];\n const index = eventListener.indexOf(handler);\n index > -1 && eventListener.splice(index, 1);\n } else {\n this.__eventListeners[eventName] = [];\n }\n }\n\n /**\n * Unsubscribe all event listeners for eventname.\n * Do not use this pattern. You could kill internal fabricJS events.\n * We know we should have protected events for internal flows, but we don't have yet\n * @deprecated\n * @param {string} eventName event name (eg. 'after:render')\n */\n off(eventName: K): void;\n /**\n * unsubscribe an event listener\n * @param {string} eventName event name (eg. 'after:render')\n * @param {TEventCallback} handler event listener to unsubscribe\n */\n off(eventName: K, handler: TEventCallback): void;\n /**\n * unsubscribe event listeners\n * @param handlers handlers key/value pairs (eg. {'after:render': handler, 'selection:cleared': handler})\n */\n off(handlers: EventRegistryObject): void;\n /**\n * unsubscribe all event listeners\n */\n off(): void;\n off(\n arg0?: K | EventRegistryObject,\n handler?: TEventCallback,\n ) {\n if (!this.__eventListeners) {\n return;\n }\n\n // remove all key/value pairs (event name -> event handler)\n if (typeof arg0 === 'undefined') {\n for (const eventName in this.__eventListeners) {\n this._removeEventListener(eventName);\n }\n }\n // one object with key/value pairs was passed\n else if (typeof arg0 === 'object') {\n Object.entries(arg0).forEach(([eventName, handler]) => {\n this._removeEventListener(eventName as K, handler as TEventCallback);\n });\n } else {\n this._removeEventListener(arg0, handler);\n }\n }\n\n /**\n * Fires event with an optional options object\n * @param {String} eventName Event name to fire\n * @param {Object} [options] Options object\n */\n fire(eventName: K, options?: EventSpec[K]) {\n if (!this.__eventListeners) {\n return;\n }\n\n const listenersForEvent = this.__eventListeners[eventName]?.concat();\n if (listenersForEvent) {\n for (let i = 0; i < listenersForEvent.length; i++) {\n listenersForEvent[i].call(this, options || {});\n }\n }\n }\n}\n","/**\n * Removes value from an array.\n * Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`\n * @param {Array} array\n * @param {*} value\n * @return {Array} original array\n */\nexport const removeFromArray = (array: T[], value: T): T[] => {\n const idx = array.indexOf(value);\n if (idx !== -1) {\n array.splice(idx, 1);\n }\n return array;\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the cosin value for angle.\n */\nexport const cos = (angle: TRadian): number => {\n if (angle === 0) {\n return 1;\n }\n const angleSlice = Math.abs(angle) / halfPI;\n switch (angleSlice) {\n case 1:\n case 3:\n return 0;\n case 2:\n return -1;\n }\n return Math.cos(angle);\n};\n","import type { TRadian } from '../../typedefs';\nimport { halfPI } from '../../constants';\n\n/**\n * Calculate the cos of an angle, avoiding returning floats for known results\n * This function is here just to avoid getting 0.999999999999999 when dealing\n * with numbers that are really 1 or 0.\n * @param {TRadian} angle the angle\n * @return {Number} the sin value for angle.\n */\nexport const sin = (angle: TRadian): number => {\n if (angle === 0) {\n return 0;\n }\n const angleSlice = angle / halfPI;\n const value = Math.sign(angle);\n switch (angleSlice) {\n case 1:\n return value;\n case 2:\n return 0;\n case 3:\n return -value;\n }\n return Math.sin(angle);\n};\n","import type { TMat2D, TRadian } from './typedefs';\nimport { cos } from './util/misc/cos';\nimport { sin } from './util/misc/sin';\n\nexport interface XY {\n x: number;\n y: number;\n}\n\n/**\n * Adaptation of work of Kevin Lindsey(kevin@kevlindev.com)\n */\nexport class Point implements XY {\n declare x: number;\n\n declare y: number;\n\n constructor();\n constructor(x: number, y: number);\n constructor(point?: XY);\n constructor(arg0: number | XY = 0, y = 0) {\n if (typeof arg0 === 'object') {\n this.x = arg0.x;\n this.y = arg0.y;\n } else {\n this.x = arg0;\n this.y = y;\n }\n }\n\n /**\n * Adds another point to this one and returns another one\n * @param {XY} that\n * @return {Point} new Point instance with added values\n */\n add(that: XY): Point {\n return new Point(this.x + that.x, this.y + that.y);\n }\n\n /**\n * Adds another point to this one\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n addEquals(that: XY): Point {\n this.x += that.x;\n this.y += that.y;\n return this;\n }\n\n /**\n * Adds value to this point and returns a new one\n * @param {Number} scalar\n * @return {Point} new Point with added value\n */\n scalarAdd(scalar: number): Point {\n return new Point(this.x + scalar, this.y + scalar);\n }\n\n /**\n * Adds value to this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarAddEquals(scalar: number): Point {\n this.x += scalar;\n this.y += scalar;\n return this;\n }\n\n /**\n * Subtracts another point from this point and returns a new one\n * @param {XY} that\n * @return {Point} new Point object with subtracted values\n */\n subtract(that: XY): Point {\n return new Point(this.x - that.x, this.y - that.y);\n }\n\n /**\n * Subtracts another point from this point\n * @param {XY} that\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n subtractEquals(that: XY): Point {\n this.x -= that.x;\n this.y -= that.y;\n return this;\n }\n\n /**\n * Subtracts value from this point and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarSubtract(scalar: number): Point {\n return new Point(this.x - scalar, this.y - scalar);\n }\n\n /**\n * Subtracts value from this point\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarSubtractEquals(scalar: number): Point {\n this.x -= scalar;\n this.y -= scalar;\n return this;\n }\n\n /**\n * Multiplies this point by another value and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n multiply(that: XY): Point {\n return new Point(this.x * that.x, this.y * that.y);\n }\n\n /**\n * Multiplies this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarMultiply(scalar: number): Point {\n return new Point(this.x * scalar, this.y * scalar);\n }\n\n /**\n * Multiplies this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarMultiplyEquals(scalar: number): Point {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n }\n\n /**\n * Divides this point by another and returns a new one\n * @param {XY} that\n * @return {Point}\n */\n divide(that: XY): Point {\n return new Point(this.x / that.x, this.y / that.y);\n }\n\n /**\n * Divides this point by a value and returns a new one\n * @param {Number} scalar\n * @return {Point}\n */\n scalarDivide(scalar: number): Point {\n return new Point(this.x / scalar, this.y / scalar);\n }\n\n /**\n * Divides this point by a value\n * @param {Number} scalar\n * @return {Point} thisArg\n * @chainable\n * @deprecated\n */\n scalarDivideEquals(scalar: number): Point {\n this.x /= scalar;\n this.y /= scalar;\n return this;\n }\n\n /**\n * Returns true if this point is equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n eq(that: XY): boolean {\n return this.x === that.x && this.y === that.y;\n }\n\n /**\n * Returns true if this point is less than another one\n * @param {XY} that\n * @return {Boolean}\n */\n lt(that: XY): boolean {\n return this.x < that.x && this.y < that.y;\n }\n\n /**\n * Returns true if this point is less than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n lte(that: XY): boolean {\n return this.x <= that.x && this.y <= that.y;\n }\n\n /**\n\n * Returns true if this point is greater another one\n * @param {XY} that\n * @return {Boolean}\n */\n gt(that: XY): boolean {\n return this.x > that.x && this.y > that.y;\n }\n\n /**\n * Returns true if this point is greater than or equal to another one\n * @param {XY} that\n * @return {Boolean}\n */\n gte(that: XY): boolean {\n return this.x >= that.x && this.y >= that.y;\n }\n\n /**\n * Returns new point which is the result of linear interpolation with this one and another one\n * @param {XY} that\n * @param {Number} t , position of interpolation, between 0 and 1 default 0.5\n * @return {Point}\n */\n lerp(that: XY, t = 0.5): Point {\n t = Math.max(Math.min(1, t), 0);\n return new Point(\n this.x + (that.x - this.x) * t,\n this.y + (that.y - this.y) * t,\n );\n }\n\n /**\n * Returns distance from this point and another one\n * @param {XY} that\n * @return {Number}\n */\n distanceFrom(that: XY): number {\n const dx = this.x - that.x,\n dy = this.y - that.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n /**\n * Returns the point between this point and another one\n * @param {XY} that\n * @return {Point}\n */\n midPointFrom(that: XY): Point {\n return this.lerp(that);\n }\n\n /**\n * Returns a new point which is the min of this and another one\n * @param {XY} that\n * @return {Point}\n */\n min(that: XY): Point {\n return new Point(Math.min(this.x, that.x), Math.min(this.y, that.y));\n }\n\n /**\n * Returns a new point which is the max of this and another one\n * @param {XY} that\n * @return {Point}\n */\n max(that: XY): Point {\n return new Point(Math.max(this.x, that.x), Math.max(this.y, that.y));\n }\n\n /**\n * Returns string representation of this point\n * @return {String}\n */\n toString(): string {\n return `${this.x},${this.y}`;\n }\n\n /**\n * Sets x/y of this point\n * @param {Number} x\n * @param {Number} y\n * @chainable\n */\n setXY(x: number, y: number) {\n this.x = x;\n this.y = y;\n return this;\n }\n\n /**\n * Sets x of this point\n * @param {Number} x\n * @chainable\n */\n setX(x: number) {\n this.x = x;\n return this;\n }\n\n /**\n * Sets y of this point\n * @param {Number} y\n * @chainable\n */\n setY(y: number) {\n this.y = y;\n return this;\n }\n\n /**\n * Sets x/y of this point from another point\n * @param {XY} that\n * @chainable\n */\n setFromPoint(that: XY) {\n this.x = that.x;\n this.y = that.y;\n return this;\n }\n\n /**\n * Swaps x/y of this point and another point\n * @param {XY} that\n */\n swap(that: XY) {\n const x = this.x,\n y = this.y;\n this.x = that.x;\n this.y = that.y;\n that.x = x;\n that.y = y;\n }\n\n /**\n * return a cloned instance of the point\n * @return {Point}\n */\n clone(): Point {\n return new Point(this.x, this.y);\n }\n\n /**\n * Rotates `point` around `origin` with `radians`\n * @static\n * @memberOf fabric.util\n * @param {XY} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\n rotate(radians: TRadian, origin: XY = ZERO): Point {\n // TODO benchmark and verify the add and subtract how much cost\n // and then in case early return if no origin is passed\n const sinus = sin(radians),\n cosinus = cos(radians);\n const p = this.subtract(origin);\n const rotated = new Point(\n p.x * cosinus - p.y * sinus,\n p.x * sinus + p.y * cosinus,\n );\n return rotated.add(origin);\n }\n\n /**\n * Apply transform t to point p\n * @static\n * @memberOf fabric.util\n * @param {TMat2D} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\n transform(t: TMat2D, ignoreOffset = false): Point {\n return new Point(\n t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]),\n t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5]),\n );\n }\n}\n\nexport const ZERO = new Point(0, 0);\n","import type { Constructor, TBBox } from './typedefs';\nimport { removeFromArray } from './util/internals/removeFromArray';\nimport { Point } from './Point';\nimport type { ActiveSelection } from './shapes/ActiveSelection';\nimport type { Group } from './shapes/Group';\nimport type { InteractiveFabricObject } from './shapes/Object/InteractiveObject';\nimport type { FabricObject } from './shapes/Object/FabricObject';\n\nexport const isCollection = (\n fabricObject?: FabricObject,\n): fabricObject is Group | ActiveSelection => {\n return !!fabricObject && Array.isArray((fabricObject as Group)._objects);\n};\n\nexport function createCollectionMixin(Base: TBase) {\n class Collection extends Base {\n /**\n * @type {FabricObject[]}\n * @TODO needs to end up in the constructor too\n */\n _objects: FabricObject[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectAdded(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onObjectRemoved(object: FabricObject) {\n // subclasses should override this method\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _onStackOrderChanged(object: FabricObject) {\n // subclasses should override this method\n }\n\n /**\n * Adds objects to collection\n * Objects should be instances of (or inherit from) FabricObject\n * @param {...FabricObject[]} objects to add\n * @returns {number} new array length\n */\n add(...objects: FabricObject[]): number {\n const size = this._objects.push(...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {number} index Index to insert object at\n * @param {...FabricObject[]} objects Object(s) to insert\n * @returns {number} new array length\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n this._objects.splice(index, 0, ...objects);\n objects.forEach((object) => this._onObjectAdded(object));\n return this._objects.length;\n }\n\n /**\n * Removes objects from a collection, then renders canvas (if `renderOnAddRemove` is not `false`)\n * @private\n * @param {...FabricObject[]} objects objects to remove\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const array = this._objects,\n removed: FabricObject[] = [];\n objects.forEach((object) => {\n const index = array.indexOf(object);\n // only call onObjectRemoved if an object was actually removed\n if (index !== -1) {\n array.splice(index, 1);\n removed.push(object);\n this._onObjectRemoved(object);\n }\n });\n return removed;\n }\n\n /**\n * Executes given function for each object in this group\n * A simple shortcut for getObjects().forEach, before es6 was more complicated,\n * now is just a shortcut.\n * @param {Function} callback\n * Callback invoked with current object as first argument,\n * index - as second and an array of all objects - as third.\n */\n forEachObject(\n callback: (\n object: FabricObject,\n index: number,\n array: FabricObject[],\n ) => any,\n ) {\n this.getObjects().forEach((object, index, objects) =>\n callback(object, index, objects),\n );\n }\n\n /**\n * Returns an array of children objects of this instance\n * @param {...String} [types] When specified, only objects of these types are returned\n * @return {Array}\n */\n getObjects(...types: string[]) {\n if (types.length === 0) {\n return [...this._objects];\n }\n return this._objects.filter((o) => o.isType(...types));\n }\n\n /**\n * Returns object at specified index\n * @param {Number} index\n * @return {Object} object at index\n */\n item(index: number) {\n return this._objects[index];\n }\n\n /**\n * Returns true if collection contains no objects\n * @return {Boolean} true if collection is empty\n */\n isEmpty() {\n return this._objects.length === 0;\n }\n\n /**\n * Returns a size of a collection (i.e: length of an array containing its objects)\n * @return {Number} Collection size\n */\n size() {\n return this._objects.length;\n }\n\n /**\n * Returns true if collection contains an object.\\\n * **Prefer using {@link FabricObject#isDescendantOf} for performance reasons**\n * instead of `a.contains(b)` use `b.isDescendantOf(a)`\n * @param {Object} object Object to check against\n * @param {Boolean} [deep=false] `true` to check all descendants, `false` to check only `_objects`\n * @return {Boolean} `true` if collection contains an object\n */\n contains(object: FabricObject, deep?: boolean): boolean {\n if (this._objects.includes(object)) {\n return true;\n } else if (deep) {\n return this._objects.some(\n (obj) =>\n obj instanceof Collection &&\n (obj as unknown as Collection).contains(object, true),\n );\n }\n return false;\n }\n\n /**\n * Returns number representation of a collection complexity\n * @return {Number} complexity\n */\n complexity() {\n return this._objects.reduce((memo, current) => {\n memo += current.complexity ? current.complexity() : 0;\n return memo;\n }, 0);\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the bottom of the stack of drawn objects\n * @param {fabric.Object} object Object to send to back\n * @returns {boolean} true if change occurred\n */\n sendObjectToBack(object: FabricObject) {\n if (!object || object === this._objects[0]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.unshift(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or the objects of a multiple selection\n * to the top of the stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @returns {boolean} true if change occurred\n */\n bringObjectToFront(object: FabricObject) {\n if (!object || object === this._objects[this._objects.length - 1]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.push(object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n /**\n * Moves an object or a selection down in stack of drawn objects\n * An optional parameter, `intersecting` allows to move the object in behind\n * the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object behind next lower intersecting object\n * @returns {boolean} true if change occurred\n */\n sendObjectBackwards(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== 0) {\n // if object is not on the bottom of stack\n const newIdx = this.findNewLowerIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object or a selection up in stack of drawn objects\n * An optional parameter, intersecting allows to move the object in front\n * of the first intersecting object. Where intersection is calculated with\n * bounding box. If no intersection is found, there will not be change in the\n * stack.\n * @param {fabric.Object} object Object to send\n * @param {boolean} [intersecting] If `true`, send object in front of next upper intersecting object\n * @returns {boolean} true if change occurred\n */\n bringObjectForward(object: FabricObject, intersecting?: boolean) {\n if (!object) {\n return false;\n }\n const idx = this._objects.indexOf(object);\n if (idx !== this._objects.length - 1) {\n // if object is not on top of stack (last item in an array)\n const newIdx = this.findNewUpperIndex(object, idx, intersecting);\n removeFromArray(this._objects, object);\n this._objects.splice(newIdx, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n return false;\n }\n\n /**\n * Moves an object to specified level in stack of drawn objects\n * @param {fabric.Object} object Object to send\n * @param {number} index Position to move to\n * @returns {boolean} true if change occurred\n */\n moveObjectTo(object: FabricObject, index: number) {\n if (object === this._objects[index]) {\n return false;\n }\n removeFromArray(this._objects, object);\n this._objects.splice(index, 0, object);\n this._onStackOrderChanged(object);\n return true;\n }\n\n findNewLowerIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse down the stack looking for the nearest intersecting object\n for (let i = idx - 1; i >= 0; --i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx - 1;\n }\n\n return newIdx;\n }\n\n findNewUpperIndex(\n object: FabricObject,\n idx: number,\n intersecting?: boolean,\n ) {\n let newIdx;\n\n if (intersecting) {\n newIdx = idx;\n // traverse up the stack looking for the nearest intersecting object\n for (let i = idx + 1; i < this._objects.length; ++i) {\n if (object.isOverlapping(this._objects[i])) {\n newIdx = i;\n break;\n }\n }\n } else {\n newIdx = idx + 1;\n }\n\n return newIdx;\n }\n\n /**\n * Given a bounding box, return all the objects of the collection that are contained in the bounding box.\n * If `includeIntersecting` is true, return also the objects that intersect the bounding box as well.\n * This is meant to work with selection. Is not a generic method.\n * @param {TBBox} bbox a bounding box in scene coordinates\n * @param {{ includeIntersecting?: boolean }} options an object with includeIntersecting\n * @returns array of objects contained in the bounding box, ordered from top to bottom stacking wise\n */\n collectObjects(\n { left, top, width, height }: TBBox,\n { includeIntersecting = true }: { includeIntersecting?: boolean } = {},\n ) {\n const objects: InteractiveFabricObject[] = [],\n tl = new Point(left, top),\n br = tl.add(new Point(width, height));\n\n // we iterate reverse order to collect top first in case of click.\n for (let i = this._objects.length - 1; i >= 0; i--) {\n const object = this._objects[i] as unknown as InteractiveFabricObject;\n if (\n object.selectable &&\n object.visible &&\n ((includeIntersecting && object.intersectsWithRect(tl, br)) ||\n object.isContainedWithinRect(tl, br) ||\n (includeIntersecting && object.containsPoint(tl)) ||\n (includeIntersecting && object.containsPoint(br)))\n ) {\n objects.push(object);\n }\n }\n\n return objects;\n }\n }\n\n // https://github.com/microsoft/TypeScript/issues/32080\n return Collection as typeof Collection & TBase;\n}\n","import { Observable } from './Observable';\n\nexport class CommonMethods extends Observable {\n /**\n * Sets object's properties from options, for initialization only\n * @protected\n * @param {Object} [options] Options object\n */\n protected _setOptions(options: any = {}) {\n for (const prop in options) {\n this.set(prop, options[prop]);\n }\n }\n\n /**\n * @private\n */\n _setObject(obj: Record) {\n for (const prop in obj) {\n this._set(prop, obj[prop]);\n }\n }\n\n /**\n * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`.\n * @param {String|Object} key Property name or object (if object, iterate over the object properties)\n * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one)\n */\n set(key: string | Record, value?: any) {\n if (typeof key === 'object') {\n this._setObject(key);\n } else {\n this._set(key, value);\n }\n return this;\n }\n\n _set(key: string, value: any) {\n this[key as keyof this] = value;\n }\n\n /**\n * Toggles specified property from `true` to `false` or from `false` to `true`\n * @param {String} property Property to toggle\n */\n toggle(property: string) {\n const value = this.get(property);\n if (typeof value === 'boolean') {\n this.set(property, !value);\n }\n return this;\n }\n\n /**\n * Basic getter\n * @param {String} property Property name\n * @return {*} value of a property\n */\n get(property: string): any {\n return this[property as keyof this];\n }\n}\n","import { getFabricWindow } from '../../env';\n\nexport function requestAnimFrame(callback: FrameRequestCallback): number {\n return getFabricWindow().requestAnimationFrame(callback);\n}\n\nexport function cancelAnimFrame(handle: number): void {\n return getFabricWindow().cancelAnimationFrame(handle);\n}\n","let id = 0;\n\nexport const uid = () => id++;\n","import { getFabricDocument } from '../../env';\nimport type { ImageFormat } from '../../typedefs';\nimport { FabricError } from '../internals/console';\n/**\n * Creates canvas element\n * @return {CanvasElement} initialized canvas element\n */\nexport const createCanvasElement = (): HTMLCanvasElement => {\n const element = getFabricDocument().createElement('canvas');\n if (!element || typeof element.getContext === 'undefined') {\n throw new FabricError('Failed to create `canvas` element');\n }\n return element;\n};\n\n/**\n * Creates image element (works on client and node)\n * @return {HTMLImageElement} HTML image element\n */\nexport const createImage = (): HTMLImageElement =>\n getFabricDocument().createElement('img');\n\n/**\n * Creates a canvas element that is a copy of another and is also painted\n * @param {CanvasElement} canvas to copy size and content of\n * @return {CanvasElement} initialized canvas element\n */\nexport const copyCanvasElement = (\n canvas: HTMLCanvasElement,\n): HTMLCanvasElement => {\n const newCanvas = createCanvasElement();\n newCanvas.width = canvas.width;\n newCanvas.height = canvas.height;\n newCanvas.getContext('2d')?.drawImage(canvas, 0, 0);\n return newCanvas;\n};\n\n/**\n * since 2.6.0 moved from canvas instance to utility.\n * possibly useless\n * @param {CanvasElement} canvasEl to copy size and content of\n * @param {String} format 'jpeg' or 'png', in some browsers 'webp' is ok too\n * @param {Number} quality <= 1 and > 0\n * @return {String} data url\n */\nexport const toDataURL = (\n canvasEl: HTMLCanvasElement,\n format: ImageFormat,\n quality: number,\n) => canvasEl.toDataURL(`image/${format}`, quality);\n\nexport const isHTMLCanvas = (\n canvas?: HTMLCanvasElement | string,\n): canvas is HTMLCanvasElement => {\n return !!canvas && (canvas as HTMLCanvasElement).getContext !== undefined;\n};\n","import type { TRadian, TDegree } from '../../typedefs';\nimport { PiBy180 } from '../../constants';\n\n/**\n * Transforms degrees to radians.\n * @param {TDegree} degrees value in degrees\n * @return {TRadian} value in radians\n */\nexport const degreesToRadians = (degrees: TDegree): TRadian =>\n (degrees * PiBy180) as TRadian;\n\n/**\n * Transforms radians to degrees.\n * @param {TRadian} radians value in radians\n * @return {TDegree} value in degrees\n */\nexport const radiansToDegrees = (radians: TRadian): TDegree =>\n (radians / PiBy180) as TDegree;\n","import { iMatrix } from '../../constants';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TDegree, TRadian, TMat2D } from '../../typedefs';\nimport { cos } from './cos';\nimport { degreesToRadians, radiansToDegrees } from './radiansDegreesConversion';\nimport { sin } from './sin';\n\nexport type TRotateMatrixArgs = {\n angle?: TDegree;\n};\n\nexport type TTranslateMatrixArgs = {\n translateX?: number;\n translateY?: number;\n};\n\nexport type TScaleMatrixArgs = {\n scaleX?: number;\n scaleY?: number;\n flipX?: boolean;\n flipY?: boolean;\n skewX?: TDegree;\n skewY?: TDegree;\n};\n\nexport type TComposeMatrixArgs = TTranslateMatrixArgs &\n TRotateMatrixArgs &\n TScaleMatrixArgs;\n\nexport type TQrDecomposeOut = Required<\n Omit\n>;\n\nexport const isIdentityMatrix = (mat: TMat2D) =>\n mat.every((value, index) => value === iMatrix[index]);\n\n/**\n * Apply transform t to point p\n * @deprecated use {@link Point#transform}\n * @param {Point | XY} p The point to transform\n * @param {Array} t The transform\n * @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied\n * @return {Point} The transformed point\n */\nexport const transformPoint = (\n p: XY,\n t: TMat2D,\n ignoreOffset?: boolean,\n): Point => new Point(p).transform(t, ignoreOffset);\n\n/**\n * Invert transformation t\n * @param {Array} t The transform\n * @return {Array} The inverted transform\n */\nexport const invertTransform = (t: TMat2D): TMat2D => {\n const a = 1 / (t[0] * t[3] - t[1] * t[2]),\n r = [a * t[3], -a * t[1], -a * t[2], a * t[0], 0, 0] as TMat2D,\n { x, y } = new Point(t[4], t[5]).transform(r, true);\n r[4] = -x;\n r[5] = -y;\n return r;\n};\n\n/**\n * Multiply matrix A by matrix B to nest transformations\n * @param {TMat2D} a First transformMatrix\n * @param {TMat2D} b Second transformMatrix\n * @param {Boolean} is2x2 flag to multiply matrices as 2x2 matrices\n * @return {TMat2D} The product of the two transform matrices\n */\nexport const multiplyTransformMatrices = (\n a: TMat2D,\n b: TMat2D,\n is2x2?: boolean,\n): TMat2D =>\n [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n is2x2 ? 0 : a[0] * b[4] + a[2] * b[5] + a[4],\n is2x2 ? 0 : a[1] * b[4] + a[3] * b[5] + a[5],\n ] as TMat2D;\n\n/**\n * Multiplies {@link matrices} such that a matrix defines the plane for the rest of the matrices **after** it\n *\n * `multiplyTransformMatrixArray([A, B, C, D])` is equivalent to `A(B(C(D)))`\n *\n * @param matrices an array of matrices\n * @param [is2x2] flag to multiply matrices as 2x2 matrices\n * @returns the multiplication product\n */\nexport const multiplyTransformMatrixArray = (\n matrices: (TMat2D | undefined | null | false)[],\n is2x2?: boolean,\n) =>\n matrices.reduceRight(\n (product: TMat2D, curr) =>\n curr && product\n ? multiplyTransformMatrices(curr, product, is2x2)\n : curr || product,\n undefined as unknown as TMat2D,\n ) || iMatrix.concat();\n\nexport const calcPlaneRotation = ([a, b]: TMat2D) =>\n Math.atan2(b, a) as TRadian;\n\n/**\n * Decomposes standard 2x3 matrix into transform components\n * @param {TMat2D} a transformMatrix\n * @return {Object} Components of transform\n */\nexport const qrDecompose = (a: TMat2D): TQrDecomposeOut => {\n const angle = calcPlaneRotation(a),\n denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),\n scaleX = Math.sqrt(denom),\n scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX,\n skewX = Math.atan2(a[0] * a[2] + a[1] * a[3], denom);\n return {\n angle: radiansToDegrees(angle),\n scaleX,\n scaleY,\n skewX: radiansToDegrees(skewX),\n skewY: 0 as TDegree,\n translateX: a[4] || 0,\n translateY: a[5] || 0,\n };\n};\n\n/**\n * Generate a translation matrix\n *\n * A translation matrix in the form of\n * [ 1 0 x ]\n * [ 0 1 y ]\n * [ 0 0 1 ]\n *\n * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details\n *\n * @param {number} x translation on X axis\n * @param {number} [y] translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createTranslateMatrix = (x: number, y = 0): TMat2D => [\n 1,\n 0,\n 0,\n 1,\n x,\n y,\n];\n\n/**\n * Generate a rotation matrix around around a point (x,y), defaulting to (0,0)\n *\n * A matrix in the form of\n * [cos(a) -sin(a) -x*cos(a)+y*sin(a)+x]\n * [sin(a) cos(a) -x*sin(a)-y*cos(a)+y]\n * [0 0 1 ]\n *\n *\n * @param {TDegree} angle rotation in degrees\n * @param {XY} [pivotPoint] pivot point to rotate around\n * @returns {TMat2D} matrix\n */\nexport function createRotateMatrix(\n { angle = 0 }: TRotateMatrixArgs = {},\n { x = 0, y = 0 }: Partial = {},\n): TMat2D {\n const angleRadiant = degreesToRadians(angle),\n cosValue = cos(angleRadiant),\n sinValue = sin(angleRadiant);\n return [\n cosValue,\n sinValue,\n -sinValue,\n cosValue,\n x ? x - (cosValue * x - sinValue * y) : 0,\n y ? y - (sinValue * x + cosValue * y) : 0,\n ];\n}\n\n/**\n * Generate a scale matrix around the point (0,0)\n *\n * A matrix in the form of\n * [x 0 0]\n * [0 y 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale\n *\n * @param {number} x scale on X axis\n * @param {number} [y] scale on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createScaleMatrix = (x: number, y: number = x): TMat2D => [\n x,\n 0,\n 0,\n y,\n 0,\n 0,\n];\n\nexport const angleToSkew = (angle: TDegree) =>\n Math.tan(degreesToRadians(angle));\n\nexport const skewToAngle = (value: TRadian) =>\n radiansToDegrees(Math.atan(value));\n\n/**\n * Generate a skew matrix for the X axis\n *\n * A matrix in the form of\n * [1 x 0]\n * [0 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx\n *\n * @param {TDegree} skewValue translation on X axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewXMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n 0,\n angleToSkew(skewValue),\n 1,\n 0,\n 0,\n];\n\n/**\n * Generate a skew matrix for the Y axis\n *\n * A matrix in the form of\n * [1 0 0]\n * [y 1 0]\n * [0 0 1]\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewy\n *\n * @param {TDegree} skewValue translation on Y axis\n * @returns {TMat2D} matrix\n */\nexport const createSkewYMatrix = (skewValue: TDegree): TMat2D => [\n 1,\n angleToSkew(skewValue),\n 0,\n 1,\n 0,\n 0,\n];\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet.\n * is called DimensionsTransformMatrix because those properties are the one that influence\n * the size of the resulting box of the object.\n * @param {Object} options\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @return {Number[]} transform matrix\n */\nexport const calcDimensionsMatrix = ({\n scaleX = 1,\n scaleY = 1,\n flipX = false,\n flipY = false,\n skewX = 0 as TDegree,\n skewY = 0 as TDegree,\n}: TScaleMatrixArgs) => {\n let matrix = createScaleMatrix(\n flipX ? -scaleX : scaleX,\n flipY ? -scaleY : scaleY,\n );\n if (skewX) {\n matrix = multiplyTransformMatrices(matrix, createSkewXMatrix(skewX), true);\n }\n if (skewY) {\n matrix = multiplyTransformMatrices(matrix, createSkewYMatrix(skewY), true);\n }\n return matrix;\n};\n\n/**\n * Returns a transform matrix starting from an object of the same kind of\n * the one returned from qrDecompose, useful also if you want to calculate some\n * transformations from an object that is not enlived yet\n * Before changing this function look at: src/benchmarks/calcTransformMatrix.mjs\n * @param {Object} options\n * @param {Number} [options.angle]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Boolean} [options.flipX]\n * @param {Boolean} [options.flipY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @param {Number} [options.translateX]\n * @param {Number} [options.translateY]\n * @return {Number[]} transform matrix\n */\nexport const composeMatrix = (options: TComposeMatrixArgs): TMat2D => {\n const { translateX = 0, translateY = 0, angle = 0 as TDegree } = options;\n let matrix = createTranslateMatrix(translateX, translateY);\n if (angle) {\n matrix = multiplyTransformMatrices(matrix, createRotateMatrix({ angle }));\n }\n const scaleMatrix = calcDimensionsMatrix(options);\n if (!isIdentityMatrix(scaleMatrix)) {\n matrix = multiplyTransformMatrices(matrix, scaleMatrix);\n }\n return matrix;\n};\n","import { noop } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport type {\n Abortable,\n Constructor,\n TCrossOrigin,\n TFiller,\n} from '../../typedefs';\nimport { createImage } from './dom';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { BaseFilter } from '../../filters/BaseFilter';\nimport type { FabricObject as BaseFabricObject } from '../../shapes/Object/Object';\nimport { FabricError, SignalAbortedError } from '../internals/console';\nimport type { Shadow } from '../../Shadow';\n\nexport type LoadImageOptions = Abortable & {\n /**\n * cors value for the image loading, default to anonymous\n */\n crossOrigin?: TCrossOrigin;\n};\n\n/**\n * Loads image element from given url and resolve it, or catch.\n * @param {String} url URL representing an image\n * @param {LoadImageOptions} [options] image loading options\n * @returns {Promise} the loaded image.\n */\nexport const loadImage = (\n url: string,\n { signal, crossOrigin = null }: LoadImageOptions = {},\n) =>\n new Promise(function (resolve, reject) {\n if (signal && signal.aborted) {\n return reject(new SignalAbortedError('loadImage'));\n }\n const img = createImage();\n let abort: EventListenerOrEventListenerObject;\n if (signal) {\n abort = function (err: Event) {\n img.src = '';\n reject(err);\n };\n signal.addEventListener('abort', abort, { once: true });\n }\n const done = function () {\n img.onload = img.onerror = null;\n abort && signal?.removeEventListener('abort', abort);\n resolve(img);\n };\n if (!url) {\n done();\n return;\n }\n img.onload = done;\n img.onerror = function () {\n abort && signal?.removeEventListener('abort', abort);\n reject(new FabricError(`Error loading ${img.src}`));\n };\n crossOrigin && (img.crossOrigin = crossOrigin);\n img.src = url;\n });\n\nexport type EnlivenObjectOptions = Abortable & {\n /**\n * Method for further parsing of object elements,\n * called after each fabric object created.\n */\n reviver?: <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n >(\n serializedObj: Record,\n instance: T,\n ) => void;\n};\n\n/**\n * @TODO type this correctly.\n * Creates corresponding fabric instances from their object representations\n * @param {Object[]} objects Objects to enliven\n * @param {EnlivenObjectOptions} [options]\n * @param {(serializedObj: object, instance: FabricObject) => any} [options.reviver] Method for further parsing of object elements,\n * called after each fabric object created.\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\nexport const enlivenObjects = <\n T extends\n | BaseFabricObject\n | FabricObject\n | BaseFilter\n | Shadow\n | TFiller,\n>(\n objects: any[],\n { signal, reviver = noop }: EnlivenObjectOptions = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: T[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n Promise.all(\n objects.map((obj) =>\n classRegistry\n .getClass<\n Constructor & {\n fromObject(options: any, context: Abortable): Promise;\n }\n >(obj.type)\n .fromObject(obj, { signal })\n .then((fabricInstance) => {\n reviver(obj, fabricInstance);\n instances.push(fabricInstance);\n return fabricInstance;\n }),\n ),\n )\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance) => {\n (instance as FabricObject).dispose &&\n (instance as FabricObject).dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n\n/**\n * Creates corresponding fabric instances residing in an object, e.g. `clipPath`\n * @param {Object} object with properties to enlive ( fill, stroke, clipPath, path )\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise>} the input object with enlived values\n */\nexport const enlivenObjectEnlivables = <\n R = Record,\n>(\n serializedObject: any,\n { signal }: Abortable = {},\n) =>\n new Promise((resolve, reject) => {\n const instances: (FabricObject | TFiller | Shadow)[] = [];\n signal && signal.addEventListener('abort', reject, { once: true });\n // enlive every possible property\n const promises = Object.values(serializedObject).map((value: any) => {\n if (!value) {\n return value;\n }\n /**\n * clipPath or shadow or gradient or text on a path or a pattern,\n * or the backgroundImage or overlayImage of canvas\n * If we have a type and there is a classe registered for it, we enlive it.\n * If there is no class registered for it we return the value as is\n * */\n if (value.type && classRegistry.has(value.type)) {\n return enlivenObjects([value], {\n signal,\n }).then(([enlived]) => {\n instances.push(enlived);\n return enlived;\n });\n }\n return value;\n });\n const keys = Object.keys(serializedObject);\n Promise.all(promises)\n .then((enlived) => {\n return enlived.reduce((acc, instance, index) => {\n acc[keys[index]] = instance;\n return acc;\n }, {});\n })\n .then(resolve)\n .catch((error) => {\n // cleanup\n instances.forEach((instance: any) => {\n instance.dispose && instance.dispose();\n });\n reject(error);\n })\n .finally(() => {\n signal && signal.removeEventListener('abort', reject);\n });\n });\n","/**\n * Populates an object with properties of another object\n * @param {Object} source Source object\n * @param {string[]} properties Properties names to include\n * @returns object populated with the picked keys\n */\nexport const pick = >(\n source: T,\n keys: (keyof T)[] = [],\n) => {\n return keys.reduce((o, key) => {\n if (key in source) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n\nexport const pickBy = >(\n source: T,\n predicate: (value: T[K], key: K, collection: T) => boolean,\n) => {\n return (Object.keys(source) as (keyof T)[]).reduce((o, key) => {\n if (predicate(source[key], key, source)) {\n o[key] = source[key];\n }\n return o;\n }, {} as Partial);\n};\n","/**\n * Map of the 148 color names with HEX code\n * @see: https://www.w3.org/TR/css3-color/#svg-color\n */\nexport const ColorNameMap = {\n aliceblue: '#F0F8FF',\n antiquewhite: '#FAEBD7',\n aqua: '#0FF',\n aquamarine: '#7FFFD4',\n azure: '#F0FFFF',\n beige: '#F5F5DC',\n bisque: '#FFE4C4',\n black: '#000',\n blanchedalmond: '#FFEBCD',\n blue: '#00F',\n blueviolet: '#8A2BE2',\n brown: '#A52A2A',\n burlywood: '#DEB887',\n cadetblue: '#5F9EA0',\n chartreuse: '#7FFF00',\n chocolate: '#D2691E',\n coral: '#FF7F50',\n cornflowerblue: '#6495ED',\n cornsilk: '#FFF8DC',\n crimson: '#DC143C',\n cyan: '#0FF',\n darkblue: '#00008B',\n darkcyan: '#008B8B',\n darkgoldenrod: '#B8860B',\n darkgray: '#A9A9A9',\n darkgrey: '#A9A9A9',\n darkgreen: '#006400',\n darkkhaki: '#BDB76B',\n darkmagenta: '#8B008B',\n darkolivegreen: '#556B2F',\n darkorange: '#FF8C00',\n darkorchid: '#9932CC',\n darkred: '#8B0000',\n darksalmon: '#E9967A',\n darkseagreen: '#8FBC8F',\n darkslateblue: '#483D8B',\n darkslategray: '#2F4F4F',\n darkslategrey: '#2F4F4F',\n darkturquoise: '#00CED1',\n darkviolet: '#9400D3',\n deeppink: '#FF1493',\n deepskyblue: '#00BFFF',\n dimgray: '#696969',\n dimgrey: '#696969',\n dodgerblue: '#1E90FF',\n firebrick: '#B22222',\n floralwhite: '#FFFAF0',\n forestgreen: '#228B22',\n fuchsia: '#F0F',\n gainsboro: '#DCDCDC',\n ghostwhite: '#F8F8FF',\n gold: '#FFD700',\n goldenrod: '#DAA520',\n gray: '#808080',\n grey: '#808080',\n green: '#008000',\n greenyellow: '#ADFF2F',\n honeydew: '#F0FFF0',\n hotpink: '#FF69B4',\n indianred: '#CD5C5C',\n indigo: '#4B0082',\n ivory: '#FFFFF0',\n khaki: '#F0E68C',\n lavender: '#E6E6FA',\n lavenderblush: '#FFF0F5',\n lawngreen: '#7CFC00',\n lemonchiffon: '#FFFACD',\n lightblue: '#ADD8E6',\n lightcoral: '#F08080',\n lightcyan: '#E0FFFF',\n lightgoldenrodyellow: '#FAFAD2',\n lightgray: '#D3D3D3',\n lightgrey: '#D3D3D3',\n lightgreen: '#90EE90',\n lightpink: '#FFB6C1',\n lightsalmon: '#FFA07A',\n lightseagreen: '#20B2AA',\n lightskyblue: '#87CEFA',\n lightslategray: '#789',\n lightslategrey: '#789',\n lightsteelblue: '#B0C4DE',\n lightyellow: '#FFFFE0',\n lime: '#0F0',\n limegreen: '#32CD32',\n linen: '#FAF0E6',\n magenta: '#F0F',\n maroon: '#800000',\n mediumaquamarine: '#66CDAA',\n mediumblue: '#0000CD',\n mediumorchid: '#BA55D3',\n mediumpurple: '#9370DB',\n mediumseagreen: '#3CB371',\n mediumslateblue: '#7B68EE',\n mediumspringgreen: '#00FA9A',\n mediumturquoise: '#48D1CC',\n mediumvioletred: '#C71585',\n midnightblue: '#191970',\n mintcream: '#F5FFFA',\n mistyrose: '#FFE4E1',\n moccasin: '#FFE4B5',\n navajowhite: '#FFDEAD',\n navy: '#000080',\n oldlace: '#FDF5E6',\n olive: '#808000',\n olivedrab: '#6B8E23',\n orange: '#FFA500',\n orangered: '#FF4500',\n orchid: '#DA70D6',\n palegoldenrod: '#EEE8AA',\n palegreen: '#98FB98',\n paleturquoise: '#AFEEEE',\n palevioletred: '#DB7093',\n papayawhip: '#FFEFD5',\n peachpuff: '#FFDAB9',\n peru: '#CD853F',\n pink: '#FFC0CB',\n plum: '#DDA0DD',\n powderblue: '#B0E0E6',\n purple: '#800080',\n rebeccapurple: '#639',\n red: '#F00',\n rosybrown: '#BC8F8F',\n royalblue: '#4169E1',\n saddlebrown: '#8B4513',\n salmon: '#FA8072',\n sandybrown: '#F4A460',\n seagreen: '#2E8B57',\n seashell: '#FFF5EE',\n sienna: '#A0522D',\n silver: '#C0C0C0',\n skyblue: '#87CEEB',\n slateblue: '#6A5ACD',\n slategray: '#708090',\n slategrey: '#708090',\n snow: '#FFFAFA',\n springgreen: '#00FF7F',\n steelblue: '#4682B4',\n tan: '#D2B48C',\n teal: '#008080',\n thistle: '#D8BFD8',\n tomato: '#FF6347',\n turquoise: '#40E0D0',\n violet: '#EE82EE',\n wheat: '#F5DEB3',\n white: '#FFF',\n whitesmoke: '#F5F5F5',\n yellow: '#FF0',\n yellowgreen: '#9ACD32',\n};\n","/**\n * Regex matching color in RGB or RGBA formats (ex: `rgb(0, 0, 0)`, `rgba(255, 100, 10, 0.5)`, `rgba( 255 , 100 , 10 , 0.5 )`, `rgb(1,1,1)`, `rgba(100%, 60%, 10%, 0.5)`)\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/rgb\n * Formal syntax at the time of writing:\n * =\n * rgb( [ | none ]{3} [ / [ | none ] ]? ) |\n * rgb( [ | none ]{3} [ / [ | none ] ]? )\n * = | \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an rgba or rgb CSS color value\n *\n * /^ # Beginning of the string\n * rgba? # \"rgb\" or \"rgba\"\n * \\(\\s* # Opening parenthesis and optional whitespace\n * (\\d{0,3} # 0 to three digits R channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the first color component\n * %? # Optional percent sign after the first color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits G channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the second color component\n * %? # Optional percent sign after the second color component\n * \\s* # Optional whitespace\n * [\\s|,] # Separator between color components can be a space or comma\n * \\s* # Optional whitespace\n * (\\d{0,3} # 0 to three digits B channel\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for the third color component\n * %? # Optional percent sign after the third color component\n * \\s* # Optional whitespace\n * (?: # Beginning of non-capturing group for alpha value\n * \\s* # Optional whitespace\n * [,/] # Comma or slash separator for alpha value\n * \\s* # Optional whitespace\n * (\\d{0,3} # Zero to three digits\n * (?:\\.\\d+)? # Optional decimal with one or more digits\n * ) # End of capturing group for alpha value\n * %? # Optional percent sign after alpha value\n * \\s* # Optional whitespace\n * )? # End of non-capturing group for alpha value (optional)\n * \\) # Closing parenthesis\n * $ # End of the string\n *\n * The alpha channel can be in the format 0.4 .7 or 1 or 73%\n *\n * WARNING this regex doesn't fail on off spec colors. it matches everything that could be a color.\n * So the spec does not allow for `rgba(30 , 45% 35, 49%)` but this will work anyways for us\n */\nexport const reRGBa = () =>\n /^rgba?\\(\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HSL or HSLA formats (ex: hsl(0, 0, 0), rgba(255, 100, 10, 0.5), rgba( 255 , 100 , 10 , 0.5 ), rgb(1,1,1), rgba(100%, 60%, 10%, 0.5))\n * Also matching rgba(r g b / a) as per new specs\n * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hsl\n * Formal syntax at the time of writing:\n * =\n * hsl( [ | none ] [ | none ] [ | none ] [ / [ | none ] ]? )\n *\n * =\n * |\n * \n *\n * =\n * |\n * \n *\n * For learners this is how you can read this regex\n * Regular expression for matching an hsla or hsl CSS color value\n *\n * /^hsla?\\( // Matches the beginning of the string and the opening parenthesis of \"hsl\" or \"hsla\"\n * \\s* // Matches any whitespace characters (space, tab, etc.) zero or more times\n * (\\d{0,3} // Hue: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Hue: Optional (non capture group) decimal with one or more digits.\n * (?:deg|turn|rad)? // Hue: Optionally include suffix deg or turn or rad\n * ) // Hue: End capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Saturation: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Saturation: Optional decimal with one or more digits in a non-capturing group\n * %?) // Saturation: match optional % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * [\\s|,] // Matches a space, tab or comma\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d{0,3} // Lightness: 0 to three digits - start capture in a group\n * (?:\\.\\d+)? // Lightness: Optional decimal with one or more digits in a non-capturing group\n * %?) // Lightness: match % character and end capture group\n * \\s* // Matches any whitespace characters zero or more times\n * (?: // Alpha: Begins a non-capturing group for the alpha value\n * \\s* // Matches any whitespace characters zero or more times\n * [,/] // Matches a comma or forward slash\n * \\s* // Matches any whitespace characters zero or more times\n * (\\d*(?:\\.\\d+)?%?) // Matches zero or more digits, optionally followed by a decimal point and one or more digits, followed by an optional percentage sign and captures it in a group\n * \\s* // Matches any whitespace characters zero or more times\n * )? // Makes the alpha value group optional\n * \\) // Matches the closing parenthesis\n * $/i // Matches the end of the string and sets the regular expression to case-insensitive mode\n *\n * WARNING this regex doesn't fail on off spec colors. It matches everything that could be a color.\n * So the spec does not allow `hsl(30 , 45% 35, 49%)` but this will work anyways for us.\n */\nexport const reHSLa = () =>\n /^hsla?\\(\\s*([+-]?\\d{0,3}(?:\\.\\d+)?(?:deg|turn|rad)?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*[\\s|,]\\s*(\\d{0,3}(?:\\.\\d+)?%?)\\s*(?:\\s*[,/]\\s*(\\d*(?:\\.\\d+)?%?)\\s*)?\\)$/i;\n\n/**\n * Regex matching color in HEX format (ex: #FF5544CC, #FF5555, 010155, aff)\n */\nexport const reHex = () => /^#?(([0-9a-f]){3,4}|([0-9a-f]{2}){3,4})$/i;\n","import type { TRGBAColorSource } from './typedefs';\n\n/**\n * @param {Number} p\n * @param {Number} q\n * @param {Number} t\n * @return {Number}\n */\nexport const hue2rgb = (p: number, q: number, t: number): number => {\n if (t < 0) {\n t += 1;\n }\n if (t > 1) {\n t -= 1;\n }\n if (t < 1 / 6) {\n return p + (q - p) * 6 * t;\n }\n if (t < 1 / 2) {\n return q;\n }\n if (t < 2 / 3) {\n return p + (q - p) * (2 / 3 - t) * 6;\n }\n return p;\n};\n\n/**\n * Adapted from {@link https://gist.github.com/mjackson/5311256 https://gist.github.com/mjackson}\n * @param {Number} r Red color value\n * @param {Number} g Green color value\n * @param {Number} b Blue color value\n * @param {Number} a Alpha color value pass through\n * @return {TRGBColorSource} Hsl color\n */\nexport const rgb2Hsl = (\n r: number,\n g: number,\n b: number,\n a: number,\n): TRGBAColorSource => {\n r /= 255;\n g /= 255;\n b /= 255;\n const maxValue = Math.max(r, g, b),\n minValue = Math.min(r, g, b);\n\n let h!: number, s: number;\n const l = (maxValue + minValue) / 2;\n\n if (maxValue === minValue) {\n h = s = 0; // achromatic\n } else {\n const d = maxValue - minValue;\n s = l > 0.5 ? d / (2 - maxValue - minValue) : d / (maxValue + minValue);\n switch (maxValue) {\n case r:\n h = (g - b) / d + (g < b ? 6 : 0);\n break;\n case g:\n h = (b - r) / d + 2;\n break;\n case b:\n h = (r - g) / d + 4;\n break;\n }\n h /= 6;\n }\n\n return [Math.round(h * 360), Math.round(s * 100), Math.round(l * 100), a];\n};\n\nexport const fromAlphaToFloat = (value = '1') =>\n parseFloat(value) / (value.endsWith('%') ? 100 : 1);\n\n/**\n * Convert a value in the inclusive range [0, 255] to hex\n */\nexport const hexify = (value: number) =>\n Math.min(Math.round(value), 255).toString(16).toUpperCase().padStart(2, '0');\n\n/**\n * Calculate the grey average value for rgb and pass through alpha\n */\nexport const greyAverage = ([\n r,\n g,\n b,\n a = 1,\n]: TRGBAColorSource): TRGBAColorSource => {\n const avg = Math.round(r * 0.3 + g * 0.59 + b * 0.11);\n return [avg, avg, avg, a];\n};\n","import { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { ColorNameMap } from './color_map';\nimport { reHSLa, reHex, reRGBa } from './constants';\nimport type { TRGBAColorSource, TColorArg } from './typedefs';\nimport {\n hue2rgb,\n hexify,\n rgb2Hsl,\n fromAlphaToFloat,\n greyAverage,\n} from './util';\n\n/**\n * @class Color common color operations\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2/#colors colors}\n */\nexport class Color {\n private declare _source: TRGBAColorSource;\n isUnrecognised = false;\n\n /**\n *\n * @param {string} [color] optional in hex or rgb(a) or hsl format or from known color list\n */\n constructor(color?: TColorArg) {\n if (!color) {\n // we default to black as canvas does\n this.setSource([0, 0, 0, 1]);\n } else if (color instanceof Color) {\n this.setSource([...color._source]);\n } else if (Array.isArray(color)) {\n const [r, g, b, a = 1] = color;\n this.setSource([r, g, b, a]);\n } else {\n this.setSource(this._tryParsingColor(color));\n }\n }\n\n /**\n * @private\n * @param {string} [color] Color value to parse\n * @returns {TRGBAColorSource}\n */\n protected _tryParsingColor(color: string) {\n if (color in ColorNameMap) {\n color = ColorNameMap[color as keyof typeof ColorNameMap];\n }\n return color === 'transparent'\n ? ([255, 255, 255, 0] as TRGBAColorSource)\n : Color.sourceFromHex(color) ||\n Color.sourceFromRgb(color) ||\n Color.sourceFromHsl(color) ||\n // color is not recognized\n // we default to black as canvas does\n // eslint-disable-next-line no-constant-binary-expression\n ((this.isUnrecognised = true) && ([0, 0, 0, 1] as TRGBAColorSource));\n }\n\n /**\n * Returns source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @return {TRGBAColorSource}\n */\n getSource() {\n return this._source;\n }\n\n /**\n * Sets source of this color (where source is an array representation; ex: [200, 200, 100, 1])\n * @param {TRGBAColorSource} source\n */\n setSource(source: TRGBAColorSource) {\n this._source = source;\n }\n\n /**\n * Returns color representation in RGB format\n * @return {String} ex: rgb(0-255,0-255,0-255)\n */\n toRgb() {\n const [r, g, b] = this.getSource();\n return `rgb(${r},${g},${b})`;\n }\n\n /**\n * Returns color representation in RGBA format\n * @return {String} ex: rgba(0-255,0-255,0-255,0-1)\n */\n toRgba() {\n return `rgba(${this.getSource().join(',')})`;\n }\n\n /**\n * Returns color representation in HSL format\n * @return {String} ex: hsl(0-360,0%-100%,0%-100%)\n */\n toHsl() {\n const [h, s, l] = rgb2Hsl(...this.getSource());\n return `hsl(${h},${s}%,${l}%)`;\n }\n\n /**\n * Returns color representation in HSLA format\n * @return {String} ex: hsla(0-360,0%-100%,0%-100%,0-1)\n */\n toHsla() {\n const [h, s, l, a] = rgb2Hsl(...this.getSource());\n return `hsla(${h},${s}%,${l}%,${a})`;\n }\n\n /**\n * Returns color representation in HEX format\n * @return {String} ex: FF5555\n */\n toHex() {\n const fullHex = this.toHexa();\n return fullHex.slice(0, 6);\n }\n\n /**\n * Returns color representation in HEXA format\n * @return {String} ex: FF5555CC\n */\n toHexa() {\n const [r, g, b, a] = this.getSource();\n return `${hexify(r)}${hexify(g)}${hexify(b)}${hexify(Math.round(a * 255))}`;\n }\n\n /**\n * Gets value of alpha channel for this color\n * @return {Number} 0-1\n */\n getAlpha() {\n return this.getSource()[3];\n }\n\n /**\n * Sets value of alpha channel for this color\n * @param {Number} alpha Alpha value 0-1\n * @return {Color} thisArg\n */\n setAlpha(alpha: number) {\n this._source[3] = alpha;\n return this;\n }\n\n /**\n * Transforms color to its grayscale representation\n * @return {Color} thisArg\n */\n toGrayscale() {\n this.setSource(greyAverage(this.getSource()));\n return this;\n }\n\n /**\n * Transforms color to its black and white representation\n * @param {Number} threshold\n * @return {Color} thisArg\n */\n toBlackWhite(threshold: number) {\n const [average, , , a] = greyAverage(this.getSource()),\n bOrW = average < (threshold || 127) ? 0 : 255;\n this.setSource([bOrW, bOrW, bOrW, a]);\n return this;\n }\n\n /**\n * Overlays color with another color\n * @param {String|Color} otherColor\n * @return {Color} thisArg\n */\n overlayWith(otherColor: string | Color) {\n if (!(otherColor instanceof Color)) {\n otherColor = new Color(otherColor);\n }\n\n const source = this.getSource(),\n otherAlpha = 0.5,\n otherSource = otherColor.getSource(),\n [R, G, B] = source.map((value, index) =>\n Math.round(value * (1 - otherAlpha) + otherSource[index] * otherAlpha),\n );\n\n this.setSource([R, G, B, source[3]]);\n return this;\n }\n\n /**\n * Returns new color object, when given a color in RGB format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255)\n * @return {Color}\n */\n static fromRgb(color: string): Color {\n return Color.fromRgba(color);\n }\n\n /**\n * Returns new color object, when given a color in RGBA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromRgba(color: string): Color {\n return new Color(Color.sourceFromRgb(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in RGB or RGBA format\n * @memberOf Color\n * @param {String} color Color value ex: rgb(0-255,0-255,0-255), rgb(0%-100%,0%-100%,0%-100%)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromRgb(color: string): TRGBAColorSource | undefined {\n const match = color.match(reRGBa());\n if (match) {\n const [r, g, b] = match.slice(1, 4).map((value) => {\n const parsedValue = parseFloat(value);\n return value.endsWith('%')\n ? Math.round(parsedValue * 2.55)\n : parsedValue;\n });\n return [r, g, b, fromAlphaToFloat(match[4])];\n }\n }\n\n /**\n * Returns new color object, when given a color in HSL format\n * @param {String} color Color value ex: hsl(0-260,0%-100%,0%-100%)\n * @memberOf Color\n * @return {Color}\n */\n static fromHsl(color: string): Color {\n return Color.fromHsla(color);\n }\n\n /**\n * Returns new color object, when given a color in HSLA format\n * @static\n * @function\n * @memberOf Color\n * @param {String} color\n * @return {Color}\n */\n static fromHsla(color: string): Color {\n return new Color(Color.sourceFromHsl(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HSL or HSLA format.\n * Adapted from https://github.com/mjijackson\n * @memberOf Color\n * @param {String} color Color value ex: hsl(0-360,0%-100%,0%-100%) or hsla(0-360,0%-100%,0%-100%, 0-1)\n * @return {TRGBAColorSource | undefined} source\n * @see http://http://www.w3.org/TR/css3-color/#hsl-color\n */\n static sourceFromHsl(color: string): TRGBAColorSource | undefined {\n const match = color.match(reHSLa());\n if (!match) {\n return;\n }\n const match1degrees = Color.parseAngletoDegrees(match[1]);\n\n const h = (((match1degrees % 360) + 360) % 360) / 360,\n s = parseFloat(match[2]) / 100,\n l = parseFloat(match[3]) / 100;\n let r: number, g: number, b: number;\n\n if (s === 0) {\n r = g = b = l;\n } else {\n const q = l <= 0.5 ? l * (s + 1) : l + s - l * s,\n p = l * 2 - q;\n\n r = hue2rgb(p, q, h + 1 / 3);\n g = hue2rgb(p, q, h);\n b = hue2rgb(p, q, h - 1 / 3);\n }\n\n return [\n Math.round(r * 255),\n Math.round(g * 255),\n Math.round(b * 255),\n fromAlphaToFloat(match[4]),\n ];\n }\n\n /**\n * Returns new color object, when given a color in HEX format\n * @static\n * @memberOf Color\n * @param {String} color Color value ex: FF5555\n * @return {Color}\n */\n static fromHex(color: string): Color {\n return new Color(Color.sourceFromHex(color));\n }\n\n /**\n * Returns array representation (ex: [100, 100, 200, 1]) of a color that's in HEX format\n * @static\n * @memberOf Color\n * @param {String} color ex: FF5555 or FF5544CC (RGBa)\n * @return {TRGBAColorSource | undefined} source\n */\n static sourceFromHex(color: string): TRGBAColorSource | undefined {\n if (color.match(reHex())) {\n const value = color.slice(color.indexOf('#') + 1),\n isShortNotation = value.length <= 4;\n let expandedValue: string[];\n if (isShortNotation) {\n expandedValue = value.split('').map((hex) => hex + hex);\n } else {\n expandedValue = value.match(/.{2}/g)!;\n }\n const [r, g, b, a = 255] = expandedValue.map((hexCouple) =>\n parseInt(hexCouple, 16),\n );\n return [r, g, b, a / 255];\n }\n }\n\n /**\n * Converts a string that could be any angle notation (50deg, 0.5turn, 2rad)\n * into degrees without the 'deg' suffix\n * @static\n * @memberOf Color\n * @param {String} value ex: 0deg, 0.5turn, 2rad\n * @return {Number} number in degrees or NaN if inputs are invalid\n */\n static parseAngletoDegrees(value: string): number {\n const lowercase = value.toLowerCase();\n const numeric = parseFloat(lowercase);\n\n if (lowercase.includes('rad')) {\n return radiansToDegrees(numeric);\n }\n\n if (lowercase.includes('turn')) {\n return numeric * 360;\n }\n\n // Value is probably just a number already in degrees eg '50'\n return numeric;\n }\n}\n","/**\n * A wrapper around Number#toFixed, which contrary to native method returns number, not string.\n * @param {number|string} number number to operate on\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {number}\n */\nexport const toFixed = (number: number | string, fractionDigits: number) =>\n parseFloat(Number(number).toFixed(fractionDigits));\n","import { Color } from '../../color/Color';\nimport { config } from '../../config';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';\nimport type {\n TBBox,\n TMat2D,\n SVGElementName,\n SupportedSVGUnit,\n} from '../../typedefs';\nimport { toFixed } from './toFixed';\n\n/**\n * Returns array of attributes for given svg that fabric parses\n * @param {SVGElementName} type Type of svg element (eg. 'circle')\n * @return {Array} string names of supported attributes\n */\nexport const getSvgAttributes = (type: SVGElementName) => {\n const commonAttributes = ['instantiated_by_use', 'style', 'id', 'class'];\n switch (type) {\n case 'linearGradient':\n return commonAttributes.concat([\n 'x1',\n 'y1',\n 'x2',\n 'y2',\n 'gradientUnits',\n 'gradientTransform',\n ]);\n case 'radialGradient':\n return commonAttributes.concat([\n 'gradientUnits',\n 'gradientTransform',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n 'fr',\n ]);\n case 'stop':\n return commonAttributes.concat(['offset', 'stop-color', 'stop-opacity']);\n }\n return commonAttributes;\n};\n\n/**\n * Converts from attribute value to pixel value if applicable.\n * Returns converted pixels or original value not converted.\n * @param {string} value number to operate on\n * @param {number} fontSize\n * @return {number}\n */\nexport const parseUnit = (value: string, fontSize = DEFAULT_SVG_FONT_SIZE) => {\n const unit = /\\D{0,2}$/.exec(value),\n number = parseFloat(value);\n const dpi = config.DPI;\n switch (unit?.[0] as SupportedSVGUnit) {\n case 'mm':\n return (number * dpi) / 25.4;\n\n case 'cm':\n return (number * dpi) / 2.54;\n\n case 'in':\n return number * dpi;\n\n case 'pt':\n return (number * dpi) / 72; // or * 4 / 3\n\n case 'pc':\n return ((number * dpi) / 72) * 12; // or * 16\n\n case 'em':\n return number * fontSize;\n\n default:\n return number;\n }\n};\n\nexport type MeetOrSlice = 'meet' | 'slice';\n\nexport type MinMidMax = 'Min' | 'Mid' | 'Max' | 'none';\n\nexport type TPreserveArParsed = {\n meetOrSlice: MeetOrSlice;\n alignX: MinMidMax;\n alignY: MinMidMax;\n};\n\n// align can be either none or undefined or a combination of mid/max\nconst parseAlign = (align: string): MinMidMax[] => {\n //divide align in alignX and alignY\n if (align && align !== NONE) {\n return [align.slice(1, 4) as MinMidMax, align.slice(5, 8) as MinMidMax];\n } else if (align === NONE) {\n return [align, align];\n }\n return ['Mid', 'Mid'];\n};\n\n/**\n * Parse preserveAspectRatio attribute from element\n * https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio\n * @param {string} attribute to be parsed\n * @return {Object} an object containing align and meetOrSlice attribute\n */\nexport const parsePreserveAspectRatioAttribute = (\n attribute: string,\n): TPreserveArParsed => {\n const [firstPart, secondPart] = attribute.trim().split(' ') as [\n MinMidMax,\n MeetOrSlice | undefined,\n ];\n const [alignX, alignY] = parseAlign(firstPart);\n return {\n meetOrSlice: secondPart || 'meet',\n alignX,\n alignY,\n };\n};\n\n/**\n * given an array of 6 number returns something like `\"matrix(...numbers)\"`\n * @param {TMat2D} transform an array with 6 numbers\n * @return {String} transform matrix for svg\n */\nexport const matrixToSVG = (transform: TMat2D) =>\n 'matrix(' +\n transform\n .map((value) => toFixed(value, config.NUM_FRACTION_DIGITS))\n .join(' ') +\n ')';\n\n/**\n * Adobe Illustrator (at least CS5) is unable to render rgba()-based fill values\n * we work around it by \"moving\" alpha channel into opacity attribute and setting fill's alpha to 1\n * @param prop\n * @param value\n * @param {boolean} inlineStyle The default is inline style, the separator used is \":\", The other is \"=\"\n * @returns\n */\nexport const colorPropToSVG = (\n prop: string,\n value?: any,\n inlineStyle = true,\n) => {\n let colorValue;\n let opacityValue;\n if (!value) {\n colorValue = 'none';\n } else if (value.toLive) {\n colorValue = `url(#SVGID_${value.id})`;\n } else {\n const color = new Color(value),\n opacity = color.getAlpha();\n\n colorValue = color.toRgb();\n if (opacity !== 1) {\n opacityValue = opacity.toString();\n }\n }\n if (inlineStyle) {\n return `${prop}: ${colorValue}; ${\n opacityValue ? `${prop}-opacity: ${opacityValue}; ` : ''\n }`;\n } else {\n return `${prop}=\"${colorValue}\" ${\n opacityValue ? `${prop}-opacity=\"${opacityValue}\" ` : ''\n }`;\n }\n};\n\nexport const createSVGRect = (\n color: string,\n { left, top, width, height }: TBBox,\n precision = config.NUM_FRACTION_DIGITS,\n) => {\n const svgColor = colorPropToSVG(FILL, color, false);\n const [x, y, w, h] = [left, top, width, height].map((value) =>\n toFixed(value, precision),\n );\n return ``;\n};\n","import type { FabricObject } from '../shapes/Object/Object';\nimport type { TFiller } from '../typedefs';\nimport type { FabricText } from '../shapes/Text/Text';\nimport type { Pattern } from '../Pattern';\nimport type { Path } from '../shapes/Path';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\n\nexport const isFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && (filler as TFiller).toLive !== undefined;\n};\n\nexport const isSerializableFiller = (\n filler: TFiller | string | null,\n): filler is TFiller => {\n return !!filler && typeof (filler as TFiller).toObject === 'function';\n};\n\nexport const isPattern = (filler: TFiller): filler is Pattern => {\n return (\n !!filler && (filler as Pattern).offsetX !== undefined && 'source' in filler\n );\n};\n\nexport const isTextObject = (\n fabricObject?: FabricObject,\n): fabricObject is FabricText => {\n return (\n !!fabricObject &&\n typeof (fabricObject as FabricText)._renderText === 'function'\n );\n};\n\nexport const isPath = (fabricObject?: FabricObject): fabricObject is Path => {\n // we could use instanceof but that would mean pulling in Text code for a simple check\n // @todo discuss what to do and how to do\n return (\n !!fabricObject &&\n typeof (fabricObject as Path)._renderPathCommands === 'function'\n );\n};\n\nexport const isActiveSelection = (\n fabricObject?: FabricObject,\n): fabricObject is ActiveSelection =>\n !!fabricObject && 'multiSelectionStacking' in fabricObject;\n","/**\n * Returns element scroll offsets\n * @param {HTMLElement} element Element to operate on\n * @return {Object} Object with left/top values\n */\nexport function getScrollLeftTop(element: HTMLElement | null) {\n const doc = element && getDocumentFromElement(element);\n let left = 0,\n top = 0;\n if (!element || !doc) {\n return { left, top };\n }\n let elementLoop: HTMLElement | Document | ShadowRoot = element;\n const docElement = doc.documentElement,\n body = doc.body || {\n scrollLeft: 0,\n scrollTop: 0,\n };\n // While loop checks (and then sets element to) .parentNode OR .host\n // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,\n // but the .parentNode of a root ShadowDOM node will always be null, instead\n // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938\n while (\n elementLoop &&\n (elementLoop.parentNode || (elementLoop as unknown as ShadowRoot).host)\n ) {\n elementLoop = (elementLoop.parentNode ||\n (elementLoop as unknown as ShadowRoot).host) as\n | HTMLElement\n | Document\n | ShadowRoot;\n if (elementLoop === doc) {\n left = body.scrollLeft || docElement.scrollLeft || 0;\n top = body.scrollTop || docElement.scrollTop || 0;\n } else {\n left += (elementLoop as HTMLElement).scrollLeft || 0;\n top += (elementLoop as HTMLElement).scrollTop || 0;\n }\n\n if (\n elementLoop.nodeType === 1 &&\n (elementLoop as HTMLElement).style.position === 'fixed'\n ) {\n break;\n }\n }\n\n return { left, top };\n}\n\nexport const getDocumentFromElement = (el: HTMLElement) =>\n el.ownerDocument || null;\n\nexport const getWindowFromElement = (el: HTMLElement) =>\n el.ownerDocument?.defaultView || null;\n","import { NONE } from '../../constants';\nimport type { TSize } from '../../typedefs';\nimport {\n getDocumentFromElement,\n getWindowFromElement,\n getScrollLeftTop,\n} from '../../util/dom_misc';\n\nexport const setCanvasDimensions = (\n el: HTMLCanvasElement,\n ctx: CanvasRenderingContext2D,\n { width, height }: TSize,\n retinaScaling = 1,\n) => {\n el.width = width;\n el.height = height;\n if (retinaScaling > 1) {\n el.setAttribute('width', (width * retinaScaling).toString());\n el.setAttribute('height', (height * retinaScaling).toString());\n ctx.scale(retinaScaling, retinaScaling);\n }\n};\n\nexport type CSSDimensions = {\n width: number | string;\n height: number | string;\n};\n\nexport const setCSSDimensions = (\n el: HTMLElement,\n { width, height }: Partial,\n) => {\n width && (el.style.width = typeof width === 'number' ? `${width}px` : width);\n height &&\n (el.style.height = typeof height === 'number' ? `${height}px` : height);\n};\n\n/**\n * Returns offset for a given element\n * @param {HTMLElement} element Element to get offset for\n * @return {Object} Object with \"left\" and \"top\" properties\n */\nexport function getElementOffset(element: HTMLElement) {\n const doc = element && getDocumentFromElement(element),\n offset = { left: 0, top: 0 };\n\n if (!doc) {\n return offset;\n }\n const elemStyle: CSSStyleDeclaration =\n getWindowFromElement(element)?.getComputedStyle(element, null) ||\n ({} as CSSStyleDeclaration);\n offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;\n offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;\n offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;\n offset.top += parseInt(elemStyle.paddingTop, 10) || 0;\n\n let box = { left: 0, top: 0 };\n\n const docElem = doc.documentElement;\n if (typeof element.getBoundingClientRect !== 'undefined') {\n box = element.getBoundingClientRect();\n }\n\n const scrollLeftTop = getScrollLeftTop(element);\n\n return {\n left:\n box.left + scrollLeftTop.left - (docElem.clientLeft || 0) + offset.left,\n top: box.top + scrollLeftTop.top - (docElem.clientTop || 0) + offset.top,\n };\n}\n\n/**\n * Makes element unselectable\n * @param {HTMLElement} element Element to make unselectable\n * @return {HTMLElement} Element that was passed in\n */\nexport function makeElementUnselectable(element: HTMLElement) {\n if (typeof element.onselectstart !== 'undefined') {\n element.onselectstart = () => false;\n }\n element.style.userSelect = NONE;\n return element;\n}\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport type { CSSDimensions } from './util';\nimport { setCSSDimensions, getElementOffset } from './util';\nimport { createCanvasElement, isHTMLCanvas } from '../../util/misc/dom';\nimport { setCanvasDimensions } from './util';\nimport { FabricError } from '../../util/internals/console';\n\nexport type CanvasItem = {\n el: HTMLCanvasElement;\n ctx: CanvasRenderingContext2D;\n};\n\nexport class StaticCanvasDOMManager {\n /**\n * Keeps a copy of the canvas style before setting retina scaling and other potions\n * in order to return it to original state on dispose\n * @type string\n */\n private _originalCanvasStyle?: string;\n\n lower: CanvasItem;\n\n constructor(arg0?: string | HTMLCanvasElement) {\n const el = this.createLowerCanvas(arg0);\n this.lower = { el, ctx: el.getContext('2d')! };\n }\n\n protected createLowerCanvas(arg0?: HTMLCanvasElement | string) {\n // canvasEl === 'HTMLCanvasElement' does not work on jsdom/node\n const el = isHTMLCanvas(arg0)\n ? arg0\n : (arg0 &&\n (getFabricDocument().getElementById(arg0) as HTMLCanvasElement)) ||\n createCanvasElement();\n if (el.hasAttribute('data-fabric')) {\n throw new FabricError(\n 'Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?',\n );\n }\n this._originalCanvasStyle = el.style.cssText;\n el.setAttribute('data-fabric', 'main');\n el.classList.add('lower-canvas');\n return el;\n }\n\n cleanupDOM({ width, height }: TSize) {\n const { el } = this.lower;\n // restore canvas style and attributes\n el.classList.remove('lower-canvas');\n el.removeAttribute('data-fabric');\n // restore canvas size to original size in case retina scaling was applied\n el.setAttribute('width', `${width}`);\n el.setAttribute('height', `${height}`);\n el.style.cssText = this._originalCanvasStyle || '';\n this._originalCanvasStyle = undefined;\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n const { el, ctx } = this.lower;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial) {\n setCSSDimensions(this.lower.el, size);\n }\n\n /**\n * Calculates canvas element offset relative to the document\n */\n calcOffset() {\n return getElementOffset(this.lower.el);\n }\n\n dispose() {\n getEnv().dispose(this.lower.el);\n // @ts-expect-error disposing\n delete this.lower;\n }\n}\n","import { iMatrix } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TFiller, TMat2D, TOptions } from '../typedefs';\n\ninterface CanvasDrawableOptions {\n /**\n * if set to false background image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n backgroundVpt: boolean;\n\n /**\n * Background color of canvas instance.\n * @type {(String|TFiller)}\n * @default\n */\n backgroundColor: TFiller | string;\n\n /**\n * Background image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as background, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n backgroundImage?: FabricObject;\n\n /**\n * if set to false overlay image is not affected by viewport transform\n * @since 1.6.3\n * @type Boolean\n * @todo we should really find a different way to do this\n * @default\n */\n overlayVpt: boolean;\n\n /**\n * Overlay color of canvas instance.\n * @since 1.3.9\n * @type {(String|TFiller)}\n * @default\n */\n overlayColor: TFiller | string;\n\n /**\n * Overlay image of canvas instance.\n * since 2.4.0 image caching is active, please when putting an image as overlay, add to the\n * canvas property a reference to the canvas it is on. Otherwise the image cannot detect the zoom\n * vale. As an alternative you can disable image objectCaching\n * @type FabricObject\n * @default\n */\n overlayImage?: FabricObject;\n}\n\ninterface CanvasRenderingOptions {\n /**\n * Indicates whether {@link StaticCanvas#add}, {@link StaticCanvas#insertAt} and {@link StaticCanvas#remove},\n * {@link StaticCanvas#moveTo}, {@link StaticCanvas#clear} and many more, should also re-render canvas.\n * Disabling this option will not give a performance boost when adding/removing a lot of objects to/from canvas at once\n * since the renders are queued and executed one per frame.\n * Disabling is suggested anyway and managing the renders of the app manually is not a big effort ( canvas.requestRenderAll() )\n * Left default to true to do not break documentation and old app, fiddles.\n * @type Boolean\n * @default\n */\n renderOnAddRemove: boolean;\n\n /**\n * Based on vptCoords and object.aCoords, skip rendering of objects that\n * are not included in current viewport.\n * May greatly help in applications with crowded canvas and use of zoom/pan\n * If One of the corner of the bounding box of the object is on the canvas\n * the objects get rendered.\n * @type Boolean\n * @default true\n */\n skipOffscreen: boolean;\n\n /**\n * When true, canvas is scaled by devicePixelRatio for better rendering on retina screens\n * @type Boolean\n * @default\n */\n enableRetinaScaling: boolean;\n\n /**\n * Indicates whether this canvas will use image smoothing, this is on by default in browsers\n * @type Boolean\n * @default\n */\n imageSmoothingEnabled: boolean;\n\n /**\n * a fabricObject that, without stroke define a clipping area with their shape. filled in black\n * the clipPath object gets used when the canvas has rendered, and the context is placed in the\n * top left corner of the canvas.\n * clipPath will clip away controls, if you do not want this to happen use controlsAboveOverlay = true\n * @type FabricObject\n */\n clipPath?: FabricObject;\n}\n\nexport interface CanvasExportOptions {\n /**\n * Indicates whether toObject/toDatalessObject should include default values\n * if set to false, takes precedence over the object value.\n * @type Boolean\n * @default\n */\n includeDefaultValues: boolean;\n\n /**\n * When true, getSvgTransform() will apply the StaticCanvas.viewportTransform to the SVG transformation. When true,\n * a zoomed canvas will then produce zoomed SVG output.\n * @type Boolean\n * @default\n */\n svgViewportTransformation: boolean;\n}\n\nexport interface StaticCanvasOptions\n extends CanvasDrawableOptions,\n CanvasRenderingOptions,\n CanvasExportOptions {\n /**\n * Width in virtual/logical pixels of the canvas.\n * The canvas can be larger than width if retina scaling is active\n * @type number\n */\n width: number;\n\n /**\n * Height in virtual/logical pixels of the canvas.\n * The canvas can be taller than width if retina scaling is active\n * @type height\n */\n height: number;\n\n /**\n * Indicates whether object controls (borders/controls) are rendered above overlay image\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n controlsAboveOverlay: boolean;\n\n /**\n * Indicates whether the browser can be scrolled when using a touchscreen and dragging on the canvas\n * @type Boolean\n * @default\n *\n * @todo move to Canvas\n */\n allowTouchScrolling: boolean;\n\n /**\n * The transformation (a Canvas 2D API transform matrix) which focuses the viewport\n * @type Array\n * @example Default transform\n * canvas.viewportTransform = [1, 0, 0, 1, 0, 0];\n * @example Scale by 70% and translate toward bottom-right by 50, without skewing\n * canvas.viewportTransform = [0.7, 0, 0, 0.7, 50, 50];\n * @default\n */\n viewportTransform: TMat2D;\n}\n\nexport const staticCanvasDefaults: TOptions = {\n backgroundVpt: true,\n backgroundColor: '',\n overlayVpt: true,\n overlayColor: '',\n\n includeDefaultValues: true,\n svgViewportTransformation: true,\n\n renderOnAddRemove: true,\n skipOffscreen: true,\n enableRetinaScaling: true,\n imageSmoothingEnabled: true,\n\n /**\n * @todo move to Canvas\n */\n controlsAboveOverlay: false,\n /**\n * @todo move to Canvas\n */\n allowTouchScrolling: false,\n\n viewportTransform: [...iMatrix],\n};\n","import { config } from '../config';\nimport { CENTER, VERSION } from '../constants';\nimport type { CanvasEvents, StaticCanvasEvents } from '../EventTypeDefs';\nimport type { Gradient } from '../gradient/Gradient';\nimport { createCollectionMixin, isCollection } from '../Collection';\nimport { CommonMethods } from '../CommonMethods';\nimport type { Pattern } from '../Pattern';\nimport { Point } from '../Point';\nimport type { TCachedFabricObject } from '../shapes/Object/Object';\nimport type {\n Abortable,\n Constructor,\n TCornerPoint,\n TDataUrlOptions,\n TFiller,\n TMat2D,\n TSize,\n TSVGReviver,\n TToCanvasElementOptions,\n TValidToObjectMethod,\n TOptions,\n} from '../typedefs';\nimport {\n cancelAnimFrame,\n requestAnimFrame,\n} from '../util/animation/AnimationFrameProvider';\nimport { runningAnimations } from '../util/animation/AnimationRegistry';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement, toDataURL } from '../util/misc/dom';\nimport { invertTransform, transformPoint } from '../util/misc/matrix';\nimport type { EnlivenObjectOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { toFixed } from '../util/misc/toFixed';\nimport { isFiller, isPattern, isTextObject } from '../util/typeAssertions';\nimport { StaticCanvasDOMManager } from './DOMManagers/StaticCanvasDOMManager';\nimport type { CSSDimensions } from './DOMManagers/util';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\nimport { staticCanvasDefaults } from './StaticCanvasOptions';\nimport { log, FabricError } from '../util/internals/console';\nimport { getDevicePixelRatio } from '../env';\n\n/**\n * Having both options in TCanvasSizeOptions set to true transform the call in a calcOffset\n * Better try to restrict with types to avoid confusion.\n */\nexport type TCanvasSizeOptions =\n | {\n backstoreOnly?: true;\n cssOnly?: false;\n }\n | {\n backstoreOnly?: false;\n cssOnly?: true;\n };\n\nexport type TSVGExportOptions = {\n suppressPreamble?: boolean;\n viewBox?: {\n x: number;\n y: number;\n width: number;\n height: number;\n };\n encoding?: 'UTF-8'; // test Encoding type and see what happens\n width?: string;\n height?: string;\n reviver?: TSVGReviver;\n};\n\n/**\n * Static canvas class\n * @see {@link http://fabricjs.com/static_canvas|StaticCanvas demo}\n * @fires before:render\n * @fires after:render\n * @fires canvas:cleared\n * @fires object:added\n * @fires object:removed\n */\n// TODO: fix `EventSpec` inheritance https://github.com/microsoft/TypeScript/issues/26154#issuecomment-1366616260\nexport class StaticCanvas<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends StaticCanvasEvents = StaticCanvasEvents,\n >\n extends createCollectionMixin(CommonMethods)\n implements StaticCanvasOptions\n{\n declare width: number;\n declare height: number;\n\n // background\n declare backgroundVpt: boolean;\n declare backgroundColor: TFiller | string;\n declare backgroundImage?: FabricObject;\n // overlay\n declare overlayVpt: boolean;\n declare overlayColor: TFiller | string;\n declare overlayImage?: FabricObject;\n\n declare clipPath?: FabricObject;\n\n declare includeDefaultValues: boolean;\n\n // rendering config\n declare renderOnAddRemove: boolean;\n declare skipOffscreen: boolean;\n declare enableRetinaScaling: boolean;\n declare imageSmoothingEnabled: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare controlsAboveOverlay: boolean;\n\n /**\n * @todo move to Canvas\n */\n declare allowTouchScrolling: boolean;\n\n declare viewportTransform: TMat2D;\n\n /**\n * The viewport bounding box in scene plane coordinates, see {@link calcViewportBoundaries}\n */\n declare vptCoords: TCornerPoint;\n\n /**\n * A reference to the canvas actual HTMLCanvasElement.\n * Can be use to read the raw pixels, but never write or manipulate\n * @type HTMLCanvasElement\n */\n get lowerCanvasEl() {\n return this.elements.lower?.el;\n }\n\n get contextContainer() {\n return this.elements.lower?.ctx;\n }\n\n /**\n * If true the Canvas is in the process or has been disposed/destroyed.\n * No more rendering operation will be executed on this canvas.\n * @type boolean\n */\n declare destroyed?: boolean;\n\n /**\n * Started the process of disposing but not done yet.\n * WIll likely complete the render cycle already scheduled but stopping adding more.\n * @type boolean\n */\n declare disposed?: boolean;\n\n declare _offset: { left: number; top: number };\n protected declare hasLostContext: boolean;\n protected declare nextRenderHandle: number;\n\n declare elements: StaticCanvasDOMManager;\n\n /**\n * When true control drawing is skipped.\n * This boolean is used to avoid toDataURL to export controls.\n * Usage of this boolean to build up other flows and features is not supported\n * @type Boolean\n * @default false\n */\n protected declare skipControlsDrawing: boolean;\n\n static ownDefaults = staticCanvasDefaults;\n\n // reference to\n protected declare __cleanupTask?: {\n (): void;\n kill: (reason?: any) => void;\n };\n\n static getDefaults(): Record {\n return StaticCanvas.ownDefaults;\n }\n\n constructor(\n el?: string | HTMLCanvasElement,\n options: TOptions = {},\n ) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof StaticCanvas).getDefaults(),\n );\n this.set(options);\n this.initElements(el);\n this._setDimensionsImpl({\n width: this.width || this.elements.lower.el.width || 0,\n height: this.height || this.elements.lower.el.height || 0,\n });\n this.skipControlsDrawing = false;\n this.viewportTransform = [...this.viewportTransform];\n this.calcViewportBoundaries();\n }\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new StaticCanvasDOMManager(el);\n }\n\n add(...objects: FabricObject[]) {\n const size = super.add(...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n insertAt(index: number, ...objects: FabricObject[]) {\n const size = super.insertAt(index, ...objects);\n objects.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return size;\n }\n\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n removed.length > 0 && this.renderOnAddRemove && this.requestRenderAll();\n return removed;\n }\n\n _onObjectAdded(obj: FabricObject) {\n if (obj.canvas && (obj.canvas as StaticCanvas) !== this) {\n log(\n 'warn',\n 'Canvas is trying to add an object that belongs to a different canvas.\\n' +\n 'Resulting to default behavior: removing object from previous canvas and adding to new canvas',\n );\n obj.canvas.remove(obj);\n }\n obj._set('canvas', this);\n obj.setCoords();\n this.fire('object:added', { target: obj });\n obj.fire('added', { target: this });\n }\n\n _onObjectRemoved(obj: FabricObject) {\n obj._set('canvas', undefined);\n this.fire('object:removed', { target: obj });\n obj.fire('removed', { target: this });\n }\n\n _onStackOrderChanged() {\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * @private\n * @see https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/HTML-canvas-guide/SettingUptheCanvas/SettingUptheCanvas.html\n * @return {Number} retinaScaling if applied, otherwise 1;\n */\n getRetinaScaling() {\n return this.enableRetinaScaling ? getDevicePixelRatio() : 1;\n }\n\n /**\n * Calculates canvas element offset relative to the document\n * This method is also attached as \"resize\" event handler of window\n */\n calcOffset() {\n return (this._offset = this.elements.calcOffset());\n }\n\n /**\n * Returns canvas width (in px)\n * @return {Number}\n */\n getWidth(): number {\n return this.width;\n }\n\n /**\n * Returns canvas height (in px)\n * @return {Number}\n */\n getHeight(): number {\n return this.height;\n }\n\n /**\n * Sets width of this canvas instance\n * @param {Number|String} value Value to set width to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setWidth(\n value: TSize['width'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setWidth(\n value: CSSDimensions['width'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setWidth(value: number, options?: never) {\n return this.setDimensions({ width: value }, options);\n }\n\n /**s\n * Sets height of this canvas instance\n * @param {Number|String} value Value to set height to\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n * @deprecated will be removed in 7.0\n */\n setHeight(\n value: TSize['height'],\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setHeight(\n value: CSSDimensions['height'],\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setHeight(value: CSSDimensions['height'], options?: never) {\n return this.setDimensions({ height: value }, options);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: Partial,\n { cssOnly = false, backstoreOnly = false }: TCanvasSizeOptions = {},\n ) {\n if (!cssOnly) {\n const size = {\n width: this.width,\n height: this.height,\n ...(dimensions as Partial),\n };\n this.elements.setDimensions(size, this.getRetinaScaling());\n this.hasLostContext = true;\n this.width = size.width;\n this.height = size.height;\n }\n if (!backstoreOnly) {\n this.elements.setCSSDimensions(dimensions);\n }\n\n this.calcOffset();\n }\n\n /**\n * Sets dimensions (width, height) of this canvas instance. when options.cssOnly flag active you should also supply the unit of measure (px/%/em)\n * @param {Object} dimensions Object with width/height properties\n * @param {Number|String} [dimensions.width] Width of canvas element\n * @param {Number|String} [dimensions.height] Height of canvas element\n * @param {Object} [options] Options object\n * @param {Boolean} [options.backstoreOnly=false] Set the given dimensions only as canvas backstore dimensions\n * @param {Boolean} [options.cssOnly=false] Set the given dimensions only as css dimensions\n */\n setDimensions(\n dimensions: Partial,\n options?: { cssOnly?: true; backstoreOnly?: false },\n ): void;\n setDimensions(\n dimensions: Partial,\n options?: { backstoreOnly?: true; cssOnly?: false },\n ): void;\n setDimensions(dimensions: Partial, options?: never): void;\n setDimensions(\n dimensions: Partial,\n options?: TCanvasSizeOptions,\n ) {\n this._setDimensionsImpl(dimensions, options);\n if (!options || !options.cssOnly) {\n this.requestRenderAll();\n }\n }\n\n /**\n * Returns canvas zoom level\n * @return {Number}\n */\n getZoom() {\n return this.viewportTransform[0];\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n this.viewportTransform = vpt;\n this.calcViewportBoundaries();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Sets zoom level of this canvas instance, the zoom centered around point\n * meaning that following zoom to point with the same point will have the visual\n * effect of the zoom originating from that point. The point won't move.\n * It has nothing to do with canvas center or visual center of the viewport.\n * @param {Point} point to zoom with respect to\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n zoomToPoint(point: Point, value: number) {\n // TODO: just change the scale, preserve other transformations\n const before = point,\n vpt: TMat2D = [...this.viewportTransform];\n const newPoint = transformPoint(point, invertTransform(vpt));\n vpt[0] = value;\n vpt[3] = value;\n const after = transformPoint(newPoint, vpt);\n vpt[4] += before.x - after.x;\n vpt[5] += before.y - after.y;\n this.setViewportTransform(vpt);\n }\n\n /**\n * Sets zoom level of this canvas instance\n * @param {Number} value to set zoom to, less than 1 zooms out\n */\n setZoom(value: number) {\n this.zoomToPoint(new Point(0, 0), value);\n }\n\n /**\n * Pan viewport so as to place point at top left corner of canvas\n * @param {Point} point to move to\n */\n absolutePan(point: Point) {\n const vpt: TMat2D = [...this.viewportTransform];\n vpt[4] = -point.x;\n vpt[5] = -point.y;\n return this.setViewportTransform(vpt);\n }\n\n /**\n * Pans viewpoint relatively\n * @param {Point} point (position vector) to move by\n */\n relativePan(point: Point) {\n return this.absolutePan(\n new Point(\n -point.x - this.viewportTransform[4],\n -point.y - this.viewportTransform[5],\n ),\n );\n }\n\n /**\n * Returns <canvas> element corresponding to this instance\n * @return {HTMLCanvasElement}\n */\n getElement(): HTMLCanvasElement {\n return this.elements.lower.el;\n }\n\n /**\n * Clears specified context of canvas element\n * @param {CanvasRenderingContext2D} ctx Context to clear\n */\n clearContext(ctx: CanvasRenderingContext2D) {\n ctx.clearRect(0, 0, this.width, this.height);\n }\n\n /**\n * Returns context of canvas where objects are drawn\n * @return {CanvasRenderingContext2D}\n */\n getContext(): CanvasRenderingContext2D {\n return this.elements.lower.ctx;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n this.remove(...this.getObjects());\n this.backgroundImage = undefined;\n this.overlayImage = undefined;\n this.backgroundColor = '';\n this.overlayColor = '';\n this.clearContext(this.getContext());\n this.fire('canvas:cleared');\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Renders the canvas\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n this.renderCanvas(this.getContext(), this._objects);\n }\n\n /**\n * Function created to be instance bound at initialization\n * used in requestAnimationFrame rendering\n * Let the fabricJS call it. If you call it manually you could have more\n * animationFrame stacking on to of each other\n * for an imperative rendering, use canvas.renderAll\n * @private\n */\n renderAndReset() {\n this.nextRenderHandle = 0;\n this.renderAll();\n }\n\n /**\n * Append a renderAll request to next animation frame.\n * unless one is already in progress, in that case nothing is done\n * a boolean flag will avoid appending more.\n */\n requestRenderAll() {\n if (!this.nextRenderHandle && !this.disposed && !this.destroyed) {\n this.nextRenderHandle = requestAnimFrame(() => this.renderAndReset());\n }\n }\n\n /**\n * Calculate the position of the 4 corner of canvas with current viewportTransform.\n * helps to determinate when an object is in the current rendering viewport\n */\n calcViewportBoundaries(): TCornerPoint {\n const width = this.width,\n height = this.height,\n iVpt = invertTransform(this.viewportTransform),\n a = transformPoint({ x: 0, y: 0 }, iVpt),\n b = transformPoint({ x: width, y: height }, iVpt),\n // we don't support vpt flipping\n // but the code is robust enough to mostly work with flipping\n min = a.min(b),\n max = a.max(b);\n return (this.vptCoords = {\n tl: min,\n tr: new Point(max.x, min.y),\n bl: new Point(min.x, max.y),\n br: max,\n });\n }\n\n cancelRequestedRender() {\n if (this.nextRenderHandle) {\n cancelAnimFrame(this.nextRenderHandle);\n this.nextRenderHandle = 0;\n }\n }\n\n drawControls(_ctx: CanvasRenderingContext2D) {\n // Static canvas has no controls\n }\n\n /**\n * Renders background, objects, overlay and controls.\n * @param {CanvasRenderingContext2D} ctx\n * @param {Array} objects to render\n */\n renderCanvas(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n if (this.destroyed) {\n return;\n }\n\n const v = this.viewportTransform,\n path = this.clipPath;\n this.calcViewportBoundaries();\n this.clearContext(ctx);\n ctx.imageSmoothingEnabled = this.imageSmoothingEnabled;\n // @ts-expect-error node-canvas stuff\n ctx.patternQuality = 'best';\n this.fire('before:render', { ctx });\n this._renderBackground(ctx);\n\n ctx.save();\n //apply viewport transform once for all rendering process\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this._renderObjects(ctx, objects);\n ctx.restore();\n if (!this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n if (path) {\n path._set('canvas', this);\n // needed to setup a couple of variables\n path.shouldCache();\n path._transformDone = true;\n path.renderCache({ forClipping: true });\n this.drawClipPathOnCanvas(ctx, path as TCachedFabricObject);\n }\n this._renderOverlay(ctx);\n if (this.controlsAboveOverlay && !this.skipControlsDrawing) {\n this.drawControls(ctx);\n }\n this.fire('after:render', { ctx });\n\n if (this.__cleanupTask) {\n this.__cleanupTask();\n this.__cleanupTask = undefined;\n }\n }\n\n /**\n * Paint the cached clipPath on the lowerCanvasEl\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawClipPathOnCanvas(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n const v = this.viewportTransform;\n ctx.save();\n ctx.transform(...v);\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4;\n ctx.globalCompositeOperation = 'destination-in';\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} objects to render\n */\n _renderObjects(ctx: CanvasRenderingContext2D, objects: FabricObject[]) {\n for (let i = 0, len = objects.length; i < len; ++i) {\n objects[i] && objects[i].render(ctx);\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {string} property 'background' or 'overlay'\n */\n _renderBackgroundOrOverlay(\n ctx: CanvasRenderingContext2D,\n property: 'background' | 'overlay',\n ) {\n const fill = this[`${property}Color`],\n object = this[`${property}Image`],\n v = this.viewportTransform,\n needsVpt = this[`${property}Vpt`];\n if (!fill && !object) {\n return;\n }\n const isAFiller = isFiller(fill);\n if (fill) {\n ctx.save();\n ctx.beginPath();\n ctx.moveTo(0, 0);\n ctx.lineTo(this.width, 0);\n ctx.lineTo(this.width, this.height);\n ctx.lineTo(0, this.height);\n ctx.closePath();\n ctx.fillStyle = isAFiller ? fill.toLive(ctx /* this */)! : fill;\n if (needsVpt) {\n ctx.transform(...v);\n }\n if (isAFiller) {\n ctx.transform(1, 0, 0, 1, fill.offsetX || 0, fill.offsetY || 0);\n const m = ((fill as Gradient<'linear'>).gradientTransform ||\n (fill as Pattern).patternTransform) as TMat2D;\n m && ctx.transform(...m);\n }\n ctx.fill();\n ctx.restore();\n }\n if (object) {\n ctx.save();\n const { skipOffscreen } = this;\n // if the object doesn't move with the viewport,\n // the offscreen concept does not apply;\n this.skipOffscreen = needsVpt;\n if (needsVpt) {\n ctx.transform(...v);\n }\n object.render(ctx);\n this.skipOffscreen = skipOffscreen;\n ctx.restore();\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'background');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderOverlay(ctx: CanvasRenderingContext2D) {\n this._renderBackgroundOrOverlay(ctx, 'overlay');\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * Returned value is an object with top and left properties\n * @return {Object} object with \"top\" and \"left\" number values\n * @deprecated migrate to `getCenterPoint`\n */\n getCenter() {\n return {\n top: this.height / 2,\n left: this.width / 2,\n };\n }\n\n /**\n * Returns coordinates of a center of canvas.\n * @return {Point}\n */\n getCenterPoint() {\n return new Point(this.width / 2, this.height / 2);\n }\n\n /**\n * Centers object horizontally in the canvas\n */\n centerObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getCenterPoint().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically in the canvas\n * @param {FabricObject} object Object to center vertically\n */\n centerObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object vertically and horizontally in the canvas\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n centerObject(object: FabricObject) {\n return this._centerObject(object, this.getCenterPoint());\n }\n\n /**\n * Centers object vertically and horizontally in the viewport\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObject(object: FabricObject) {\n return this._centerObject(object, this.getVpCenter());\n }\n\n /**\n * Centers object horizontally in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectH(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(this.getVpCenter().x, object.getCenterPoint().y),\n );\n }\n\n /**\n * Centers object Vertically in the viewport, object.top is unchanged\n * @param {FabricObject} object Object to center vertically and horizontally\n */\n viewportCenterObjectV(object: FabricObject) {\n return this._centerObject(\n object,\n new Point(object.getCenterPoint().x, this.getVpCenter().y),\n );\n }\n\n /**\n * Calculate the point in canvas that correspond to the center of actual viewport.\n * @return {Point} vpCenter, viewport center\n */\n getVpCenter(): Point {\n return transformPoint(\n this.getCenterPoint(),\n invertTransform(this.viewportTransform),\n );\n }\n\n /**\n * @private\n * @param {FabricObject} object Object to center\n * @param {Point} center Center point\n */\n _centerObject(object: FabricObject, center: Point) {\n object.setXY(center, CENTER, CENTER);\n object.setCoords();\n this.renderOnAddRemove && this.requestRenderAll();\n }\n\n /**\n * Returns dataless JSON representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {String} json string\n */\n toDatalessJSON(propertiesToInclude?: string[]) {\n return this.toDatalessObject(propertiesToInclude);\n }\n\n /**\n * Returns object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toObject', propertiesToInclude);\n }\n\n /**\n * Returns Object representation of canvas\n * this alias is provided because if you call JSON.stringify on an instance,\n * the toJSON object will be invoked if it exists.\n * Having a toJSON method means you can do JSON.stringify(myCanvas)\n * @return {Object} JSON compatible object\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/pec86/|jsFiddle demo}\n * @example JSON without additional properties\n * var json = canvas.toJSON();\n * @example JSON with additional properties included\n * var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);\n * @example JSON without default values\n * var json = canvas.toJSON();\n */\n toJSON() {\n return this.toObject();\n }\n\n /**\n * Returns dataless object representation of canvas\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: string[]) {\n return this._toObjectMethod('toDatalessObject', propertiesToInclude);\n }\n\n /**\n * @private\n */\n _toObjectMethod(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const clipPath = this.clipPath;\n const clipPathData =\n clipPath && !clipPath.excludeFromExport\n ? this._toObject(clipPath, methodName, propertiesToInclude)\n : null;\n return {\n version: VERSION,\n ...pick(this, propertiesToInclude as (keyof this)[]),\n objects: this._objects\n .filter((object) => !object.excludeFromExport)\n .map((instance) =>\n this._toObject(instance, methodName, propertiesToInclude),\n ),\n ...this.__serializeBgOverlay(methodName, propertiesToInclude),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n let originalValue;\n\n if (!this.includeDefaultValues) {\n originalValue = instance.includeDefaultValues;\n instance.includeDefaultValues = false;\n }\n\n const object = instance[methodName](propertiesToInclude);\n if (!this.includeDefaultValues) {\n instance.includeDefaultValues = !!originalValue;\n }\n return object;\n }\n\n /**\n * @private\n */\n __serializeBgOverlay(\n methodName: TValidToObjectMethod,\n propertiesToInclude?: string[],\n ) {\n const data: any = {},\n bgImage = this.backgroundImage,\n overlayImage = this.overlayImage,\n bgColor = this.backgroundColor,\n overlayColor = this.overlayColor;\n\n if (isFiller(bgColor)) {\n if (!bgColor.excludeFromExport) {\n data.background = bgColor.toObject(propertiesToInclude);\n }\n } else if (bgColor) {\n data.background = bgColor;\n }\n\n if (isFiller(overlayColor)) {\n if (!overlayColor.excludeFromExport) {\n data.overlay = overlayColor.toObject(propertiesToInclude);\n }\n } else if (overlayColor) {\n data.overlay = overlayColor;\n }\n\n if (bgImage && !bgImage.excludeFromExport) {\n data.backgroundImage = this._toObject(\n bgImage,\n methodName,\n propertiesToInclude,\n );\n }\n if (overlayImage && !overlayImage.excludeFromExport) {\n data.overlayImage = this._toObject(\n overlayImage,\n methodName,\n propertiesToInclude,\n );\n }\n\n return data;\n }\n\n /* _TO_SVG_START_ */\n\n declare svgViewportTransformation: boolean;\n\n /**\n * Returns SVG representation of canvas\n * @function\n * @param {Object} [options] Options object for SVG output\n * @param {Boolean} [options.suppressPreamble=false] If true xml tag is not included\n * @param {Object} [options.viewBox] SVG viewbox object\n * @param {Number} [options.viewBox.x] x-coordinate of viewbox\n * @param {Number} [options.viewBox.y] y-coordinate of viewbox\n * @param {Number} [options.viewBox.width] Width of viewbox\n * @param {Number} [options.viewBox.height] Height of viewbox\n * @param {String} [options.encoding=UTF-8] Encoding of SVG output\n * @param {String} [options.width] desired width of svg with or without units\n * @param {String} [options.height] desired height of svg with or without units\n * @param {Function} [reviver] Method for further parsing of svg elements, called after each fabric object converted into svg representation.\n * @return {String} SVG string\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#serialization}\n * @see {@link http://jsfiddle.net/fabricjs/jQ3ZZ/|jsFiddle demo}\n * @example Normal SVG output\n * var svg = canvas.toSVG();\n * @example SVG output without preamble (without <?xml ../>)\n * var svg = canvas.toSVG({suppressPreamble: true});\n * @example SVG output with viewBox attribute\n * var svg = canvas.toSVG({\n * viewBox: {\n * x: 100,\n * y: 100,\n * width: 200,\n * height: 300\n * }\n * });\n * @example SVG output with different encoding (default: UTF-8)\n * var svg = canvas.toSVG({encoding: 'ISO-8859-1'});\n * @example Modify SVG output with reviver function\n * var svg = canvas.toSVG(null, function(svg) {\n * return svg.replace('stroke-dasharray: ; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; ', '');\n * });\n */\n toSVG(options: TSVGExportOptions = {}, reviver?: TSVGReviver) {\n options.reviver = reviver;\n const markup: string[] = [];\n\n this._setSVGPreamble(markup, options);\n this._setSVGHeader(markup, options);\n if (this.clipPath) {\n markup.push(`\\n`);\n }\n this._setSVGBgOverlayColor(markup, 'background');\n this._setSVGBgOverlayImage(markup, 'backgroundImage', reviver);\n this._setSVGObjects(markup, reviver);\n if (this.clipPath) {\n markup.push('\\n');\n }\n this._setSVGBgOverlayColor(markup, 'overlay');\n this._setSVGBgOverlayImage(markup, 'overlayImage', reviver);\n\n markup.push('');\n\n return markup.join('');\n }\n\n /**\n * @private\n */\n _setSVGPreamble(markup: string[], options: TSVGExportOptions): void {\n if (options.suppressPreamble) {\n return;\n }\n markup.push(\n '\\n',\n '\\n',\n );\n }\n\n /**\n * @private\n */\n _setSVGHeader(markup: string[], options: TSVGExportOptions): void {\n const width = options.width || `${this.width}`,\n height = options.height || `${this.height}`,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS,\n optViewBox = options.viewBox;\n let viewBox: string;\n if (optViewBox) {\n viewBox = `viewBox=\"${optViewBox.x} ${optViewBox.y} ${optViewBox.width} ${optViewBox.height}\" `;\n } else if (this.svgViewportTransformation) {\n const vpt = this.viewportTransform;\n viewBox = `viewBox=\"${toFixed(\n -vpt[4] / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(-vpt[5] / vpt[3], NUM_FRACTION_DIGITS)} ${toFixed(\n this.width / vpt[0],\n NUM_FRACTION_DIGITS,\n )} ${toFixed(this.height / vpt[3], NUM_FRACTION_DIGITS)}\" `;\n } else {\n viewBox = `viewBox=\"0 0 ${this.width} ${this.height}\" `;\n }\n\n markup.push(\n '\\n',\n 'Created with Fabric.js ',\n VERSION,\n '\\n',\n '\\n',\n this.createSVGFontFacesMarkup(),\n this.createSVGRefElementsMarkup(),\n this.createSVGClipPathMarkup(options),\n '\\n',\n );\n }\n\n createSVGClipPathMarkup(options: TSVGExportOptions): string {\n const clipPath = this.clipPath;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n return `\\n${clipPath.toClipPathSVG(\n options.reviver,\n )}\\n`;\n }\n return '';\n }\n\n /**\n * Creates markup containing SVG referenced elements like patterns, gradients etc.\n * @return {String}\n */\n createSVGRefElementsMarkup(): string {\n return (['background', 'overlay'] as const)\n .map((prop) => {\n const fill = this[`${prop}Color`];\n if (isFiller(fill)) {\n const shouldTransform = this[`${prop}Vpt`],\n vpt = this.viewportTransform,\n object = {\n // otherwise circular dependency\n isType: () => false,\n width: this.width / (shouldTransform ? vpt[0] : 1),\n height: this.height / (shouldTransform ? vpt[3] : 1),\n };\n return fill.toSVG(object as FabricObject, {\n additionalTransform: shouldTransform ? matrixToSVG(vpt) : '',\n });\n }\n })\n .join('');\n }\n\n /**\n * Creates markup containing SVG font faces,\n * font URLs for font faces must be collected by developers\n * and are not extracted from the DOM by fabricjs\n * @param {Array} objects Array of fabric objects\n * @return {String}\n */\n createSVGFontFacesMarkup(): string {\n const objects: FabricObject[] = [],\n fontList: Record = {},\n fontPaths = config.fontPaths;\n\n this._objects.forEach(function add(object) {\n objects.push(object);\n if (isCollection(object)) {\n object._objects.forEach(add);\n }\n });\n\n objects.forEach((obj) => {\n if (!isTextObject(obj)) {\n return;\n }\n const { styles, fontFamily } = obj;\n if (fontList[fontFamily] || !fontPaths[fontFamily]) {\n return;\n }\n fontList[fontFamily] = true;\n if (!styles) {\n return;\n }\n Object.values(styles).forEach((styleRow) => {\n Object.values(styleRow).forEach(({ fontFamily = '' }) => {\n if (!fontList[fontFamily] && fontPaths[fontFamily]) {\n fontList[fontFamily] = true;\n }\n });\n });\n });\n\n const fontListMarkup = Object.keys(fontList)\n .map(\n (fontFamily) =>\n `\\t\\t@font-face {\\n\\t\\t\\tfont-family: '${fontFamily}';\\n\\t\\t\\tsrc: url('${fontPaths[fontFamily]}');\\n\\t\\t}\\n`,\n )\n .join('');\n\n if (fontListMarkup) {\n return `\\t\\n`;\n }\n return '';\n }\n\n /**\n * @private\n */\n _setSVGObjects(markup: string[], reviver?: TSVGReviver) {\n this.forEachObject((fabricObject) => {\n if (fabricObject.excludeFromExport) {\n return;\n }\n this._setSVGObject(markup, fabricObject, reviver);\n });\n }\n\n /**\n * This is its own function because the Canvas ( non static ) requires extra code here\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n markup.push(instance.toSVG(reviver));\n }\n\n /**\n * @private\n */\n _setSVGBgOverlayImage(\n markup: string[],\n property: 'overlayImage' | 'backgroundImage',\n reviver?: TSVGReviver,\n ) {\n const bgOrOverlay = this[property];\n if (bgOrOverlay && !bgOrOverlay.excludeFromExport && bgOrOverlay.toSVG) {\n markup.push(bgOrOverlay.toSVG(reviver));\n }\n }\n\n /**\n * @TODO this seems to handle patterns but fail at gradients.\n * @private\n */\n _setSVGBgOverlayColor(markup: string[], property: 'background' | 'overlay') {\n const filler = this[`${property}Color`];\n if (!filler) {\n return;\n }\n if (isFiller(filler)) {\n const repeat = (filler as Pattern).repeat || '',\n finalWidth = this.width,\n finalHeight = this.height,\n shouldInvert = this[`${property}Vpt`],\n additionalTransform = shouldInvert\n ? matrixToSVG(invertTransform(this.viewportTransform))\n : '';\n markup.push(\n `\\n`,\n );\n } else {\n markup.push(\n '\\n',\n );\n }\n }\n /* _TO_SVG_END_ */\n\n /**\n * Populates canvas with data from the specified JSON.\n * JSON format must conform to the one of {@link fabric.Canvas#toJSON}\n *\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n *\n * @param {String|Object} json JSON string or object\n * @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.\n * @param {Object} [options] options\n * @param {AbortSignal} [options.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {Promise} instance\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-3#deserialization}\n * @see {@link http://jsfiddle.net/fabricjs/fmgXt/|jsFiddle demo}\n * @example loadFromJSON\n * canvas.loadFromJSON(json).then((canvas) => canvas.requestRenderAll());\n * @example loadFromJSON with reviver\n * canvas.loadFromJSON(json, function(o, object) {\n * // `o` = json object\n * // `object` = fabric.Object instance\n * // ... do some stuff ...\n * }).then((canvas) => {\n * ... canvas is restored, add your code.\n * });\n *\n */\n loadFromJSON(\n json: string | Record,\n reviver?: EnlivenObjectOptions['reviver'],\n { signal }: Abortable = {},\n ): Promise {\n if (!json) {\n return Promise.reject(new FabricError('`json` is undefined'));\n }\n\n // parse json if it wasn't already\n const serialized = typeof json === 'string' ? JSON.parse(json) : json;\n const {\n objects = [],\n backgroundImage,\n background,\n overlayImage,\n overlay,\n clipPath,\n } = serialized;\n const renderOnAddRemove = this.renderOnAddRemove;\n this.renderOnAddRemove = false;\n\n return Promise.all([\n enlivenObjects(objects, {\n reviver,\n signal,\n }),\n enlivenObjectEnlivables(\n {\n backgroundImage,\n backgroundColor: background,\n overlayImage,\n overlayColor: overlay,\n clipPath,\n },\n { signal },\n ),\n ]).then(([enlived, enlivedMap]) => {\n this.clear();\n this.add(...enlived);\n this.set(serialized);\n this.set(enlivedMap);\n this.renderOnAddRemove = renderOnAddRemove;\n return this;\n });\n }\n\n /**\n * Clones canvas instance\n * @param {string[]} [properties] Array of properties to include in the cloned canvas and children\n */\n clone(properties: string[]) {\n const data = this.toObject(properties);\n const canvas = this.cloneWithoutData();\n return canvas.loadFromJSON(data);\n }\n\n /**\n * Clones canvas instance without cloning existing data.\n * This essentially copies canvas dimensions since loadFromJSON does not affect canvas size.\n */\n cloneWithoutData() {\n const el = createCanvasElement();\n el.width = this.width;\n el.height = this.height;\n return new (this.constructor as Constructor)(el);\n }\n\n /**\n * Exports canvas element to a dataurl image. Note that when multiplier is used, cropping is scaled appropriately\n * @param {Object} [options] Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by, to have consistent\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 2.0.0\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n * @see {@link https://jsfiddle.net/xsjua1rd/ demo}\n * @example Generate jpeg dataURL with lower quality\n * var dataURL = canvas.toDataURL({\n * format: 'jpeg',\n * quality: 0.8\n * });\n * @example Generate cropped png dataURL (clipping of canvas)\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * left: 100,\n * top: 100,\n * width: 200,\n * height: 200\n * });\n * @example Generate double scaled png dataURL\n * var dataURL = canvas.toDataURL({\n * format: 'png',\n * multiplier: 2\n * });\n * @example Generate dataURL with objects that overlap a specified object\n * var myObject;\n * var dataURL = canvas.toDataURL({\n * filter: (object) => object.isContainedWithinObject(myObject) || object.intersectsWithObject(myObject)\n * });\n */\n toDataURL(options = {} as TDataUrlOptions): string {\n const {\n format = 'png',\n quality = 1,\n multiplier = 1,\n enableRetinaScaling = false,\n } = options;\n const finalMultiplier =\n multiplier * (enableRetinaScaling ? this.getRetinaScaling() : 1);\n\n return toDataURL(\n this.toCanvasElement(finalMultiplier, options),\n format,\n quality,\n );\n }\n\n /**\n * Create a new HTMLCanvas element painted with the current canvas content.\n * No need to resize the actual one or repaint it.\n * Will transfer object ownership to a new canvas, paint it, and set everything back.\n * This is an intermediary step used to get to a dataUrl but also it is useful to\n * create quick image copies of a canvas without passing for the dataUrl string\n * @param {Number} [multiplier] a zoom factor.\n * @param {Object} [options] Cropping informations\n * @param {Number} [options.left] Cropping left offset.\n * @param {Number} [options.top] Cropping top offset.\n * @param {Number} [options.width] Cropping width.\n * @param {Number} [options.height] Cropping height.\n * @param {(object: fabric.Object) => boolean} [options.filter] Function to filter objects.\n */\n toCanvasElement(\n multiplier = 1,\n { width, height, left, top, filter } = {} as TToCanvasElementOptions,\n ): HTMLCanvasElement {\n const scaledWidth = (width || this.width) * multiplier,\n scaledHeight = (height || this.height) * multiplier,\n zoom = this.getZoom(),\n originalWidth = this.width,\n originalHeight = this.height,\n originalSkipControlsDrawing = this.skipControlsDrawing,\n newZoom = zoom * multiplier,\n vp = this.viewportTransform,\n translateX = (vp[4] - (left || 0)) * multiplier,\n translateY = (vp[5] - (top || 0)) * multiplier,\n newVp = [newZoom, 0, 0, newZoom, translateX, translateY] as TMat2D,\n originalRetina = this.enableRetinaScaling,\n canvasEl = createCanvasElement(),\n objectsToRender = filter\n ? this._objects.filter((obj) => filter(obj))\n : this._objects;\n canvasEl.width = scaledWidth;\n canvasEl.height = scaledHeight;\n this.enableRetinaScaling = false;\n this.viewportTransform = newVp;\n this.width = scaledWidth;\n this.height = scaledHeight;\n this.skipControlsDrawing = true;\n this.calcViewportBoundaries();\n this.renderCanvas(canvasEl.getContext('2d')!, objectsToRender);\n this.viewportTransform = vp;\n this.width = originalWidth;\n this.height = originalHeight;\n this.calcViewportBoundaries();\n this.enableRetinaScaling = originalRetina;\n this.skipControlsDrawing = originalSkipControlsDrawing;\n return canvasEl;\n }\n\n /**\n * Waits until rendering has settled to destroy the canvas\n * @returns {Promise} a promise resolving to `true` once the canvas has been destroyed or to `false` if the canvas has was already destroyed\n * @throws if aborted by a consequent call\n */\n dispose() {\n !this.disposed &&\n this.elements.cleanupDOM({ width: this.width, height: this.height });\n runningAnimations.cancelByCanvas(this);\n this.disposed = true;\n return new Promise((resolve, reject) => {\n const task = () => {\n this.destroy();\n resolve(true);\n };\n task.kill = reject;\n if (this.__cleanupTask) {\n this.__cleanupTask.kill('aborted');\n }\n\n if (this.destroyed) {\n resolve(false);\n } else if (this.nextRenderHandle) {\n this.__cleanupTask = task;\n } else {\n task();\n }\n });\n }\n\n /**\n * Clears the canvas element, disposes objects and frees resources.\n *\n * Invoked as part of the **async** operation of {@link dispose}.\n *\n * **CAUTION**:\n *\n * This method is **UNSAFE**.\n * You may encounter a race condition using it if there's a requested render.\n * Call this method only if you are sure rendering has settled.\n * Consider using {@link dispose} as it is **SAFE**\n *\n * @private\n */\n destroy() {\n this.destroyed = true;\n this.cancelRequestedRender();\n this.forEachObject((object) => object.dispose());\n this._objects = [];\n if (this.backgroundImage) {\n this.backgroundImage.dispose();\n }\n this.backgroundImage = undefined;\n if (this.overlayImage) {\n this.overlayImage.dispose();\n }\n this.overlayImage = undefined;\n this.elements.dispose();\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String} string representation of an instance\n */\n toString() {\n return `#`;\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport { getScrollLeftTop } from './dom_misc';\n\nconst touchEvents = ['touchstart', 'touchmove', 'touchend'];\n\nfunction getTouchInfo(event: TouchEvent | MouseEvent): MouseEvent | Touch {\n const touchProp = (event as TouchEvent).changedTouches;\n if (touchProp && touchProp[0]) {\n return touchProp[0];\n }\n return event as MouseEvent;\n}\n\nexport const getPointer = (event: TPointerEvent): Point => {\n const element = event.target as HTMLElement,\n scroll = getScrollLeftTop(element),\n _evt = getTouchInfo(event);\n return new Point(_evt.clientX + scroll.left, _evt.clientY + scroll.top);\n};\n\nexport const isTouchEvent = (event: TPointerEvent) =>\n touchEvents.includes(event.type) ||\n (event as PointerEvent).pointerType === 'touch';\n\nexport const stopEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n};\n","import type { XY } from '../../Point';\nimport type { TBBox } from '../../typedefs';\n\n/**\n * Calculates bounding box (left, top, width, height) from given `points`\n * @param {XY[]} points\n * @return {Object} Object with left, top, width, height properties\n */\nexport const makeBoundingBoxFromPoints = (points: XY[]): TBBox => {\n let left = 0,\n top = 0,\n width = 0,\n height = 0;\n\n for (let i = 0, len = points.length; i < len; i++) {\n const { x, y } = points[i];\n if (x > width || !i) width = x;\n if (x < left || !i) left = x;\n if (y > height || !i) height = y;\n if (y < top || !i) top = y;\n }\n\n return {\n left,\n top,\n width: width - left,\n height: height - top,\n };\n};\n","import { Point } from '../../Point';\nimport { CENTER } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from './matrix';\n\n/**\n * given an object and a transform, apply the inverse transform to the object,\n * this is equivalent to remove from that object that transformation, so that\n * added in a space with the removed transform, the object will be the same as before.\n * Removing from an object a transform that scale by 2 is like scaling it by 1/2.\n * Removing from an object a transform that rotate by 30deg is like rotating by 30deg\n * in the opposite direction.\n * This util is used to add objects inside transformed groups or nested groups.\n * @param {FabricObject} object the object you want to transform\n * @param {TMat2D} transform the destination transform\n */\nexport const removeTransformFromObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const inverted = invertTransform(transform),\n finalTransform = multiplyTransformMatrices(\n inverted,\n object.calcOwnMatrix(),\n );\n applyTransformToObject(object, finalTransform);\n};\n\n/**\n * given an object and a transform, apply the transform to the object.\n * this is equivalent to change the space where the object is drawn.\n * Adding to an object a transform that scale by 2 is like scaling it by 2.\n * This is used when removing an object from an active selection for example.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const addTransformToObject = (object: FabricObject, transform: TMat2D) =>\n applyTransformToObject(\n object,\n multiplyTransformMatrices(transform, object.calcOwnMatrix()),\n );\n\n/**\n * discard an object transform state and apply the one from the matrix.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const applyTransformToObject = (\n object: FabricObject,\n transform: TMat2D,\n) => {\n const { translateX, translateY, scaleX, scaleY, ...otherOptions } =\n qrDecompose(transform),\n center = new Point(translateX, translateY);\n object.flipX = false;\n object.flipY = false;\n Object.assign(object, otherOptions);\n object.set({ scaleX, scaleY });\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n/**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @param {FabricObject} target object to transform\n */\nexport const resetObjectTransform = (target: FabricObject) => {\n target.scaleX = 1;\n target.scaleY = 1;\n target.skewX = 0;\n target.skewY = 0;\n target.flipX = false;\n target.flipY = false;\n target.rotate(0);\n};\n\n/**\n * Extract Object transform values\n * @param {FabricObject} target object to read from\n * @return {Object} Components of transform\n */\nexport const saveObjectTransform = (target: FabricObject) => ({\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n angle: target.angle,\n left: target.left,\n flipX: target.flipX,\n flipY: target.flipY,\n top: target.top,\n});\n\n/**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform.\n * Use to calculate the boxes around objects for controls.\n * @param {Number} width\n * @param {Number} height\n * @param {TMat2D} t\n * @returns {Point} size\n */\nexport const sizeAfterTransform = (\n width: number,\n height: number,\n t: TMat2D,\n) => {\n const dimX = width / 2,\n dimY = height / 2,\n points = [\n new Point(-dimX, -dimY),\n new Point(dimX, -dimY),\n new Point(-dimX, dimY),\n new Point(dimX, dimY),\n ].map((p) => p.transform(t)),\n bbox = makeBoundingBoxFromPoints(points);\n return new Point(bbox.width, bbox.height);\n};\n","import { iMatrix } from '../../constants';\nimport type { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { invertTransform, multiplyTransformMatrices } from './matrix';\nimport { applyTransformToObject } from './objectTransforms';\n\n/**\n * We are actually looking for the transformation from the destination plane to the source plane (change of basis matrix)\\\n * The object will exist on the destination plane and we want it to seem unchanged by it so we invert the destination matrix (`to`) and then apply the source matrix (`from`)\n * @param [from]\n * @param [to]\n * @returns\n */\nexport const calcPlaneChangeMatrix = (\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n) => multiplyTransformMatrices(invertTransform(to), from);\n\n/**\n * Sends a point from the source coordinate plane to the destination coordinate plane.\\\n * From the canvas/viewer's perspective the point remains unchanged.\n *\n * @example Send point from canvas plane to group plane\n * var obj = new Rect({ left: 20, top: 20, width: 60, height: 60, strokeWidth: 0 });\n * var group = new Group([obj], { strokeWidth: 0 });\n * var sentPoint1 = sendPointToPlane(new Point(50, 50), undefined, group.calcTransformMatrix());\n * var sentPoint2 = sendPointToPlane(new Point(50, 50), iMatrix, group.calcTransformMatrix());\n * console.log(sentPoint1, sentPoint2) // both points print (0,0) which is the center of group\n *\n * @param {Point} point\n * @param {TMat2D} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `point` exists in the canvas coordinate plane.\n * @param {TMat2D} [to] destination plane matrix to contain object. Passing `undefined` means `point` should be sent to the canvas coordinate plane.\n * @returns {Point} transformed point\n */\nexport const sendPointToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to));\n\n/**\n * See {@link sendPointToPlane}\n */\nexport const sendVectorToPlane = (\n point: Point,\n from: TMat2D = iMatrix,\n to: TMat2D = iMatrix,\n): Point => point.transform(calcPlaneChangeMatrix(from, to), true);\n\n/**\n *\n * A util that abstracts applying transform to objects.\\\n * Sends `object` to the destination coordinate plane by applying the relevant transformations.\\\n * Changes the space/plane where `object` is drawn.\\\n * From the canvas/viewer's perspective `object` remains unchanged.\n *\n * @example Move clip path from one object to another while preserving it's appearance as viewed by canvas/viewer\n * let obj, obj2;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * // render\n * sendObjectToPlane(clipPath, obj.calcTransformMatrix(), obj2.calcTransformMatrix());\n * obj.clipPath = undefined;\n * obj2.clipPath = clipPath;\n * // render, clipPath now clips obj2 but seems unchanged from the eyes of the viewer\n *\n * @example Clip an object's clip path with an existing object\n * let obj, existingObj;\n * let clipPath = new Circle({ radius: 50 });\n * obj.clipPath = clipPath;\n * let transformTo = multiplyTransformMatrices(obj.calcTransformMatrix(), clipPath.calcTransformMatrix());\n * sendObjectToPlane(existingObj, existingObj.group?.calcTransformMatrix(), transformTo);\n * clipPath.clipPath = existingObj;\n *\n * @param {FabricObject} object\n * @param {Matrix} [from] plane matrix containing object. Passing `undefined` is equivalent to passing the identity matrix, which means `object` is a direct child of canvas.\n * @param {Matrix} [to] destination plane matrix to contain object. Passing `undefined` means `object` should be sent to the canvas coordinate plane.\n * @returns {Matrix} the transform matrix that was applied to `object`\n */\nexport const sendObjectToPlane = (\n object: FabricObject,\n from?: TMat2D,\n to?: TMat2D,\n): TMat2D => {\n const t = calcPlaneChangeMatrix(from, to);\n applyTransformToObject(\n object,\n multiplyTransformMatrices(t, object.calcOwnMatrix()),\n );\n return t;\n};\n","import type {\n ObjectModificationEvents,\n TModificationEvents,\n} from '../EventTypeDefs';\n\nexport const fireEvent = (\n eventName: TModificationEvents,\n options: ObjectModificationEvents[typeof eventName],\n) => {\n const {\n transform: { target },\n } = options;\n target.canvas?.fire(`object:${eventName}`, {\n ...options,\n target,\n });\n target.fire(eventName, options);\n};\n","import type { TOriginX, TOriginY } from '../../typedefs';\n\nconst originOffset = {\n left: -0.5,\n top: -0.5,\n center: 0,\n bottom: 0.5,\n right: 0.5,\n};\n/**\n * Resolves origin value relative to center\n * @private\n * @param {TOriginX | TOriginY} originValue originX / originY\n * @returns number\n */\n\nexport const resolveOrigin = (\n originValue: TOriginX | TOriginY | number,\n): number =>\n typeof originValue === 'string'\n ? originOffset[originValue]\n : originValue - 0.5;\n","import type {\n TPointerEvent,\n Transform,\n TransformAction,\n BasicTransformEvent,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TOriginX, TOriginY } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\nimport { CENTER } from '../constants';\n\nexport const NOT_ALLOWED_CURSOR = 'not-allowed';\n\n/**\n * @param {Boolean} alreadySelected true if target is already selected\n * @param {String} corner a string representing the corner ml, mr, tl ...\n * @param {Event} e Event object\n * @param {FabricObject} [target] inserted back to help overriding. Unused\n */\nexport const getActionFromCorner = (\n alreadySelected: boolean,\n corner: string | undefined,\n e: TPointerEvent,\n target: FabricObject,\n) => {\n if (!corner || !alreadySelected) {\n return 'drag';\n }\n const control = target.controls[corner];\n return control.getActionName(e, control, target);\n};\n\n/**\n * Checks if transform is centered\n * @param {Object} transform transform data\n * @return {Boolean} true if transform is centered\n */\nexport function isTransformCentered(transform: Transform) {\n return (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) &&\n resolveOrigin(transform.originY) === resolveOrigin(CENTER)\n );\n}\n\nexport function invertOrigin(origin: TOriginX | TOriginY) {\n return -resolveOrigin(origin) + 0.5;\n}\n\nexport const isLocked = (\n target: FabricObject,\n lockingKey:\n | 'lockMovementX'\n | 'lockMovementY'\n | 'lockRotation'\n | 'lockScalingX'\n | 'lockScalingY'\n | 'lockSkewingX'\n | 'lockSkewingY'\n | 'lockScalingFlip',\n) => target[lockingKey];\n\nexport const commonEventInfo: TransformAction<\n Transform,\n BasicTransformEvent\n> = (eventData, transform, x, y) => {\n return {\n e: eventData,\n transform,\n pointer: new Point(x, y),\n };\n};\n\n/**\n * Combine control position and object angle to find the control direction compared\n * to the object center.\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n * @param {Control} control the control class\n * @return {Number} 0 - 7 a quadrant number\n */\nexport function findCornerQuadrant(\n fabricObject: FabricObject,\n control: Control,\n): number {\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle(),\n cornerAngle =\n angle + radiansToDegrees(Math.atan2(control.y, control.x)) + 360;\n return Math.round((cornerAngle % 360) / 45);\n}\n\n/**\n * @returns the normalized point (rotated relative to center) in local coordinates\n */\nfunction normalizePoint(\n target: FabricObject,\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n): Point {\n const center = target.getRelativeCenterPoint(),\n p =\n typeof originX !== 'undefined' && typeof originY !== 'undefined'\n ? target.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n )\n : new Point(target.left, target.top),\n p2 = target.angle\n ? point.rotate(-degreesToRadians(target.angle), center)\n : point;\n return p2.subtract(p);\n}\n\n/**\n * Transforms a point to the offset from the given origin\n * @param {Object} transform\n * @param {String} originX\n * @param {String} originY\n * @param {number} x\n * @param {number} y\n * @return {Fabric.Point} the normalized point\n */\nexport function getLocalPoint(\n { target, corner }: Transform,\n originX: TOriginX,\n originY: TOriginY,\n x: number,\n y: number,\n) {\n const control = target.controls[corner],\n zoom = target.canvas?.getZoom() || 1,\n padding = target.padding / zoom,\n localPoint = normalizePoint(target, new Point(x, y), originX, originY);\n if (localPoint.x >= padding) {\n localPoint.x -= padding;\n }\n if (localPoint.x <= -padding) {\n localPoint.x += padding;\n }\n if (localPoint.y >= padding) {\n localPoint.y -= padding;\n }\n if (localPoint.y <= padding) {\n localPoint.y += padding;\n }\n localPoint.x -= control.offsetX;\n localPoint.y -= control.offsetY;\n return localPoint;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { LEFT, TOP, MOVING } from '../constants';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo, isLocked } from './util';\n\n/**\n * Action handler\n * @private\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if the translation occurred\n */\nexport const dragHandler: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const { target, offsetX, offsetY } = transform,\n newLeft = x - offsetX,\n newTop = y - offsetY,\n moveX = !isLocked(target, 'lockMovementX') && target.left !== newLeft,\n moveY = !isLocked(target, 'lockMovementY') && target.top !== newTop;\n moveX && target.set(LEFT, newLeft);\n moveY && target.set(TOP, newTop);\n if (moveX || moveY) {\n fireEvent(MOVING, commonEventInfo(eventData, transform, x, y));\n }\n return moveX || moveY;\n};\n","import type { TSVGReviver } from '../../typedefs';\nimport { uid } from '../../util/internals/uid';\nimport { colorPropToSVG, matrixToSVG } from '../../util/misc/svgParsing';\nimport { FILL, NONE, STROKE } from '../../constants';\nimport type { FabricObject } from './FabricObject';\nimport { isFiller } from '../../util/typeAssertions';\n\nexport class FabricObjectSVGExportMixin {\n /**\n * When an object is being exported as SVG as a clippath, a reference inside the SVG is needed.\n * This reference is a UID in the fabric namespace and is temporary stored here.\n * @type {String}\n */\n declare clipPathId?: string;\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(\n this: FabricObjectSVGExportMixin & FabricObject,\n skipShadow?: boolean,\n ) {\n const fillRule = this.fillRule ? this.fillRule : 'nonzero',\n strokeWidth = this.strokeWidth ? this.strokeWidth : '0',\n strokeDashArray = this.strokeDashArray\n ? this.strokeDashArray.join(' ')\n : NONE,\n strokeDashOffset = this.strokeDashOffset ? this.strokeDashOffset : '0',\n strokeLineCap = this.strokeLineCap ? this.strokeLineCap : 'butt',\n strokeLineJoin = this.strokeLineJoin ? this.strokeLineJoin : 'miter',\n strokeMiterLimit = this.strokeMiterLimit ? this.strokeMiterLimit : '4',\n opacity = typeof this.opacity !== 'undefined' ? this.opacity : '1',\n visibility = this.visible ? '' : ' visibility: hidden;',\n filter = skipShadow ? '' : this.getSvgFilter(),\n fill = colorPropToSVG(FILL, this.fill),\n stroke = colorPropToSVG(STROKE, this.stroke);\n\n return [\n stroke,\n 'stroke-width: ',\n strokeWidth,\n '; ',\n 'stroke-dasharray: ',\n strokeDashArray,\n '; ',\n 'stroke-linecap: ',\n strokeLineCap,\n '; ',\n 'stroke-dashoffset: ',\n strokeDashOffset,\n '; ',\n 'stroke-linejoin: ',\n strokeLineJoin,\n '; ',\n 'stroke-miterlimit: ',\n strokeMiterLimit,\n '; ',\n fill,\n 'fill-rule: ',\n fillRule,\n '; ',\n 'opacity: ',\n opacity,\n ';',\n filter,\n visibility,\n ].join('');\n }\n\n /**\n * Returns filter for svg shadow\n * @return {String}\n */\n getSvgFilter(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.shadow ? `filter: url(#SVGID_${this.shadow.id});` : '';\n }\n\n /**\n * Returns id attribute for svg output\n * @return {String}\n */\n getSvgCommons(\n this: FabricObjectSVGExportMixin & FabricObject & { id?: string },\n ) {\n return [\n this.id ? `id=\"${this.id}\" ` : '',\n this.clipPath\n ? `clip-path=\"url(#${\n (this.clipPath as FabricObjectSVGExportMixin & FabricObject)\n .clipPathId\n })\" `\n : '',\n ].join('');\n }\n\n /**\n * Returns transform-string for svg-export\n * @param {Boolean} use the full transform or the single object one.\n * @return {String}\n */\n getSvgTransform(\n this: FabricObjectSVGExportMixin & FabricObject,\n full?: boolean,\n additionalTransform = '',\n ) {\n const transform = full ? this.calcTransformMatrix() : this.calcOwnMatrix(),\n svgTransform = `transform=\"${matrixToSVG(transform)}`;\n return `${svgTransform}${additionalTransform}\" `;\n }\n\n /**\n * Returns svg representation of an instance\n * This function is implemented in each subclass\n * This is just because typescript otherwise cryies all the time\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(_reviver?: TSVGReviver): string[] {\n return [''];\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return this._createBaseSVGMarkup(this._toSVG(reviver), {\n reviver,\n });\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(\n this: FabricObjectSVGExportMixin & FabricObject,\n reviver?: TSVGReviver,\n ) {\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(reviver), {\n reviver,\n })\n );\n }\n\n /**\n * @private\n */\n _createBaseClipPathSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n reviver,\n additionalTransform = '',\n }: { reviver?: TSVGReviver; additionalTransform?: string } = {},\n ) {\n const commonPieces = [\n this.getSvgTransform(true, additionalTransform),\n this.getSvgCommons(),\n ].join(''),\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n objectMarkup[index] = commonPieces;\n return reviver ? reviver(objectMarkup.join('')) : objectMarkup.join('');\n }\n\n /**\n * @private\n */\n _createBaseSVGMarkup(\n this: FabricObjectSVGExportMixin & FabricObject,\n objectMarkup: string[],\n {\n noStyle,\n reviver,\n withShadow,\n additionalTransform,\n }: {\n noStyle?: boolean;\n reviver?: TSVGReviver;\n withShadow?: boolean;\n additionalTransform?: string;\n } = {},\n ): string {\n const styleInfo = noStyle ? '' : `style=\"${this.getSvgStyles()}\" `,\n shadowInfo = withShadow ? `style=\"${this.getSvgFilter()}\" ` : '',\n clipPath = this.clipPath as FabricObjectSVGExportMixin & FabricObject,\n vectorEffect = this.strokeUniform\n ? 'vector-effect=\"non-scaling-stroke\" '\n : '',\n absoluteClipPath = clipPath && clipPath.absolutePositioned,\n stroke = this.stroke,\n fill = this.fill,\n shadow = this.shadow,\n markup = [],\n // insert commons in the markup, style and svgCommons\n index = objectMarkup.indexOf('COMMON_PARTS');\n let clipPathMarkup;\n if (clipPath) {\n clipPath.clipPathId = `CLIPPATH_${uid()}`;\n clipPathMarkup = `\\n${clipPath.toClipPathSVG(reviver)}\\n`;\n }\n if (absoluteClipPath) {\n markup.push('\\n');\n }\n markup.push(\n '\\n',\n );\n const commonPieces = [\n styleInfo,\n vectorEffect,\n noStyle ? '' : this.addPaintOrder(),\n ' ',\n additionalTransform ? `transform=\"${additionalTransform}\" ` : '',\n ].join('');\n objectMarkup[index] = commonPieces;\n if (isFiller(fill)) {\n markup.push(fill.toSVG(this));\n }\n if (isFiller(stroke)) {\n markup.push(stroke.toSVG(this));\n }\n if (shadow) {\n markup.push(shadow.toSVG(this));\n }\n if (clipPath) {\n markup.push(clipPathMarkup);\n }\n markup.push(objectMarkup.join(''));\n markup.push('\\n');\n absoluteClipPath && markup.push('\\n');\n return reviver ? reviver(markup.join('')) : markup.join('');\n }\n\n addPaintOrder(this: FabricObjectSVGExportMixin & FabricObject) {\n return this.paintFirst !== FILL ? ` paint-order=\"${this.paintFirst}\" ` : '';\n }\n}\n","export function getSvgRegex(arr: string[]) {\n return new RegExp('^(' + arr.join('|') + ')\\\\b', 'i');\n}\n","import { getSvgRegex } from './getSvgRegex';\nimport { LEFT, TOP } from '../constants';\n\nexport const reNum = String.raw`(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)`;\n\nexport const svgNS = 'http://www.w3.org/2000/svg';\n\nexport const reFontDeclaration = new RegExp(\n '(normal|italic)?\\\\s*(normal|small-caps)?\\\\s*' +\n '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\\\s*(' +\n reNum +\n '(?:px|cm|mm|em|pt|pc|in)*)(?:\\\\/(normal|' +\n reNum +\n '))?\\\\s+(.*)',\n);\n\nexport const svgValidTagNames = [\n 'path',\n 'circle',\n 'polygon',\n 'polyline',\n 'ellipse',\n 'rect',\n 'line',\n 'image',\n 'text',\n ],\n svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],\n svgInvalidAncestors = [\n 'pattern',\n 'defs',\n 'symbol',\n 'metadata',\n 'clipPath',\n 'mask',\n 'desc',\n ],\n svgValidParents = ['symbol', 'g', 'a', 'svg', 'clipPath', 'defs'],\n attributesMap = {\n cx: LEFT,\n x: LEFT,\n r: 'radius',\n cy: TOP,\n y: TOP,\n display: 'visible',\n visibility: 'visible',\n transform: 'transformMatrix',\n 'fill-opacity': 'fillOpacity',\n 'fill-rule': 'fillRule',\n 'font-family': 'fontFamily',\n 'font-size': 'fontSize',\n 'font-style': 'fontStyle',\n 'font-weight': 'fontWeight',\n 'letter-spacing': 'charSpacing',\n 'paint-order': 'paintFirst',\n 'stroke-dasharray': 'strokeDashArray',\n 'stroke-dashoffset': 'strokeDashOffset',\n 'stroke-linecap': 'strokeLineCap',\n 'stroke-linejoin': 'strokeLineJoin',\n 'stroke-miterlimit': 'strokeMiterLimit',\n 'stroke-opacity': 'strokeOpacity',\n 'stroke-width': 'strokeWidth',\n 'text-decoration': 'textDecoration',\n 'text-anchor': 'textAnchor',\n opacity: 'opacity',\n 'clip-path': 'clipPath',\n 'clip-rule': 'clipRule',\n 'vector-effect': 'strokeUniform',\n 'image-rendering': 'imageSmoothing',\n },\n fSize = 'font-size',\n cPath = 'clip-path';\n\nexport const svgValidTagNamesRegEx = getSvgRegex(svgValidTagNames);\n\nexport const svgViewBoxElementsRegEx = getSvgRegex(svgViewBoxElements);\n\nexport const svgValidParentsRegEx = getSvgRegex(svgValidParents);\n\n// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute\n// matches, e.g.: +14.56e-12, etc.\nexport const reViewBoxAttrValue = new RegExp(\n '^' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*,?' +\n '\\\\s*(' +\n reNum +\n '+)\\\\s*' +\n '$',\n);\n","import type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n\nconst unitVectorX = new Point(1, 0);\nconst zero = new Point();\n\n/**\n * Rotates `vector` with `radians`\n * @param {Point} vector The vector to rotate (x and y)\n * @param {Number} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotateVector = (vector: Point, radians: TRadian) =>\n vector.rotate(radians);\n\n/**\n * Creates a vector from points represented as a point\n *\n * @param {Point} from\n * @param {Point} to\n * @returns {Point} vector\n */\nexport const createVector = (from: XY, to: XY): Point =>\n new Point(to).subtract(from);\n\n/**\n * return the magnitude of a vector\n * @return {number}\n */\nexport const magnitude = (point: Point) => point.distanceFrom(zero);\n\n/**\n * Calculates the angle between 2 vectors\n * @param {Point} a\n * @param {Point} b\n * @returns the angle in radians from `a` to `b`\n */\nexport const calcAngleBetweenVectors = (a: Point, b: Point): TRadian =>\n Math.atan2(crossProduct(a, b), dotProduct(a, b)) as TRadian;\n\n/**\n * Calculates the angle between the x axis and the vector\n * @param {Point} v\n * @returns the angle in radians of `v`\n */\nexport const calcVectorRotation = (v: Point) =>\n calcAngleBetweenVectors(unitVectorX, v);\n\n/**\n * @param {Point} v\n * @returns {Point} vector representing the unit vector pointing to the direction of `v`\n */\nexport const getUnitVector = (v: Point): Point =>\n v.eq(zero) ? v : v.scalarDivide(magnitude(v));\n\n/**\n * @param {Point} v\n * @param {Boolean} [counterClockwise] the direction of the orthogonal vector, defaults to `true`\n * @returns {Point} the unit orthogonal vector\n */\nexport const getOrthonormalVector = (\n v: Point,\n counterClockwise = true,\n): Point =>\n getUnitVector(new Point(-v.y, v.x).scalarMultiply(counterClockwise ? 1 : -1));\n\n/**\n * Cross product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number} the magnitude of Z vector\n */\nexport const crossProduct = (a: Point, b: Point): number =>\n a.x * b.y - a.y * b.x;\n\n/**\n * Dot product of two vectors in 2D\n * @param {Point} a\n * @param {Point} b\n * @returns {number}\n */\nexport const dotProduct = (a: Point, b: Point): number => a.x * b.x + a.y * b.y;\n\n/**\n * Checks if the vector is between two others. It is considered\n * to be inside when the vector to be tested is between the\n * initial vector and the final vector (included) in a counterclockwise direction.\n * @param {Point} t vector to be tested\n * @param {Point} a initial vector\n * @param {Point} b final vector\n * @returns {boolean} true if the vector is among the others\n */\nexport const isBetweenVectors = (t: Point, a: Point, b: Point): boolean => {\n if (t.eq(a) || t.eq(b)) return true;\n const AxB = crossProduct(a, b),\n AxT = crossProduct(a, t),\n BxT = crossProduct(b, t);\n return AxB >= 0 ? AxT >= 0 && BxT <= 0 : !(AxT <= 0 && BxT >= 0);\n};\n","import { classRegistry } from './ClassRegistry';\nimport { Color } from './color/Color';\nimport { config } from './config';\nimport { reNum } from './parser/constants';\nimport { Point } from './Point';\nimport type { FabricObject } from './shapes/Object/FabricObject';\nimport type { TClassProperties } from './typedefs';\nimport { uid } from './util/internals/uid';\nimport { pickBy } from './util/misc/pick';\nimport { degreesToRadians } from './util/misc/radiansDegreesConversion';\nimport { toFixed } from './util/misc/toFixed';\nimport { rotateVector } from './util/misc/vectors';\n\n/**\n * Regex matching shadow offsetX, offsetY and blur (ex: \"2px 2px 10px rgba(0,0,0,0.2)\", \"rgb(0,255,0) 2px 2px\")\n * - (?:\\s|^): This part captures either a whitespace character (\\s) or the beginning of a line (^). It's non-capturing (due to (?:...)), meaning it doesn't create a capturing group.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: This captures the first component of the shadow, which is the horizontal offset. Breaking it down:\n * - (-?\\d+): Captures an optional minus sign followed by one or more digits (integer part of the number).\n * - (?:\\.\\d*)?: Optionally captures a decimal point followed by zero or more digits (decimal part of the number).\n * - (?:px)?: Optionally captures the \"px\" unit.\n * - (?:\\s?|$): Captures either an optional whitespace or the end of the line. This whole part is wrapped in a non-capturing group and marked as optional with ?.\n * - (-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?: Similar to the previous step, this captures the vertical offset.\n\n(\\d+(?:\\.\\d*)?(?:px)?)?: This captures the blur radius. It's similar to the horizontal offset but without the optional minus sign.\n\n(?:\\s+(-?\\d+(?:\\.\\d*)?(?:px)?(?:\\s?|$))?){0,1}: This captures an optional part for the color. It allows for whitespace followed by a component with an optional minus sign, digits, decimal point, and \"px\" unit.\n\n(?:$|\\s): This captures either the end of the line or a whitespace character. It ensures that the match ends either at the end of the string or with a whitespace character.\n */\n// eslint-disable-next-line max-len\n\nconst shadowOffsetRegex = '(-?\\\\d+(?:\\\\.\\\\d*)?(?:px)?(?:\\\\s?|$))?';\n\nconst reOffsetsAndBlur = new RegExp(\n '(?:\\\\s|^)' +\n shadowOffsetRegex +\n shadowOffsetRegex +\n '(' +\n reNum +\n '?(?:px)?)?(?:\\\\s?|$)(?:$|\\\\s)',\n);\n\nexport const shadowDefaultValues: Partial> = {\n color: 'rgb(0,0,0)',\n blur: 0,\n offsetX: 0,\n offsetY: 0,\n affectStroke: false,\n includeDefaultValues: true,\n nonScaling: false,\n};\n\nexport type SerializedShadowOptions = {\n color: string;\n blur: number;\n offsetX: number;\n offsetY: number;\n affectStroke: boolean;\n nonScaling: boolean;\n type: string;\n};\n\nexport class Shadow {\n /**\n * Shadow color\n * @type String\n * @default\n */\n declare color: string;\n\n /**\n * Shadow blur\n * @type Number\n */\n declare blur: number;\n\n /**\n * Shadow horizontal offset\n * @type Number\n * @default\n */\n declare offsetX: number;\n\n /**\n * Shadow vertical offset\n * @type Number\n * @default\n */\n declare offsetY: number;\n\n /**\n * Whether the shadow should affect stroke operations\n * @type Boolean\n * @default\n */\n declare affectStroke: boolean;\n\n /**\n * Indicates whether toObject should include default values\n * @type Boolean\n * @default\n */\n declare includeDefaultValues: boolean;\n\n /**\n * When `false`, the shadow will scale with the object.\n * When `true`, the shadow's offsetX, offsetY, and blur will not be affected by the object's scale.\n * default to false\n * @type Boolean\n * @default\n */\n declare nonScaling: boolean;\n\n declare id: number;\n\n static ownDefaults = shadowDefaultValues;\n\n static type = 'shadow';\n\n /**\n * @see {@link http://fabricjs.com/shadows|Shadow demo}\n * @param {Object|String} [options] Options object with any of color, blur, offsetX, offsetY properties or string (e.g. \"rgba(0,0,0,0.2) 2px 2px 10px\")\n */\n constructor(options: Partial>);\n constructor(svgAttribute: string);\n constructor(arg0: string | Partial>) {\n const options: Partial> =\n typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;\n Object.assign(this, Shadow.ownDefaults, options);\n this.id = uid();\n }\n\n /**\n * @param {String} value Shadow value to parse\n * @return {Object} Shadow object with color, offsetX, offsetY and blur\n */\n static parseShadow(value: string) {\n const shadowStr = value.trim(),\n [, offsetX = 0, offsetY = 0, blur = 0] = (\n reOffsetsAndBlur.exec(shadowStr) || []\n ).map((value) => parseFloat(value) || 0),\n color = (shadowStr.replace(reOffsetsAndBlur, '') || 'rgb(0,0,0)').trim();\n\n return {\n color,\n offsetX,\n offsetY,\n blur,\n };\n }\n\n /**\n * Returns a string representation of an instance\n * @see http://www.w3.org/TR/css-text-decor-3/#text-shadow\n * @return {String} Returns CSS3 text-shadow declaration\n */\n toString() {\n return [this.offsetX, this.offsetY, this.blur, this.color].join('px ');\n }\n\n /**\n * Returns SVG representation of a shadow\n * @param {FabricObject} object\n * @return {String} SVG representation of a shadow\n */\n toSVG(object: FabricObject) {\n const offset = rotateVector(\n new Point(this.offsetX, this.offsetY),\n degreesToRadians(-object.angle),\n ),\n BLUR_BOX = 20,\n color = new Color(this.color);\n let fBoxX = 40,\n fBoxY = 40;\n\n if (object.width && object.height) {\n //http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion\n // we add some extra space to filter box to contain the blur ( 20 )\n fBoxX =\n toFixed(\n (Math.abs(offset.x) + this.blur) / object.width,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n fBoxY =\n toFixed(\n (Math.abs(offset.y) + this.blur) / object.height,\n config.NUM_FRACTION_DIGITS,\n ) *\n 100 +\n BLUR_BOX;\n }\n if (object.flipX) {\n offset.x *= -1;\n }\n if (object.flipY) {\n offset.y *= -1;\n }\n\n return `\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\n\\t\\t\\n\\t\\t\\n\\t\\n\\n`;\n }\n\n /**\n * Returns object representation of a shadow\n * @return {Object} Object representation of a shadow instance\n */\n toObject() {\n const data: SerializedShadowOptions = {\n color: this.color,\n blur: this.blur,\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n affectStroke: this.affectStroke,\n nonScaling: this.nonScaling,\n type: (this.constructor as typeof Shadow).type,\n };\n const defaults = Shadow.ownDefaults as SerializedShadowOptions;\n return !this.includeDefaultValues\n ? pickBy(data, (value, key) => value !== defaults[key])\n : data;\n }\n\n static async fromObject(options: Partial>) {\n return new this(options);\n }\n}\n\nclassRegistry.setClass(Shadow, 'shadow');\n","export const capValue = (min: number, value: number, max: number) =>\n Math.max(min, Math.min(value, max));\n","import {\n TOP,\n LEFT,\n SCALE_Y,\n SCALE_X,\n SKEW_X,\n SKEW_Y,\n FILL,\n STROKE,\n} from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { InteractiveFabricObject } from './InteractiveObject';\nimport type { FabricObject } from './Object';\n\nexport const stateProperties = [\n TOP,\n LEFT,\n SCALE_X,\n SCALE_Y,\n 'flipX',\n 'flipY',\n 'originX',\n 'originY',\n 'angle',\n 'opacity',\n 'globalCompositeOperation',\n 'shadow',\n 'visible',\n SKEW_X,\n SKEW_Y,\n];\n\nexport const cacheProperties = [\n FILL,\n STROKE,\n 'strokeWidth',\n 'strokeDashArray',\n 'width',\n 'height',\n 'paintFirst',\n 'strokeUniform',\n 'strokeLineCap',\n 'strokeDashOffset',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'backgroundColor',\n 'clipPath',\n];\n\nexport const fabricObjectDefaultValues: Partial<\n TClassProperties\n> = {\n // see composeMatrix() to see order of transforms. First defaults listed based on this\n top: 0,\n left: 0,\n width: 0,\n height: 0,\n angle: 0,\n flipX: false,\n flipY: false,\n scaleX: 1,\n scaleY: 1,\n minScaleLimit: 0,\n skewX: 0,\n skewY: 0,\n originX: LEFT,\n originY: TOP,\n strokeWidth: 1,\n strokeUniform: false,\n padding: 0,\n opacity: 1,\n paintFirst: FILL,\n fill: 'rgb(0,0,0)',\n fillRule: 'nonzero',\n stroke: null,\n strokeDashArray: null,\n strokeDashOffset: 0,\n strokeLineCap: 'butt',\n strokeLineJoin: 'miter',\n strokeMiterLimit: 4,\n globalCompositeOperation: 'source-over',\n backgroundColor: '',\n shadow: null,\n visible: true,\n includeDefaultValues: true,\n excludeFromExport: false,\n objectCaching: true,\n clipPath: undefined,\n inverted: false,\n absolutePositioned: false,\n centeredRotation: true,\n centeredScaling: false,\n dirty: true,\n} as const;\n\nexport const interactiveObjectDefaultValues: Partial<\n TClassProperties\n> = {\n noScaleCache: true,\n lockMovementX: false,\n lockMovementY: false,\n lockRotation: false,\n lockScalingX: false,\n lockScalingY: false,\n lockSkewingX: false,\n lockSkewingY: false,\n lockScalingFlip: false,\n cornerSize: 13,\n touchCornerSize: 24,\n transparentCorners: true,\n cornerColor: 'rgb(178,204,255)',\n cornerStrokeColor: '',\n cornerStyle: 'rect',\n cornerDashArray: null,\n hasControls: true,\n borderColor: 'rgb(178,204,255)',\n borderDashArray: null,\n borderOpacityWhenMoving: 0.4,\n borderScaleFactor: 1,\n hasBorders: true,\n selectionBackgroundColor: '',\n selectable: true,\n evented: true,\n perPixelTargetFind: false,\n activeOn: 'down',\n hoverCursor: null,\n moveCursor: null,\n};\n","/**\n * Easing functions\n * @see {@link http://gizma.com/easing/ Easing Equations by Robert Penner}\n */\n\nimport { twoMathPi, halfPI } from '../../constants';\nimport type { TEasingFunction } from './types';\n\nconst normalize = (a: number, c: number, p: number, s: number) => {\n if (a < Math.abs(c)) {\n a = c;\n s = p / 4;\n } else {\n //handle the 0/0 case:\n if (c === 0 && a === 0) {\n s = (p / twoMathPi) * Math.asin(1);\n } else {\n s = (p / twoMathPi) * Math.asin(c / a);\n }\n }\n return { a, c, p, s };\n};\n\nconst elastic = (\n a: number,\n s: number,\n p: number,\n t: number,\n d: number,\n): number =>\n a * Math.pow(2, 10 * (t -= 1)) * Math.sin(((t * d - s) * twoMathPi) / p);\n\n/**\n * Default sinusoidal easing\n */\nexport const defaultEasing: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Cubic easing in\n */\nexport const easeInCubic: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 3 + b;\n\n/**\n * Cubic easing out\n */\nexport const easeOutCubic: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 3 + 1) + b;\n\n/**\n * Cubic easing in and out\n */\nexport const easeInOutCubic: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 3 + b;\n }\n return (c / 2) * ((t - 2) ** 3 + 2) + b;\n};\n\n/**\n * Quartic easing in\n */\nexport const easeInQuart: TEasingFunction = (t, b, c, d) =>\n c * (t /= d) * t ** 3 + b;\n\n/**\n * Quartic easing out\n */\nexport const easeOutQuart: TEasingFunction = (t, b, c, d) =>\n -c * ((t = t / d - 1) * t ** 3 - 1) + b;\n\n/**\n * Quartic easing in and out\n */\nexport const easeInOutQuart: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 4 + b;\n }\n return (-c / 2) * ((t -= 2) * t ** 3 - 2) + b;\n};\n\n/**\n * Quintic easing in\n */\nexport const easeInQuint: TEasingFunction = (t, b, c, d) =>\n c * (t / d) ** 5 + b;\n\n/**\n * Quintic easing out\n */\nexport const easeOutQuint: TEasingFunction = (t, b, c, d) =>\n c * ((t / d - 1) ** 5 + 1) + b;\n\n/**\n * Quintic easing in and out\n */\nexport const easeInOutQuint: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 5 + b;\n }\n return (c / 2) * ((t - 2) ** 5 + 2) + b;\n};\n\n/**\n * Sinusoidal easing in\n */\nexport const easeInSine: TEasingFunction = (t, b, c, d) =>\n -c * Math.cos((t / d) * halfPI) + c + b;\n\n/**\n * Sinusoidal easing out\n */\nexport const easeOutSine: TEasingFunction = (t, b, c, d) =>\n c * Math.sin((t / d) * halfPI) + b;\n\n/**\n * Sinusoidal easing in and out\n */\nexport const easeInOutSine: TEasingFunction = (t, b, c, d) =>\n (-c / 2) * (Math.cos((Math.PI * t) / d) - 1) + b;\n\n/**\n * Exponential easing in\n */\nexport const easeInExpo: TEasingFunction = (t, b, c, d) =>\n t === 0 ? b : c * 2 ** (10 * (t / d - 1)) + b;\n\n/**\n * Exponential easing out\n */\nexport const easeOutExpo: TEasingFunction = (t, b, c, d) =>\n t === d ? b + c : c * -(2 ** ((-10 * t) / d) + 1) + b;\n\n/**\n * Exponential easing in and out\n */\nexport const easeInOutExpo: TEasingFunction = (t, b, c, d) => {\n if (t === 0) {\n return b;\n }\n if (t === d) {\n return b + c;\n }\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * 2 ** (10 * (t - 1)) + b;\n }\n return (c / 2) * -(2 ** (-10 * --t) + 2) + b;\n};\n\n/**\n * Circular easing in\n */\nexport const easeInCirc: TEasingFunction = (t, b, c, d) =>\n -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;\n\n/**\n * Circular easing out\n */\nexport const easeOutCirc: TEasingFunction = (t, b, c, d) =>\n c * Math.sqrt(1 - (t = t / d - 1) * t) + b;\n\n/**\n * Circular easing in and out\n */\nexport const easeInOutCirc: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (-c / 2) * (Math.sqrt(1 - t ** 2) - 1) + b;\n }\n return (c / 2) * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;\n};\n\n/**\n * Elastic easing in\n */\nexport const easeInElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP } = normalize(a, c, p, s);\n return -elastic(normA, normS, normP, t, d) + b;\n};\n\n/**\n * Elastic easing out\n */\nexport const easeOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d;\n if (t === 1) {\n return b + c;\n }\n if (!p) {\n p = d * 0.3;\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n return (\n normA * 2 ** (-10 * t) * Math.sin(((t * d - normS) * twoMathPi) / normP) +\n normC +\n b\n );\n};\n\n/**\n * Elastic easing in and out\n */\nexport const easeInOutElastic: TEasingFunction = (t, b, c, d) => {\n const s = 1.70158,\n a = c;\n let p = 0;\n if (t === 0) {\n return b;\n }\n t /= d / 2;\n if (t === 2) {\n return b + c;\n }\n if (!p) {\n p = d * (0.3 * 1.5);\n }\n const { a: normA, s: normS, p: normP, c: normC } = normalize(a, c, p, s);\n if (t < 1) {\n return -0.5 * elastic(normA, normS, normP, t, d) + b;\n }\n return (\n normA *\n Math.pow(2, -10 * (t -= 1)) *\n Math.sin(((t * d - normS) * twoMathPi) / normP) *\n 0.5 +\n normC +\n b\n );\n};\n\n/**\n * Backwards easing in\n */\nexport const easeInBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * (t /= d) * t * ((s + 1) * t - s) + b;\n\n/**\n * Backwards easing out\n */\nexport const easeOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) =>\n c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;\n\n/**\n * Backwards easing in and out\n */\nexport const easeInOutBack: TEasingFunction = (t, b, c, d, s = 1.70158) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * (t * t * (((s *= 1.525) + 1) * t - s)) + b;\n }\n return (c / 2) * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b;\n};\n\n/**\n * Bouncing easing out\n */\nexport const easeOutBounce: TEasingFunction = (t, b, c, d) => {\n if ((t /= d) < 1 / 2.75) {\n return c * (7.5625 * t * t) + b;\n } else if (t < 2 / 2.75) {\n return c * (7.5625 * (t -= 1.5 / 2.75) * t + 0.75) + b;\n } else if (t < 2.5 / 2.75) {\n return c * (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375) + b;\n } else {\n return c * (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375) + b;\n }\n};\n\n/**\n * Bouncing easing in\n */\nexport const easeInBounce: TEasingFunction = (t, b, c, d) =>\n c - easeOutBounce(d - t, 0, c, d) + b;\n\n/**\n * Bouncing easing in and out\n */\nexport const easeInOutBounce: TEasingFunction = (t, b, c, d) =>\n t < d / 2\n ? easeInBounce(t * 2, 0, c, d) * 0.5 + b\n : easeOutBounce(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;\n\n/**\n * Quadratic easing in\n */\nexport const easeInQuad: TEasingFunction = (t, b, c, d) => c * (t /= d) * t + b;\n\n/**\n * Quadratic easing out\n */\nexport const easeOutQuad: TEasingFunction = (t, b, c, d) =>\n -c * (t /= d) * (t - 2) + b;\n\n/**\n * Quadratic easing in and out\n */\nexport const easeInOutQuad: TEasingFunction = (t, b, c, d) => {\n t /= d / 2;\n if (t < 1) {\n return (c / 2) * t ** 2 + b;\n }\n return (-c / 2) * (--t * (t - 2) - 1) + b;\n};\n","import { noop } from '../../constants';\nimport { requestAnimFrame } from './AnimationFrameProvider';\nimport { runningAnimations } from './AnimationRegistry';\nimport { defaultEasing } from './easing';\nimport type {\n AnimationState,\n TAbortCallback,\n TBaseAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultAbort = () => false;\n\nexport abstract class AnimationBase<\n T extends number | number[] = number | number[],\n> {\n declare readonly startValue: T;\n declare readonly endValue: T;\n declare readonly duration: number;\n declare readonly delay: number;\n\n protected declare readonly byValue: T;\n protected declare readonly easing: TEasingFunction;\n\n private declare readonly _onStart: VoidFunction;\n private declare readonly _onChange: TOnAnimationChangeCallback;\n private declare readonly _onComplete: TOnAnimationChangeCallback;\n private declare readonly _abort: TAbortCallback;\n\n /**\n * Used to register the animation to a target object\n * so that it can be cancelled within the object context\n */\n declare readonly target?: unknown;\n\n private _state: AnimationState = 'pending';\n /**\n * Time %, or the ratio of `timeElapsed / duration`\n * @see tick\n */\n durationProgress = 0;\n /**\n * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)`\n */\n valueProgress = 0;\n /**\n * Current value\n */\n declare value: T;\n /**\n * Animation start time ms\n */\n private declare startTime: number;\n\n constructor({\n startValue,\n byValue,\n duration = 500,\n delay = 0,\n easing = defaultEasing,\n onStart = noop,\n onChange = noop,\n onComplete = noop,\n abort = defaultAbort,\n target,\n }: TBaseAnimationOptions) {\n this.tick = this.tick.bind(this);\n\n this.duration = duration;\n this.delay = delay;\n this.easing = easing;\n this._onStart = onStart;\n this._onChange = onChange;\n this._onComplete = onComplete;\n this._abort = abort;\n this.target = target;\n\n this.startValue = startValue;\n this.byValue = byValue;\n this.value = this.startValue;\n this.endValue = Object.freeze(this.calculate(this.duration).value);\n }\n\n get state() {\n return this._state;\n }\n\n isDone() {\n return this._state === 'aborted' || this._state === 'completed';\n }\n\n /**\n * Calculate the current value based on the easing parameters\n * @param timeElapsed in ms\n * @protected\n */\n protected abstract calculate(timeElapsed: number): {\n value: T;\n valueProgress: number;\n };\n\n start() {\n const firstTick: FrameRequestCallback = (timestamp) => {\n if (this._state !== 'pending') return;\n this.startTime = timestamp || +new Date();\n this._state = 'running';\n this._onStart();\n this.tick(this.startTime);\n };\n\n this.register();\n\n // setTimeout(cb, 0) will run cb on the next frame, causing a delay\n // we don't want that\n if (this.delay > 0) {\n setTimeout(() => requestAnimFrame(firstTick), this.delay);\n } else {\n requestAnimFrame(firstTick);\n }\n }\n\n private tick(t: number) {\n const durationMs = (t || +new Date()) - this.startTime;\n const boundDurationMs = Math.min(durationMs, this.duration);\n this.durationProgress = boundDurationMs / this.duration;\n const { value, valueProgress } = this.calculate(boundDurationMs);\n this.value = Object.freeze(value);\n this.valueProgress = valueProgress;\n\n if (this._state === 'aborted') {\n return;\n } else if (\n this._abort(this.value, this.valueProgress, this.durationProgress)\n ) {\n this._state = 'aborted';\n this.unregister();\n } else if (durationMs >= this.duration) {\n this.durationProgress = this.valueProgress = 1;\n this._onChange(this.endValue, this.valueProgress, this.durationProgress);\n this._state = 'completed';\n this._onComplete(\n this.endValue,\n this.valueProgress,\n this.durationProgress,\n );\n this.unregister();\n } else {\n this._onChange(this.value, this.valueProgress, this.durationProgress);\n requestAnimFrame(this.tick);\n }\n }\n\n private register() {\n runningAnimations.push(this as unknown as AnimationBase);\n }\n\n private unregister() {\n runningAnimations.remove(this as unknown as AnimationBase);\n }\n\n abort() {\n this._state = 'aborted';\n this.unregister();\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ValueAnimationOptions } from './types';\n\nexport class ValueAnimation extends AnimationBase {\n constructor({\n startValue = 0,\n endValue = 100,\n ...otherOptions\n }: ValueAnimationOptions) {\n super({\n ...otherOptions,\n startValue,\n byValue: endValue - startValue,\n });\n }\n\n protected calculate(timeElapsed: number) {\n const value = this.easing(\n timeElapsed,\n this.startValue,\n this.byValue,\n this.duration,\n );\n return {\n value,\n valueProgress: Math.abs((value - this.startValue) / this.byValue),\n };\n }\n}\n","import { AnimationBase } from './AnimationBase';\nimport type { ArrayAnimationOptions } from './types';\n\nexport class ArrayAnimation extends AnimationBase {\n constructor({\n startValue = [0],\n endValue = [100],\n ...options\n }: ArrayAnimationOptions) {\n super({\n ...options,\n startValue,\n byValue: endValue.map((value, i) => value - startValue[i]),\n });\n }\n protected calculate(timeElapsed: number) {\n const values = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n );\n return {\n value: values,\n valueProgress: Math.abs(\n (values[0] - this.startValue[0]) / this.byValue[0],\n ),\n };\n }\n}\n","import { Color } from '../../color/Color';\nimport type { TRGBAColorSource } from '../../color/typedefs';\nimport { halfPI } from '../../constants';\nimport { capValue } from '../misc/capValue';\nimport { AnimationBase } from './AnimationBase';\nimport type {\n ColorAnimationOptions,\n TEasingFunction,\n TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultColorEasing: TEasingFunction = (\n timeElapsed,\n startValue,\n byValue,\n duration,\n) => {\n const durationProgress = 1 - Math.cos((timeElapsed / duration) * halfPI);\n return startValue + byValue * durationProgress;\n};\n\nconst wrapColorCallback = (\n callback?: TOnAnimationChangeCallback,\n) =>\n callback &&\n ((rgba: TRGBAColorSource, valueProgress: number, durationProgress: number) =>\n callback(new Color(rgba).toRgba(), valueProgress, durationProgress));\n\nexport class ColorAnimation extends AnimationBase {\n constructor({\n startValue,\n endValue,\n easing = defaultColorEasing,\n onChange,\n onComplete,\n abort,\n ...options\n }: ColorAnimationOptions) {\n const startColor = new Color(startValue).getSource();\n const endColor = new Color(endValue).getSource();\n super({\n ...options,\n startValue: startColor,\n byValue: endColor.map(\n (value, i) => value - startColor[i],\n ) as TRGBAColorSource,\n easing,\n onChange: wrapColorCallback(onChange),\n onComplete: wrapColorCallback(onComplete),\n abort: wrapColorCallback(abort),\n });\n }\n protected calculate(timeElapsed: number) {\n const [r, g, b, a] = this.startValue.map((value, i) =>\n this.easing(timeElapsed, value, this.byValue[i], this.duration, i),\n ) as TRGBAColorSource;\n const value = [\n ...[r, g, b].map(Math.round),\n capValue(0, a, 1),\n ] as TRGBAColorSource;\n return {\n value,\n valueProgress:\n // to correctly calculate the change ratio we must find a changed value\n value\n .map((p, i) =>\n this.byValue[i] !== 0\n ? Math.abs((p - this.startValue[i]) / this.byValue[i])\n : 0,\n )\n .find((p) => p !== 0) || 0,\n };\n }\n}\n","import { ValueAnimation } from './ValueAnimation';\nimport { ArrayAnimation } from './ArrayAnimation';\nimport { ColorAnimation } from './ColorAnimation';\nimport type {\n ValueAnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n} from './types';\nimport type { TColorArg } from '../../color/typedefs';\n\nexport type TAnimation =\n T extends TColorArg\n ? ColorAnimation\n : T extends number[]\n ? ArrayAnimation\n : ValueAnimation;\n\nconst isArrayAnimation = (\n options: ArrayAnimationOptions | ValueAnimationOptions,\n): options is ArrayAnimationOptions => {\n return Array.isArray(options.startValue) || Array.isArray(options.endValue);\n};\n\n/**\n * Changes value(s) from startValue to endValue within a certain period of time,\n * invoking callbacks as the value(s) change.\n *\n * @example\n * animate({\n * startValue: 1,\n * endValue: 0,\n * onChange: (v) => {\n * obj.set('opacity', v);\n * // since we are running in a requested frame we should call `renderAll` and not `requestRenderAll`\n * canvas.renderAll();\n * }\n * });\n *\n * @example Using lists:\n * animate({\n * startValue: [1, 2, 3],\n * endValue: [2, 4, 6],\n * onChange: ([x, y, zoom]) => {\n * canvas.zoomToPoint(new Point(x, y), zoom);\n * canvas.renderAll();\n * }\n * });\n *\n */\nexport function animate(options: ArrayAnimationOptions): ArrayAnimation;\nexport function animate(options: ValueAnimationOptions): ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n>(\n options: T,\n): T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation;\nexport function animate<\n T extends ValueAnimationOptions | ArrayAnimationOptions,\n R extends T extends ArrayAnimationOptions ? ArrayAnimation : ValueAnimation,\n>(options: T): R {\n const animation = (\n isArrayAnimation(options)\n ? new ArrayAnimation(options)\n : new ValueAnimation(options)\n ) as R;\n animation.start();\n return animation;\n}\n\nexport function animateColor(options: ColorAnimationOptions) {\n const animation = new ColorAnimation(options);\n animation.start();\n return animation;\n}\n","import { Point } from './Point';\nimport { createVector } from './util/misc/vectors';\n\n/* Adaptation of work of Kevin Lindsey (kevin@kevlindev.com) */\n\nexport type IntersectionType = 'Intersection' | 'Coincident' | 'Parallel';\n\nexport class Intersection {\n declare points: Point[];\n\n declare status?: IntersectionType;\n\n constructor(status?: IntersectionType) {\n this.status = status;\n this.points = [];\n }\n\n /**\n * Used to verify if a point is alredy in the collection\n * @param {Point} point\n * @returns {boolean}\n */\n private includes(point: Point): boolean {\n return this.points.some((p) => p.eq(point));\n }\n\n /**\n * Appends points of intersection\n * @param {...Point[]} points\n * @return {Intersection} thisArg\n * @chainable\n */\n private append(...points: Point[]): Intersection {\n this.points = this.points.concat(\n points.filter((point) => {\n return !this.includes(point);\n }),\n );\n return this;\n }\n\n /**\n * check if point T is on the segment or line defined between A and B\n *\n * @param {Point} T the point we are checking for\n * @param {Point} A one extremity of the segment\n * @param {Point} B the other extremity of the segment\n * @param [infinite] if true checks if `T` is on the line defined by `A` and `B`\n * @returns true if `T` is contained\n */\n static isPointContained(T: Point, A: Point, B: Point, infinite = false) {\n if (A.eq(B)) {\n // Edge case: the segment is a point, we check for coincidence,\n // infinite param has no meaning because there are infinite lines to consider\n return T.eq(A);\n } else if (A.x === B.x) {\n // Edge case: horizontal line.\n // we first check if T.x has the same value, and then if T.y is contained between A.y and B.y\n return (\n T.x === A.x &&\n (infinite || (T.y >= Math.min(A.y, B.y) && T.y <= Math.max(A.y, B.y)))\n );\n } else if (A.y === B.y) {\n // Edge case: vertical line.\n // we first check if T.y has the same value, and then if T.x is contained between A.x and B.x\n return (\n T.y === A.y &&\n (infinite || (T.x >= Math.min(A.x, B.x) && T.x <= Math.max(A.x, B.x)))\n );\n } else {\n // Generic case: sloped line.\n // we check that AT has the same slope as AB\n // for the segment case we need both the vectors to have the same direction and for AT to be lte AB in size\n // for the infinite case we check the absolute value of the slope, since direction is meaningless\n const AB = createVector(A, B);\n const AT = createVector(A, T);\n const s = AT.divide(AB);\n return infinite\n ? Math.abs(s.x) === Math.abs(s.y)\n : s.x === s.y && s.x >= 0 && s.x <= 1;\n }\n }\n\n /**\n * Use the ray casting algorithm to determine if {@link point} is in the polygon defined by {@link points}\n * @see https://en.wikipedia.org/wiki/Point_in_polygon\n * @param point\n * @param points polygon points\n * @returns\n */\n static isPointInPolygon(point: Point, points: Point[]) {\n const other = new Point(point).setX(\n Math.min(point.x - 1, ...points.map((p) => p.x)),\n );\n let hits = 0;\n for (let index = 0; index < points.length; index++) {\n const inter = this.intersectSegmentSegment(\n // polygon side\n points[index],\n points[(index + 1) % points.length],\n // ray\n point,\n other,\n );\n if (inter.includes(point)) {\n // point is on the polygon side\n return true;\n }\n hits += Number(inter.status === 'Intersection');\n }\n return hits % 2 === 1;\n }\n\n /**\n * Checks if a line intersects another\n * @see {@link https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection line intersection}\n * @see {@link https://en.wikipedia.org/wiki/Cramer%27s_rule Cramer's rule}\n * @static\n * @param {Point} a1\n * @param {Point} a2\n * @param {Point} b1\n * @param {Point} b2\n * @param {boolean} [aInfinite=true] check segment intersection by passing `false`\n * @param {boolean} [bInfinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLineLine(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n aInfinite = true,\n bInfinite = true,\n ): Intersection {\n const a2xa1x = a2.x - a1.x,\n a2ya1y = a2.y - a1.y,\n b2xb1x = b2.x - b1.x,\n b2yb1y = b2.y - b1.y,\n a1xb1x = a1.x - b1.x,\n a1yb1y = a1.y - b1.y,\n uaT = b2xb1x * a1yb1y - b2yb1y * a1xb1x,\n ubT = a2xa1x * a1yb1y - a2ya1y * a1xb1x,\n uB = b2yb1y * a2xa1x - b2xb1x * a2ya1y;\n if (uB !== 0) {\n const ua = uaT / uB,\n ub = ubT / uB;\n if (\n (aInfinite || (0 <= ua && ua <= 1)) &&\n (bInfinite || (0 <= ub && ub <= 1))\n ) {\n return new Intersection('Intersection').append(\n new Point(a1.x + ua * a2xa1x, a1.y + ua * a2ya1y),\n );\n } else {\n return new Intersection();\n }\n } else {\n if (uaT === 0 || ubT === 0) {\n const segmentsCoincide =\n aInfinite ||\n bInfinite ||\n Intersection.isPointContained(a1, b1, b2) ||\n Intersection.isPointContained(a2, b1, b2) ||\n Intersection.isPointContained(b1, a1, a2) ||\n Intersection.isPointContained(b2, a1, a2);\n return new Intersection(segmentsCoincide ? 'Coincident' : undefined);\n } else {\n return new Intersection('Parallel');\n }\n }\n }\n\n /**\n * Checks if a segment intersects a line\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} s1 boundary point of segment\n * @param {Point} s2 other boundary point of segment\n * @param {Point} l1 point on line\n * @param {Point} l2 other point on line\n * @return {Intersection}\n */\n static intersectSegmentLine(\n s1: Point,\n s2: Point,\n l1: Point,\n l2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(s1, s2, l1, l2, false, true);\n }\n\n /**\n * Checks if a segment intersects another\n * @see {@link intersectLineLine} for line intersection\n * @static\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point} b1 boundary point of segment\n * @param {Point} b2 other boundary point of segment\n * @return {Intersection}\n */\n static intersectSegmentSegment(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n ): Intersection {\n return Intersection.intersectLineLine(a1, a2, b1, b2, false, false);\n }\n\n /**\n * Checks if line intersects polygon\n *\n * @todo account for stroke\n *\n * @static\n * @see {@link intersectSegmentPolygon} for segment intersection\n * @param {Point} a1 point on line\n * @param {Point} a2 other point on line\n * @param {Point[]} points polygon points\n * @param {boolean} [infinite=true] check segment intersection by passing `false`\n * @return {Intersection}\n */\n static intersectLinePolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n infinite = true,\n ): Intersection {\n const result = new Intersection();\n const length = points.length;\n\n for (let i = 0, b1, b2, inter; i < length; i++) {\n b1 = points[i];\n b2 = points[(i + 1) % length];\n inter = Intersection.intersectLineLine(a1, a2, b1, b2, infinite, false);\n if (inter.status === 'Coincident') {\n return inter;\n }\n result.append(...inter.points);\n }\n\n if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if segment intersects polygon\n * @static\n * @see {@link intersectLinePolygon} for line intersection\n * @param {Point} a1 boundary point of segment\n * @param {Point} a2 other boundary point of segment\n * @param {Point[]} points polygon points\n * @return {Intersection}\n */\n static intersectSegmentPolygon(\n a1: Point,\n a2: Point,\n points: Point[],\n ): Intersection {\n return Intersection.intersectLinePolygon(a1, a2, points, false);\n }\n\n /**\n * Checks if polygon intersects another polygon\n *\n * @todo account for stroke\n *\n * @static\n * @param {Point[]} points1\n * @param {Point[]} points2\n * @return {Intersection}\n */\n static intersectPolygonPolygon(\n points1: Point[],\n points2: Point[],\n ): Intersection {\n const result = new Intersection(),\n length = points1.length;\n const coincidences: Intersection[] = [];\n\n for (let i = 0; i < length; i++) {\n const a1 = points1[i],\n a2 = points1[(i + 1) % length],\n inter = Intersection.intersectSegmentPolygon(a1, a2, points2);\n if (inter.status === 'Coincident') {\n coincidences.push(inter);\n result.append(a1, a2);\n } else {\n result.append(...inter.points);\n }\n }\n\n if (coincidences.length > 0 && coincidences.length === points1.length) {\n return new Intersection('Coincident');\n } else if (result.points.length > 0) {\n result.status = 'Intersection';\n }\n\n return result;\n }\n\n /**\n * Checks if polygon intersects rectangle\n * @static\n * @see {@link intersectPolygonPolygon} for polygon intersection\n * @param {Point[]} points polygon points\n * @param {Point} r1 top left point of rect\n * @param {Point} r2 bottom right point of rect\n * @return {Intersection}\n */\n static intersectPolygonRectangle(\n points: Point[],\n r1: Point,\n r2: Point,\n ): Intersection {\n const min = r1.min(r2),\n max = r1.max(r2),\n topRight = new Point(max.x, min.y),\n bottomLeft = new Point(min.x, max.y);\n\n return Intersection.intersectPolygonPolygon(points, [\n min,\n topRight,\n max,\n bottomLeft,\n ]);\n }\n}\n","import type {\n TBBox,\n TCornerPoint,\n TDegree,\n TMat2D,\n TOriginX,\n TOriginY,\n} from '../../typedefs';\nimport { SCALE_X, SCALE_Y, iMatrix } from '../../constants';\nimport { Intersection } from '../../Intersection';\nimport { Point } from '../../Point';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n createRotateMatrix,\n createTranslateMatrix,\n composeMatrix,\n invertTransform,\n multiplyTransformMatrices,\n transformPoint,\n calcPlaneRotation,\n} from '../../util/misc/matrix';\nimport { radiansToDegrees } from '../../util/misc/radiansDegreesConversion';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { StaticCanvas } from '../../canvas/StaticCanvas';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type { ControlProps } from './types/ControlProps';\nimport { resolveOrigin } from '../../util/misc/resolveOrigin';\nimport type { Group } from '../Group';\nimport { calcDimensionsMatrix } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport { CommonMethods } from '../../CommonMethods';\nimport type { BaseProps } from './types/BaseProps';\nimport type { FillStrokeProps } from './types/FillStrokeProps';\nimport { CENTER, LEFT, TOP } from '../../constants';\n\ntype TMatrixCache = {\n key: number[];\n value: TMat2D;\n};\n\ntype TACoords = TCornerPoint;\n\nexport class ObjectGeometry\n extends CommonMethods\n implements\n Pick,\n BaseProps,\n Pick\n{\n // #region Geometry\n\n declare padding: number;\n\n /**\n * Describe object's corner position in scene coordinates.\n * The coordinates are derived from the following:\n * left, top, width, height, scaleX, scaleY, skewX, skewY, angle, strokeWidth.\n * The coordinates do not depend on viewport changes.\n * The coordinates get updated with {@link setCoords}.\n * You can calculate them without updating with {@link calcACoords()}\n */\n declare aCoords: TACoords;\n\n /**\n * storage cache for object transform matrix\n */\n declare ownMatrixCache?: TMatrixCache;\n\n /**\n * storage cache for object full transform matrix\n */\n declare matrixCache?: TMatrixCache;\n\n /**\n * A Reference of the Canvas where the object is actually added\n * @type StaticCanvas | Canvas;\n * @default undefined\n * @private\n */\n declare canvas?: StaticCanvas | Canvas;\n\n /**\n * @returns {number} x position according to object's {@link originX} property in canvas coordinate plane\n */\n getX(): number {\n return this.getXY().x;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in canvas coordinate plane\n */\n setX(value: number) {\n this.setXY(this.getXY().setX(value));\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in canvas coordinate plane\n */\n getY(): number {\n return this.getXY().y;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in canvas coordinate plane\n */\n setY(value: number) {\n this.setXY(this.getXY().setY(value));\n }\n\n /**\n * @returns {number} x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getX}\n */\n getRelativeX(): number {\n return this.left;\n }\n\n /**\n * @param {number} value x position according to object's {@link originX} property in parent's coordinate plane\\\n * if parent is canvas then this method is identical to {@link setX}\n */\n setRelativeX(value: number) {\n this.left = value;\n }\n\n /**\n * @returns {number} y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link getY}\n */\n getRelativeY(): number {\n return this.top;\n }\n\n /**\n * @param {number} value y position according to object's {@link originY} property in parent's coordinate plane\\\n * if parent is canvas then this property is identical to {@link setY}\n */\n setRelativeY(value: number) {\n this.top = value;\n }\n\n /**\n * @returns {Point} x position according to object's {@link originX} {@link originY} properties in canvas coordinate plane\n */\n getXY(): Point {\n const relativePosition = this.getRelativeXY();\n return this.group\n ? transformPoint(relativePosition, this.group.calcTransformMatrix())\n : relativePosition;\n }\n\n /**\n * Set an object position to a particular point, the point is intended in absolute ( canvas ) coordinate.\n * You can specify {@link originX} and {@link originY} values,\n * that otherwise are the object's current values.\n * @example Set object's bottom left corner to point (5,5) on canvas\n * object.setXY(new Point(5, 5), 'left', 'bottom').\n * @param {Point} point position in scene coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setXY(point: Point, originX?: TOriginX, originY?: TOriginY) {\n if (this.group) {\n point = transformPoint(\n point,\n invertTransform(this.group.calcTransformMatrix()),\n );\n }\n this.setRelativeXY(point, originX, originY);\n }\n\n /**\n * @returns {Point} x,y position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n */\n getRelativeXY(): Point {\n return new Point(this.left, this.top);\n }\n\n /**\n * As {@link setXY}, but in current parent's coordinate plane (the current group if any or the canvas)\n * @param {Point} point position according to object's {@link originX} {@link originY} properties in parent's coordinate plane\n * @param {TOriginX} [originX] Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} [originY] Vertical origin: 'top', 'center' or 'bottom'\n */\n setRelativeXY(\n point: Point,\n originX: TOriginX = this.originX,\n originY: TOriginY = this.originY,\n ) {\n this.setPositionByOrigin(point, originX, originY);\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return false;\n }\n\n /**\n * @return {Point[]} [tl, tr, br, bl] in the scene plane\n */\n getCoords(): Point[] {\n const { tl, tr, br, bl } =\n this.aCoords || (this.aCoords = this.calcACoords());\n const coords = [tl, tr, br, bl];\n if (this.group) {\n const t = this.group.calcTransformMatrix();\n return coords.map((p) => transformPoint(p, t));\n }\n return coords;\n }\n\n /**\n * Checks if object intersects with the scene rect formed by {@link tl} and {@link br}\n */\n intersectsWithRect(tl: Point, br: Point): boolean {\n const intersection = Intersection.intersectPolygonRectangle(\n this.getCoords(),\n tl,\n br,\n );\n return intersection.status === 'Intersection';\n }\n\n /**\n * Checks if object intersects with another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object intersects with another object\n */\n intersectsWithObject(other: ObjectGeometry): boolean {\n const intersection = Intersection.intersectPolygonPolygon(\n this.getCoords(),\n other.getCoords(),\n );\n\n return (\n intersection.status === 'Intersection' ||\n intersection.status === 'Coincident' ||\n other.isContainedWithinObject(this) ||\n this.isContainedWithinObject(other)\n );\n }\n\n /**\n * Checks if object is fully contained within area of another object\n * @param {Object} other Object to test\n * @return {Boolean} true if object is fully contained within area of another object\n */\n isContainedWithinObject(other: ObjectGeometry): boolean {\n const points = this.getCoords();\n return points.every((point) => other.containsPoint(point));\n }\n\n /**\n * Checks if object is fully contained within the scene rect formed by {@link tl} and {@link br}\n */\n isContainedWithinRect(tl: Point, br: Point): boolean {\n const { left, top, width, height } = this.getBoundingRect();\n return (\n left >= tl.x &&\n left + width <= br.x &&\n top >= tl.y &&\n top + height <= br.y\n );\n }\n\n isOverlapping(other: T): boolean {\n return (\n this.intersectsWithObject(other) ||\n this.isContainedWithinObject(other) ||\n other.isContainedWithinObject(this)\n );\n }\n\n /**\n * Checks if point is inside the object\n * @param {Point} point Point to check against\n * @return {Boolean} true if point is inside the object\n */\n containsPoint(point: Point): boolean {\n return Intersection.isPointInPolygon(point, this.getCoords());\n }\n\n /**\n * Checks if object is contained within the canvas with current viewportTransform\n * the check is done stopping at first point that appears on screen\n * @return {Boolean} true if object is fully or partially contained within canvas\n */\n isOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n const points = this.getCoords();\n // if some point is on screen, the object is on screen.\n if (\n points.some(\n (point) =>\n point.x <= br.x &&\n point.x >= tl.x &&\n point.y <= br.y &&\n point.y >= tl.y,\n )\n ) {\n return true;\n }\n // no points on screen, check intersection with absolute coordinates\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n // check if the object is so big that it contains the entire viewport\n return this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Checks if object is partially contained within the canvas with current viewportTransform\n * @return {Boolean} true if object is partially contained within canvas\n */\n isPartiallyOnScreen(): boolean {\n if (!this.canvas) {\n return false;\n }\n const { tl, br } = this.canvas.vptCoords;\n if (this.intersectsWithRect(tl, br)) {\n return true;\n }\n const allPointsAreOutside = this.getCoords().every(\n (point) =>\n (point.x >= br.x || point.x <= tl.x) &&\n (point.y >= br.y || point.y <= tl.y),\n );\n // check if the object is so big that it contains the entire viewport\n return allPointsAreOutside && this.containsPoint(tl.midPointFrom(br));\n }\n\n /**\n * Returns coordinates of object's bounding rectangle (left, top, width, height)\n * the box is intended as aligned to axis of canvas.\n * @return {Object} Object with left, top, width, height properties\n */\n getBoundingRect(): TBBox {\n return makeBoundingBoxFromPoints(this.getCoords());\n }\n\n /**\n * Returns width of an object's bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} width value\n */\n getScaledWidth(): number {\n return this._getTransformedDimensions().x;\n }\n\n /**\n * Returns height of an object bounding box counting transformations\n * @todo shouldn't this account for group transform and return the actual size in canvas coordinate plane?\n * @return {Number} height value\n */\n getScaledHeight(): number {\n return this._getTransformedDimensions().y;\n }\n\n /**\n * Scales an object (equally by x and y)\n * @param {Number} value Scale factor\n * @return {void}\n */\n scale(value: number): void {\n this._set(SCALE_X, value);\n this._set(SCALE_Y, value);\n this.setCoords();\n }\n\n /**\n * Scales an object to a given width, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New width value\n * @return {void}\n */\n scaleToWidth(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().width / this.getScaledWidth();\n return this.scale(value / this.width / boundingRectFactor);\n }\n\n /**\n * Scales an object to a given height, with respect to bounding box (scaling by x/y equally)\n * @param {Number} value New height value\n * @return {void}\n */\n scaleToHeight(value: number) {\n // adjust to bounding rect factor so that rotated shapes would fit as well\n const boundingRectFactor =\n this.getBoundingRect().height / this.getScaledHeight();\n return this.scale(value / this.height / boundingRectFactor);\n }\n\n getCanvasRetinaScaling() {\n return this.canvas?.getRetinaScaling() || 1;\n }\n\n /**\n * Returns the object angle relative to canvas counting also the group property\n * @returns {TDegree}\n */\n getTotalAngle(): TDegree {\n return this.group\n ? radiansToDegrees(calcPlaneRotation(this.calcTransformMatrix()))\n : this.angle;\n }\n\n /**\n * Retrieves viewportTransform from Object's canvas if available\n * @return {TMat2D}\n */\n getViewportTransform(): TMat2D {\n return this.canvas?.viewportTransform || (iMatrix.concat() as TMat2D);\n }\n\n /**\n * Calculates the coordinates of the 4 corner of the bbox, in absolute coordinates.\n * those never change with zoom or viewport changes.\n * @return {TCornerPoint}\n */\n calcACoords(): TCornerPoint {\n const rotateMatrix = createRotateMatrix({ angle: this.angle }),\n { x, y } = this.getRelativeCenterPoint(),\n tMatrix = createTranslateMatrix(x, y),\n finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),\n dim = this._getTransformedDimensions(),\n w = dim.x / 2,\n h = dim.y / 2;\n return {\n // corners\n tl: transformPoint({ x: -w, y: -h }, finalMatrix),\n tr: transformPoint({ x: w, y: -h }, finalMatrix),\n bl: transformPoint({ x: -w, y: h }, finalMatrix),\n br: transformPoint({ x: w, y: h }, finalMatrix),\n };\n }\n\n /**\n * Sets corner and controls position coordinates based on current angle, width and height, left and top.\n * aCoords are used to quickly find an object on the canvas.\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n */\n setCoords(): void {\n this.aCoords = this.calcACoords();\n }\n\n transformMatrixKey(skipGroup = false): number[] {\n let prefix: number[] = [];\n if (!skipGroup && this.group) {\n prefix = this.group.transformMatrixKey(skipGroup);\n }\n prefix.push(\n this.top,\n this.left,\n this.width,\n this.height,\n this.scaleX,\n this.scaleY,\n this.angle,\n this.strokeWidth,\n this.skewX,\n this.skewY,\n +this.flipX,\n +this.flipY,\n resolveOrigin(this.originX),\n resolveOrigin(this.originY),\n );\n\n return prefix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties.\n * @param {Boolean} [skipGroup] return transform matrix for object not counting parent transformations\n * There are some situation in which this is useful to avoid the fake rotation.\n * @return {TMat2D} transform matrix for the object\n */\n calcTransformMatrix(skipGroup = false): TMat2D {\n let matrix = this.calcOwnMatrix();\n if (skipGroup || !this.group) {\n return matrix;\n }\n const key = this.transformMatrixKey(skipGroup),\n cache = this.matrixCache;\n if (cache && cache.key.every((x, i) => x === key[i])) {\n return cache.value;\n }\n if (this.group) {\n matrix = multiplyTransformMatrices(\n this.group.calcTransformMatrix(false),\n matrix,\n );\n }\n this.matrixCache = {\n key,\n value: matrix,\n };\n return matrix;\n }\n\n /**\n * calculate transform matrix that represents the current transformations from the\n * object's properties, this matrix does not include the group transformation\n * @return {TMat2D} transform matrix for the object\n */\n calcOwnMatrix(): TMat2D {\n const key = this.transformMatrixKey(true),\n cache = this.ownMatrixCache;\n if (cache && cache.key === key) {\n return cache.value;\n }\n const center = this.getRelativeCenterPoint(),\n options = {\n angle: this.angle,\n translateX: center.x,\n translateY: center.y,\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n flipX: this.flipX,\n flipY: this.flipY,\n },\n value = composeMatrix(options);\n this.ownMatrixCache = {\n key,\n value,\n };\n return value;\n }\n\n /**\n * Calculate object dimensions from its properties\n * @private\n * @returns {Point} dimensions\n */\n _getNonTransformedDimensions(): Point {\n return new Point(this.width, this.height).scalarAdd(this.strokeWidth);\n }\n\n /**\n * Calculate object dimensions for controls box, including padding and canvas zoom.\n * and active selection\n * @private\n * @param {object} [options] transform options\n * @returns {Point} dimensions\n */\n _calculateCurrentDimensions(options?: any): Point {\n return this._getTransformedDimensions(options)\n .transform(this.getViewportTransform(), true)\n .scalarAdd(2 * this.padding);\n }\n\n // #region Origin\n\n declare top: number;\n declare left: number;\n declare width: number;\n declare height: number;\n declare flipX: boolean;\n declare flipY: boolean;\n declare scaleX: number;\n declare scaleY: number;\n declare skewX: number;\n declare skewY: number;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originX: TOriginX;\n /**\n * @deprecated please use 'center' as value in new projects\n * */\n declare originY: TOriginY;\n declare angle: TDegree;\n declare strokeWidth: number;\n declare strokeUniform: boolean;\n\n /**\n * Object containing this object.\n * can influence its size and position\n */\n declare group?: Group;\n\n /**\n * Calculate object bounding box dimensions from its properties scale, skew.\n * This bounding box is aligned with object angle and not with canvas axis or screen.\n * @param {Object} [options]\n * @param {Number} [options.scaleX]\n * @param {Number} [options.scaleY]\n * @param {Number} [options.skewX]\n * @param {Number} [options.skewY]\n * @private\n * @returns {Point} dimensions\n */\n _getTransformedDimensions(options: any = {}): Point {\n const dimOptions = {\n // if scaleX or scaleY are negative numbers,\n // this will return dimensions that are negative.\n // and this will break assumptions around the codebase\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n width: this.width,\n height: this.height,\n strokeWidth: this.strokeWidth,\n ...options,\n };\n // stroke is applied before/after transformations are applied according to `strokeUniform`\n const strokeWidth = dimOptions.strokeWidth;\n let preScalingStrokeValue = strokeWidth,\n postScalingStrokeValue = 0;\n\n if (this.strokeUniform) {\n preScalingStrokeValue = 0;\n postScalingStrokeValue = strokeWidth;\n }\n const dimX = dimOptions.width + preScalingStrokeValue,\n dimY = dimOptions.height + preScalingStrokeValue,\n noSkew = dimOptions.skewX === 0 && dimOptions.skewY === 0;\n let finalDimensions;\n if (noSkew) {\n finalDimensions = new Point(\n dimX * dimOptions.scaleX,\n dimY * dimOptions.scaleY,\n );\n } else {\n finalDimensions = sizeAfterTransform(\n dimX,\n dimY,\n calcDimensionsMatrix(dimOptions),\n );\n }\n\n return finalDimensions.scalarAdd(postScalingStrokeValue);\n }\n\n /**\n * Translates the coordinates from a set of origin to another (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} fromOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} fromOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @param {TOriginX} toOriginX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} toOriginY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToGivenOrigin(\n point: Point,\n fromOriginX: TOriginX,\n fromOriginY: TOriginY,\n toOriginX: TOriginX,\n toOriginY: TOriginY,\n ): Point {\n let x = point.x,\n y = point.y;\n const offsetX = resolveOrigin(toOriginX) - resolveOrigin(fromOriginX),\n offsetY = resolveOrigin(toOriginY) - resolveOrigin(fromOriginY);\n\n if (offsetX || offsetY) {\n const dim = this._getTransformedDimensions();\n x += offsetX * dim.x;\n y += offsetY * dim.y;\n }\n\n return new Point(x, y);\n }\n\n /**\n * Translates the coordinates from origin to center coordinates (based on the object's dimensions)\n * @param {Point} point The point which corresponds to the originX and originY params\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToCenterPoint(\n point: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n if (originX === CENTER && originY === CENTER) {\n return point;\n }\n const p = this.translateToGivenOrigin(\n point,\n originX,\n originY,\n CENTER,\n CENTER,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), point);\n }\n return p;\n }\n\n /**\n * Translates the coordinates from center to origin coordinates (based on the object's dimensions)\n * @param {Point} center The point which corresponds to center of the object\n * @param {OriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {OriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n translateToOriginPoint(\n center: Point,\n originX: TOriginX,\n originY: TOriginY,\n ): Point {\n const p = this.translateToGivenOrigin(\n center,\n CENTER,\n CENTER,\n originX,\n originY,\n );\n if (this.angle) {\n return p.rotate(degreesToRadians(this.angle), center);\n }\n return p;\n }\n\n /**\n * Returns the center coordinates of the object relative to canvas\n * @return {Point}\n */\n getCenterPoint(): Point {\n const relCenter = this.getRelativeCenterPoint();\n return this.group\n ? transformPoint(relCenter, this.group.calcTransformMatrix())\n : relCenter;\n }\n\n /**\n * Returns the center coordinates of the object relative to it's parent\n * @return {Point}\n */\n getRelativeCenterPoint(): Point {\n return this.translateToCenterPoint(\n new Point(this.left, this.top),\n this.originX,\n this.originY,\n );\n }\n\n /**\n * Returns the position of the object as if it has a different origin.\n * Take an object that has left, top set to 100, 100 with origin 'left', 'top'.\n * Return the values of left top ( wrapped in a point ) that you would need to keep\n * the same position if origin where different.\n * Alternatively you can use this to also find which point in the parent plane is a specific origin\n * ( where is the bottom right corner of my object? )\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {Point}\n */\n getPointByOrigin(originX: TOriginX, originY: TOriginY): Point {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n }\n\n /**\n * Sets the position of the object taking into consideration the object's origin\n * @param {Point} pos The new position of the object\n * @param {TOriginX} originX Horizontal origin: 'left', 'center' or 'right'\n * @param {TOriginY} originY Vertical origin: 'top', 'center' or 'bottom'\n * @return {void}\n */\n setPositionByOrigin(pos: Point, originX: TOriginX, originY: TOriginY) {\n const center = this.translateToCenterPoint(pos, originX, originY),\n position = this.translateToOriginPoint(\n center,\n this.originX,\n this.originY,\n );\n this.set({ left: position.x, top: position.y });\n }\n\n /**\n * @private\n */\n _getLeftTopCoords() {\n return this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n LEFT,\n TOP,\n );\n }\n}\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport {\n ALIASING_LIMIT,\n CENTER,\n iMatrix,\n LEFT,\n SCALE_X,\n SCALE_Y,\n STROKE,\n FILL,\n TOP,\n VERSION,\n} from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport { Shadow } from '../../Shadow';\nimport type {\n TDegree,\n TFiller,\n TSize,\n TCacheCanvasDimensions,\n Abortable,\n TOptions,\n ImageFormat,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { runningAnimations } from '../../util/animation/AnimationRegistry';\nimport { capValue } from '../../util/misc/capValue';\nimport { createCanvasElement, toDataURL } from '../../util/misc/dom';\nimport { invertTransform, qrDecompose } from '../../util/misc/matrix';\nimport { enlivenObjectEnlivables } from '../../util/misc/objectEnlive';\nimport {\n resetObjectTransform,\n saveObjectTransform,\n} from '../../util/misc/objectTransforms';\nimport { sendObjectToPlane } from '../../util/misc/planeChange';\nimport { pick, pickBy } from '../../util/misc/pick';\nimport { toFixed } from '../../util/misc/toFixed';\nimport type { Group } from '../Group';\nimport { StaticCanvas } from '../../canvas/StaticCanvas';\nimport {\n isFiller,\n isSerializableFiller,\n isTextObject,\n} from '../../util/typeAssertions';\nimport type { FabricImage } from '../Image';\nimport {\n cacheProperties,\n fabricObjectDefaultValues,\n stateProperties,\n} from './defaultValues';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { SerializedObjectProps } from './types/SerializedObjectProps';\nimport type { ObjectProps } from './types/ObjectProps';\nimport { getDevicePixelRatio, getEnv } from '../../env';\nimport { log } from '../../util/internals/console';\nimport type { TColorArg } from '../../color/typedefs';\nimport type { TAnimation } from '../../util/animation/animate';\nimport { animate, animateColor } from '../../util/animation/animate';\nimport type {\n AnimationOptions,\n ArrayAnimationOptions,\n ColorAnimationOptions,\n ValueAnimationOptions,\n} from '../../util/animation/types';\nimport { ObjectGeometry } from './ObjectGeometry';\n\ntype TAncestor = FabricObject;\ntype TCollection = Group;\n\nexport type Ancestors =\n | [FabricObject | Group]\n | [FabricObject | Group, ...Group[]]\n | Group[];\n\nexport type AncestryComparison = {\n /**\n * common ancestors of `this` and`other`(may include`this` | `other`)\n */\n common: Ancestors;\n /**\n * ancestors that are of `this` only\n */\n fork: Ancestors;\n /**\n * ancestors that are of `other` only\n */\n otherFork: Ancestors;\n};\n\nexport type TCachedFabricObject = T &\n Required<\n Pick<\n T,\n | 'zoomX'\n | 'zoomY'\n | '_cacheCanvas'\n | '_cacheContext'\n | 'cacheTranslationX'\n | 'cacheTranslationY'\n >\n > & {\n _cacheContext: CanvasRenderingContext2D;\n };\n\nexport type ObjectToCanvasElementOptions = {\n format?: ImageFormat;\n /** Multiplier to scale by */\n multiplier?: number;\n /** Cropping left offset. Introduced in v1.2.14 */\n left?: number;\n /** Cropping top offset. Introduced in v1.2.14 */\n top?: number;\n /** Cropping width. Introduced in v1.2.14 */\n width?: number;\n /** Cropping height. Introduced in v1.2.14 */\n height?: number;\n /** Enable retina scaling for clone image. Introduce in 1.6.4 */\n enableRetinaScaling?: boolean;\n /** Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4 */\n withoutTransform?: boolean;\n /** Remove current object shadow. Introduced in 2.4.2 */\n withoutShadow?: boolean;\n /** Account for canvas viewport transform */\n viewportTransform?: boolean;\n /** Function to create the output canvas to export onto */\n canvasProvider?: (el?: HTMLCanvasElement) => T;\n};\n\ntype toDataURLOptions = ObjectToCanvasElementOptions & {\n quality?: number;\n};\n\n/**\n * Root object class from which all 2d shape classes inherit from\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#objects}\n *\n * @fires added\n * @fires removed\n *\n * @fires selected\n * @fires deselected\n *\n * @fires rotating\n * @fires scaling\n * @fires moving\n * @fires skewing\n * @fires modified\n *\n * @fires mousedown\n * @fires mouseup\n * @fires mouseover\n * @fires mouseout\n * @fires mousewheel\n * @fires mousedblclick\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drop\n */\nexport class FabricObject<\n Props extends TOptions = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends ObjectGeometry\n implements ObjectProps\n{\n declare minScaleLimit: number;\n\n declare opacity: number;\n\n declare paintFirst: 'fill' | 'stroke';\n declare fill: string | TFiller | null;\n declare fillRule: CanvasFillRule;\n declare stroke: string | TFiller | null;\n declare strokeDashArray: number[] | null;\n declare strokeDashOffset: number;\n declare strokeLineCap: CanvasLineCap;\n declare strokeLineJoin: CanvasLineJoin;\n declare strokeMiterLimit: number;\n\n declare globalCompositeOperation: GlobalCompositeOperation;\n declare backgroundColor: string;\n\n declare shadow: Shadow | null;\n\n declare visible: boolean;\n\n declare includeDefaultValues: boolean;\n declare excludeFromExport: boolean;\n\n declare objectCaching: boolean;\n\n declare clipPath?: FabricObject;\n declare inverted: boolean;\n declare absolutePositioned: boolean;\n declare centeredRotation: boolean;\n declare centeredScaling: boolean;\n\n /**\n * This list of properties is used to check if the state of an object is changed.\n * This state change now is only used for children of groups to understand if a group\n * needs its cache regenerated during a .set call\n * @type Array\n */\n static stateProperties: string[] = stateProperties;\n\n /**\n * List of properties to consider when checking if cache needs refresh\n * Those properties are checked by\n * calls to Object.set(key, value). If the key is in this list, the object is marked as dirty\n * and refreshed at the next render\n * @type Array\n */\n static cacheProperties: string[] = cacheProperties;\n\n /**\n * When set to `true`, object's cache will be rerendered next render call.\n * since 1.7.0\n * @type Boolean\n * @default true\n */\n declare dirty: boolean;\n\n /**\n * Quick access for the _cacheCanvas rendering context\n * This is part of the objectCaching feature\n * since 1.7.0\n * @type boolean\n * @default undefined\n * @private\n */\n _cacheContext: CanvasRenderingContext2D | null = null;\n\n /**\n * A reference to the HTMLCanvasElement that is used to contain the cache of the object\n * this canvas element is resized and cleared as needed\n * Is marked private, you can read it, don't use it since it is handled by fabric\n * since 1.7.0\n * @type HTMLCanvasElement\n * @default undefined\n * @private\n */\n declare _cacheCanvas?: HTMLCanvasElement;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, X axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomX?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare zoomY?: number;\n\n /**\n * zoom level used on the cacheCanvas to draw the cache, Y axe\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationX?: number;\n\n /**\n * translation of the cacheCanvas away from the center, for subpixel accuracy and crispness\n * since 1.7.0\n * @type number\n * @default undefined\n * @private\n */\n declare cacheTranslationY?: number;\n\n /**\n * A reference to the parent of the object, usually a Group\n * @type number\n * @default undefined\n * @private\n */\n declare group?: Group;\n\n /**\n * Indicate if the object is sitting on a cache dedicated to it\n * or is part of a larger cache for many object ( a group for example)\n * @type number\n * @default undefined\n * @private\n */\n declare ownCaching?: boolean;\n\n /**\n * Private. indicates if the object inside a group is on a transformed context or not\n * or is part of a larger cache for many object ( a group for example)\n * @type boolean\n * @default undefined\n * @private\n */\n declare _transformDone?: boolean;\n\n static ownDefaults = fabricObjectDefaultValues;\n\n static getDefaults(): Record {\n return FabricObject.ownDefaults;\n }\n\n /**\n * The class type.\n * This is used for serialization and deserialization purposes and internally it can be used\n * to identify classes.\n * When we transform a class in a plain JS object we need a way to recognize which class it was,\n * and the type is the way we do that. It has no other purposes and you should not give one.\n * Hard to reach on instances and please do not use to drive instance's logic (this.constructor.type).\n * To idenfity a class use instanceof class ( instanceof Rect ).\n * We do not do that in fabricJS code because we want to try to have code splitting possible.\n */\n static type = 'FabricObject';\n\n /**\n * Legacy identifier of the class. Prefer using utils like isType or instanceOf\n * Will be removed in fabric 7 or 8.\n * The setter exists to avoid type errors in old code and possibly current deserialization code.\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n const name = (this.constructor as typeof FabricObject).type;\n if (name === 'FabricObject') {\n return 'object';\n }\n return name.toLowerCase();\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, FabricObject.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * Create a the canvas used to keep the cached copy of the object\n * @private\n */\n _createCacheCanvas() {\n this._cacheCanvas = createCanvasElement();\n this._cacheContext = this._cacheCanvas.getContext('2d');\n this._updateCacheCanvas();\n // if canvas gets created, is empty, so dirty.\n this.dirty = true;\n }\n\n /**\n * Limit the cache dimensions so that X * Y do not cross config.perfLimitSizeTotal\n * and each side do not cross fabric.cacheSideLimit\n * those numbers are configurable so that you can get as much detail as you want\n * making bargain with performances.\n * @param {Object} dims\n * @param {Object} dims.width width of canvas\n * @param {Object} dims.height height of canvas\n * @param {Object} dims.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @param {Object} dims.zoomY zoomY zoom value to unscale the canvas before drawing cache\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _limitCacheSize(\n dims: TSize & { zoomX: number; zoomY: number; capped: boolean } & any,\n ) {\n const width = dims.width,\n height = dims.height,\n max = config.maxCacheSideLimit,\n min = config.minCacheSideLimit;\n if (\n width <= max &&\n height <= max &&\n width * height <= config.perfLimitSizeTotal\n ) {\n if (width < min) {\n dims.width = min;\n }\n if (height < min) {\n dims.height = min;\n }\n return dims;\n }\n const ar = width / height,\n [limX, limY] = cache.limitDimsByArea(ar),\n x = capValue(min, limX, max),\n y = capValue(min, limY, max);\n if (width > x) {\n dims.zoomX /= width / x;\n dims.width = x;\n dims.capped = true;\n }\n if (height > y) {\n dims.zoomY /= height / y;\n dims.height = y;\n dims.capped = true;\n }\n return dims;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @return {Object}.x width of object to be cached\n * @return {Object}.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const objectScale = this.getTotalObjectScaling(),\n // calculate dimensions without skewing\n dim = this._getTransformedDimensions({ skewX: 0, skewY: 0 }),\n neededX = (dim.x * objectScale.x) / this.scaleX,\n neededY = (dim.y * objectScale.y) / this.scaleY;\n return {\n // for sure this ALIASING_LIMIT is slightly creating problem\n // in situation in which the cache canvas gets an upper limit\n // also objectScale contains already scaleX and scaleY\n width: neededX + ALIASING_LIMIT,\n height: neededY + ALIASING_LIMIT,\n zoomX: objectScale.x,\n zoomY: objectScale.y,\n x: neededX,\n y: neededY,\n };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const canvas = this._cacheCanvas!,\n context = this._cacheContext,\n dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n minCacheSize = config.minCacheSideLimit,\n width = dims.width,\n height = dims.height,\n zoomX = dims.zoomX,\n zoomY = dims.zoomY,\n dimensionsChanged = width !== canvas.width || height !== canvas.height,\n zoomChanged = this.zoomX !== zoomX || this.zoomY !== zoomY;\n\n if (!canvas || !context) {\n return false;\n }\n\n let drawingWidth,\n drawingHeight,\n shouldRedraw = dimensionsChanged || zoomChanged,\n additionalWidth = 0,\n additionalHeight = 0,\n shouldResizeCanvas = false;\n\n if (dimensionsChanged) {\n const canvasWidth = (this._cacheCanvas as HTMLCanvasElement).width,\n canvasHeight = (this._cacheCanvas as HTMLCanvasElement).height,\n sizeGrowing = width > canvasWidth || height > canvasHeight,\n sizeShrinking =\n (width < canvasWidth * 0.9 || height < canvasHeight * 0.9) &&\n canvasWidth > minCacheSize &&\n canvasHeight > minCacheSize;\n shouldResizeCanvas = sizeGrowing || sizeShrinking;\n if (\n sizeGrowing &&\n !dims.capped &&\n (width > minCacheSize || height > minCacheSize)\n ) {\n additionalWidth = width * 0.1;\n additionalHeight = height * 0.1;\n }\n }\n if (isTextObject(this) && this.path) {\n shouldRedraw = true;\n shouldResizeCanvas = true;\n // IMHO in those lines we are using zoomX and zoomY not the this version.\n additionalWidth += this.getHeightOfLine(0) * this.zoomX!;\n additionalHeight += this.getHeightOfLine(0) * this.zoomY!;\n }\n if (shouldRedraw) {\n if (shouldResizeCanvas) {\n canvas.width = Math.ceil(width + additionalWidth);\n canvas.height = Math.ceil(height + additionalHeight);\n } else {\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n drawingWidth = dims.x / 2;\n drawingHeight = dims.y / 2;\n this.cacheTranslationX =\n Math.round(canvas.width / 2 - drawingWidth) + drawingWidth;\n this.cacheTranslationY =\n Math.round(canvas.height / 2 - drawingHeight) + drawingHeight;\n context.translate(this.cacheTranslationX, this.cacheTranslationY);\n context.scale(zoomX, zoomY);\n this.zoomX = zoomX;\n this.zoomY = zoomY;\n return true;\n }\n return false;\n }\n\n /**\n * Sets object's properties from options, for class constructor only.\n * Needs to be overridden for different defaults.\n * @protected\n * @param {Object} [options] Options object\n */\n protected setOptions(options: Record = {}) {\n this._setOptions(options);\n }\n\n /**\n * Transforms context when rendering an object\n * @param {CanvasRenderingContext2D} ctx Context\n */\n transform(ctx: CanvasRenderingContext2D) {\n const needFullTransform =\n (this.group && !this.group._transformDone) ||\n (this.group && this.canvas && ctx === (this.canvas as Canvas).contextTop);\n const m = this.calcTransformMatrix(!needFullTransform);\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n\n /**\n * Return the object scale factor counting also the group scaling\n * @return {Point}\n */\n getObjectScaling() {\n // if the object is a top level one, on the canvas, we go for simple aritmetic\n // otherwise the complex method with angles will return approximations and decimals\n // and will likely kill the cache when not needed\n // https://github.com/fabricjs/fabric.js/issues/7157\n if (!this.group) {\n return new Point(Math.abs(this.scaleX), Math.abs(this.scaleY));\n }\n // if we are inside a group total zoom calculation is complex, we defer to generic matrices\n const options = qrDecompose(this.calcTransformMatrix());\n return new Point(Math.abs(options.scaleX), Math.abs(options.scaleY));\n }\n\n /**\n * Return the object scale factor counting also the group scaling, zoom and retina\n * @return {Object} object with scaleX and scaleY properties\n */\n getTotalObjectScaling() {\n const scale = this.getObjectScaling();\n if (this.canvas) {\n const zoom = this.canvas.getZoom();\n const retina = this.getCanvasRetinaScaling();\n return scale.scalarMultiply(zoom * retina);\n }\n return scale;\n }\n\n /**\n * Return the object opacity counting also the group property\n * @return {Number}\n */\n getObjectOpacity() {\n let opacity = this.opacity;\n if (this.group) {\n opacity *= this.group.getObjectOpacity();\n }\n return opacity;\n }\n\n /**\n * Makes sure the scale is valid and modifies it if necessary\n * @todo: this is a control action issue, not a geometry one\n * @private\n * @param {Number} value, unconstrained\n * @return {Number} constrained value;\n */\n _constrainScale(value: number): number {\n if (Math.abs(value) < this.minScaleLimit) {\n if (value < 0) {\n return -this.minScaleLimit;\n } else {\n return this.minScaleLimit;\n }\n } else if (value === 0) {\n return 0.0001;\n }\n return value;\n }\n\n /**\n * Handles setting values on the instance and handling internal side effects\n * @protected\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (key === SCALE_X || key === SCALE_Y) {\n value = this._constrainScale(value);\n }\n if (key === SCALE_X && value < 0) {\n this.flipX = !this.flipX;\n value *= -1;\n } else if (key === 'scaleY' && value < 0) {\n this.flipY = !this.flipY;\n value *= -1;\n // i don't like this automatic initialization here\n } else if (key === 'shadow' && value && !(value instanceof Shadow)) {\n value = new Shadow(value);\n }\n\n const isChanged = this[key as keyof this] !== value;\n this[key as keyof this] = value;\n\n // invalidate caches\n if (\n isChanged &&\n (this.constructor as typeof FabricObject).cacheProperties.includes(key)\n ) {\n this.dirty = true;\n }\n // a dirty child makes the parent dirty.\n // but a non dirty child does not make the parent not dirty.\n // the parent could be dirty for some other reason.\n this.parent &&\n (this.dirty ||\n (isChanged &&\n (this.constructor as typeof FabricObject).stateProperties.includes(\n key,\n ))) &&\n this.parent._set('dirty', true);\n\n return this;\n }\n\n /*\n * @private\n * return if the object would be visible in rendering\n * @memberOf FabricObject.prototype\n * @return {Boolean}\n */\n isNotVisible() {\n return (\n this.opacity === 0 ||\n (!this.width && !this.height && this.strokeWidth === 0) ||\n !this.visible\n );\n }\n\n /**\n * Renders an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n // do not render if width/height are zeros or object is not visible\n if (this.isNotVisible()) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n ctx.save();\n this._setupCompositeOperation(ctx);\n this.drawSelectionBackground(ctx);\n this.transform(ctx);\n this._setOpacity(ctx);\n this._setShadow(ctx);\n if (this.shouldCache()) {\n this.renderCache();\n (this as TCachedFabricObject).drawCacheOnCanvas(ctx);\n } else {\n this._removeCacheCanvas();\n this.drawObject(ctx);\n this.dirty = false;\n }\n ctx.restore();\n }\n\n drawSelectionBackground(_ctx: CanvasRenderingContext2D) {\n /* no op */\n }\n\n renderCache(options?: any) {\n options = options || {};\n if (!this._cacheCanvas || !this._cacheContext) {\n this._createCacheCanvas();\n }\n if (this.isCacheDirty() && this._cacheContext) {\n this.drawObject(this._cacheContext, options.forClipping);\n this.dirty = false;\n }\n }\n\n /**\n * Remove cacheCanvas and its dimensions from the objects\n */\n _removeCacheCanvas() {\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n /**\n * return true if the object will draw a stroke\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when stroke happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the stroke is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasStroke() {\n return (\n this.stroke && this.stroke !== 'transparent' && this.strokeWidth !== 0\n );\n }\n\n /**\n * return true if the object will draw a fill\n * Does not consider text styles. This is just a shortcut used at rendering time\n * We want it to be an approximation and be fast.\n * wrote to avoid extra caching, it has to return true when fill happens,\n * can guess when it will not happen at 100% chance, does not matter if it misses\n * some use case where the fill is invisible.\n * @since 3.0.0\n * @returns Boolean\n */\n hasFill() {\n return this.fill && this.fill !== 'transparent';\n }\n\n /**\n * When set to `true`, force the object to have its own cache, even if it is inside a group\n * it may be needed when your object behave in a particular way on the cache and always needs\n * its own isolated canvas to render correctly.\n * Created to be overridden\n * since 1.7.12\n * @returns Boolean\n */\n needsItsOwnCache() {\n if (\n this.paintFirst === STROKE &&\n this.hasFill() &&\n this.hasStroke() &&\n !!this.shadow\n ) {\n return true;\n }\n if (this.clipPath) {\n return true;\n }\n return false;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * Read as: cache if is needed, or if the feature is enabled but we are not already caching.\n * @return {Boolean}\n */\n shouldCache() {\n this.ownCaching =\n this.needsItsOwnCache() ||\n (this.objectCaching && (!this.parent || !this.parent.isOnACache()));\n return this.ownCaching;\n }\n\n /**\n * Check if this object will cast a shadow with an offset.\n * used by Group.shouldCache to know if child has a shadow recursively\n * @return {Boolean}\n * @deprecated\n */\n willDrawShadow() {\n return (\n !!this.shadow && (this.shadow.offsetX !== 0 || this.shadow.offsetY !== 0)\n );\n }\n\n /**\n * Execute the drawing operation for an object clipPath\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {FabricObject} clipPath\n */\n drawClipPathOnCache(\n ctx: CanvasRenderingContext2D,\n clipPath: TCachedFabricObject,\n ) {\n ctx.save();\n // DEBUG: uncomment this line, comment the following\n // ctx.globalAlpha = 0.4\n if (clipPath.inverted) {\n ctx.globalCompositeOperation = 'destination-out';\n } else {\n ctx.globalCompositeOperation = 'destination-in';\n }\n //ctx.scale(1 / 2, 1 / 2);\n if (clipPath.absolutePositioned) {\n const m = invertTransform(this.calcTransformMatrix());\n ctx.transform(m[0], m[1], m[2], m[3], m[4], m[5]);\n }\n clipPath.transform(ctx);\n ctx.scale(1 / clipPath.zoomX, 1 / clipPath.zoomY);\n ctx.drawImage(\n clipPath._cacheCanvas,\n -clipPath.cacheTranslationX,\n -clipPath.cacheTranslationY,\n );\n ctx.restore();\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {boolean} forClipping apply clipping styles\n */\n drawObject(ctx: CanvasRenderingContext2D, forClipping?: boolean) {\n const originalFill = this.fill,\n originalStroke = this.stroke;\n if (forClipping) {\n this.fill = 'black';\n this.stroke = '';\n this._setClippingProperties(ctx);\n } else {\n this._renderBackground(ctx);\n }\n this._render(ctx);\n this._drawClipPath(ctx, this.clipPath);\n this.fill = originalFill;\n this.stroke = originalStroke;\n }\n\n /**\n * Prepare clipPath state and cache and draw it on instance's cache\n * @param {CanvasRenderingContext2D} ctx\n * @param {FabricObject} clipPath\n */\n _drawClipPath(ctx: CanvasRenderingContext2D, clipPath?: FabricObject) {\n if (!clipPath) {\n return;\n }\n // needed to setup a couple of variables\n // path canvas gets overridden with this one.\n // TODO find a better solution?\n clipPath._set('canvas', this.canvas);\n clipPath.shouldCache();\n clipPath._transformDone = true;\n clipPath.renderCache({ forClipping: true });\n this.drawClipPathOnCache(ctx, clipPath as TCachedFabricObject);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(this: TCachedFabricObject, ctx: CanvasRenderingContext2D) {\n ctx.scale(1 / this.zoomX, 1 / this.zoomY);\n ctx.drawImage(\n this._cacheCanvas,\n -this.cacheTranslationX,\n -this.cacheTranslationY,\n );\n }\n\n /**\n * Check if cache is dirty\n * @param {Boolean} skipCanvas skip canvas checks because this object is painted\n * on parent canvas.\n */\n isCacheDirty(skipCanvas = false) {\n if (this.isNotVisible()) {\n return false;\n }\n const canvas = this._cacheCanvas;\n const ctx = this._cacheContext;\n if (canvas && ctx && !skipCanvas && this._updateCacheCanvas()) {\n // in this case the context is already cleared.\n return true;\n } else {\n if (this.dirty || (this.clipPath && this.clipPath.absolutePositioned)) {\n if (canvas && ctx && !skipCanvas) {\n ctx.save();\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.restore();\n }\n return true;\n }\n }\n return false;\n }\n\n /**\n * Draws a background for the object big as its untransformed dimensions\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderBackground(ctx: CanvasRenderingContext2D) {\n if (!this.backgroundColor) {\n return;\n }\n const dim = this._getNonTransformedDimensions();\n ctx.fillStyle = this.backgroundColor;\n\n ctx.fillRect(-dim.x / 2, -dim.y / 2, dim.x, dim.y);\n // if there is background color no other shadows\n // should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setOpacity(ctx: CanvasRenderingContext2D) {\n if (this.group && !this.group._transformDone) {\n ctx.globalAlpha = this.getObjectOpacity();\n } else {\n ctx.globalAlpha *= this.opacity;\n }\n }\n\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n decl: Pick<\n this,\n | 'stroke'\n | 'strokeWidth'\n | 'strokeLineCap'\n | 'strokeDashOffset'\n | 'strokeLineJoin'\n | 'strokeMiterLimit'\n >,\n ) {\n const stroke = decl.stroke;\n if (stroke) {\n ctx.lineWidth = decl.strokeWidth;\n ctx.lineCap = decl.strokeLineCap;\n ctx.lineDashOffset = decl.strokeDashOffset;\n ctx.lineJoin = decl.strokeLineJoin;\n ctx.miterLimit = decl.strokeMiterLimit;\n if (isFiller(stroke)) {\n if (\n (stroke as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (stroke as Gradient<'linear'>).gradientTransform ||\n (stroke as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n this._applyPatternForTransformedGradient(ctx, stroke);\n } else {\n // is a simple gradient or pattern\n ctx.strokeStyle = stroke.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, stroke);\n }\n } else {\n // is a color\n ctx.strokeStyle = decl.stroke as string;\n }\n }\n }\n\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n if (fill) {\n if (isFiller(fill)) {\n ctx.fillStyle = fill.toLive(ctx)!;\n this._applyPatternGradientTransform(ctx, fill);\n } else {\n ctx.fillStyle = fill;\n }\n }\n }\n\n _setClippingProperties(ctx: CanvasRenderingContext2D) {\n ctx.globalAlpha = 1;\n ctx.strokeStyle = 'transparent';\n ctx.fillStyle = '#000000';\n }\n\n /**\n * @private\n * Sets line dash\n * @param {CanvasRenderingContext2D} ctx Context to set the dash line on\n * @param {Array} dashArray array representing dashes\n */\n _setLineDash(ctx: CanvasRenderingContext2D, dashArray?: number[] | null) {\n if (!dashArray || dashArray.length === 0) {\n return;\n }\n // Spec requires the concatenation of two copies of the dash array when the number of elements is odd\n if (1 & dashArray.length) {\n dashArray.push(...dashArray);\n }\n ctx.setLineDash(dashArray);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _setShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n const shadow = this.shadow,\n canvas = this.canvas,\n retinaScaling = this.getCanvasRetinaScaling(),\n [sx, , , sy] = canvas?.viewportTransform || iMatrix,\n multX = sx * retinaScaling,\n multY = sy * retinaScaling,\n scaling = shadow.nonScaling ? new Point(1, 1) : this.getObjectScaling();\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur =\n (shadow.blur *\n config.browserShadowBlurConstant *\n (multX + multY) *\n (scaling.x + scaling.y)) /\n 4;\n ctx.shadowOffsetX = shadow.offsetX * multX * scaling.x;\n ctx.shadowOffsetY = shadow.offsetY * multY * scaling.y;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _removeShadow(ctx: CanvasRenderingContext2D) {\n if (!this.shadow) {\n return;\n }\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TFiller} filler {@link Pattern} or {@link Gradient}\n */\n _applyPatternGradientTransform(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n if (!isFiller(filler)) {\n return { offsetX: 0, offsetY: 0 };\n }\n const t =\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform;\n const offsetX = -this.width / 2 + filler.offsetX || 0,\n offsetY = -this.height / 2 + filler.offsetY || 0;\n\n if ((filler as Gradient<'linear'>).gradientUnits === 'percentage') {\n ctx.transform(this.width, 0, 0, this.height, offsetX, offsetY);\n } else {\n ctx.transform(1, 0, 0, 1, offsetX, offsetY);\n }\n if (t) {\n ctx.transform(t[0], t[1], t[2], t[3], t[4], t[5]);\n }\n return { offsetX: offsetX, offsetY: offsetY };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderPaintInOrder(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderStroke(ctx);\n this._renderFill(ctx);\n } else {\n this._renderFill(ctx);\n this._renderStroke(ctx);\n }\n }\n\n /**\n * @private\n * function that actually render something on the context.\n * empty here to allow Obects to work on tests to benchmark fabric functionalites\n * not related to rendering\n * @param {CanvasRenderingContext2D} _ctx Context to render on\n */\n _render(_ctx: CanvasRenderingContext2D) {\n // placeholder to be overridden\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill) {\n return;\n }\n\n ctx.save();\n this._setFillStyles(ctx, this);\n if (this.fillRule === 'evenodd') {\n ctx.fill('evenodd');\n } else {\n ctx.fill();\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderStroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n if (this.strokeUniform) {\n const scaling = this.getObjectScaling();\n ctx.scale(1 / scaling.x, 1 / scaling.y);\n }\n this._setLineDash(ctx, this.strokeDashArray);\n this._setStrokeStyles(ctx, this);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Gradient} filler\n */\n _applyPatternForTransformedGradient(\n ctx: CanvasRenderingContext2D,\n filler: TFiller,\n ) {\n const dims = this._limitCacheSize(this._getCacheCanvasDimensions()),\n pCanvas = createCanvasElement(),\n retinaScaling = this.getCanvasRetinaScaling(),\n width = dims.x / this.scaleX / retinaScaling,\n height = dims.y / this.scaleY / retinaScaling;\n // in case width and height are less than 1px, we have to round up.\n // since the pattern is no-repeat, this is fine\n pCanvas.width = Math.ceil(width);\n pCanvas.height = Math.ceil(height);\n const pCtx = pCanvas.getContext('2d');\n if (!pCtx) {\n return;\n }\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.scale(\n dims.zoomX / this.scaleX / retinaScaling,\n dims.zoomY / this.scaleY / retinaScaling,\n );\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fillStyle = filler.toLive(ctx)!;\n pCtx.fill();\n ctx.translate(\n -this.width / 2 - this.strokeWidth / 2,\n -this.height / 2 - this.strokeWidth / 2,\n );\n ctx.scale(\n (retinaScaling * this.scaleX) / dims.zoomX,\n (retinaScaling * this.scaleY) / dims.zoomY,\n );\n ctx.strokeStyle = pCtx.createPattern(pCanvas, 'no-repeat') ?? '';\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement() {\n return new Point(this.left + this.width / 2, this.top + this.height / 2);\n }\n\n /**\n * Clones an instance.\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {Promise}\n */\n clone(propertiesToInclude?: string[]): Promise {\n const objectForm = this.toObject(propertiesToInclude);\n return (this.constructor as typeof FabricObject).fromObject(\n objectForm,\n ) as unknown as Promise;\n }\n\n /**\n * Creates an instance of Image out of an object\n * makes use of toCanvasElement.\n * Once this method was based on toDataUrl and loadImage, so it also had a quality\n * and format option. toCanvasElement is faster and produce no loss of quality.\n * If you need to get a real Jpeg or Png from an object, using toDataURL is the right way to do it.\n * toCanvasElement and then toBlob from the obtained canvas is also a good option.\n * @todo fix the export type, it could not be Image but the type that getClass return for 'image'.\n * @param {ObjectToCanvasElementOptions} [options] for clone as image, passed to toDataURL\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {FabricImage} Object cloned as image.\n */\n cloneAsImage(options: ObjectToCanvasElementOptions): FabricImage {\n const canvasEl = this.toCanvasElement(options);\n // TODO: how to import Image w/o an import cycle?\n const ImageClass = classRegistry.getClass('image');\n return new ImageClass(canvasEl);\n }\n\n /**\n * Converts an object into a HTMLCanvas element\n * @param {ObjectToCanvasElementOptions} options Options object\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @param {Boolean} [options.viewportTransform] Account for canvas viewport transform\n * @param {(el?: HTMLCanvasElement) => StaticCanvas} [options.canvasProvider] Create the output canvas\n * @return {HTMLCanvasElement} Returns DOM element with the FabricObject\n */\n toCanvasElement(options: ObjectToCanvasElementOptions = {}) {\n const origParams = saveObjectTransform(this),\n originalGroup = this.group,\n originalShadow = this.shadow,\n abs = Math.abs,\n retinaScaling = options.enableRetinaScaling ? getDevicePixelRatio() : 1,\n multiplier = (options.multiplier || 1) * retinaScaling,\n canvasProvider: (el: HTMLCanvasElement) => StaticCanvas =\n options.canvasProvider ||\n ((el: HTMLCanvasElement) =>\n new StaticCanvas(el, {\n enableRetinaScaling: false,\n renderOnAddRemove: false,\n skipOffscreen: false,\n }));\n delete this.group;\n if (options.withoutTransform) {\n resetObjectTransform(this);\n }\n if (options.withoutShadow) {\n this.shadow = null;\n }\n if (options.viewportTransform) {\n sendObjectToPlane(this, this.getViewportTransform());\n }\n\n this.setCoords();\n const el = createCanvasElement(),\n boundingRect = this.getBoundingRect(),\n shadow = this.shadow,\n shadowOffset = new Point();\n\n if (shadow) {\n const shadowBlur = shadow.blur;\n const scaling = shadow.nonScaling\n ? new Point(1, 1)\n : this.getObjectScaling();\n // consider non scaling shadow.\n shadowOffset.x =\n 2 * Math.round(abs(shadow.offsetX) + shadowBlur) * abs(scaling.x);\n shadowOffset.y =\n 2 * Math.round(abs(shadow.offsetY) + shadowBlur) * abs(scaling.y);\n }\n const width = boundingRect.width + shadowOffset.x,\n height = boundingRect.height + shadowOffset.y;\n // if the current width/height is not an integer\n // we need to make it so.\n el.width = Math.ceil(width);\n el.height = Math.ceil(height);\n const canvas = canvasProvider(el);\n if (options.format === 'jpeg') {\n canvas.backgroundColor = '#fff';\n }\n this.setPositionByOrigin(\n new Point(canvas.width / 2, canvas.height / 2),\n CENTER,\n CENTER,\n );\n const originalCanvas = this.canvas;\n // static canvas and canvas have both an array of InteractiveObjects\n // @ts-expect-error this needs to be fixed somehow, or ignored globally\n canvas._objects = [this];\n this.set('canvas', canvas);\n this.setCoords();\n const canvasEl = canvas.toCanvasElement(multiplier || 1, options);\n this.set('canvas', originalCanvas);\n this.shadow = originalShadow;\n if (originalGroup) {\n this.group = originalGroup;\n }\n this.set(origParams);\n this.setCoords();\n // canvas.dispose will call image.dispose that will nullify the elements\n // since this canvas is a simple element for the process, we remove references\n // to objects in this way in order to avoid object trashing.\n canvas._objects = [];\n // since render has settled it is safe to destroy canvas\n canvas.destroy();\n return canvasEl;\n }\n\n /**\n * Converts an object into a data-url-like string\n * @param {Object} options Options object\n * @param {String} [options.format=png] The format of the output image. Either \"jpeg\" or \"png\"\n * @param {Number} [options.quality=1] Quality level (0..1). Only used for jpeg.\n * @param {Number} [options.multiplier=1] Multiplier to scale by\n * @param {Number} [options.left] Cropping left offset. Introduced in v1.2.14\n * @param {Number} [options.top] Cropping top offset. Introduced in v1.2.14\n * @param {Number} [options.width] Cropping width. Introduced in v1.2.14\n * @param {Number} [options.height] Cropping height. Introduced in v1.2.14\n * @param {Boolean} [options.enableRetinaScaling] Enable retina scaling for clone image. Introduce in 1.6.4\n * @param {Boolean} [options.withoutTransform] Remove current object transform ( no scale , no angle, no flip, no skew ). Introduced in 2.3.4\n * @param {Boolean} [options.withoutShadow] Remove current object shadow. Introduced in 2.4.2\n * @return {String} Returns a data: URL containing a representation of the object in the format specified by options.format\n */\n toDataURL(options: toDataURLOptions = {}) {\n return toDataURL(\n this.toCanvasElement(options),\n options.format || 'png',\n options.quality || 1,\n );\n }\n\n /**\n * Returns true if any of the specified types is identical to the type of an instance\n * @param {String} type Type to check against\n * @return {Boolean}\n */\n isType(...types: string[]) {\n return (\n types.includes((this.constructor as typeof FabricObject).type) ||\n types.includes(this.type)\n );\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance (is 1 unless subclassed)\n */\n complexity() {\n return 1;\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n /**\n * Sets \"angle\" of an instance with centered rotation\n * @param {TDegree} angle Angle value (in degrees)\n */\n rotate(angle: TDegree) {\n const { centeredRotation, originX, originY } = this;\n\n if (centeredRotation) {\n const { x, y } = this.getRelativeCenterPoint();\n this.originX = CENTER;\n this.originY = CENTER;\n this.left = x;\n this.top = y;\n }\n\n this.set('angle', angle);\n\n if (centeredRotation) {\n const { x, y } = this.translateToOriginPoint(\n this.getRelativeCenterPoint(),\n originX,\n originY,\n );\n this.left = x;\n this.top = y;\n this.originX = originX;\n this.originY = originY;\n }\n }\n\n /**\n * This callback function is called by the parent group of an object every\n * time a non-delegated property changes on the group. It is passed the key\n * and value as parameters. Not adding in this function's signature to avoid\n * Travis build error about unused variables.\n */\n setOnGroup() {\n // implemented by sub-classes, as needed.\n }\n\n /**\n * Sets canvas globalCompositeOperation for specific object\n * custom composition operation for the particular object can be specified using globalCompositeOperation property\n * @param {CanvasRenderingContext2D} ctx Rendering canvas context\n */\n _setupCompositeOperation(ctx: CanvasRenderingContext2D) {\n if (this.globalCompositeOperation) {\n ctx.globalCompositeOperation = this.globalCompositeOperation;\n }\n }\n\n /**\n * cancel instance's running animations\n * override if necessary to dispose artifacts such as `clipPath`\n */\n dispose() {\n runningAnimations.cancelByTarget(this);\n this.off();\n this._set('canvas', undefined);\n // clear caches\n this._cacheCanvas && getEnv().dispose(this._cacheCanvas);\n this._cacheCanvas = undefined;\n this._cacheContext = null;\n }\n\n // #region Animation methods\n /**\n * List of properties to consider for animating colors.\n * @type String[]\n */\n static colorProperties: string[] = [FILL, STROKE, 'backgroundColor'];\n\n /**\n * Animates object's properties\n * @param {Record} animatable map of keys and end values\n * @param {Partial>} options\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#animation}\n * @return {Record>} map of animation contexts\n *\n * As object — multiple properties\n *\n * object.animate({ left: ..., top: ... });\n * object.animate({ left: ..., top: ... }, { duration: ... });\n */\n animate(\n animatable: Record,\n options?: Partial>,\n ): Record> {\n return Object.entries(animatable).reduce(\n (acc, [key, endValue]) => {\n acc[key] = this._animate(key, endValue, options);\n return acc;\n },\n {} as Record>,\n );\n }\n\n /**\n * @private\n * @param {String} key Property to animate\n * @param {String} to Value to animate to\n * @param {Object} [options] Options object\n */\n _animate(\n key: string,\n endValue: T,\n options: Partial> = {},\n ): TAnimation {\n const path = key.split('.');\n const propIsColor = (\n this.constructor as typeof FabricObject\n ).colorProperties.includes(path[path.length - 1]);\n const { abort, startValue, onChange, onComplete } = options;\n const animationOptions = {\n ...options,\n target: this,\n // path.reduce... is the current value in case start value isn't provided\n startValue:\n startValue ?? path.reduce((deep: any, key) => deep[key], this),\n endValue,\n abort: abort?.bind(this),\n onChange: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n path.reduce((deep: Record, key, index) => {\n if (index === path.length - 1) {\n deep[key] = value;\n }\n return deep[key];\n }, this);\n onChange &&\n // @ts-expect-error generic callback arg0 is wrong\n onChange(value, valueProgress, durationProgress);\n },\n onComplete: (\n value: number | number[] | string,\n valueProgress: number,\n durationProgress: number,\n ) => {\n this.setCoords();\n onComplete &&\n // @ts-expect-error generic callback arg0 is wrong\n onComplete(value, valueProgress, durationProgress);\n },\n } as AnimationOptions;\n\n return (\n propIsColor\n ? animateColor(animationOptions as ColorAnimationOptions)\n : animate(\n animationOptions as ValueAnimationOptions | ArrayAnimationOptions,\n )\n ) as TAnimation;\n }\n\n // #region Object stacking methods\n\n /**\n * A reference to the parent of the object\n * Used to keep the original parent ref when the object has been added to an ActiveSelection, hence loosing the `group` ref\n */\n declare parent?: Group;\n\n /**\n * Checks if object is descendant of target\n * Should be used instead of {@link Group.contains} or {@link StaticCanvas.contains} for performance reasons\n * @param {TAncestor} target\n * @returns {boolean}\n */\n isDescendantOf(target: TAncestor): boolean {\n const { parent, group } = this;\n return (\n parent === target ||\n group === target ||\n // walk up\n (!!parent && parent.isDescendantOf(target)) ||\n (!!group && group !== parent && group.isDescendantOf(target))\n );\n }\n\n /**\n * @returns {Ancestors} ancestors (excluding `ActiveSelection`) from bottom to top\n */\n getAncestors(): Ancestors {\n const ancestors: TAncestor[] = [];\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n let parent: TAncestor | undefined = this;\n do {\n parent = parent.parent;\n parent && ancestors.push(parent);\n } while (parent);\n return ancestors as Ancestors;\n }\n\n /**\n * Compare ancestors\n *\n * @param {StackedObject} other\n * @returns {AncestryComparison} an object that represent the ancestry situation.\n */\n findCommonAncestors(other: T): AncestryComparison {\n if (this === other) {\n return {\n fork: [],\n otherFork: [],\n common: [this, ...this.getAncestors()],\n } as AncestryComparison;\n }\n const ancestors = this.getAncestors();\n const otherAncestors = other.getAncestors();\n // if `this` has no ancestors and `this` is top ancestor of `other` we must handle the following case\n if (\n ancestors.length === 0 &&\n otherAncestors.length > 0 &&\n this === otherAncestors[otherAncestors.length - 1]\n ) {\n return {\n fork: [],\n otherFork: [\n other,\n ...otherAncestors.slice(0, otherAncestors.length - 1),\n ],\n common: [this],\n } as AncestryComparison;\n }\n // compare ancestors\n for (let i = 0, ancestor; i < ancestors.length; i++) {\n ancestor = ancestors[i];\n if (ancestor === other) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n for (let j = 0; j < otherAncestors.length; j++) {\n if (this === otherAncestors[j]) {\n return {\n fork: [],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: [this, ...ancestors],\n } as AncestryComparison;\n }\n if (ancestor === otherAncestors[j]) {\n return {\n fork: [this, ...ancestors.slice(0, i)],\n otherFork: [other, ...otherAncestors.slice(0, j)],\n common: ancestors.slice(i),\n } as AncestryComparison;\n }\n }\n }\n // nothing shared\n return {\n fork: [this, ...ancestors],\n otherFork: [other, ...otherAncestors],\n common: [],\n } as AncestryComparison;\n }\n\n /**\n *\n * @param {StackedObject} other\n * @returns {boolean}\n */\n hasCommonAncestors(other: T): boolean {\n const commonAncestors = this.findCommonAncestors(other);\n return commonAncestors && !!commonAncestors.common.length;\n }\n\n /**\n *\n * @param {FabricObject} other object to compare against\n * @returns {boolean | undefined} if objects do not share a common ancestor or they are strictly equal it is impossible to determine which is in front of the other; in such cases the function returns `undefined`\n */\n isInFrontOf(other: T): boolean | undefined {\n if (this === other) {\n return undefined;\n }\n const ancestorData = this.findCommonAncestors(other);\n\n if (ancestorData.fork.includes(other as any)) {\n return true;\n }\n if (ancestorData.otherFork.includes(this as any)) {\n return false;\n }\n // if there isn't a common ancestor, we take the canvas.\n // if there is no canvas, there is nothing to compare\n const firstCommonAncestor = ancestorData.common[0] || this.canvas;\n if (!firstCommonAncestor) {\n return undefined;\n }\n const headOfFork = ancestorData.fork.pop(),\n headOfOtherFork = ancestorData.otherFork.pop(),\n thisIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfFork as any,\n ),\n otherIndex = (firstCommonAncestor as TCollection)._objects.indexOf(\n headOfOtherFork as any,\n );\n return thisIndex > -1 && thisIndex > otherIndex;\n }\n\n // #region Serialization\n /**\n * Define a list of custom properties that will be serialized when\n * instance.toObject() gets called\n */\n static customProperties: string[] = [];\n\n /**\n * Returns an object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject(propertiesToInclude: any[] = []): any {\n const propertiesToSerialize = propertiesToInclude.concat(\n FabricObject.customProperties,\n (this.constructor as typeof FabricObject).customProperties || [],\n );\n let clipPathData: Partial | undefined;\n const NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n const {\n clipPath,\n fill,\n stroke,\n shadow,\n strokeDashArray,\n left,\n top,\n originX,\n originY,\n width,\n height,\n strokeWidth,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit,\n scaleX,\n scaleY,\n angle,\n flipX,\n flipY,\n opacity,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX,\n skewY,\n } = this;\n if (clipPath && !clipPath.excludeFromExport) {\n clipPathData = clipPath.toObject(\n propertiesToSerialize.concat('inverted', 'absolutePositioned'),\n );\n }\n const toFixedBound = (val: number) => toFixed(val, NUM_FRACTION_DIGITS);\n const object = {\n ...pick(this, propertiesToSerialize as (keyof this)[]),\n type: (this.constructor as typeof FabricObject).type,\n version: VERSION,\n originX,\n originY,\n left: toFixedBound(left),\n top: toFixedBound(top),\n width: toFixedBound(width),\n height: toFixedBound(height),\n fill: isSerializableFiller(fill) ? fill.toObject() : fill,\n stroke: isSerializableFiller(stroke) ? stroke.toObject() : stroke,\n strokeWidth: toFixedBound(strokeWidth),\n strokeDashArray: strokeDashArray\n ? strokeDashArray.concat()\n : strokeDashArray,\n strokeLineCap,\n strokeDashOffset,\n strokeLineJoin,\n strokeUniform,\n strokeMiterLimit: toFixedBound(strokeMiterLimit),\n scaleX: toFixedBound(scaleX),\n scaleY: toFixedBound(scaleY),\n angle: toFixedBound(angle),\n flipX,\n flipY,\n opacity: toFixedBound(opacity),\n shadow: shadow ? shadow.toObject() : shadow,\n visible,\n backgroundColor,\n fillRule,\n paintFirst,\n globalCompositeOperation,\n skewX: toFixedBound(skewX),\n skewY: toFixedBound(skewY),\n ...(clipPathData ? { clipPath: clipPathData } : null),\n };\n\n return !this.includeDefaultValues\n ? this._removeDefaultValues(object)\n : object;\n }\n\n /**\n * Returns (dataless) object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toDatalessObject(propertiesToInclude?: any[]): any {\n // will be overwritten by subclasses\n return this.toObject(propertiesToInclude);\n }\n\n /**\n * @private\n * @param {Object} object\n */\n _removeDefaultValues(object: T): Partial {\n // getDefaults() ( get from static ownDefaults ) should win over prototype since anyway they get assigned to instance\n // ownDefault vs prototype is swappable only if you change all the fabric objects consistently.\n const defaults = (this.constructor as typeof FabricObject).getDefaults();\n const hasStaticDefaultValues = Object.keys(defaults).length > 0;\n const baseValues = hasStaticDefaultValues\n ? defaults\n : Object.getPrototypeOf(this);\n\n return pickBy(object, (value, key) => {\n if (key === LEFT || key === TOP || key === 'type') {\n return true;\n }\n const baseValue = baseValues[key];\n return (\n value !== baseValue &&\n // basically a check for [] === []\n !(\n Array.isArray(value) &&\n Array.isArray(baseValue) &&\n value.length === 0 &&\n baseValue.length === 0\n )\n );\n });\n }\n\n /**\n * Returns a string representation of an instance\n * @return {String}\n */\n toString() {\n return `#<${(this.constructor as typeof FabricObject).type}>`;\n }\n\n /**\n *\n * @param {Function} klass\n * @param {object} object\n * @param {object} [options]\n * @param {string} [options.extraParam] property to pass as first argument to the constructor\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static _fromObject(\n { type, ...serializedObjectOptions }: Record,\n { extraParam, ...options }: Abortable & { extraParam?: string } = {},\n ): Promise {\n return enlivenObjectEnlivables(serializedObjectOptions, options).then(\n (enlivedObjectOptions) => {\n // from the resulting enlived options, extract options.extraParam to arg0\n // to avoid accidental overrides later\n if (extraParam) {\n delete enlivedObjectOptions[extraParam];\n return new this(\n serializedObjectOptions[extraParam],\n // @ts-expect-error different signature\n enlivedObjectOptions,\n );\n } else {\n return new this(enlivedObjectOptions);\n }\n },\n ) as Promise;\n }\n\n /**\n *\n * @param {object} object\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n object: T,\n options?: Abortable,\n ) {\n return this._fromObject(object, options);\n }\n}\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n","import type {\n TModificationEvents,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\n/**\n * Wrap an action handler with firing an event if the action is performed\n * @param {TModificationEvents} eventName the event we want to fire\n * @param {TransformActionHandler} actionHandler the function to wrap\n * @param {object} extraEventInfo extra information to pas to the event handler\n * @return {TransformActionHandler} a function with an action handler signature\n */\nexport const wrapWithFireEvent = <\n T extends Transform,\n P extends object = Record,\n>(\n eventName: TModificationEvents,\n actionHandler: TransformActionHandler,\n extraEventInfo?: P,\n) => {\n return ((eventData, transform, x, y) => {\n const actionPerformed = actionHandler(eventData, transform, x, y);\n if (actionPerformed) {\n fireEvent(eventName, {\n ...commonEventInfo(eventData, transform, x, y),\n ...extraEventInfo,\n });\n }\n return actionPerformed;\n }) as TransformActionHandler;\n};\n","import type { Transform, TransformActionHandler } from '../EventTypeDefs';\n\n/**\n * Wrap an action handler with saving/restoring object position on the transform.\n * this is the code that permits to objects to keep their position while transforming.\n * @param {Function} actionHandler the function to wrap\n * @return {Function} a function with an action handler signature\n */\nexport function wrapWithFixedAnchor(\n actionHandler: TransformActionHandler,\n) {\n return ((eventData, transform, x, y) => {\n const { target, originX, originY } = transform,\n centerPoint = target.getRelativeCenterPoint(),\n constraint = target.translateToOriginPoint(centerPoint, originX, originY),\n actionPerformed = actionHandler(eventData, transform, x, y);\n // flipping requires to change the transform origin, so we read from the mutated transform\n // instead of leveraging the one destructured before\n target.setPositionByOrigin(\n constraint,\n transform.originX,\n transform.originY,\n );\n return actionPerformed;\n }) as TransformActionHandler;\n}\n","import type { TransformActionHandler } from '../EventTypeDefs';\nimport { CENTER, LEFT, RESIZING, RIGHT } from '../constants';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { getLocalPoint, isTransformCentered } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Action handler to change object's width\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const changeObjectWidth: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n const localPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // make sure the control changes width ONLY from it's side of target\n if (\n resolveOrigin(transform.originX) === resolveOrigin(CENTER) ||\n (resolveOrigin(transform.originX) === resolveOrigin(RIGHT) &&\n localPoint.x < 0) ||\n (resolveOrigin(transform.originX) === resolveOrigin(LEFT) &&\n localPoint.x > 0)\n ) {\n const { target } = transform,\n strokePadding =\n target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),\n multiplier = isTransformCentered(transform) ? 2 : 1,\n oldWidth = target.width,\n newWidth = Math.ceil(\n Math.abs((localPoint.x * multiplier) / target.scaleX) - strokePadding,\n );\n target.set('width', Math.max(newWidth, 0));\n // check against actual target width in case `newWidth` was rejected\n return oldWidth !== target.width;\n }\n return false;\n};\n\nexport const changeWidth = wrapWithFireEvent(\n RESIZING,\n wrapWithFixedAnchor(changeObjectWidth),\n);\n","import { FILL, STROKE, twoMathPi } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport type { Control } from './Control';\n\nexport type ControlRenderingStyleOverride = Partial<\n Pick<\n InteractiveFabricObject,\n | 'cornerStyle'\n | 'cornerSize'\n | 'cornerColor'\n | 'cornerStrokeColor'\n | 'cornerDashArray'\n | 'transparentCorners'\n >\n>;\n\nexport type ControlRenderer<\n O extends InteractiveFabricObject = InteractiveFabricObject,\n> = (\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: O,\n) => void;\n\n/**\n * Render a round control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderCircleControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor);\n let myLeft = left,\n myTop = top,\n size;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // TODO: use proper ellipse code.\n if (xSize > ySize) {\n size = xSize;\n ctx.scale(1.0, ySize / xSize);\n myTop = (top * xSize) / ySize;\n } else if (ySize > xSize) {\n size = ySize;\n ctx.scale(xSize / ySize, 1.0);\n myLeft = (left * ySize) / xSize;\n } else {\n size = xSize;\n }\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.beginPath();\n ctx.arc(myLeft, myTop, size / 2, 0, twoMathPi, false);\n ctx[methodName]();\n if (stroke) {\n ctx.stroke();\n }\n ctx.restore();\n}\n\n/**\n * Render a square control, as per fabric features.\n * This function is written to respect object properties like transparentCorners, cornerSize\n * cornerColor, cornerStrokeColor\n * plus the addition of offsetY and offsetX.\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @param {Number} left x coordinate where the control center should be\n * @param {Number} top y coordinate where the control center should be\n * @param {Object} styleOverride override for FabricObject controls style\n * @param {FabricObject} fabricObject the fabric object for which we are rendering controls\n */\nexport function renderSquareControl(\n this: Control,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride,\n fabricObject: InteractiveFabricObject,\n) {\n styleOverride = styleOverride || {};\n const xSize =\n this.sizeX || styleOverride.cornerSize || fabricObject.cornerSize,\n ySize = this.sizeY || styleOverride.cornerSize || fabricObject.cornerSize,\n transparentCorners =\n typeof styleOverride.transparentCorners !== 'undefined'\n ? styleOverride.transparentCorners\n : fabricObject.transparentCorners,\n methodName = transparentCorners ? STROKE : FILL,\n stroke =\n !transparentCorners &&\n (styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor),\n xSizeBy2 = xSize / 2,\n ySizeBy2 = ySize / 2;\n ctx.save();\n ctx.fillStyle = styleOverride.cornerColor || fabricObject.cornerColor || '';\n ctx.strokeStyle =\n styleOverride.cornerStrokeColor || fabricObject.cornerStrokeColor || '';\n // this is still wrong\n ctx.lineWidth = 1;\n ctx.translate(left, top);\n // angle is relative to canvas plane\n const angle = fabricObject.getTotalAngle();\n ctx.rotate(degreesToRadians(angle));\n // this does not work, and fixed with ( && ) does not make sense.\n // to have real transparent corners we need the controls on upperCanvas\n // transparentCorners || ctx.clearRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n ctx[`${methodName}Rect`](-xSizeBy2, -ySizeBy2, xSize, ySize);\n if (stroke) {\n ctx.strokeRect(-xSizeBy2, -ySizeBy2, xSize, ySize);\n }\n ctx.restore();\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport type {\n ControlActionHandler,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { Intersection } from '../Intersection';\nimport { Point } from '../Point';\nimport { SCALE } from '../constants';\nimport type { InteractiveFabricObject } from '../shapes/Object/InteractiveObject';\nimport type { TCornerPoint, TDegree, TMat2D } from '../typedefs';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { renderCircleControl, renderSquareControl } from './controlRendering';\n\nexport class Control {\n /**\n * keep track of control visibility.\n * mainly for backward compatibility.\n * if you do not want to see a control, you can remove it\n * from the control set.\n * @type {Boolean}\n * @default true\n */\n visible = true;\n\n /**\n * Name of the action that the control will likely execute.\n * This is optional. FabricJS uses to identify what the user is doing for some\n * extra optimizations. If you are writing a custom control and you want to know\n * somewhere else in the code what is going on, you can use this string here.\n * you can also provide a custom getActionName if your control run multiple actions\n * depending on some external state.\n * default to scale since is the most common, used on 4 corners by default\n * @type {String}\n * @default 'scale'\n */\n actionName = SCALE;\n\n /**\n * Drawing angle of the control.\n * NOT used for now, but name marked as needed for internal logic\n * example: to reuse the same drawing function for different rotated controls\n * @type {Number}\n * @default 0\n */\n angle = 0;\n\n /**\n * Relative position of the control. X\n * 0,0 is the center of the Object, while -0.5 (left) or 0.5 (right) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n x = 0;\n\n /**\n * Relative position of the control. Y\n * 0,0 is the center of the Object, while -0.5 (top) or 0.5 (bottom) are the extremities\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n y = 0;\n\n /**\n * Horizontal offset of the control from the defined position. In pixels\n * Positive offset moves the control to the right, negative to the left.\n * It used when you want to have position of control that does not scale with\n * the bounding box. Example: rotation control is placed at x:0, y: 0.5 on\n * the boundind box, with an offset of 30 pixels vertically. Those 30 pixels will\n * stay 30 pixels no matter how the object is big. Another example is having 2\n * controls in the corner, that stay in the same position when the object scale.\n * of the bounding box.\n * @type {Number}\n * @default 0\n */\n offsetX = 0;\n\n /**\n * Vertical offset of the control from the defined position. In pixels\n * Positive offset moves the control to the bottom, negative to the top.\n * @type {Number}\n * @default 0\n */\n offsetY = 0;\n\n /**\n * Sets the length of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeX = 0;\n\n /**\n * Sets the height of the control. If null, defaults to object's cornerSize.\n * Expects both sizeX and sizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n sizeY = 0;\n\n /**\n * Sets the length of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeX = 0;\n\n /**\n * Sets the height of the touch area of the control. If null, defaults to object's touchCornerSize.\n * Expects both touchSizeX and touchSizeY to be set when set.\n * @type {?Number}\n * @default null\n */\n touchSizeY = 0;\n\n /**\n * Css cursor style to display when the control is hovered.\n * if the method `cursorStyleHandler` is provided, this property is ignored.\n * @type {String}\n * @default 'crosshair'\n */\n cursorStyle = 'crosshair';\n\n /**\n * If controls has an offsetY or offsetX, draw a line that connects\n * the control to the bounding box\n * @type {Boolean}\n * @default false\n */\n withConnection = false;\n\n constructor(options?: Partial) {\n Object.assign(this, options);\n }\n\n /**\n * The control actionHandler, provide one to handle action ( control being moved )\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare actionHandler: TransformActionHandler;\n\n /**\n * The control handler for mouse down, provide one to handle mouse down on control\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseDownHandler?: ControlActionHandler;\n\n /**\n * The control mouseUpHandler, provide one to handle an effect on mouse up.\n * @param {Event} eventData the native mouse event\n * @param {Transform} transformData properties of the current transform\n * @param {Number} x x position of the cursor\n * @param {Number} y y position of the cursor\n * @return {Boolean} true if the action/event modified the object\n */\n declare mouseUpHandler?: ControlActionHandler;\n\n shouldActivate(\n controlKey: string,\n fabricObject: InteractiveFabricObject,\n pointer: Point,\n { tl, tr, br, bl }: TCornerPoint,\n ) {\n // TODO: locking logic can be handled here instead of in the control handler logic\n return (\n fabricObject.canvas?.getActiveObject() === fabricObject &&\n fabricObject.isControlVisible(controlKey) &&\n Intersection.isPointInPolygon(pointer, [tl, tr, br, bl])\n );\n }\n\n /**\n * Returns control actionHandler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getActionHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): TransformActionHandler | undefined {\n return this.actionHandler;\n }\n\n /**\n * Returns control mouseDown handler\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseDownHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseDownHandler;\n }\n\n /**\n * Returns control mouseUp handler.\n * During actions the fabricObject or the control can be of different obj\n * @param {Event} eventData the native mouse event\n * @param {FabricObject} fabricObject on which the control is displayed\n * @param {Control} control control for which the action handler is being asked\n * @return {Function} the action handler\n */\n getMouseUpHandler(\n eventData: TPointerEvent,\n fabricObject: InteractiveFabricObject,\n control: Control,\n ): ControlActionHandler | undefined {\n return this.mouseUpHandler;\n }\n\n /**\n * Returns control cursorStyle for css using cursorStyle. If you need a more elaborate\n * function you can pass one in the constructor\n * the cursorStyle property\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n cursorStyleHandler(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.cursorStyle;\n }\n\n /**\n * Returns the action name. The basic implementation just return the actionName property.\n * @param {Event} eventData the native mouse event\n * @param {Control} control the current control ( likely this)\n * @param {FabricObject} object on which the control is displayed\n * @return {String}\n */\n getActionName(\n eventData: TPointerEvent,\n control: Control,\n fabricObject: InteractiveFabricObject,\n ) {\n return control.actionName;\n }\n\n /**\n * Returns controls visibility\n * @param {FabricObject} object on which the control is displayed\n * @param {String} controlKey key where the control is memorized on the\n * @return {Boolean}\n */\n getVisibility(fabricObject: InteractiveFabricObject, controlKey: string) {\n return fabricObject._controlsVisibility?.[controlKey] ?? this.visible;\n }\n\n /**\n * Sets controls visibility\n * @param {Boolean} visibility for the object\n * @return {Void}\n */\n setVisibility(\n visibility: boolean,\n name: string,\n fabricObject: InteractiveFabricObject,\n ) {\n this.visible = visibility;\n }\n\n positionHandler(\n dim: Point,\n finalMatrix: TMat2D,\n fabricObject: InteractiveFabricObject,\n currentControl: Control,\n ) {\n return new Point(\n this.x * dim.x + this.offsetX,\n this.y * dim.y + this.offsetY,\n ).transform(finalMatrix);\n }\n\n /**\n * Returns the coords for this control based on object values.\n * @param {Number} objectAngle angle from the fabric object holding the control\n * @param {Number} objectCornerSize cornerSize from the fabric object holding the control (or touchCornerSize if\n * isTouch is true)\n * @param {Number} centerX x coordinate where the control center should be\n * @param {Number} centerY y coordinate where the control center should be\n * @param {boolean} isTouch true if touch corner, false if normal corner\n */\n calcCornerCoords(\n angle: TDegree,\n objectCornerSize: number,\n centerX: number,\n centerY: number,\n isTouch: boolean,\n fabricObject: InteractiveFabricObject,\n ) {\n const t = multiplyTransformMatrixArray([\n createTranslateMatrix(centerX, centerY),\n createRotateMatrix({ angle }),\n createScaleMatrix(\n (isTouch ? this.touchSizeX : this.sizeX) || objectCornerSize,\n (isTouch ? this.touchSizeY : this.sizeY) || objectCornerSize,\n ),\n ]);\n return {\n tl: new Point(-0.5, -0.5).transform(t),\n tr: new Point(0.5, -0.5).transform(t),\n br: new Point(0.5, 0.5).transform(t),\n bl: new Point(-0.5, 0.5).transform(t),\n };\n }\n\n /**\n * Render function for the control.\n * When this function runs the context is unscaled. unrotate. Just retina scaled.\n * all the functions will have to translate to the point left,top before starting Drawing\n * if they want to draw a control where the position is detected.\n * left and top are the result of the positionHandler function\n * @param {RenderingContext2D} ctx the context where the control will be drawn\n * @param {Number} left position of the canvas where we are about to render the control.\n * @param {Number} top position of the canvas where we are about to render the control.\n * @param {Object} styleOverride\n * @param {FabricObject} fabricObject the object where the control is about to be rendered\n */\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: InteractiveFabricObject,\n ) {\n styleOverride = styleOverride || {};\n switch (styleOverride.cornerStyle || fabricObject.cornerStyle) {\n case 'circle':\n renderCircleControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n break;\n default:\n renderSquareControl.call(\n this,\n ctx,\n left,\n top,\n styleOverride,\n fabricObject,\n );\n }\n }\n}\n","import type {\n ControlCursorCallback,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { ROTATING } from '../constants';\nimport { radiansToDegrees } from '../util/misc/radiansDegreesConversion';\nimport { isLocked, NOT_ALLOWED_CURSOR } from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\n\n/**\n * Find the correct style for the control that is used for rotation.\n * this function is very simple and it just take care of not-allowed or standard cursor\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const rotationStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (fabricObject.lockRotation) {\n return NOT_ALLOWED_CURSOR;\n }\n return control.cursorStyle;\n};\n\n/**\n * Action handler for rotation and snapping, without anchor point.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n * @private\n */\nconst rotateObjectWithSnapping: TransformActionHandler = (\n eventData,\n { target, ex, ey, theta, originX, originY },\n x,\n y,\n) => {\n const pivotPoint = target.translateToOriginPoint(\n target.getRelativeCenterPoint(),\n originX,\n originY,\n );\n\n if (isLocked(target, 'lockRotation')) {\n return false;\n }\n\n const lastAngle = Math.atan2(ey - pivotPoint.y, ex - pivotPoint.x),\n curAngle = Math.atan2(y - pivotPoint.y, x - pivotPoint.x);\n let angle = radiansToDegrees(curAngle - lastAngle + theta);\n\n if (target.snapAngle && target.snapAngle > 0) {\n const snapAngle = target.snapAngle,\n snapThreshold = target.snapThreshold || snapAngle,\n rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,\n leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;\n\n if (Math.abs(angle - leftAngleLocked) < snapThreshold) {\n angle = leftAngleLocked;\n } else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {\n angle = rightAngleLocked;\n }\n }\n\n // normalize angle to positive value\n if (angle < 0) {\n angle = 360 + angle;\n }\n angle %= 360;\n\n const hasRotated = target.angle !== angle;\n // TODO: why aren't we using set?\n target.angle = angle;\n return hasRotated;\n};\n\nexport const rotationWithSnapping = wrapWithFireEvent(\n ROTATING,\n wrapWithFixedAnchor(rotateObjectWithSnapping),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxis } from '../typedefs';\nimport type { Canvas } from '../canvas/Canvas';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n invertOrigin,\n isLocked,\n isTransformCentered,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport { SCALE_X, SCALE_Y, SCALING } from '../constants';\n\ntype ScaleTransform = Transform & {\n gestureScale?: number;\n signX?: number;\n signY?: number;\n};\n\ntype ScaleBy = TAxis | 'equally' | '' | undefined;\n\n/**\n * Inspect event and fabricObject properties to understand if the scaling action\n * @param {Event} eventData from the user action\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @return {Boolean} true if scale is proportional\n */\nexport function scaleIsProportional(\n eventData: TPointerEvent,\n fabricObject: FabricObject,\n): boolean {\n const canvas = fabricObject.canvas as Canvas,\n uniformIsToggled = eventData[canvas.uniScaleKey!];\n return (\n (canvas.uniformScaling && !uniformIsToggled) ||\n (!canvas.uniformScaling && uniformIsToggled)\n );\n}\n\n/**\n * Inspect fabricObject to understand if the current scaling action is allowed\n * @param {FabricObject} fabricObject the fabric object about to scale\n * @param {String} by 'x' or 'y' or ''\n * @param {Boolean} scaleProportionally true if we are trying to scale proportionally\n * @return {Boolean} true if scaling is not allowed at current conditions\n */\nexport function scalingIsForbidden(\n fabricObject: FabricObject,\n by: ScaleBy,\n scaleProportionally: boolean,\n) {\n const lockX = isLocked(fabricObject, 'lockScalingX'),\n lockY = isLocked(fabricObject, 'lockScalingY');\n if (lockX && lockY) {\n return true;\n }\n if (!by && (lockX || lockY) && scaleProportionally) {\n return true;\n }\n if (lockX && by === 'x') {\n return true;\n }\n if (lockY && by === 'y') {\n return true;\n }\n // code crashes because of a division by 0 if a 0 sized object is scaled\n // forbid to prevent scaling to happen. ISSUE-9475\n const { width, height, strokeWidth } = fabricObject;\n if (width === 0 && strokeWidth === 0 && by !== 'y') {\n return true;\n }\n if (height === 0 && strokeWidth === 0 && by !== 'x') {\n return true;\n }\n return false;\n}\n\nconst scaleMap = ['e', 'se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e'];\n\n/**\n * return the correct cursor style for the scale action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n const scaleProportionally = scaleIsProportional(eventData, fabricObject),\n by =\n control.x !== 0 && control.y === 0\n ? 'x'\n : control.x === 0 && control.y !== 0\n ? 'y'\n : '';\n if (scalingIsForbidden(fabricObject, by, scaleProportionally)) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control);\n return `${scaleMap[n]}-resize`;\n};\n\n/**\n * Basic scaling logic, reused with different constrain for scaling X,Y, freely or equally.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @param {Object} options additional information for scaling\n * @param {String} options.by 'x', 'y', 'equally' or '' to indicate type of scaling\n * @return {Boolean} true if some change happened\n * @private\n */\nfunction scaleObject(\n eventData: TPointerEvent,\n transform: ScaleTransform,\n x: number,\n y: number,\n options: { by?: ScaleBy } = {},\n) {\n const target = transform.target,\n by = options.by,\n scaleProportionally = scaleIsProportional(eventData, target),\n forbidScaling = scalingIsForbidden(target, by, scaleProportionally);\n let newPoint, scaleX, scaleY, dim, signX, signY;\n\n if (forbidScaling) {\n return false;\n }\n if (transform.gestureScale) {\n scaleX = transform.scaleX * transform.gestureScale;\n scaleY = transform.scaleY * transform.gestureScale;\n } else {\n newPoint = getLocalPoint(\n transform,\n transform.originX,\n transform.originY,\n x,\n y,\n );\n // use of sign: We use sign to detect change of direction of an action. sign usually change when\n // we cross the origin point with the mouse. So a scale flip for example. There is an issue when scaling\n // by center and scaling using one middle control ( default: mr, mt, ml, mb), the mouse movement can easily\n // cross many time the origin point and flip the object. so we need a way to filter out the noise.\n // This ternary here should be ok to filter out X scaling when we want Y only and vice versa.\n signX = by !== 'y' ? Math.sign(newPoint.x || transform.signX || 1) : 1;\n signY = by !== 'x' ? Math.sign(newPoint.y || transform.signY || 1) : 1;\n if (!transform.signX) {\n transform.signX = signX;\n }\n if (!transform.signY) {\n transform.signY = signY;\n }\n\n if (\n isLocked(target, 'lockScalingFlip') &&\n (transform.signX !== signX || transform.signY !== signY)\n ) {\n return false;\n }\n\n dim = target._getTransformedDimensions();\n // missing detection of flip and logic to switch the origin\n if (scaleProportionally && !by) {\n // uniform scaling\n const distance = Math.abs(newPoint.x) + Math.abs(newPoint.y),\n { original } = transform,\n originalDistance =\n Math.abs((dim.x * original.scaleX) / target.scaleX) +\n Math.abs((dim.y * original.scaleY) / target.scaleY),\n scale = distance / originalDistance;\n scaleX = original.scaleX * scale;\n scaleY = original.scaleY * scale;\n } else {\n scaleX = Math.abs((newPoint.x * target.scaleX) / dim.x);\n scaleY = Math.abs((newPoint.y * target.scaleY) / dim.y);\n }\n // if we are scaling by center, we need to double the scale\n if (isTransformCentered(transform)) {\n scaleX *= 2;\n scaleY *= 2;\n }\n if (transform.signX !== signX && by !== 'y') {\n transform.originX = invertOrigin(transform.originX);\n scaleX *= -1;\n transform.signX = signX;\n }\n if (transform.signY !== signY && by !== 'x') {\n transform.originY = invertOrigin(transform.originY);\n scaleY *= -1;\n transform.signY = signY;\n }\n }\n // minScale is taken care of in the setter.\n const oldScaleX = target.scaleX,\n oldScaleY = target.scaleY;\n if (!by) {\n !isLocked(target, 'lockScalingX') && target.set(SCALE_X, scaleX);\n !isLocked(target, 'lockScalingY') && target.set(SCALE_Y, scaleY);\n } else {\n // forbidden cases already handled on top here.\n by === 'x' && target.set(SCALE_X, scaleX);\n by === 'y' && target.set(SCALE_Y, scaleY);\n }\n return oldScaleX !== target.scaleX || oldScaleY !== target.scaleY;\n}\n\n/**\n * Generic scaling logic, to scale from corners either equally or freely.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scaleObjectFromCorner: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y);\n};\n\n/**\n * Scaling logic for the X axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'x' });\n};\n\n/**\n * Scaling logic for the Y axis.\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nconst scaleObjectY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return scaleObject(eventData, transform, x, y, { by: 'y' });\n};\n\nexport const scalingEqually = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectFromCorner),\n);\n\nexport const scalingX = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectX),\n);\n\nexport const scalingY = wrapWithFireEvent(\n SCALING,\n wrapWithFixedAnchor(scaleObjectY),\n);\n","import type {\n ControlCursorCallback,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { Point } from '../Point';\nimport type { TAxis, TAxisKey } from '../typedefs';\nimport {\n degreesToRadians,\n radiansToDegrees,\n} from '../util/misc/radiansDegreesConversion';\nimport {\n findCornerQuadrant,\n getLocalPoint,\n isLocked,\n NOT_ALLOWED_CURSOR,\n} from './util';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { wrapWithFixedAnchor } from './wrapWithFixedAnchor';\nimport {\n CENTER,\n SCALE_X,\n SCALE_Y,\n SKEWING,\n SKEW_X,\n SKEW_Y,\n} from '../constants';\n\nexport type SkewTransform = Transform & { skewingSide: -1 | 1 };\n\nconst AXIS_KEYS: Record<\n TAxis,\n {\n counterAxis: TAxis;\n scale: TAxisKey<'scale'>;\n skew: TAxisKey<'skew'>;\n lockSkewing: TAxisKey<'lockSkewing'>;\n origin: TAxisKey<'origin'>;\n flip: TAxisKey<'flip'>;\n }\n> = {\n x: {\n counterAxis: 'y',\n scale: SCALE_X,\n skew: SKEW_X,\n lockSkewing: 'lockSkewingX',\n origin: 'originX',\n flip: 'flipX',\n },\n y: {\n counterAxis: 'x',\n scale: SCALE_Y,\n skew: SKEW_Y,\n lockSkewing: 'lockSkewingY',\n origin: 'originY',\n flip: 'flipY',\n },\n};\n\nconst skewMap = ['ns', 'nesw', 'ew', 'nwse'];\n\n/**\n * return the correct cursor style for the skew action\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const skewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n if (control.x !== 0 && isLocked(fabricObject, 'lockSkewingY')) {\n return NOT_ALLOWED_CURSOR;\n }\n if (control.y !== 0 && isLocked(fabricObject, 'lockSkewingX')) {\n return NOT_ALLOWED_CURSOR;\n }\n const n = findCornerQuadrant(fabricObject, control) % 4;\n return `${skewMap[n]}-resize`;\n};\n\n/**\n * Since skewing is applied before scaling, calculations are done in a scaleless plane\n * @see https://github.com/fabricjs/fabric.js/pull/8380\n */\nfunction skewObject(\n axis: TAxis,\n { target, ex, ey, skewingSide, ...transform }: SkewTransform,\n pointer: Point,\n) {\n const { skew: skewKey } = AXIS_KEYS[axis],\n offset = pointer\n .subtract(new Point(ex, ey))\n .divide(new Point(target.scaleX, target.scaleY))[axis],\n skewingBefore = target[skewKey],\n skewingStart = transform[skewKey],\n shearingStart = Math.tan(degreesToRadians(skewingStart)),\n // let a, b be the size of target\n // let a' be the value of a after applying skewing\n // then:\n // a' = a + b * skewA => skewA = (a' - a) / b\n // the value b is tricky since skewY is applied before skewX\n b =\n axis === 'y'\n ? target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n // since skewY is applied before skewX, b (=width) is not affected by skewX\n skewX: 0,\n }).x\n : target._getTransformedDimensions({\n scaleX: 1,\n scaleY: 1,\n }).y;\n\n const shearing =\n (2 * offset * skewingSide) /\n // we max out fractions to safeguard from asymptotic behavior\n Math.max(b, 1) +\n // add starting state\n shearingStart;\n\n const skewing = radiansToDegrees(Math.atan(shearing));\n\n target.set(skewKey, skewing);\n const changed = skewingBefore !== target[skewKey];\n\n if (changed && axis === 'y') {\n // we don't want skewing to affect scaleX\n // so we factor it by the inverse skewing diff to make it seem unchanged to the viewer\n const { skewX, scaleX } = target,\n dimBefore = target._getTransformedDimensions({ skewY: skewingBefore }),\n dimAfter = target._getTransformedDimensions(),\n compensationFactor = skewX !== 0 ? dimBefore.x / dimAfter.x : 1;\n compensationFactor !== 1 &&\n target.set(SCALE_X, compensationFactor * scaleX);\n }\n\n return changed;\n}\n\n/**\n * Wrapped Action handler for skewing on a given axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nfunction skewHandler(\n axis: TAxis,\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n) {\n const { target } = transform,\n {\n counterAxis,\n origin: originKey,\n lockSkewing: lockSkewingKey,\n skew: skewKey,\n flip: flipKey,\n } = AXIS_KEYS[axis];\n if (isLocked(target, lockSkewingKey)) {\n return false;\n }\n\n const { origin: counterOriginKey, flip: counterFlipKey } =\n AXIS_KEYS[counterAxis],\n counterOriginFactor =\n resolveOrigin(transform[counterOriginKey]) *\n (target[counterFlipKey] ? -1 : 1),\n // if the counter origin is top/left (= -0.5) then we are skewing x/y values on the bottom/right side of target respectively.\n // if the counter origin is bottom/right (= 0.5) then we are skewing x/y values on the top/left side of target respectively.\n // skewing direction on the top/left side of target is OPPOSITE to the direction of the movement of the pointer,\n // so we factor skewing direction by this value.\n skewingSide = (-Math.sign(counterOriginFactor) *\n (target[flipKey] ? -1 : 1)) as 1 | -1,\n skewingDirection =\n ((target[skewKey] === 0 &&\n // in case skewing equals 0 we use the pointer offset from target center to determine the direction of skewing\n getLocalPoint(transform, CENTER, CENTER, x, y)[axis] > 0) ||\n // in case target has skewing we use that as the direction\n target[skewKey] > 0\n ? 1\n : -1) * skewingSide,\n // anchor to the opposite side of the skewing direction\n // normalize value from [-1, 1] to origin value [0, 1]\n origin = -skewingDirection * 0.5 + 0.5;\n\n const finalHandler = wrapWithFireEvent(\n SKEWING,\n wrapWithFixedAnchor((eventData, transform, x, y) =>\n skewObject(axis, transform, new Point(x, y)),\n ),\n );\n\n return finalHandler(\n eventData,\n {\n ...transform,\n [originKey]: origin,\n skewingSide,\n },\n x,\n y,\n );\n}\n\n/**\n * Wrapped Action handler for skewing on the X axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('x', eventData, transform, x, y);\n};\n\n/**\n * Wrapped Action handler for skewing on the Y axis, takes care of the\n * skew direction and determines the correct transform origin for the anchor point\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const skewHandlerY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return skewHandler('y', eventData, transform, x, y);\n};\n","import type {\n ControlCallback,\n ControlCursorCallback,\n TPointerEvent,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { SCALE_X, SCALE_Y, SKEW_X, SKEW_Y } from '../constants';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TAxisKey } from '../typedefs';\nimport { scaleCursorStyleHandler, scalingX, scalingY } from './scale';\nimport { skewCursorStyleHandler, skewHandlerX, skewHandlerY } from './skew';\n\nfunction isAltAction(eventData: TPointerEvent, target: FabricObject) {\n return eventData[target.canvas!.altActionKey!];\n}\n\n/**\n * Inspect event, control and fabricObject to return the correct action name\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} an action name\n */\nexport const scaleOrSkewActionName: ControlCallback<\n TAxisKey<'skew' | 'scale'> | ''\n> = (eventData, control, fabricObject) => {\n const isAlternative = isAltAction(eventData, fabricObject);\n if (control.x === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_X : SCALE_Y;\n }\n if (control.y === 0) {\n // then is scaleY or skewX\n return isAlternative ? SKEW_Y : SCALE_X;\n }\n return '';\n};\n\n/**\n * Combine skew and scale style handlers to cover fabric standard use case\n * @param {Event} eventData the javascript event that is causing the scale\n * @param {Control} control the control that is interested in the action\n * @param {FabricObject} fabricObject the fabric object that is interested in the action\n * @return {String} a valid css string for the cursor\n */\nexport const scaleSkewCursorStyleHandler: ControlCursorCallback = (\n eventData,\n control,\n fabricObject,\n) => {\n return isAltAction(eventData, fabricObject)\n ? skewCursorStyleHandler(eventData, control, fabricObject)\n : scaleCursorStyleHandler(eventData, control, fabricObject);\n};\n/**\n * Composed action handler to either scale X or skew Y\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingXOrSkewingY: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerY(eventData, transform, x, y)\n : scalingX(eventData, transform, x, y);\n};\n\n/**\n * Composed action handler to either scale Y or skew X\n * Needs to be wrapped with `wrapWithFixedAnchor` to be effective\n * @param {Event} eventData javascript event that is doing the transform\n * @param {Object} transform javascript object containing a series of information around the current transform\n * @param {number} x current mouse x position, canvas normalized\n * @param {number} y current mouse y position, canvas normalized\n * @return {Boolean} true if some change happened\n */\nexport const scalingYOrSkewingX: TransformActionHandler = (\n eventData,\n transform,\n x,\n y,\n) => {\n return isAltAction(eventData, transform.target)\n ? skewHandlerX(eventData, transform, x, y)\n : scalingY(eventData, transform, x, y);\n};\n","import { RESIZING, ROTATE } from '../constants';\nimport { changeWidth } from './changeWidth';\nimport { Control } from './Control';\nimport { rotationStyleHandler, rotationWithSnapping } from './rotate';\nimport { scaleCursorStyleHandler, scalingEqually } from './scale';\nimport {\n scaleOrSkewActionName,\n scaleSkewCursorStyleHandler,\n scalingXOrSkewingY,\n scalingYOrSkewingX,\n} from './scaleSkew';\n\n// use this function if you want to generate new controls for every instance\nexport const createObjectDefaultControls = () => ({\n ml: new Control({\n x: -0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mr: new Control({\n x: 0.5,\n y: 0,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingXOrSkewingY,\n getActionName: scaleOrSkewActionName,\n }),\n\n mb: new Control({\n x: 0,\n y: 0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n mt: new Control({\n x: 0,\n y: -0.5,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionHandler: scalingYOrSkewingX,\n getActionName: scaleOrSkewActionName,\n }),\n\n tl: new Control({\n x: -0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n tr: new Control({\n x: 0.5,\n y: -0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n bl: new Control({\n x: -0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n br: new Control({\n x: 0.5,\n y: 0.5,\n cursorStyleHandler: scaleCursorStyleHandler,\n actionHandler: scalingEqually,\n }),\n\n mtr: new Control({\n x: 0,\n y: -0.5,\n actionHandler: rotationWithSnapping,\n cursorStyleHandler: rotationStyleHandler,\n offsetY: -40,\n withConnection: true,\n actionName: ROTATE,\n }),\n});\n\nexport const createResizeControls = () => ({\n mr: new Control({\n x: 0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n ml: new Control({\n x: -0.5,\n y: 0,\n actionHandler: changeWidth,\n cursorStyleHandler: scaleSkewCursorStyleHandler,\n actionName: RESIZING,\n }),\n});\n\nexport const createTextboxDefaultControls = () => ({\n ...createObjectDefaultControls(),\n ...createResizeControls(),\n});\n","import { Point, ZERO } from '../../Point';\nimport type { TCornerPoint, TDegree } from '../../typedefs';\nimport { FabricObject } from './Object';\nimport { degreesToRadians } from '../../util/misc/radiansDegreesConversion';\nimport type { TQrDecomposeOut } from '../../util/misc/matrix';\nimport {\n calcDimensionsMatrix,\n createRotateMatrix,\n createTranslateMatrix,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../../util/misc/matrix';\nimport type { Control } from '../../controls/Control';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport type { ObjectEvents, TPointerEvent } from '../../EventTypeDefs';\nimport type { Canvas } from '../../canvas/Canvas';\nimport type { ControlRenderingStyleOverride } from '../../controls/controlRendering';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { createObjectDefaultControls } from '../../controls/commonControls';\nimport { interactiveObjectDefaultValues } from './defaultValues';\nimport { SCALE } from '../../constants';\n\nexport type TOCoord = Point & {\n corner: TCornerPoint;\n touchCorner: TCornerPoint;\n};\n\nexport type TControlSet = Record;\n\nexport type TBorderRenderingStyleOverride = Partial<\n Pick\n>;\n\nexport type TStyleOverride = ControlRenderingStyleOverride &\n TBorderRenderingStyleOverride &\n Partial<\n Pick & {\n forActiveSelection: boolean;\n }\n >;\n\nexport class InteractiveFabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n declare noScaleCache: boolean;\n\n declare snapAngle?: TDegree;\n declare snapThreshold?: TDegree;\n\n declare lockMovementX: boolean;\n declare lockMovementY: boolean;\n declare lockRotation: boolean;\n declare lockScalingX: boolean;\n declare lockScalingY: boolean;\n declare lockSkewingX: boolean;\n declare lockSkewingY: boolean;\n declare lockScalingFlip: boolean;\n\n declare cornerSize: number;\n declare touchCornerSize: number;\n declare transparentCorners: boolean;\n declare cornerColor: string;\n declare cornerStrokeColor: string;\n declare cornerStyle: 'rect' | 'circle';\n declare cornerDashArray: number[] | null;\n declare hasControls: boolean;\n\n declare borderColor: string;\n declare borderDashArray: number[] | null;\n declare borderOpacityWhenMoving: number;\n declare borderScaleFactor: number;\n declare hasBorders: boolean;\n declare selectionBackgroundColor: string;\n\n declare selectable: boolean;\n declare evented: boolean;\n declare perPixelTargetFind: boolean;\n declare activeOn: 'down' | 'up';\n\n declare hoverCursor: CSSStyleDeclaration['cursor'] | null;\n declare moveCursor: CSSStyleDeclaration['cursor'] | null;\n\n /**\n * The object's controls' position in viewport coordinates\n * Calculated by {@link Control#positionHandler} and {@link Control#calcCornerCoords}, depending on {@link padding}.\n * `corner/touchCorner` describe the 4 points forming the interactive area of the corner.\n * Used to draw and locate controls.\n */\n declare oCoords: Record;\n\n /**\n * keeps the value of the last hovered corner during mouse move.\n * 0 is no corner, or 'mt', 'ml', 'mtr' etc..\n * It should be private, but there is no harm in using it as\n * a read-only property.\n * this isn't cleaned automatically. Non selected objects may have wrong values\n * @type [string]\n */\n declare __corner?: string;\n\n /**\n * a map of control visibility for this object.\n * this was left when controls were introduced to not break the api too much\n * this takes priority over the generic control visibility\n */\n declare _controlsVisibility: Record;\n\n /**\n * holds the controls for the object.\n * controls are added by default_controls.js\n */\n declare controls: TControlSet;\n\n /**\n * internal boolean to signal the code that the object is\n * part of the move action.\n */\n declare isMoving?: boolean;\n\n /**\n * A boolean used from the gesture module to keep tracking of a scaling\n * action when there is no scaling transform in place.\n * This is an edge case and is used twice in all codebase.\n * Probably added to keep track of some performance issues\n * @TODO use git blame to investigate why it was added\n * DON'T USE IT. WE WILL TRY TO REMOVE IT\n */\n declare _scaling?: boolean;\n\n declare canvas?: Canvas;\n\n static ownDefaults = interactiveObjectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...InteractiveFabricObject.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(\n this,\n (this.constructor as typeof InteractiveFabricObject).createControls(),\n InteractiveFabricObject.ownDefaults,\n );\n this.setOptions(options);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults\n * @param {Object} [options] Options object\n */\n static createControls(): { controls: Record } {\n return { controls: createObjectDefaultControls() };\n }\n\n /**\n * Update width and height of the canvas for cache\n * returns true or false if canvas needed resize.\n * @private\n * @return {Boolean} true if the canvas has been resized\n */\n _updateCacheCanvas() {\n const targetCanvas = this.canvas;\n if (this.noScaleCache && targetCanvas && targetCanvas._currentTransform) {\n const transform = targetCanvas._currentTransform,\n target = transform.target,\n action = transform.action;\n if (\n this === (target as unknown as this) &&\n action &&\n action.startsWith(SCALE)\n ) {\n return false;\n }\n }\n return super._updateCacheCanvas();\n }\n\n getActiveControl() {\n const key = this.__corner;\n return key\n ? {\n key,\n control: this.controls[key],\n coord: this.oCoords[key],\n }\n : undefined;\n }\n\n /**\n * Determines which corner is under the mouse cursor, represented by `pointer`.\n * This function is return a corner only if the object is the active one.\n * This is done to avoid selecting corner of non active object and activating transformations\n * rather than drag action. The default behavior of fabricJS is that if you want to transform\n * an object, first you select it to show the control set\n * @private\n * @param {Object} pointer The pointer indicating the mouse position\n * @param {boolean} forTouch indicates if we are looking for interaction area with a touch action\n * @return {String|Boolean} corner code (tl, tr, bl, br, etc.), or 0 if nothing is found.\n */\n findControl(\n pointer: Point,\n forTouch = false,\n ): { key: string; control: Control; coord: TOCoord } | undefined {\n if (!this.hasControls || !this.canvas) {\n return undefined;\n }\n\n this.__corner = undefined;\n const cornerEntries = Object.entries(this.oCoords);\n for (let i = cornerEntries.length - 1; i >= 0; i--) {\n const [key, corner] = cornerEntries[i];\n const control = this.controls[key];\n\n if (\n control.shouldActivate(\n key,\n this,\n pointer,\n forTouch ? corner.touchCorner : corner.corner,\n )\n ) {\n // this.canvas.contextTop.fillRect(pointer.x - 1, pointer.y - 1, 2, 2);\n this.__corner = key;\n\n return { key, control, coord: this.oCoords[key] };\n }\n }\n\n return undefined;\n }\n\n /**\n * Calculates the coordinates of the center of each control plus the corners of the control itself\n * This basically just delegates to each control positionHandler\n * WARNING: changing what is passed to positionHandler is a breaking change, since position handler\n * is a public api and should be done just if extremely necessary\n * @return {Record}\n */\n calcOCoords(): Record {\n const vpt = this.getViewportTransform(),\n center = this.getCenterPoint(),\n tMatrix = createTranslateMatrix(center.x, center.y),\n rMatrix = createRotateMatrix({\n angle: this.getTotalAngle() - (!!this.group && this.flipX ? 180 : 0),\n }),\n positionMatrix = multiplyTransformMatrices(tMatrix, rMatrix),\n startMatrix = multiplyTransformMatrices(vpt, positionMatrix),\n finalMatrix = multiplyTransformMatrices(startMatrix, [\n 1 / vpt[0],\n 0,\n 0,\n 1 / vpt[3],\n 0,\n 0,\n ]),\n transformOptions = this.group\n ? qrDecompose(this.calcTransformMatrix())\n : undefined;\n // decomposing could bring negative scaling and `_calculateCurrentDimensions` can't take it\n if (transformOptions) {\n transformOptions.scaleX = Math.abs(transformOptions.scaleX);\n transformOptions.scaleY = Math.abs(transformOptions.scaleY);\n }\n const dim = this._calculateCurrentDimensions(transformOptions),\n coords: Record = {};\n\n this.forEachControl((control, key) => {\n const position = control.positionHandler(dim, finalMatrix, this, control);\n // coords[key] are sometimes used as points. Those are points to which we add\n // the property corner and touchCorner from `_calcCornerCoords`.\n // don't remove this assign for an object spread.\n coords[key] = Object.assign(\n position,\n this._calcCornerCoords(control, position),\n );\n });\n\n // debug code\n /*\n const canvas = this.canvas;\n setTimeout(function () {\n if (!canvas) return;\n canvas.contextTop.clearRect(0, 0, 700, 700);\n canvas.contextTop.fillStyle = 'green';\n Object.keys(coords).forEach(function(key) {\n const control = coords[key];\n canvas.contextTop.fillRect(control.x, control.y, 3, 3);\n });\n } 50);\n */\n return coords;\n }\n\n /**\n * Sets the coordinates that determine the interaction area of each control\n * note: if we would switch to ROUND corner area, all of this would disappear.\n * everything would resolve to a single point and a pythagorean theorem for the distance\n * @todo evaluate simplification of code switching to circle interaction area at runtime\n * @private\n */\n private _calcCornerCoords(control: Control, position: Point) {\n const angle = this.getTotalAngle();\n const corner = control.calcCornerCoords(\n angle,\n this.cornerSize,\n position.x,\n position.y,\n false,\n this,\n );\n const touchCorner = control.calcCornerCoords(\n angle,\n this.touchCornerSize,\n position.x,\n position.y,\n true,\n this,\n );\n return { corner, touchCorner };\n }\n\n /**\n * @override set controls' coordinates as well\n * See {@link https://github.com/fabricjs/fabric.js/wiki/When-to-call-setCoords} and {@link http://fabricjs.com/fabric-gotchas}\n * @return {void}\n */\n setCoords(): void {\n super.setCoords();\n this.canvas && (this.oCoords = this.calcOCoords());\n }\n\n /**\n * Calls a function for each control. The function gets called,\n * with the control, the control's key and the object that is calling the iterator\n * @param {Function} fn function to iterate over the controls over\n */\n forEachControl(\n fn: (\n control: Control,\n key: string,\n fabricObject: InteractiveFabricObject,\n ) => any,\n ) {\n for (const i in this.controls) {\n fn(this.controls[i], i, this);\n }\n }\n\n /**\n * Draws a colored layer behind the object, inside its selection borders.\n * Requires public options: padding, selectionBackgroundColor\n * this function is called when the context is transformed\n * has checks to be skipped when the object is on a staticCanvas\n * @todo evaluate if make this disappear in favor of a pre-render hook for objects\n * this was added by Andrea Bogazzi to make possible some feature for work reasons\n * it seemed a good option, now is an edge case\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n */\n drawSelectionBackground(ctx: CanvasRenderingContext2D): void {\n if (\n !this.selectionBackgroundColor ||\n (this.canvas && (this.canvas._activeObject as unknown as this) !== this)\n ) {\n return;\n }\n ctx.save();\n const center = this.getRelativeCenterPoint(),\n wh = this._calculateCurrentDimensions(),\n vpt = this.getViewportTransform();\n ctx.translate(center.x, center.y);\n ctx.scale(1 / vpt[0], 1 / vpt[3]);\n ctx.rotate(degreesToRadians(this.angle));\n ctx.fillStyle = this.selectionBackgroundColor;\n ctx.fillRect(-wh.x / 2, -wh.y / 2, wh.x, wh.y);\n ctx.restore();\n }\n\n /**\n * @public override this function in order to customize the drawing of the control box, e.g. rounded corners, different border style.\n * @param {CanvasRenderingContext2D} ctx ctx is rotated and translated so that (0,0) is at object's center\n * @param {Point} size the control box size used\n */\n strokeBorders(ctx: CanvasRenderingContext2D, size: Point): void {\n ctx.strokeRect(-size.x / 2, -size.y / 2, size.x, size.y);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size\n * @param {TStyleOverride} styleOverride object to override the object style\n */\n _drawBorders(\n ctx: CanvasRenderingContext2D,\n size: Point,\n styleOverride: TStyleOverride = {},\n ): void {\n const options = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n borderDashArray: this.borderDashArray,\n ...styleOverride,\n };\n ctx.save();\n ctx.strokeStyle = options.borderColor;\n this._setLineDash(ctx, options.borderDashArray);\n this.strokeBorders(ctx, size);\n options.hasControls && this.drawControlsConnectingLines(ctx, size);\n ctx.restore();\n }\n\n /**\n * Renders controls and borders for the object\n * the context here is not transformed\n * @todo move to interactivity\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {TStyleOverride} [styleOverride] properties to override the object style\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: TStyleOverride = {},\n ) {\n const { hasBorders, hasControls } = this;\n const styleOptions = {\n hasBorders,\n hasControls,\n ...styleOverride,\n };\n const vpt = this.getViewportTransform(),\n shouldDrawBorders = styleOptions.hasBorders,\n shouldDrawControls = styleOptions.hasControls;\n const matrix = multiplyTransformMatrices(vpt, this.calcTransformMatrix());\n const options = qrDecompose(matrix);\n ctx.save();\n ctx.translate(options.translateX, options.translateY);\n ctx.lineWidth = 1 * this.borderScaleFactor;\n // since interactive groups have been introduced, an object could be inside a group and needing controls\n // the following equality check `this.group === this.parent` covers:\n // object without a group ( undefined === undefined )\n // object inside a group\n // excludes object inside a group but multi selected since group and parent will differ in value\n if (this.group === this.parent) {\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n }\n if (this.flipX) {\n options.angle -= 180;\n }\n ctx.rotate(degreesToRadians(this.group ? options.angle : this.angle));\n shouldDrawBorders && this.drawBorders(ctx, options, styleOverride);\n shouldDrawControls && this.drawControls(ctx, styleOverride);\n ctx.restore();\n }\n\n /**\n * Draws borders of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {object} options object representing current object parameters\n * @param {TStyleOverride} [styleOverride] object to override the object style\n */\n drawBorders(\n ctx: CanvasRenderingContext2D,\n options: TQrDecomposeOut,\n styleOverride: TStyleOverride,\n ): void {\n let size;\n if ((styleOverride && styleOverride.forActiveSelection) || this.group) {\n const bbox = sizeAfterTransform(\n this.width,\n this.height,\n calcDimensionsMatrix(options),\n ),\n stroke = !this.isStrokeAccountedForInDimensions()\n ? (this.strokeUniform\n ? new Point().scalarAdd(this.canvas ? this.canvas.getZoom() : 1)\n : // this is extremely confusing. options comes from the upper function\n // and is the qrDecompose of a matrix that takes in account zoom too\n new Point(options.scaleX, options.scaleY)\n ).scalarMultiply(this.strokeWidth)\n : ZERO;\n size = bbox\n .add(stroke)\n .scalarAdd(this.borderScaleFactor)\n .scalarAdd(this.padding * 2);\n } else {\n size = this._calculateCurrentDimensions().scalarAdd(\n this.borderScaleFactor,\n );\n }\n this._drawBorders(ctx, size, styleOverride);\n }\n\n /**\n * Draws lines from a borders of an object's bounding box to controls that have `withConnection` property set.\n * Requires public properties: width, height\n * Requires public options: padding, borderColor\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {Point} size object size x = width, y = height\n */\n drawControlsConnectingLines(\n ctx: CanvasRenderingContext2D,\n size: Point,\n ): void {\n let shouldStroke = false;\n\n ctx.beginPath();\n this.forEachControl((control, key) => {\n // in this moment, the ctx is centered on the object.\n // width and height of the above function are the size of the bbox.\n if (control.withConnection && control.getVisibility(this, key)) {\n // reset movement for each control\n shouldStroke = true;\n ctx.moveTo(control.x * size.x, control.y * size.y);\n ctx.lineTo(\n control.x * size.x + control.offsetX,\n control.y * size.y + control.offsetY,\n );\n }\n });\n shouldStroke && ctx.stroke();\n }\n\n /**\n * Draws corners of an object's bounding box.\n * Requires public properties: width, height\n * Requires public options: cornerSize, padding\n * Be aware that since fabric 6.0 this function does not call setCoords anymore.\n * setCoords needs to be called manually if the object of which we are rendering controls\n * is outside the standard selection and transform process.\n * @param {CanvasRenderingContext2D} ctx Context to draw on\n * @param {ControlRenderingStyleOverride} styleOverride object to override the object style\n */\n drawControls(\n ctx: CanvasRenderingContext2D,\n styleOverride: ControlRenderingStyleOverride = {},\n ) {\n ctx.save();\n const retinaScaling = this.getCanvasRetinaScaling();\n const { cornerStrokeColor, cornerDashArray, cornerColor } = this;\n const options = {\n cornerStrokeColor,\n cornerDashArray,\n cornerColor,\n ...styleOverride,\n };\n ctx.setTransform(retinaScaling, 0, 0, retinaScaling, 0, 0);\n ctx.strokeStyle = ctx.fillStyle = options.cornerColor;\n if (!this.transparentCorners) {\n ctx.strokeStyle = options.cornerStrokeColor;\n }\n this._setLineDash(ctx, options.cornerDashArray);\n this.forEachControl((control, key) => {\n if (control.getVisibility(this, key)) {\n const p = this.oCoords[key];\n control.render(ctx, p.x, p.y, options, this);\n }\n });\n ctx.restore();\n }\n\n /**\n * Returns true if the specified control is visible, false otherwise.\n * @param {string} controlKey The key of the control. Possible values are usually 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr',\n * but since the control api allow for any control name, can be any string.\n * @returns {boolean} true if the specified control is visible, false otherwise\n */\n isControlVisible(controlKey: string): boolean {\n return (\n this.controls[controlKey] &&\n this.controls[controlKey].getVisibility(this, controlKey)\n );\n }\n\n /**\n * Sets the visibility of the specified control.\n * please do not use.\n * @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.\n * but since the control api allow for any control name, can be any string.\n * @param {Boolean} visible true to set the specified control visible, false otherwise\n * @todo discuss this overlap of priority here with the team. Andrea Bogazzi for details\n */\n setControlVisible(controlKey: string, visible: boolean) {\n if (!this._controlsVisibility) {\n this._controlsVisibility = {};\n }\n this._controlsVisibility[controlKey] = visible;\n }\n\n /**\n * Sets the visibility state of object controls, this is just a bulk option for setControlVisible;\n * @param {Record} [options] with an optional key per control\n * example: {Boolean} [options.bl] true to enable the bottom-left control, false to disable it\n */\n setControlsVisibility(options: Record = {}) {\n Object.entries(options).forEach(([controlKey, visibility]) =>\n this.setControlVisible(controlKey, visibility),\n );\n }\n\n /**\n * Clears the canvas.contextTop in a specific area that corresponds to the object's bounding box\n * that is in the canvas.contextContainer.\n * This function is used to clear pieces of contextTop where we render ephemeral effects on top of the object.\n * Example: blinking cursor text selection, drag effects.\n * @todo discuss swapping restoreManually with a renderCallback, but think of async issues\n * @param {Boolean} [restoreManually] When true won't restore the context after clear, in order to draw something else.\n * @return {CanvasRenderingContext2D|undefined} canvas.contextTop that is either still transformed\n * with the object transformMatrix, or restored to neutral transform\n */\n clearContextTop(\n restoreManually?: boolean,\n ): CanvasRenderingContext2D | undefined {\n if (!this.canvas) {\n return;\n }\n const ctx = this.canvas.contextTop;\n if (!ctx) {\n return;\n }\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n this.transform(ctx);\n // we add 4 pixel, to be sure to do not leave any pixel out\n const width = this.width + 4,\n height = this.height + 4;\n ctx.clearRect(-width / 2, -height / 2, width, height);\n\n restoreManually || ctx.restore();\n return ctx;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to deselect this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {TPointerEvent} [options.e] event if the process is generated by an event\n * @param {FabricObject} [options.object] next object we are setting as active, and reason why\n * this is being deselected\n */\n onDeselect(_options?: {\n e?: TPointerEvent;\n object?: InteractiveFabricObject;\n }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * This callback function is called every time _discardActiveObject or _setActiveObject\n * try to to select this object. If the function returns true, the process is cancelled\n * @param {Object} [_options] options sent from the upper functions\n * @param {Event} [_options.e] event if the process is generated by an event\n */\n onSelect(_options?: { e?: TPointerEvent }): boolean {\n // implemented by sub-classes, as needed.\n return false;\n }\n\n /**\n * Override to customize Drag behavior\n * Fired from {@link Canvas#_onMouseMove}\n * @returns true in order for the window to start a drag session\n */\n shouldStartDragging(_e: TPointerEvent) {\n return false;\n }\n\n /**\n * Override to customize Drag behavior\\\n * Fired once a drag session has started\n * @returns true to handle the drag event\n */\n onDragStart(_e: DragEvent) {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * @public\n * @param {DragEvent} _e\n * @returns {boolean} true if the object currently dragged can be dropped on the target\n */\n canDrop(_e: DragEvent): boolean {\n return false;\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the source of a drag event\n * example: render the selection status for the part of text that is being dragged from a text object\n * @public\n * @param {DragEvent} _e\n */\n renderDragSourceEffect(_e: DragEvent) {\n // for subclasses\n }\n\n /**\n * Override to customize drag and drop behavior\n * render a specific effect when an object is the target of a drag event\n * used to show that the underly object can receive a drop, or to show how the\n * object will change when dropping. example: show the cursor where the text is about to be dropped\n * @public\n * @param {DragEvent} _e\n */\n renderDropTargetEffect(_e: DragEvent) {\n // for subclasses\n }\n}\n","import type { Constructor } from '../typedefs';\n\n/***\n * https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern\n */\nexport function applyMixins(\n derivedCtor: T,\n constructors: S[],\n) {\n constructors.forEach((baseCtor) => {\n Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {\n name !== 'constructor' &&\n Object.defineProperty(\n derivedCtor.prototype,\n name,\n Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||\n Object.create(null),\n );\n });\n });\n return derivedCtor as T & { prototype: InstanceType };\n}\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport { FabricObjectSVGExportMixin } from './FabricObjectSVGExportMixin';\nimport { InteractiveFabricObject } from './InteractiveObject';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps } from './types/FabricObjectProps';\nimport type { TFabricObjectProps, SerializedObjectProps } from './types';\nimport { classRegistry } from '../../ClassRegistry';\n\n// TODO somehow we have to make a tree-shakeable import\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface FabricObject<\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n Props extends TFabricObjectProps = Partial,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n SProps extends SerializedObjectProps = SerializedObjectProps,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObjectSVGExportMixin {}\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class FabricObject<\n Props extends TFabricObjectProps = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends InteractiveFabricObject {}\n\napplyMixins(FabricObject, [FabricObjectSVGExportMixin]);\n\nclassRegistry.setClass(FabricObject);\nclassRegistry.setClass(FabricObject, 'object');\n\nexport { cacheProperties } from './defaultValues';\n","/**\n * Returns true if context has transparent pixel\n * at specified location (taking tolerance into account)\n * @param {CanvasRenderingContext2D} ctx context\n * @param {Number} x x coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} y y coordinate in canvasElementCoordinate, not fabric space. integer\n * @param {Number} tolerance Tolerance pixels around the point, not alpha tolerance, integer\n * @return {boolean} true if transparent\n */\nexport const isTransparent = (\n ctx: CanvasRenderingContext2D,\n x: number,\n y: number,\n tolerance: number,\n): boolean => {\n tolerance = Math.round(tolerance);\n const size = tolerance * 2 + 1;\n const { data } = ctx.getImageData(x - tolerance, y - tolerance, size, size);\n\n // Split image data - for tolerance > 1, pixelDataSize = 4;\n for (let i = 3; i < data.length; i += 4) {\n const alphaChannel = data[i];\n if (alphaChannel > 0) {\n return false;\n }\n }\n return true;\n};\n","import type { Point } from '../../Point';\nimport type { TRadian } from '../../typedefs';\n/**\n * Rotates `point` around `origin` with `radians`\n * @deprecated use the Point.rotate\n * @param {Point} origin The origin of the rotation\n * @param {Point} origin The origin of the rotation\n * @param {TRadian} radians The radians of the angle for the rotation\n * @return {Point} The new rotated point\n */\nexport const rotatePoint = (\n point: Point,\n origin: Point,\n radians: TRadian,\n): Point => point.rotate(radians, origin);\n","export const findIndexRight = (\n array: T[],\n predicate: (value: T, index: number, array: T[]) => boolean,\n) => {\n for (let index = array.length - 1; index >= 0; index--) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n};\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport { createVector } from '../vectors';\nimport type { TProjectStrokeOnPointsOptions, TProjection } from './types';\n\n/**\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n * @todo consider removing skewing from points before calculating stroke projection,\n * see https://github.com/fabricjs/fabric.js/commit/494a10ee2f8c2278ae9a55b20bf50cf6ee25b064#commitcomment-94751537\n */\nexport abstract class StrokeProjectionsBase {\n declare options: TProjectStrokeOnPointsOptions;\n declare scale: Point;\n declare strokeUniformScalar: Point;\n declare strokeProjectionMagnitude: number;\n\n constructor(options: TProjectStrokeOnPointsOptions) {\n this.options = options;\n this.strokeProjectionMagnitude = this.options.strokeWidth / 2;\n this.scale = new Point(this.options.scaleX, this.options.scaleY);\n this.strokeUniformScalar = this.options.strokeUniform\n ? new Point(1 / this.options.scaleX, 1 / this.options.scaleY)\n : new Point(1, 1);\n }\n\n /**\n * When the stroke is uniform, scaling affects the arrangement of points. So we must take it into account.\n */\n protected createSideVector(from: XY, to: XY) {\n const v = createVector(from, to);\n return this.options.strokeUniform ? v.multiply(this.scale) : v;\n }\n\n protected abstract calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude?: number,\n ): Point;\n\n protected projectOrthogonally(from: Point, to: Point, magnitude?: number) {\n return this.applySkew(\n from.add(this.calcOrthogonalProjection(from, to, magnitude)),\n );\n }\n\n protected isSkewed() {\n return this.options.skewX !== 0 || this.options.skewY !== 0;\n }\n\n protected applySkew(point: Point) {\n const p = new Point(point);\n // skewY must be applied before skewX as this distortion affects skewX calculation\n p.y += p.x * Math.tan(degreesToRadians(this.options.skewY));\n p.x += p.y * Math.tan(degreesToRadians(this.options.skewX));\n return p;\n }\n\n protected scaleUnitVector(unitVector: Point, scalar: number) {\n return unitVector.multiply(this.strokeUniformScalar).scalarMultiply(scalar);\n }\n\n protected abstract projectPoints(): Point[];\n\n public abstract project(): TProjection[];\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { halfPI, twoMathPi } from '../../../constants';\nimport type { TRadian } from '../../../typedefs';\nimport { degreesToRadians } from '../radiansDegreesConversion';\nimport {\n calcAngleBetweenVectors,\n calcVectorRotation,\n crossProduct,\n getOrthonormalVector,\n getUnitVector,\n isBetweenVectors,\n magnitude,\n rotateVector,\n} from '../vectors';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nconst zeroVector = new Point();\n\n/**\n * class in charge of finding projections for each type of line join\n * @see {@link [Closed path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#2-closed-path)}\n *\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin\n * - Spec: https://svgwg.org/svg2-draft/painting.html#StrokeLinejoinProperty\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n *\n */\nexport class StrokeLineJoinProjections extends StrokeProjectionsBase {\n /**\n * The point being projected (the angle ∠BAC)\n */\n declare A: Point;\n /**\n * The point before A\n */\n declare B: Point;\n /**\n * The point after A\n */\n declare C: Point;\n /**\n * The AB vector\n */\n AB: Point;\n /**\n * The AC vector\n */\n AC: Point;\n /**\n * The angle of A (∠BAC)\n */\n alpha: TRadian;\n /**\n * The bisector of A (∠BAC)\n */\n bisector: Point;\n\n static getOrthogonalRotationFactor(vector1: Point, vector2?: Point) {\n const angle = vector2\n ? calcAngleBetweenVectors(vector1, vector2)\n : calcVectorRotation(vector1);\n return Math.abs(angle) < halfPI ? -1 : 1;\n }\n\n constructor(A: XY, B: XY, C: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.B = new Point(B);\n this.C = new Point(C);\n this.AB = this.createSideVector(this.A, this.B);\n this.AC = this.createSideVector(this.A, this.C);\n this.alpha = calcAngleBetweenVectors(this.AB, this.AC);\n this.bisector = getUnitVector(\n // if AC is also the zero vector nothing will be projected\n // in that case the next point will handle the projection\n rotateVector(this.AB.eq(zeroVector) ? this.AC : this.AB, this.alpha / 2),\n );\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n const orthogonalProjection = getOrthonormalVector(vector);\n const correctSide = StrokeLineJoinProjections.getOrthogonalRotationFactor(\n orthogonalProjection,\n this.bisector,\n );\n return this.scaleUnitVector(orthogonalProjection, magnitude * correctSide);\n }\n\n /**\n * BEVEL\n * Calculation: the projection points are formed by the vector orthogonal to the vertex.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-2-bevel\n */\n projectBevel() {\n const projections: Point[] = [];\n // if `alpha` equals 0 or 2*PI, the projections are the same for `B` and `C`\n (this.alpha % twoMathPi === 0 ? [this.B] : [this.B, this.C]).forEach(\n (to) => {\n projections.push(this.projectOrthogonally(this.A, to));\n projections.push(\n this.projectOrthogonally(this.A, to, -this.strokeProjectionMagnitude),\n );\n },\n );\n return projections;\n }\n\n /**\n * MITER\n * Calculation: the corner is formed by extending the outer edges of the stroke\n * at the tangents of the path segments until they intersect.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-1-miter\n */\n projectMiter() {\n const projections: Point[] = [],\n alpha = Math.abs(this.alpha),\n hypotUnitScalar = 1 / Math.sin(alpha / 2),\n miterVector = this.scaleUnitVector(\n this.bisector,\n -this.strokeProjectionMagnitude * hypotUnitScalar,\n );\n\n // When two line segments meet at a sharp angle, it is possible for the join to extend,\n // far beyond the thickness of the line stroking the path. The stroke-miterlimit imposes\n // a limit on the extent of the line join.\n // MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit\n // When the stroke is uniform, scaling changes the arrangement of points, this changes the miter-limit\n const strokeMiterLimit = this.options.strokeUniform\n ? magnitude(\n this.scaleUnitVector(this.bisector, this.options.strokeMiterLimit),\n )\n : this.options.strokeMiterLimit;\n\n if (\n magnitude(miterVector) / this.strokeProjectionMagnitude <=\n strokeMiterLimit\n ) {\n projections.push(this.applySkew(this.A.add(miterVector)));\n }\n /* when the miter-limit is reached, the stroke line join becomes of type bevel.\n We always need two orthogonal projections which are basically bevel-type projections,\n so regardless of whether the miter-limit was reached or not, we include these projections.\n */\n projections.push(...this.projectBevel());\n\n return projections;\n }\n\n /**\n * ROUND (without skew)\n * Calculation: the projections are the two vectors parallel to X and Y axes\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-1-round-without-skew\n */\n private projectRoundNoSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [],\n // correctSide is used to only consider projecting for the outer side\n correctSide = new Point(\n StrokeLineJoinProjections.getOrthogonalRotationFactor(this.bisector),\n StrokeLineJoinProjections.getOrthogonalRotationFactor(\n new Point(this.bisector.y, this.bisector.x),\n ),\n ),\n radiusOnAxisX = new Point(1, 0)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide),\n radiusOnAxisY = new Point(0, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar)\n .multiply(correctSide);\n\n [radiusOnAxisX, radiusOnAxisY].forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.A.add(vector));\n }\n });\n return projections;\n }\n\n /**\n * ROUND (with skew)\n * Calculation: the projections are the points furthest from the vertex in\n * the direction of the X and Y axes after distortion.\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#2-3-2-round-skew\n */\n private projectRoundWithSkew(startCircle: Point, endCircle: Point) {\n const projections: Point[] = [];\n\n const { skewX, skewY, scaleX, scaleY, strokeUniform } = this.options,\n shearing = new Point(\n Math.tan(degreesToRadians(skewX)),\n Math.tan(degreesToRadians(skewY)),\n );\n // The points furthest from the vertex in the direction of the X and Y axes after distortion\n const circleRadius = this.strokeProjectionMagnitude,\n newY = strokeUniform\n ? circleRadius /\n scaleY /\n Math.sqrt(1 / scaleY ** 2 + (1 / scaleX ** 2) * shearing.y ** 2)\n : circleRadius / Math.sqrt(1 + shearing.y ** 2),\n furthestY = new Point(\n // Safe guard due to floating point precision. In some situations the square root\n // was returning NaN because of a negative number close to zero.\n Math.sqrt(Math.max(circleRadius ** 2 - newY ** 2, 0)),\n newY,\n ),\n newX = strokeUniform\n ? circleRadius /\n Math.sqrt(\n 1 +\n (shearing.x ** 2 * (1 / scaleY) ** 2) /\n (1 / scaleX + (1 / scaleX) * shearing.x * shearing.y) ** 2,\n )\n : circleRadius /\n Math.sqrt(1 + shearing.x ** 2 / (1 + shearing.x * shearing.y) ** 2),\n furthestX = new Point(\n newX,\n Math.sqrt(Math.max(circleRadius ** 2 - newX ** 2, 0)),\n );\n\n [\n furthestX,\n furthestX.scalarMultiply(-1),\n furthestY,\n furthestY.scalarMultiply(-1),\n ]\n // We need to skew the vector here as this information is used to check if\n // it is between the start and end of the circle segment\n .map((vector) =>\n this.applySkew(\n strokeUniform ? vector.multiply(this.strokeUniformScalar) : vector,\n ),\n )\n .forEach((vector) => {\n if (isBetweenVectors(vector, startCircle, endCircle)) {\n projections.push(this.applySkew(this.A).add(vector));\n }\n });\n\n return projections;\n }\n\n projectRound() {\n const projections: Point[] = [];\n /* Include the start and end points of the circle segment, so that only\n the projections contained within it are included */\n // add the orthogonal projections (start and end points of circle segment)\n projections.push(...this.projectBevel());\n // let's determines which one of the orthogonal projection is the beginning and end of the circle segment.\n // when `alpha` equals 0 or 2*PI, we have a straight line, so the way to find the start/end is different.\n const isStraightLine = this.alpha % twoMathPi === 0,\n // change the origin of the projections to point A\n // so that the cross product calculation is correct\n newOrigin = this.applySkew(this.A),\n proj0 = projections[isStraightLine ? 0 : 2].subtract(newOrigin),\n proj1 = projections[isStraightLine ? 1 : 0].subtract(newOrigin),\n // when `isStraightLine` === true, we compare with the vector opposite AB, otherwise we compare with the bisector.\n comparisonVector = isStraightLine\n ? this.applySkew(this.AB.scalarMultiply(-1))\n : this.applySkew(\n this.bisector.multiply(this.strokeUniformScalar).scalarMultiply(-1),\n ),\n // the beginning of the circle segment is always to the right of the comparison vector (cross product > 0)\n isProj0Start = crossProduct(proj0, comparisonVector) > 0,\n startCircle = isProj0Start ? proj0 : proj1,\n endCircle = isProj0Start ? proj1 : proj0;\n if (!this.isSkewed()) {\n projections.push(...this.projectRoundNoSkew(startCircle, endCircle));\n } else {\n projections.push(...this.projectRoundWithSkew(startCircle, endCircle));\n }\n return projections;\n }\n\n /**\n * Project stroke width on points returning projections for each point as follows:\n * - `miter`: 1 point corresponding to the outer boundary. If the miter limit is exceeded, it will be 2 points (becomes bevel)\n * - `bevel`: 2 points corresponding to the bevel possible boundaries, orthogonal to the stroke.\n * - `round`: same as `bevel` when it has no skew, with skew are 4 points.\n */\n protected projectPoints() {\n switch (this.options.strokeLineJoin) {\n case 'miter':\n return this.projectMiter();\n case 'round':\n return this.projectRound();\n default:\n return this.projectBevel();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n angle: this.alpha,\n bisector: this.bisector,\n }));\n }\n}\n","import type { XY } from '../../../Point';\nimport { Point } from '../../../Point';\nimport { getOrthonormalVector, getUnitVector } from '../vectors';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport { StrokeProjectionsBase } from './StrokeProjectionsBase';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\n/**\n * class in charge of finding projections for each type of line cap for start/end of an open path\n * @see {@link [Open path projections at #8344](https://github.com/fabricjs/fabric.js/pull/8344#1-open-path)}\n *\n * Reference:\n * - MDN:\n * - https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap\n * - https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap\n * - Spec: https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-linecap-dev\n * - Playground to understand how the line joins works: https://hypertolosana.github.io/efficient-webgl-stroking/index.html\n * - View the calculated projections for each of the control points: https://codesandbox.io/s/project-stroke-points-with-context-to-trace-b8jc4j?file=/src/index.js\n */\nexport class StrokeLineCapProjections extends StrokeProjectionsBase {\n /**\n * edge point\n */\n declare A: Point;\n /**\n * point next to edge point\n */\n declare T: Point;\n\n constructor(A: XY, T: XY, options: TProjectStrokeOnPointsOptions) {\n super(options);\n this.A = new Point(A);\n this.T = new Point(T);\n }\n\n calcOrthogonalProjection(\n from: Point,\n to: Point,\n magnitude: number = this.strokeProjectionMagnitude,\n ) {\n const vector = this.createSideVector(from, to);\n return this.scaleUnitVector(getOrthonormalVector(vector), magnitude);\n }\n\n /**\n * OPEN PATH START/END - Line cap: Butt\n * Calculation: to find the projections, just find the points orthogonal to the stroke\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-1-butt\n */\n projectButt() {\n return [\n this.projectOrthogonally(this.A, this.T, this.strokeProjectionMagnitude),\n this.projectOrthogonally(this.A, this.T, -this.strokeProjectionMagnitude),\n ];\n }\n\n /**\n * OPEN PATH START/END - Line cap: Round\n * Calculation: same as stroke line join `round`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-2-round\n */\n projectRound() {\n const projections: Point[] = [];\n\n if (!this.isSkewed() && this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(\n this.applySkew(this.A.add(projection)),\n this.applySkew(this.A.subtract(projection)),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(\n this.A,\n this.T,\n this.T,\n this.options,\n ).projectRound(),\n );\n }\n\n return projections;\n }\n\n /**\n * OPEN PATH START/END - Line cap: Square\n * Calculation: project a rectangle of points on the stroke in the opposite direction of the vector `AT`\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344#1-3-square\n */\n projectSquare() {\n const projections: Point[] = [];\n\n if (this.A.eq(this.T)) {\n /* 1 point case without `skew`\n When `strokeUniform` is true, scaling has no effect.\n So we divide by scale, to remove its effect.\n */\n const projection = new Point(1, 1)\n .scalarMultiply(this.strokeProjectionMagnitude)\n .multiply(this.strokeUniformScalar);\n projections.push(this.A.add(projection), this.A.subtract(projection));\n } else {\n const orthogonalProjection = this.calcOrthogonalProjection(\n this.A,\n this.T,\n this.strokeProjectionMagnitude,\n );\n const strokePointingOut = this.scaleUnitVector(\n getUnitVector(this.createSideVector(this.A, this.T)),\n -this.strokeProjectionMagnitude,\n );\n const projectedA = this.A.add(strokePointingOut);\n projections.push(\n projectedA.add(orthogonalProjection),\n projectedA.subtract(orthogonalProjection),\n );\n }\n\n return projections.map((p) => this.applySkew(p));\n }\n\n protected projectPoints() {\n switch (this.options.strokeLineCap) {\n case 'round':\n return this.projectRound();\n case 'square':\n return this.projectSquare();\n default:\n return this.projectButt();\n }\n }\n\n public project(): TProjection[] {\n return this.projectPoints().map((point) => ({\n originPoint: this.A,\n projectedPoint: point,\n }));\n }\n}\n","import { Point, type XY } from '../../../Point';\nimport { findIndexRight } from '../../internals/findRight';\nimport { StrokeLineCapProjections } from './StrokeLineCapProjections';\nimport { StrokeLineJoinProjections } from './StrokeLineJoinProjections';\nimport type { TProjection, TProjectStrokeOnPointsOptions } from './types';\n\nexport * from './types';\n\n/**\n *\n * Used to calculate object's bounding box\n *\n * @see https://github.com/fabricjs/fabric.js/pull/8344\n *\n */\nexport const projectStrokeOnPoints = (\n points: XY[],\n options: TProjectStrokeOnPointsOptions,\n openPath = false,\n): TProjection[] => {\n const projections: TProjection[] = [];\n\n if (points.length === 0) {\n return projections;\n }\n\n // first we remove duplicate neighboring points\n const reduced = points.reduce(\n (reduced, point) => {\n if (!reduced[reduced.length - 1].eq(point)) {\n reduced.push(new Point(point));\n }\n return reduced;\n },\n [new Point(points[0])],\n );\n\n if (reduced.length === 1) {\n openPath = true;\n } else if (!openPath) {\n // remove points from end in case they equal the first point\n // in order to correctly project the first point\n const start = reduced[0];\n const index = findIndexRight(reduced, (point) => !point.eq(start));\n reduced.splice(index + 1);\n }\n\n reduced.forEach((A, index, points) => {\n let B: XY, C: XY;\n if (index === 0) {\n C = points[1];\n B = openPath ? A : points[points.length - 1];\n } else if (index === points.length - 1) {\n B = points[index - 1];\n C = openPath ? A : points[0];\n } else {\n B = points[index - 1];\n C = points[index + 1];\n }\n\n if (openPath && points.length === 1) {\n projections.push(\n ...new StrokeLineCapProjections(A, A, options).project(),\n );\n } else if (openPath && (index === 0 || index === points.length - 1)) {\n projections.push(\n ...new StrokeLineCapProjections(\n A,\n index === 0 ? C : B,\n options,\n ).project(),\n );\n } else {\n projections.push(\n ...new StrokeLineJoinProjections(A, B, C, options).project(),\n );\n }\n });\n\n return projections;\n};\n","import type { TextStyle } from '../../shapes/Text/StyledText';\n\nexport const cloneStyles = (style: TextStyle): TextStyle => {\n const newObj: TextStyle = {};\n Object.keys(style).forEach((key) => {\n newObj[key] = {};\n Object.keys(style[key]).forEach((keyInner) => {\n newObj[key][keyInner] = { ...style[key][keyInner] };\n });\n });\n return newObj;\n};\n","/**\n * Capitalizes a string\n * @param {String} string String to capitalize\n * @param {Boolean} [firstLetterOnly] If true only first letter is capitalized\n * and other letters stay untouched, if false first letter is capitalized\n * and other letters are converted to lowercase.\n * @return {String} Capitalized version of a string\n */\nexport const capitalize = (string: string, firstLetterOnly = false): string =>\n `${string.charAt(0).toUpperCase()}${\n firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase()\n }`;\n\n/**\n * Escapes XML in a string\n * @param {String} string String to escape\n * @return {String} Escaped version of a string\n */\nexport const escapeXml = (string: string): string =>\n string\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(//g, '>');\n\n/**\n * Divide a string in the user perceived single units\n * @param {String} textstring String to escape\n * @return {Array} array containing the graphemes\n */\nexport const graphemeSplit = (textstring: string): string[] => {\n const graphemes = [];\n for (let i = 0, chr; i < textstring.length; i++) {\n if ((chr = getWholeChar(textstring, i)) === false) {\n continue;\n }\n graphemes.push(chr as string);\n }\n return graphemes;\n};\n\n// taken from mdn in the charAt doc page.\nconst getWholeChar = (str: string, i: number): string | boolean => {\n const code = str.charCodeAt(i);\n if (isNaN(code)) {\n return ''; // Position not found\n }\n if (code < 0xd800 || code > 0xdfff) {\n return str.charAt(i);\n }\n\n // High surrogate (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 <= code && code <= 0xdbff) {\n if (str.length <= i + 1) {\n throw 'High surrogate without following low surrogate';\n }\n const next = str.charCodeAt(i + 1);\n if (0xdc00 > next || next > 0xdfff) {\n throw 'High surrogate without following low surrogate';\n }\n return str.charAt(i) + str.charAt(i + 1);\n }\n // Low surrogate (0xDC00 <= code && code <= 0xDFFF)\n if (i === 0) {\n throw 'Low surrogate without preceding high surrogate';\n }\n const prev = str.charCodeAt(i - 1);\n\n // (could change last hex to 0xDB7F to treat high private\n // surrogates as single characters)\n if (0xd800 > prev || prev > 0xdbff) {\n throw 'Low surrogate without preceding high surrogate';\n }\n // We can pass over low surrogates now as the second component\n // in a pair which we have already processed\n return false;\n};\n","import { reNewline } from '../../constants';\nimport type {\n TextStyle,\n TextStyleDeclaration,\n} from '../../shapes/Text/StyledText';\nimport { cloneStyles } from '../internals/cloneStyles';\nimport { graphemeSplit } from '../lang_string';\n\nexport type TextStyleArray = {\n start: number;\n end: number;\n style: TextStyleDeclaration;\n}[];\n\n/**\n * @param {Object} prevStyle first style to compare\n * @param {Object} thisStyle second style to compare\n * @param {boolean} forTextSpans whether to check overline, underline, and line-through properties\n * @return {boolean} true if the style changed\n */\nexport const hasStyleChanged = (\n prevStyle: TextStyleDeclaration,\n thisStyle: TextStyleDeclaration,\n forTextSpans = false,\n) =>\n prevStyle.fill !== thisStyle.fill ||\n prevStyle.stroke !== thisStyle.stroke ||\n prevStyle.strokeWidth !== thisStyle.strokeWidth ||\n prevStyle.fontSize !== thisStyle.fontSize ||\n prevStyle.fontFamily !== thisStyle.fontFamily ||\n prevStyle.fontWeight !== thisStyle.fontWeight ||\n prevStyle.fontStyle !== thisStyle.fontStyle ||\n prevStyle.textBackgroundColor !== thisStyle.textBackgroundColor ||\n prevStyle.deltaY !== thisStyle.deltaY ||\n (forTextSpans &&\n (prevStyle.overline !== thisStyle.overline ||\n prevStyle.underline !== thisStyle.underline ||\n prevStyle.linethrough !== thisStyle.linethrough));\n\n/**\n * Returns the array form of a text object's inline styles property with styles grouped in ranges\n * rather than per character. This format is less verbose, and is better suited for storage\n * so it is used in serialization (not during runtime).\n * @param {object} styles per character styles for a text object\n * @param {String} text the text string that the styles are applied to\n * @return {{start: number, end: number, style: object}[]}\n */\nexport const stylesToArray = (\n styles: TextStyle,\n text: string,\n): TextStyleArray => {\n const textLines = text.split('\\n'),\n stylesArray = [];\n let charIndex = -1,\n prevStyle = {};\n // clone style structure to prevent mutation\n styles = cloneStyles(styles);\n\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n if (!styles[i]) {\n //no styles exist for this line, so add the line's length to the charIndex total and reset prevStyle\n charIndex += chars.length;\n prevStyle = {};\n continue;\n }\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n const thisStyle = styles[i][c];\n //check if style exists for this character\n if (thisStyle && Object.keys(thisStyle).length > 0) {\n if (hasStyleChanged(prevStyle, thisStyle, true)) {\n stylesArray.push({\n start: charIndex,\n end: charIndex + 1,\n style: thisStyle,\n });\n } else {\n //if style is the same as previous character, increase end index\n stylesArray[stylesArray.length - 1].end++;\n }\n }\n prevStyle = thisStyle || {};\n }\n }\n return stylesArray;\n};\n\n/**\n * Returns the object form of the styles property with styles that are assigned per\n * character rather than grouped by range. This format is more verbose, and is\n * only used during runtime (not for serialization/storage)\n * @param {Array} styles the serialized form of a text object's styles\n * @param {String} text the text string that the styles are applied to\n * @return {Object}\n */\nexport const stylesFromArray = (\n styles: TextStyleArray | TextStyle,\n text: string,\n): TextStyle => {\n if (!Array.isArray(styles)) {\n // clone to prevent mutation\n return cloneStyles(styles);\n }\n const textLines = text.split(reNewline),\n stylesObject: TextStyle = {};\n let charIndex = -1,\n styleIndex = 0;\n //loop through each textLine\n for (let i = 0; i < textLines.length; i++) {\n const chars = graphemeSplit(textLines[i]);\n\n //loop through each character of the current line\n for (let c = 0; c < chars.length; c++) {\n charIndex++;\n //check if there's a style collection that includes the current character\n if (\n styles[styleIndex] &&\n styles[styleIndex].start <= charIndex &&\n charIndex < styles[styleIndex].end\n ) {\n //create object for line index if it doesn't exist\n stylesObject[i] = stylesObject[i] || {};\n //assign a style at this character's index\n stylesObject[i][c] = { ...styles[styleIndex].style };\n //if character is at the end of the current style collection, move to the next\n if (charIndex === styles[styleIndex].end - 1) {\n styleIndex++;\n }\n }\n }\n }\n return stylesObject;\n};\n","import { FILL, STROKE } from '../constants';\n\n/**\n * Attributes parsed from all SVG elements\n * @type array\n */\nexport const SHARED_ATTRIBUTES = [\n 'display',\n 'transform',\n FILL,\n 'fill-opacity',\n 'fill-rule',\n 'opacity',\n STROKE,\n 'stroke-dasharray',\n 'stroke-linecap',\n 'stroke-dashoffset',\n 'stroke-linejoin',\n 'stroke-miterlimit',\n 'stroke-opacity',\n 'stroke-width',\n 'id',\n 'paint-order',\n 'vector-effect',\n 'instantiated_by_use',\n 'clip-path',\n];\n","export function selectorMatches(element: HTMLElement, selector: string) {\n const nodeName = element.nodeName;\n const classNames = element.getAttribute('class');\n const id = element.getAttribute('id');\n const azAz = '(?![a-zA-Z\\\\-]+)';\n let matcher;\n // i check if a selector matches slicing away part from it.\n // if i get empty string i should match\n matcher = new RegExp('^' + nodeName, 'i');\n selector = selector.replace(matcher, '');\n if (id && selector.length) {\n matcher = new RegExp('#' + id + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n if (classNames && selector.length) {\n const splitClassNames = classNames.split(' ');\n for (let i = splitClassNames.length; i--; ) {\n matcher = new RegExp('\\\\.' + splitClassNames[i] + azAz, 'i');\n selector = selector.replace(matcher, '');\n }\n }\n return selector.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\n\nexport function doesSomeParentMatch(element: HTMLElement, selectors: string[]) {\n let selector: string,\n parentMatching = true;\n while (\n element.parentElement &&\n element.parentElement.nodeType === 1 &&\n selectors.length\n ) {\n if (parentMatching) {\n selector = selectors.pop()!;\n }\n element = element.parentElement;\n parentMatching = selectorMatches(element, selector!);\n }\n return selectors.length === 0;\n}\n","import { selectorMatches } from './selectorMatches';\nimport { doesSomeParentMatch } from './doesSomeParentMatch';\n\n/**\n * @private\n */\n\nexport function elementMatchesRule(element: HTMLElement, selectors: string[]) {\n let parentMatching = true;\n // start from rightmost selector.\n const firstMatching = selectorMatches(element, selectors.pop()!);\n if (firstMatching && selectors.length) {\n parentMatching = doesSomeParentMatch(element, selectors);\n }\n return firstMatching && parentMatching && selectors.length === 0;\n}\n","import { elementMatchesRule } from './elementMatchesRule';\nimport type { CSSRules } from './typedefs';\n\n/**\n * @private\n */\n\nexport function getGlobalStylesForElement(\n element: HTMLElement,\n cssRules: CSSRules = {},\n) {\n let styles: Record = {};\n for (const rule in cssRules) {\n if (elementMatchesRule(element, rule.split(' '))) {\n styles = {\n ...styles,\n ...cssRules[rule],\n };\n }\n }\n return styles;\n}\n","import { attributesMap } from './constants';\n\nexport const normalizeAttr = (\n attr: keyof typeof attributesMap | string,\n): string => attributesMap[attr as keyof typeof attributesMap] ?? attr;\n","import { reNum } from '../../parser/constants';\n\nconst regex = new RegExp(`(${reNum})`, 'gi');\n\nexport const cleanupSvgAttribute = (attributeValue: string) =>\n attributeValue\n .replace(regex, ' $1 ')\n // replace annoying commas and arbitrary whitespace with single spaces\n .replace(/,/gi, ' ')\n .replace(/\\s+/gi, ' ');\n","import { ROTATE, SCALE, SKEW_X, SKEW_Y, iMatrix } from '../constants';\nimport { reNum } from './constants';\nimport type { TMat2D } from '../typedefs';\nimport { cleanupSvgAttribute } from '../util/internals/cleanupSvgAttribute';\nimport {\n createRotateMatrix,\n createScaleMatrix,\n createSkewXMatrix,\n createSkewYMatrix,\n createTranslateMatrix,\n multiplyTransformMatrixArray,\n} from '../util/misc/matrix';\n\n// == begin transform regexp\nconst p = `(${reNum})`;\nconst skewX = String.raw`(skewX)\\(${p}\\)`;\nconst skewY = String.raw`(skewY)\\(${p}\\)`;\nconst rotate = String.raw`(rotate)\\(${p}(?: ${p} ${p})?\\)`;\nconst scale = String.raw`(scale)\\(${p}(?: ${p})?\\)`;\nconst translate = String.raw`(translate)\\(${p}(?: ${p})?\\)`;\nconst matrix = String.raw`(matrix)\\(${p} ${p} ${p} ${p} ${p} ${p}\\)`;\nconst transform = `(?:${matrix}|${translate}|${rotate}|${scale}|${skewX}|${skewY})`;\nconst transforms = `(?:${transform}*)`;\nconst transformList = String.raw`^\\s*(?:${transforms}?)\\s*$`;\n// http://www.w3.org/TR/SVG/coords.html#TransformAttribute\nconst reTransformList = new RegExp(transformList);\nconst reTransform = new RegExp(transform);\nconst reTransformAll = new RegExp(transform, 'g');\n// == end transform regexp\n\n/**\n * Parses \"transform\" attribute, returning an array of values\n * @static\n * @function\n * @memberOf fabric\n * @param {String} attributeValue String containing attribute value\n * @return {TTransformMatrix} Array of 6 elements representing transformation matrix\n */\nexport function parseTransformAttribute(attributeValue: string): TMat2D {\n // first we clean the string\n attributeValue = cleanupSvgAttribute(attributeValue)\n // remove spaces around front parentheses\n .replace(/\\s*([()])\\s*/gi, '$1');\n\n // start with identity matrix\n const matrices: TMat2D[] = [];\n\n // return if no argument was given or\n // an argument does not match transform attribute regexp\n if (\n !attributeValue ||\n (attributeValue && !reTransformList.test(attributeValue))\n ) {\n return [...iMatrix];\n }\n\n for (const match of attributeValue.matchAll(reTransformAll)) {\n const transformMatch = reTransform.exec(match[0]);\n if (!transformMatch) {\n continue;\n }\n let matrix: TMat2D = iMatrix;\n const matchedParams = transformMatch.filter((m) => !!m);\n const [, operation, ...rawArgs] = matchedParams;\n const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map((arg) =>\n parseFloat(arg),\n );\n\n switch (operation) {\n case 'translate':\n matrix = createTranslateMatrix(arg0, arg1);\n break;\n case ROTATE:\n matrix = createRotateMatrix({ angle: arg0 }, { x: arg1, y: arg2 });\n break;\n case SCALE:\n matrix = createScaleMatrix(arg0, arg1);\n break;\n case SKEW_X:\n matrix = createSkewXMatrix(arg0);\n break;\n case SKEW_Y:\n matrix = createSkewYMatrix(arg0);\n break;\n case 'matrix':\n matrix = [arg0, arg1, arg2, arg3, arg4, arg5];\n break;\n }\n\n // snapshot current matrix into matrices array\n matrices.push(matrix);\n }\n\n return multiplyTransformMatrixArray(matrices);\n}\n","import { multiplyTransformMatrices } from '../util/misc/matrix';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { parseTransformAttribute } from './parseTransformAttribute';\nimport { CENTER, LEFT, RIGHT, NONE, FILL, STROKE } from '../constants';\n\nexport function normalizeValue(\n attr: string,\n value: any,\n parentAttributes: Record,\n fontSize: number,\n): string | null | boolean | number[] | number {\n const isArray = Array.isArray(value);\n let parsed: number | number[];\n let ouputValue: string | null | boolean | number[] | number = value;\n if ((attr === FILL || attr === STROKE) && value === NONE) {\n ouputValue = '';\n } else if (attr === 'strokeUniform') {\n return value === 'non-scaling-stroke';\n } else if (attr === 'strokeDashArray') {\n if (value === NONE) {\n ouputValue = null;\n } else {\n ouputValue = value.replace(/,/g, ' ').split(/\\s+/).map(parseFloat);\n }\n } else if (attr === 'transformMatrix') {\n if (parentAttributes && parentAttributes.transformMatrix) {\n ouputValue = multiplyTransformMatrices(\n parentAttributes.transformMatrix,\n parseTransformAttribute(value),\n );\n } else {\n ouputValue = parseTransformAttribute(value);\n }\n } else if (attr === 'visible') {\n ouputValue = value !== NONE && value !== 'hidden';\n // display=none on parent element always takes precedence over child element\n if (parentAttributes && parentAttributes.visible === false) {\n ouputValue = false;\n }\n } else if (attr === 'opacity') {\n ouputValue = parseFloat(value);\n if (parentAttributes && typeof parentAttributes.opacity !== 'undefined') {\n ouputValue *= parentAttributes.opacity as number;\n }\n } else if (attr === 'textAnchor' /* text-anchor */) {\n ouputValue = value === 'start' ? LEFT : value === 'end' ? RIGHT : CENTER;\n } else if (attr === 'charSpacing') {\n // parseUnit returns px and we convert it to em\n parsed = (parseUnit(value, fontSize) / fontSize) * 1000;\n } else if (attr === 'paintFirst') {\n const fillIndex = value.indexOf(FILL);\n const strokeIndex = value.indexOf(STROKE);\n ouputValue = FILL;\n if (fillIndex > -1 && strokeIndex > -1 && strokeIndex < fillIndex) {\n ouputValue = STROKE;\n } else if (fillIndex === -1 && strokeIndex > -1) {\n ouputValue = STROKE;\n }\n } else if (\n attr === 'href' ||\n attr === 'xlink:href' ||\n attr === 'font' ||\n attr === 'id'\n ) {\n return value;\n } else if (attr === 'imageSmoothing') {\n return value === 'optimizeQuality';\n } else {\n parsed = isArray\n ? (value as string[]).map(parseUnit)\n : parseUnit(value, fontSize);\n }\n\n return !isArray && isNaN(parsed! as number) ? ouputValue : parsed!;\n}\n","import { parseUnit } from '../util/misc/svgParsing';\nimport { reFontDeclaration } from './constants';\n\n/**\n * Parses a short font declaration, building adding its properties to a style object\n * @static\n * @function\n * @memberOf fabric\n * @param {String} value font declaration\n * @param {Object} oStyle definition\n */\nexport function parseFontDeclaration(\n value: string,\n oStyle: Record,\n): void {\n const match = value.match(reFontDeclaration);\n\n if (!match) {\n return;\n }\n const fontStyle = match[1],\n // font variant is not used\n // fontVariant = match[2],\n fontWeight = match[3],\n fontSize = match[4],\n lineHeight = match[5],\n fontFamily = match[6];\n\n if (fontStyle) {\n oStyle.fontStyle = fontStyle;\n }\n if (fontWeight) {\n oStyle.fontWeight = isNaN(parseFloat(fontWeight))\n ? fontWeight\n : parseFloat(fontWeight);\n }\n if (fontSize) {\n oStyle.fontSize = parseUnit(fontSize);\n }\n if (fontFamily) {\n oStyle.fontFamily = fontFamily;\n }\n if (lineHeight) {\n oStyle.lineHeight = lineHeight === 'normal' ? 1 : lineHeight;\n }\n}\n","/**\n * Takes a style object and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleObject(\n style: Record,\n oStyle: Record,\n): void {\n Object.entries(style).forEach(([prop, value]) => {\n if (value === undefined) {\n return;\n }\n oStyle[prop.toLowerCase()] = value;\n });\n}\n","/**\n * Takes a style string and parses it in one that has only defined values\n * and lowercases properties\n * @param style\n * @param oStyle\n */\nexport function parseStyleString(\n style: string,\n oStyle: Record,\n): void {\n style\n .replace(/;\\s*$/, '')\n .split(';')\n .forEach((chunk) => {\n if (!chunk) return;\n const [attr, value] = chunk.split(':');\n oStyle[attr.trim().toLowerCase()] = value.trim();\n });\n}\n","import { parseStyleObject } from './parseStyleObject';\nimport { parseStyleString } from './parseStyleString';\n\n/**\n * Parses \"style\" attribute, retuning an object with values\n * @static\n * @memberOf fabric\n * @param {SVGElement} element Element to parse\n * @return {Object} Objects with values parsed from style attribute of an element\n */\nexport function parseStyleAttribute(element: HTMLElement): Record {\n const oStyle: Record = {},\n style = element.getAttribute('style');\n\n if (!style) {\n return oStyle;\n }\n\n if (typeof style === 'string') {\n parseStyleString(style, oStyle);\n } else {\n parseStyleObject(style, oStyle);\n }\n\n return oStyle;\n}\n","import { Color } from '../color/Color';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject } from '../shapes/Object/FabricObject';\n\nconst colorAttributesMap = {\n stroke: 'strokeOpacity',\n fill: 'fillOpacity',\n};\n\n/**\n * @private\n * @param {Object} attributes Array of attributes to parse\n */\n\nexport function setStrokeFillOpacity(\n attributes: Record,\n): Record {\n const defaults = FabricObject.getDefaults();\n Object.entries(colorAttributesMap).forEach(([attr, colorAttr]) => {\n if (\n typeof attributes[colorAttr] === 'undefined' ||\n attributes[attr] === ''\n ) {\n return;\n }\n if (typeof attributes[attr] === 'undefined') {\n if (!defaults[attr]) {\n return;\n }\n attributes[attr] = defaults[attr];\n }\n if (attributes[attr].indexOf('url(') === 0) {\n return;\n }\n const color = new Color(attributes[attr]);\n attributes[attr] = color\n .setAlpha(toFixed(color.getAlpha() * attributes[colorAttr], 2))\n .toRgba();\n });\n return attributes;\n}\n","import { DEFAULT_SVG_FONT_SIZE } from '../constants';\nimport { parseUnit } from '../util/misc/svgParsing';\nimport { cPath, fSize, svgValidParentsRegEx } from './constants';\nimport { getGlobalStylesForElement } from './getGlobalStylesForElement';\nimport { normalizeAttr } from './normalizeAttr';\nimport { normalizeValue } from './normalizeValue';\nimport { parseFontDeclaration } from './parseFontDeclaration';\nimport { parseStyleAttribute } from './parseStyleAttribute';\nimport { setStrokeFillOpacity } from './setStrokeFillOpacity';\nimport type { CSSRules } from './typedefs';\n\n/**\n * Returns an object of attributes' name/value, given element and an array of attribute names;\n * Parses parent \"g\" nodes recursively upwards.\n * @param {SVGElement | HTMLElement} element Element to parse\n * @param {Array} attributes Array of attributes to parse\n * @return {Object} object containing parsed attributes' names/values\n */\nexport function parseAttributes(\n element: HTMLElement | null,\n attributes: string[],\n cssRules?: CSSRules,\n): Record {\n if (!element) {\n return {};\n }\n\n let parentAttributes: Record = {},\n fontSize: number,\n parentFontSize = DEFAULT_SVG_FONT_SIZE;\n\n // if there's a parent container (`g` or `a` or `symbol` node), parse its attributes recursively upwards\n if (\n element.parentNode &&\n svgValidParentsRegEx.test(element.parentNode.nodeName)\n ) {\n parentAttributes = parseAttributes(\n element.parentElement,\n attributes,\n cssRules,\n );\n if (parentAttributes.fontSize) {\n fontSize = parentFontSize = parseUnit(parentAttributes.fontSize);\n }\n }\n\n const ownAttributes: Record = {\n ...attributes.reduce>((memo, attr) => {\n const value = element.getAttribute(attr);\n if (value) {\n memo[attr] = value;\n }\n return memo;\n }, {}),\n // add values parsed from style, which take precedence over attributes\n // (see: http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes)\n ...getGlobalStylesForElement(element, cssRules),\n ...parseStyleAttribute(element),\n };\n\n if (ownAttributes[cPath]) {\n element.setAttribute(cPath, ownAttributes[cPath]);\n }\n if (ownAttributes[fSize]) {\n // looks like the minimum should be 9px when dealing with ems. this is what looks like in browsers.\n fontSize = parseUnit(ownAttributes[fSize], parentFontSize);\n ownAttributes[fSize] = `${fontSize}`;\n }\n\n // this should have its own complex type\n const normalizedStyle: Record<\n string,\n string | boolean | number | number[] | null\n > = {};\n for (const attr in ownAttributes) {\n const normalizedAttr = normalizeAttr(attr);\n const normalizedValue = normalizeValue(\n normalizedAttr,\n ownAttributes[attr],\n parentAttributes,\n fontSize!,\n );\n normalizedStyle[normalizedAttr] = normalizedValue;\n }\n if (normalizedStyle && normalizedStyle.font) {\n parseFontDeclaration(normalizedStyle.font as string, normalizedStyle);\n }\n const mergedAttrs = { ...parentAttributes, ...normalizedStyle };\n return svgValidParentsRegEx.test(element.nodeName)\n ? mergedAttrs\n : setStrokeFillOpacity(mergedAttrs);\n}\n","import { kRect } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const rectDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueRectProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedRectProps\n extends SerializedObjectProps,\n UniqueRectProps {}\n\nexport interface RectProps extends FabricObjectProps, UniqueRectProps {}\n\nconst RECT_PROPS = ['rx', 'ry'] as const;\n\nexport class Rect<\n Props extends TOptions = Partial,\n SProps extends SerializedRectProps = SerializedRectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements RectProps\n{\n /**\n * Horizontal border radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical border radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Rect';\n\n static cacheProperties = [...cacheProperties, ...RECT_PROPS];\n\n static ownDefaults = rectDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Rect.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Rect.ownDefaults);\n this.setOptions(options);\n this._initRxRy();\n }\n /**\n * Initializes rx/ry attributes\n * @private\n */\n _initRxRy() {\n const { rx, ry } = this;\n if (rx && !ry) {\n this.ry = rx;\n } else if (ry && !rx) {\n this.rx = ry;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const { width: w, height: h } = this;\n const x = -w / 2;\n const y = -h / 2;\n const rx = this.rx ? Math.min(this.rx, w / 2) : 0;\n const ry = this.ry ? Math.min(this.ry, h / 2) : 0;\n const isRounded = rx !== 0 || ry !== 0;\n\n ctx.beginPath();\n\n ctx.moveTo(x + rx, y);\n\n ctx.lineTo(x + w - rx, y);\n isRounded &&\n ctx.bezierCurveTo(\n x + w - kRect * rx,\n y,\n x + w,\n y + kRect * ry,\n x + w,\n y + ry,\n );\n\n ctx.lineTo(x + w, y + h - ry);\n isRounded &&\n ctx.bezierCurveTo(\n x + w,\n y + h - kRect * ry,\n x + w - kRect * rx,\n y + h,\n x + w - rx,\n y + h,\n );\n\n ctx.lineTo(x + rx, y + h);\n isRounded &&\n ctx.bezierCurveTo(\n x + kRect * rx,\n y + h,\n x,\n y + h - kRect * ry,\n x,\n y + h - ry,\n );\n\n ctx.lineTo(x, y + ry);\n isRounded &&\n ctx.bezierCurveTo(x, y + kRect * ry, x + kRect * rx, y, x + rx, y);\n\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...RECT_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { width, height, rx, ry } = this;\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Rect.fromElement`)\n * @static\n * @memberOf Rect\n * @see: http://www.w3.org/TR/SVG/shapes.html#RectElement\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'rx',\n 'ry',\n 'width',\n 'height',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns {@link Rect} instance from an SVG element\n * @static\n * @memberOf Rect\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n left = 0,\n top = 0,\n width = 0,\n height = 0,\n visible = true,\n ...restOfparsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n\n return new this({\n ...options,\n ...restOfparsedAttributes,\n left,\n top,\n width,\n height,\n visible: Boolean(visible && width && height),\n });\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Rect);\nclassRegistry.setSVGClass(Rect);\n","export const LAYOUT_TYPE_INITIALIZATION = 'initialization';\nexport const LAYOUT_TYPE_ADDED = 'added';\nexport const LAYOUT_TYPE_REMOVED = 'removed';\nexport const LAYOUT_TYPE_IMPERATIVE = 'imperative';\nexport const LAYOUT_TYPE_OBJECT_MODIFIED = 'object_modified';\nexport const LAYOUT_TYPE_OBJECT_MODIFYING = 'object_modifying';\n","import { Point, ZERO } from '../../Point';\nimport type { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { multiplyTransformMatrixArray } from '../../util/misc/matrix';\nimport { sizeAfterTransform } from '../../util/misc/objectTransforms';\nimport {\n calcPlaneChangeMatrix,\n sendVectorToPlane,\n} from '../../util/misc/planeChange';\n\n/**\n * @returns 2 points, the tl and br corners of the non rotated bounding box of an object\n * in the {@link group} plane, taking into account objects that {@link group} is their parent\n * but also belong to the active selection.\n */\nexport const getObjectBounds = (\n destinationGroup: Group,\n object: FabricObject,\n): Point[] => {\n const {\n strokeUniform,\n strokeWidth,\n width,\n height,\n group: currentGroup,\n } = object;\n const t =\n currentGroup && currentGroup !== destinationGroup\n ? calcPlaneChangeMatrix(\n currentGroup.calcTransformMatrix(),\n destinationGroup.calcTransformMatrix(),\n )\n : null;\n const objectCenter = t\n ? object.getRelativeCenterPoint().transform(t)\n : object.getRelativeCenterPoint();\n const accountForStroke = !object['isStrokeAccountedForInDimensions']();\n const strokeUniformVector =\n strokeUniform && accountForStroke\n ? sendVectorToPlane(\n new Point(strokeWidth, strokeWidth),\n undefined,\n destinationGroup.calcTransformMatrix(),\n )\n : ZERO;\n const scalingStrokeWidth =\n !strokeUniform && accountForStroke ? strokeWidth : 0;\n const sizeVector = sizeAfterTransform(\n width + scalingStrokeWidth,\n height + scalingStrokeWidth,\n multiplyTransformMatrixArray([t, object.calcOwnMatrix()], true),\n )\n .add(strokeUniformVector)\n .scalarDivide(2);\n return [objectCenter.subtract(sizeVector), objectCenter.add(sizeVector)];\n};\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_IMPERATIVE,\n} from '../constants';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { getObjectBounds } from './utils';\n\n/**\n * Exposes a main public method {@link calcLayoutResult} that is used by the `LayoutManager` to perform layout.\n * Returning `undefined` signals the `LayoutManager` to skip the layout.\n *\n * In charge of calculating the bounding box of the passed objects.\n */\nexport abstract class LayoutStrategy {\n /**\n * override by subclass for persistence (TS does not support `static abstract`)\n */\n static type = 'strategy';\n\n /**\n * Used by the `LayoutManager` to perform layout\n * @TODO/fix: if this method is calcResult, should calc unconditionally.\n * the condition to not calc should be evaluated by the layoutManager.\n * @returns layout result **OR** `undefined` to skip layout\n */\n public calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n if (this.shouldPerformLayout(context)) {\n return this.calcBoundingBox(objects, context);\n }\n }\n\n shouldPerformLayout({ type, prevStrategy, strategy }: StrictLayoutContext) {\n return (\n type === LAYOUT_TYPE_INITIALIZATION ||\n type === LAYOUT_TYPE_IMPERATIVE ||\n (!!prevStrategy && strategy !== prevStrategy)\n );\n }\n\n shouldLayoutClipPath({ type, target: { clipPath } }: StrictLayoutContext) {\n return (\n type !== LAYOUT_TYPE_INITIALIZATION &&\n clipPath &&\n !clipPath.absolutePositioned\n );\n }\n\n getInitialSize(\n context: StrictLayoutContext & InitializationLayoutContext,\n result: Pick,\n ) {\n return result.size;\n }\n\n /**\n * Override this method to customize layout.\n */\n calcBoundingBox(\n objects: FabricObject[],\n context: StrictLayoutContext,\n ): LayoutStrategyResult | undefined {\n const { type, target } = context;\n if (type === LAYOUT_TYPE_IMPERATIVE && context.overrides) {\n return context.overrides;\n }\n if (objects.length === 0) {\n return;\n }\n const { left, top, width, height } = makeBoundingBoxFromPoints(\n objects\n .map((object) => getObjectBounds(target, object))\n .reduce((coords, curr) => coords.concat(curr), []),\n );\n const bboxSize = new Point(width, height);\n const bboxLeftTop = new Point(left, top);\n const bboxCenter = bboxLeftTop.add(bboxSize.scalarDivide(2));\n\n if (type === LAYOUT_TYPE_INITIALIZATION) {\n const actualSize = this.getInitialSize(context, {\n size: bboxSize,\n center: bboxCenter,\n });\n return {\n // in `initialization` we do not account for target's transformation matrix\n center: bboxCenter,\n // TODO: investigate if this is still necessary\n relativeCorrection: new Point(0, 0),\n size: actualSize,\n };\n } else {\n // we send `relativeCenter` up to group's containing plane\n const center = bboxCenter.transform(target.calcOwnMatrix());\n return {\n center,\n size: bboxSize,\n };\n }\n }\n}\n","import type { StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to fit target's objects.\n */\nexport class FitContentLayout extends LayoutStrategy {\n static readonly type = 'fit-content';\n\n /**\n * @override layout on all triggers\n * Override at will\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n shouldPerformLayout(context: StrictLayoutContext) {\n return true;\n }\n}\n\nclassRegistry.setClass(FitContentLayout);\n","import { Point } from '../Point';\nimport {\n CENTER,\n CHANGED,\n MODIFIED,\n MODIFY_PATH,\n MODIFY_POLY,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n iMatrix,\n} from '../constants';\nimport type { Group } from '../shapes/Group';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { invertTransform } from '../util/misc/matrix';\nimport { resolveOrigin } from '../util/misc/resolveOrigin';\nimport { FitContentLayout } from './LayoutStrategies/FitContentLayout';\nimport type { LayoutStrategy } from './LayoutStrategies/LayoutStrategy';\nimport {\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_OBJECT_MODIFIED,\n LAYOUT_TYPE_OBJECT_MODIFYING,\n} from './constants';\nimport type {\n LayoutContext,\n LayoutResult,\n RegistrationContext,\n StrictLayoutContext,\n} from './types';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TModificationEvents } from '../EventTypeDefs';\n\nconst LAYOUT_MANAGER = 'layoutManager';\n\nexport type SerializedLayoutManager = {\n type: string;\n strategy: string;\n};\n\nexport class LayoutManager {\n private declare _prevLayoutStrategy?: LayoutStrategy;\n protected declare _subscriptions: Map;\n\n strategy: LayoutStrategy;\n\n constructor(strategy: LayoutStrategy = new FitContentLayout()) {\n this.strategy = strategy;\n this._subscriptions = new Map();\n }\n\n public performLayout(context: LayoutContext) {\n const strictContext: StrictLayoutContext = {\n bubbles: true,\n strategy: this.strategy,\n ...context,\n prevStrategy: this._prevLayoutStrategy,\n stopPropagation() {\n this.bubbles = false;\n },\n };\n\n this.onBeforeLayout(strictContext);\n\n const layoutResult = this.getLayoutResult(strictContext);\n if (layoutResult) {\n this.commitLayout(strictContext, layoutResult);\n }\n\n this.onAfterLayout(strictContext, layoutResult);\n this._prevLayoutStrategy = strictContext.strategy;\n }\n\n /**\n * Attach handlers for events that we know will invalidate the layout when\n * performed on child objects ( general transforms ).\n * Returns the disposers for later unsubscribing and cleanup\n * @param {FabricObject} object\n * @param {RegistrationContext & Partial} context\n * @returns {VoidFunction[]} disposers remove the handlers\n */\n protected attachHandlers(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ): VoidFunction[] {\n const { target } = context;\n return (\n [\n MODIFIED,\n MOVING,\n RESIZING,\n ROTATING,\n SCALING,\n SKEWING,\n CHANGED,\n MODIFY_POLY,\n MODIFY_PATH,\n ] as (TModificationEvents & 'modified')[]\n ).map((key) =>\n object.on(key, (e) =>\n this.performLayout(\n key === MODIFIED\n ? {\n type: LAYOUT_TYPE_OBJECT_MODIFIED,\n trigger: key,\n e,\n target,\n }\n : {\n type: LAYOUT_TYPE_OBJECT_MODIFYING,\n trigger: key,\n e,\n target,\n },\n ),\n ),\n );\n }\n\n /**\n * Subscribe an object to transform events that will trigger a layout change on the parent\n * This is important only for interactive groups.\n * @param object\n * @param context\n */\n protected subscribe(\n object: FabricObject,\n context: RegistrationContext & Partial,\n ) {\n this.unsubscribe(object, context);\n const disposers = this.attachHandlers(object, context);\n this._subscriptions.set(object, disposers);\n }\n\n /**\n * unsubscribe object layout triggers\n */\n protected unsubscribe(\n object: FabricObject,\n _context?: RegistrationContext & Partial,\n ) {\n (this._subscriptions.get(object) || []).forEach((d) => d());\n this._subscriptions.delete(object);\n }\n\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.unsubscribe(object, context));\n }\n\n subscribeTargets(\n context: RegistrationContext & Partial,\n ) {\n context.targets.forEach((object) => this.subscribe(object, context));\n }\n\n protected onBeforeLayout(context: StrictLayoutContext) {\n const { target, type } = context;\n const { canvas } = target;\n // handle layout triggers subscription\n // @TODO: gate the registration when the group is interactive\n if (type === LAYOUT_TYPE_INITIALIZATION || type === LAYOUT_TYPE_ADDED) {\n this.subscribeTargets(context);\n } else if (type === LAYOUT_TYPE_REMOVED) {\n this.unsubscribeTargets(context);\n }\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:before', {\n context,\n });\n canvas &&\n canvas.fire('object:layout:before', {\n target,\n context,\n });\n\n if (type === LAYOUT_TYPE_IMPERATIVE && context.deep) {\n const { strategy: _, ...tricklingContext } = context;\n // traverse the tree\n target.forEachObject(\n (object) =>\n (object as Group).layoutManager &&\n (object as Group).layoutManager.performLayout({\n ...tricklingContext,\n bubbles: false,\n target: object as Group,\n }),\n );\n }\n }\n\n protected getLayoutResult(\n context: StrictLayoutContext,\n ): Required | undefined {\n const { target, strategy, type } = context;\n\n const result = strategy.calcLayoutResult(context, target.getObjects());\n\n if (!result) {\n return;\n }\n\n const prevCenter =\n type === LAYOUT_TYPE_INITIALIZATION\n ? new Point()\n : target.getRelativeCenterPoint();\n\n const {\n center: nextCenter,\n correction = new Point(),\n relativeCorrection = new Point(),\n } = result;\n const offset = prevCenter\n .subtract(nextCenter)\n .add(correction)\n .transform(\n // in `initialization` we do not account for target's transformation matrix\n type === LAYOUT_TYPE_INITIALIZATION\n ? iMatrix\n : invertTransform(target.calcOwnMatrix()),\n true,\n )\n .add(relativeCorrection);\n\n return {\n result,\n prevCenter,\n nextCenter,\n offset,\n };\n }\n\n protected commitLayout(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n const {\n result: { size },\n nextCenter,\n } = layoutResult;\n // set dimensions\n target.set({ width: size.x, height: size.y });\n // layout descendants\n this.layoutObjects(context, layoutResult);\n // set position\n // in `initialization` we do not account for target's transformation matrix\n if (context.type === LAYOUT_TYPE_INITIALIZATION) {\n // TODO: what about strokeWidth?\n target.set({\n left:\n context.x ?? nextCenter.x + size.x * resolveOrigin(target.originX),\n top: context.y ?? nextCenter.y + size.y * resolveOrigin(target.originY),\n });\n } else {\n target.setPositionByOrigin(nextCenter, CENTER, CENTER);\n // invalidate\n target.setCoords();\n target.set('dirty', true);\n }\n }\n\n protected layoutObjects(\n context: StrictLayoutContext,\n layoutResult: Required,\n ) {\n const { target } = context;\n // adjust objects to account for new center\n target.forEachObject((object) => {\n object.group === target &&\n this.layoutObject(context, layoutResult, object);\n });\n // adjust clip path to account for new center\n context.strategy.shouldLayoutClipPath(context) &&\n this.layoutObject(context, layoutResult, target.clipPath as FabricObject);\n }\n\n /**\n * @param {FabricObject} object\n * @param {Point} offset\n */\n protected layoutObject(\n context: StrictLayoutContext,\n { offset }: Required,\n object: FabricObject,\n ) {\n // TODO: this is here for cache invalidation.\n // verify if this is necessary since we have explicit\n // cache invalidation at the end of commitLayout\n object.set({\n left: object.left + offset.x,\n top: object.top + offset.y,\n });\n }\n\n protected onAfterLayout(\n context: StrictLayoutContext,\n layoutResult?: LayoutResult,\n ) {\n const {\n target,\n strategy,\n bubbles,\n prevStrategy: _,\n ...bubblingContext\n } = context;\n const { canvas } = target;\n\n // fire layout event (event will fire only for layouts after initialization layout)\n target.fire('layout:after', {\n context,\n result: layoutResult,\n });\n canvas &&\n canvas.fire('object:layout:after', {\n context,\n result: layoutResult,\n target,\n });\n\n // bubble\n const parent = target.parent;\n if (bubbles && parent?.layoutManager) {\n // add target to context#path\n (bubblingContext.path || (bubblingContext.path = [])).push(target);\n // all parents should invalidate their layout\n parent.layoutManager.performLayout({\n ...bubblingContext,\n target: parent,\n });\n }\n target.set('dirty', true);\n }\n\n dispose() {\n const { _subscriptions } = this;\n _subscriptions.forEach((disposers) => disposers.forEach((d) => d()));\n _subscriptions.clear();\n }\n\n toObject() {\n return {\n type: LAYOUT_MANAGER,\n strategy: (this.strategy.constructor as typeof LayoutStrategy).type,\n };\n }\n\n toJSON() {\n return this.toObject();\n }\n}\n\nclassRegistry.setClass(LayoutManager, LAYOUT_MANAGER);\n","import type { CollectionEvents, ObjectEvents } from '../EventTypeDefs';\nimport { createCollectionMixin } from '../Collection';\nimport type {\n TClassProperties,\n TSVGReviver,\n TOptions,\n Abortable,\n} from '../typedefs';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n} from '../util/misc/matrix';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n} from '../util/misc/objectEnlive';\nimport { applyTransformToObject } from '../util/misc/objectTransforms';\nimport { FabricObject } from './Object/FabricObject';\nimport { Rect } from './Rect';\nimport { classRegistry } from '../ClassRegistry';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport { log } from '../util/internals/console';\nimport type {\n ImperativeLayoutOptions,\n LayoutBeforeEvent,\n LayoutAfterEvent,\n} from '../LayoutManager/types';\nimport { LayoutManager } from '../LayoutManager/LayoutManager';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_IMPERATIVE,\n LAYOUT_TYPE_INITIALIZATION,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { SerializedLayoutManager } from '../LayoutManager/LayoutManager';\nimport type { FitContentLayout } from '../LayoutManager';\n\n/**\n * This class handles the specific case of creating a group using {@link Group#fromObject} and is not meant to be used in any other case.\n * We could have used a boolean in the constructor, as we did previously, but we think the boolean\n * would stay in the group's constructor interface and create confusion, therefore it was removed.\n * This layout manager doesn't do anything and therefore keeps the exact layout the group had when {@link Group#toObject} was called.\n */\nclass NoopLayoutManager extends LayoutManager {\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n performLayout() {}\n}\n\nexport interface GroupEvents extends ObjectEvents, CollectionEvents {\n 'layout:before': LayoutBeforeEvent;\n 'layout:after': LayoutAfterEvent;\n}\n\nexport interface GroupOwnProps {\n subTargetCheck: boolean;\n interactive: boolean;\n}\n\nexport interface SerializedGroupProps\n extends SerializedObjectProps,\n GroupOwnProps {\n objects: SerializedObjectProps[];\n layoutManager: SerializedLayoutManager;\n}\n\nexport interface GroupProps extends FabricObjectProps, GroupOwnProps {\n layoutManager: LayoutManager;\n}\n\nexport const groupDefaultValues: Partial> = {\n strokeWidth: 0,\n subTargetCheck: false,\n interactive: false,\n};\n\n/**\n * @fires object:added\n * @fires object:removed\n * @fires layout:before\n * @fires layout:after\n */\nexport class Group\n extends createCollectionMixin(\n FabricObject,\n )\n implements GroupProps\n{\n /**\n * Used to optimize performance\n * set to `false` if you don't need contained objects to be targets of events\n * @default\n * @type boolean\n */\n declare subTargetCheck: boolean;\n\n /**\n * Used to allow targeting of object inside groups.\n * set to true if you want to select an object inside a group.\\\n * **REQUIRES** `subTargetCheck` set to true\n * This will be not removed but slowly replaced with a method setInteractive\n * that will take care of enabling subTargetCheck and necessary object events.\n * There is too much attached to group interactivity to just be evaluated by a\n * boolean in the code\n * @default\n * @deprecated\n * @type boolean\n */\n declare interactive: boolean;\n\n declare layoutManager: LayoutManager;\n\n /**\n * Used internally to optimize performance\n * Once an object is selected, instance is rendered without the selected object.\n * This way instance is cached only once for the entire interaction with the selected object.\n * @private\n */\n protected _activeObjects: FabricObject[] = [];\n\n static type = 'Group';\n\n static ownDefaults: Record = groupDefaultValues;\n private __objectSelectionTracker: (ev: ObjectEvents['selected']) => void;\n private __objectSelectionDisposer: (ev: ObjectEvents['deselected']) => void;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Group.ownDefaults,\n };\n }\n\n /**\n * Constructor\n *\n * @param {FabricObject[]} [objects] instance objects\n * @param {Object} [options] Options object\n */\n constructor(objects: FabricObject[] = [], options: Partial = {}) {\n super();\n Object.assign(this, Group.ownDefaults);\n this.setOptions(options);\n this.groupInit(objects, options);\n }\n\n /**\n * Shared code between group and active selection\n * Meant to be used by the constructor.\n */\n protected groupInit(\n objects: FabricObject[],\n options: {\n layoutManager?: LayoutManager;\n top?: number;\n left?: number;\n },\n ) {\n this._objects = [...objects]; // Avoid unwanted mutations of Collection to affect the caller\n\n this.__objectSelectionTracker = this.__objectSelectionMonitor.bind(\n this,\n true,\n );\n this.__objectSelectionDisposer = this.__objectSelectionMonitor.bind(\n this,\n false,\n );\n\n this.forEachObject((object) => {\n this.enterGroup(object, false);\n });\n\n // perform initial layout\n this.layoutManager = options.layoutManager ?? new LayoutManager();\n this.layoutManager.performLayout({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: this,\n targets: [...objects],\n // @TODO remove this concept from the layout manager.\n // Layout manager will calculate the correct position,\n // group options can override it later.\n x: options.left,\n y: options.top,\n });\n }\n\n /**\n * Checks if object can enter group and logs relevant warnings\n * @private\n * @param {FabricObject} object\n * @returns\n */\n canEnterGroup(object: FabricObject) {\n if (object === this || this.isDescendantOf(object)) {\n // prevent circular object tree\n log(\n 'error',\n 'Group: circular object trees are not supported, this call has no effect',\n );\n return false;\n } else if (this._objects.indexOf(object) !== -1) {\n // is already in the objects array\n log(\n 'error',\n 'Group: duplicate objects are not supported inside group, this call has no effect',\n );\n return false;\n }\n return true;\n }\n\n /**\n * Override this method to enhance performance (for groups with a lot of objects).\n * If Overriding, be sure not pass illegal objects to group - it will break your app.\n * @private\n */\n protected _filterObjectsBeforeEnteringGroup(objects: FabricObject[]) {\n return objects.filter((object, index, array) => {\n // can enter AND is the first occurrence of the object in the passed args (to prevent adding duplicates)\n return this.canEnterGroup(object) && array.indexOf(object) === index;\n });\n }\n\n /**\n * Add objects\n * @param {...FabricObject[]} objects\n */\n add(...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.add(...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Inserts an object into collection at specified index\n * @param {FabricObject[]} objects Object to insert\n * @param {Number} index Index to insert object at\n */\n insertAt(index: number, ...objects: FabricObject[]) {\n const allowedObjects = this._filterObjectsBeforeEnteringGroup(objects);\n const size = super.insertAt(index, ...allowedObjects);\n this._onAfterObjectsChange(LAYOUT_TYPE_ADDED, allowedObjects);\n return size;\n }\n\n /**\n * Remove objects\n * @param {...FabricObject[]} objects\n * @returns {FabricObject[]} removed objects\n */\n remove(...objects: FabricObject[]) {\n const removed = super.remove(...objects);\n this._onAfterObjectsChange(LAYOUT_TYPE_REMOVED, removed);\n return removed;\n }\n\n _onObjectAdded(object: FabricObject) {\n this.enterGroup(object, true);\n this.fire('object:added', { target: object });\n object.fire('added', { target: this });\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _onObjectRemoved(object: FabricObject, removeParentTransform?: boolean) {\n this.exitGroup(object, removeParentTransform);\n this.fire('object:removed', { target: object });\n object.fire('removed', { target: this });\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n this.layoutManager.performLayout({\n type,\n targets,\n target: this,\n });\n }\n\n _onStackOrderChanged() {\n this._set('dirty', true);\n }\n\n /**\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n const prev = this[key as keyof this];\n super._set(key, value);\n if (key === 'canvas' && prev !== value) {\n (this._objects || []).forEach((object) => {\n object._set(key, value);\n });\n }\n return this;\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return this.subTargetCheck;\n }\n\n /**\n * Remove all objects\n * @returns {FabricObject[]} removed objects\n */\n removeAll() {\n this._activeObjects = [];\n return this.remove(...this._objects);\n }\n\n /**\n * keeps track of the selected objects\n * @private\n */\n __objectSelectionMonitor(\n selected: T,\n {\n target: object,\n }: ObjectEvents[T extends true ? 'selected' : 'deselected'],\n ) {\n const activeObjects = this._activeObjects;\n if (selected) {\n activeObjects.push(object);\n this._set('dirty', true);\n } else if (activeObjects.length > 0) {\n const index = activeObjects.indexOf(object);\n if (index > -1) {\n activeObjects.splice(index, 1);\n this._set('dirty', true);\n }\n }\n }\n\n /**\n * @private\n * @param {boolean} watch\n * @param {FabricObject} object\n */\n _watchObject(watch: boolean, object: FabricObject) {\n // make sure we listen only once\n watch && this._watchObject(false, object);\n if (watch) {\n object.on('selected', this.__objectSelectionTracker);\n object.on('deselected', this.__objectSelectionDisposer);\n } else {\n object.off('selected', this.__objectSelectionTracker);\n object.off('deselected', this.__objectSelectionDisposer);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n object.group && object.group.remove(object);\n object._set('parent', this);\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n _enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n if (removeParentTransform) {\n // can this be converted to utils (sendObjectToPlane)?\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n invertTransform(this.calcTransformMatrix()),\n object.calcTransformMatrix(),\n ),\n );\n }\n this._shouldSetNestedCoords() && object.setCoords();\n object._set('group', this);\n object._set('canvas', this.canvas);\n this._watchObject(true, object);\n const activeObject =\n this.canvas &&\n this.canvas.getActiveObject &&\n this.canvas.getActiveObject();\n // if we are adding the activeObject in a group\n if (\n activeObject &&\n (activeObject === object || object.isDescendantOf(activeObject))\n ) {\n this._activeObjects.push(object);\n }\n }\n\n /**\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n object._set('parent', undefined);\n object._set('canvas', undefined);\n }\n\n /**\n * Executes the inner fabric logic of exiting a group.\n * - Stop watching the object\n * - Remove the object from the optimization map this._activeObjects\n * - unset the group property of the object\n * @protected\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n _exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n object._set('group', undefined);\n if (!removeParentTransform) {\n applyTransformToObject(\n object,\n multiplyTransformMatrices(\n this.calcTransformMatrix(),\n object.calcTransformMatrix(),\n ),\n );\n object.setCoords();\n }\n this._watchObject(false, object);\n const index =\n this._activeObjects.length > 0 ? this._activeObjects.indexOf(object) : -1;\n if (index > -1) {\n this._activeObjects.splice(index, 1);\n }\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group is already cached.\n * @return {Boolean}\n */\n shouldCache() {\n const ownCache = FabricObject.prototype.shouldCache.call(this);\n if (ownCache) {\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n this.ownCaching = false;\n return false;\n }\n }\n }\n return ownCache;\n }\n\n /**\n * Check if this object or a child object will cast a shadow\n * @return {Boolean}\n */\n willDrawShadow() {\n if (super.willDrawShadow()) {\n return true;\n }\n for (let i = 0; i < this._objects.length; i++) {\n if (this._objects[i].willDrawShadow()) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Check if instance or its group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache(): boolean {\n return this.ownCaching || (!!this.parent && this.parent.isOnACache());\n }\n\n /**\n * Execute the drawing operation for an object on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawObject(ctx: CanvasRenderingContext2D) {\n this._renderBackground(ctx);\n for (let i = 0; i < this._objects.length; i++) {\n // TODO: handle rendering edge case somehow\n if (\n this.canvas?.preserveObjectStacking &&\n this._objects[i].group !== this\n ) {\n ctx.save();\n ctx.transform(...invertTransform(this.calcTransformMatrix()));\n this._objects[i].render(ctx);\n ctx.restore();\n } else if (this._objects[i].group === this) {\n this._objects[i].render(ctx);\n }\n }\n this._drawClipPath(ctx, this.clipPath);\n }\n\n /**\n * @override\n * @return {Boolean}\n */\n setCoords() {\n super.setCoords();\n this._shouldSetNestedCoords() &&\n this.forEachObject((object) => object.setCoords());\n }\n\n triggerLayout(options: ImperativeLayoutOptions = {}) {\n this.layoutManager.performLayout({\n target: this,\n type: LAYOUT_TYPE_IMPERATIVE,\n ...options,\n });\n }\n\n /**\n * Renders instance on a given context\n * @param {CanvasRenderingContext2D} ctx context to render instance on\n */\n render(ctx: CanvasRenderingContext2D) {\n this._transformDone = true;\n super.render(ctx);\n this._transformDone = false;\n }\n\n /**\n *\n * @private\n * @param {'toObject'|'toDatalessObject'} [method]\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @returns {FabricObject[]} serialized objects\n */\n __serializeObjects(\n method: 'toObject' | 'toDatalessObject',\n propertiesToInclude?: string[],\n ) {\n const _includeDefaultValues = this.includeDefaultValues;\n return this._objects\n .filter(function (obj) {\n return !obj.excludeFromExport;\n })\n .map(function (obj) {\n const originalDefaults = obj.includeDefaultValues;\n obj.includeDefaultValues = _includeDefaultValues;\n const data = obj[method || 'toObject'](propertiesToInclude);\n obj.includeDefaultValues = originalDefaults;\n // delete data.version;\n return data;\n });\n }\n\n /**\n * Returns object representation of an instance\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit<\n GroupProps & TClassProperties,\n keyof SerializedGroupProps\n >,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SerializedGroupProps {\n const layoutManager = this.layoutManager.toObject();\n\n return {\n ...super.toObject([\n 'subTargetCheck',\n 'interactive',\n ...propertiesToInclude,\n ]),\n ...(layoutManager.strategy !== 'fit-content' || this.includeDefaultValues\n ? { layoutManager }\n : {}),\n objects: this.__serializeObjects(\n 'toObject',\n propertiesToInclude as string[],\n ),\n };\n }\n\n toString() {\n return `#`;\n }\n\n dispose() {\n this.layoutManager.unsubscribeTargets({\n targets: this.getObjects(),\n target: this,\n });\n this._activeObjects = [];\n this.forEachObject((object) => {\n this._watchObject(false, object);\n object.dispose();\n });\n super.dispose();\n }\n\n /**\n * @private\n */\n _createSVGBgRect(reviver?: TSVGReviver) {\n if (!this.backgroundColor) {\n return '';\n }\n const fillStroke = Rect.prototype._toSVG.call(this);\n const commons = fillStroke.indexOf('COMMON_PARTS');\n fillStroke[commons] = 'for=\"group\" ';\n const markup = fillStroke.join('');\n return reviver ? reviver(markup) : markup;\n }\n\n /**\n * Returns svg representation of an instance\n * @param {TSVGReviver} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n _toSVG(reviver?: TSVGReviver) {\n const svgString = ['\\n'];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t\\t', this._objects[i].toSVG(reviver));\n }\n svgString.push('\\n');\n return svgString;\n }\n\n /**\n * Returns styles-string for svg-export, specific version for group\n * @return {String}\n */\n getSvgStyles(): string {\n const opacity =\n typeof this.opacity !== 'undefined' && this.opacity !== 1\n ? `opacity: ${this.opacity};`\n : '',\n visibility = this.visible ? '' : ' visibility: hidden;';\n return [opacity, this.getSvgFilter(), visibility].join('');\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {String} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const svgString = [];\n const bg = this._createSVGBgRect(reviver);\n bg && svgString.push('\\t', bg);\n for (let i = 0; i < this._objects.length; i++) {\n svgString.push('\\t', this._objects[i].toClipPathSVG(reviver));\n }\n return this._createBaseClipPathSVGMarkup(svgString, {\n reviver,\n });\n }\n\n /**\n * @todo support loading from svg\n * @private\n * @static\n * @memberOf Group\n * @param {Object} object Object to create a group from\n * @returns {Promise}\n */\n static fromObject>(\n { type, objects = [], layoutManager, ...options }: T,\n abortable?: Abortable,\n ) {\n return Promise.all([\n enlivenObjects(objects, abortable),\n enlivenObjectEnlivables(options, abortable),\n ]).then(([objects, hydratedOptions]) => {\n const group = new this(objects, {\n ...options,\n ...hydratedOptions,\n layoutManager: new NoopLayoutManager(),\n });\n if (layoutManager) {\n const layoutClass = classRegistry.getClass(\n layoutManager.type,\n );\n const strategyClass = classRegistry.getClass(\n layoutManager.strategy,\n );\n group.layoutManager = new layoutClass(new strategyClass());\n } else {\n group.layoutManager = new LayoutManager();\n }\n group.layoutManager.subscribeTargets({\n type: LAYOUT_TYPE_INITIALIZATION,\n target: group,\n targets: group.getObjects(),\n });\n group.setCoords();\n return group;\n });\n }\n}\n\nclassRegistry.setClass(Group);\n","import type { GroupProps } from '../../shapes/Group';\nimport { Group } from '../../shapes/Group';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\n\n/**\n * TODO experiment with different layout manager and svg results ( fixed fit content )\n * Groups SVG elements (usually those retrieved from SVG document)\n * @static\n * @param {FabricObject[]} elements FabricObject(s) parsed from svg, to group\n * @return {FabricObject | Group}\n */\nexport const groupSVGElements = (\n elements: FabricObject[],\n options?: Partial,\n) => {\n if (elements && elements.length === 1) {\n return elements[0];\n }\n return new Group(elements, options);\n};\n","import type { TSize } from '../../typedefs';\n\n/**\n * Finds the scale for the object source to fit inside the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to fit into destination\n */\nexport const findScaleToFit = (source: TSize, destination: TSize) =>\n Math.min(\n destination.width / source.width,\n destination.height / source.height,\n );\n\n/**\n * Finds the scale for the object source to cover entirely the object destination,\n * keeping aspect ratio intact.\n * respect the total allowed area for the cache.\n * @param {TSize} source natural unscaled size of the object\n * @param {TSize} destination natural unscaled size of the object\n * @return {Number} scale factor to apply to source to cover destination\n */\nexport const findScaleToCover = (source: TSize, destination: TSize) =>\n Math.max(\n destination.width / source.width,\n destination.height / source.height,\n );\n","import { reNum } from '../../parser/constants';\n\nconst commaWsp = `\\\\s*,?\\\\s*`;\n\n/**\n * p for param\n * using \"bad naming\" here because it makes the regex much easier to read\n * p is a number that is preceded by an arbitary number of spaces, maybe 0,\n * a comma or not, and then possibly more spaces or not.\n */\nconst p = `${commaWsp}(${reNum})`;\n\n// const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;\n\n// const reLineCommand = `(L) ?(?:${p}${p} ?)+`;\n\n// const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;\n\n// const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;\n\n// const reClosePathCommand = String.raw`(Z)\\s*`;\n\n// const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;\n\n// const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;\n\n// const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;\n\nexport const reArcCommandPoints = `${p}${p}${p}${commaWsp}([01])${commaWsp}([01])${p}${p}`;\n// const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;\n\n// export const rePathCommandGroups =\n// `(?:(?:${reMoveToCommand})` +\n// `|(?:${reLineCommand})` +\n// `|(?:${reHorizontalLineCommand})` +\n// `|(?:${reVerticalLineCommand})` +\n// `|(?:${reClosePathCommand})` +\n// `|(?:${reCubicCurveCommand})` +\n// `|(?:${reCubicCurveShortcutCommand})` +\n// `|(?:${reQuadraticCurveCommand})` +\n// `|(?:${reQuadraticCurveShortcutCommand})` +\n// `|(?:${reArcCommand}))`;\n\nexport const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';\n","import { cache } from '../../cache';\nimport { config } from '../../config';\nimport { halfPI, PiBy180 } from '../../constants';\nimport type { TMat2D, TRadian, TRectBounds } from '../../typedefs';\nimport { cos } from '../misc/cos';\nimport { multiplyTransformMatrices, transformPoint } from '../misc/matrix';\nimport { sin } from '../misc/sin';\nimport { toFixed } from '../misc/toFixed';\nimport type {\n TCurveInfo,\n TComplexPathData,\n TParsedAbsoluteCubicCurveCommand,\n TPathSegmentInfo,\n TPointAngle,\n TSimpleParsedCommand,\n TSimplePathData,\n TPathSegmentCommandInfo,\n TComplexParsedCommand,\n TPathSegmentInfoCommon,\n TEndPathInfo,\n TParsedArcCommand,\n TComplexParsedCommandType,\n} from './typedefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { reArcCommandPoints, rePathCommand } from './regex';\nimport { reNum } from '../../parser/constants';\n\n/**\n * Commands that may be repeated\n */\nconst repeatedCommands: Record = {\n m: 'l',\n M: 'L',\n};\n\n/**\n * Convert an arc of a rotated ellipse to a Bezier Curve\n * @param {TRadian} theta1 start of the arc\n * @param {TRadian} theta2 end of the arc\n * @param cosTh cosine of the angle of rotation\n * @param sinTh sine of the angle of rotation\n * @param rx x-axis radius (before rotation)\n * @param ry y-axis radius (before rotation)\n * @param cx1 center x of the ellipse\n * @param cy1 center y of the ellipse\n * @param mT\n * @param fromX starting point of arc x\n * @param fromY starting point of arc y\n */\nconst segmentToBezier = (\n theta1: TRadian,\n theta2: TRadian,\n cosTh: number,\n sinTh: number,\n rx: number,\n ry: number,\n cx1: number,\n cy1: number,\n mT: number,\n fromX: number,\n fromY: number,\n): TParsedAbsoluteCubicCurveCommand => {\n const costh1 = cos(theta1),\n sinth1 = sin(theta1),\n costh2 = cos(theta2),\n sinth2 = sin(theta2),\n toX = cosTh * rx * costh2 - sinTh * ry * sinth2 + cx1,\n toY = sinTh * rx * costh2 + cosTh * ry * sinth2 + cy1,\n cp1X = fromX + mT * (-cosTh * rx * sinth1 - sinTh * ry * costh1),\n cp1Y = fromY + mT * (-sinTh * rx * sinth1 + cosTh * ry * costh1),\n cp2X = toX + mT * (cosTh * rx * sinth2 + sinTh * ry * costh2),\n cp2Y = toY + mT * (sinTh * rx * sinth2 - cosTh * ry * costh2);\n\n return ['C', cp1X, cp1Y, cp2X, cp2Y, toX, toY];\n};\n\n/**\n * Adapted from {@link http://dxr.mozilla.org/mozilla-central/source/dom/svg/SVGPathDataParser.cpp}\n * by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here\n * http://mozilla.org/MPL/2.0/\n * @param toX\n * @param toY\n * @param rx\n * @param ry\n * @param {number} large 0 or 1 flag\n * @param {number} sweep 0 or 1 flag\n * @param rotateX\n */\nconst arcToSegments = (\n toX: number,\n toY: number,\n rx: number,\n ry: number,\n large: number,\n sweep: number,\n rotateX: TRadian,\n): TParsedAbsoluteCubicCurveCommand[] => {\n if (rx === 0 || ry === 0) {\n return [];\n }\n let fromX = 0,\n fromY = 0,\n root = 0;\n const PI = Math.PI,\n theta = rotateX * PiBy180,\n sinTheta = sin(theta),\n cosTh = cos(theta),\n px = 0.5 * (-cosTh * toX - sinTheta * toY),\n py = 0.5 * (-cosTh * toY + sinTheta * toX),\n rx2 = rx ** 2,\n ry2 = ry ** 2,\n py2 = py ** 2,\n px2 = px ** 2,\n pl = rx2 * ry2 - rx2 * py2 - ry2 * px2;\n let _rx = Math.abs(rx);\n let _ry = Math.abs(ry);\n\n if (pl < 0) {\n const s = Math.sqrt(1 - pl / (rx2 * ry2));\n _rx *= s;\n _ry *= s;\n } else {\n root =\n (large === sweep ? -1.0 : 1.0) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2));\n }\n\n const cx = (root * _rx * py) / _ry,\n cy = (-root * _ry * px) / _rx,\n cx1 = cosTh * cx - sinTheta * cy + toX * 0.5,\n cy1 = sinTheta * cx + cosTh * cy + toY * 0.5;\n let mTheta = calcVectorAngle(1, 0, (px - cx) / _rx, (py - cy) / _ry);\n let dtheta = calcVectorAngle(\n (px - cx) / _rx,\n (py - cy) / _ry,\n (-px - cx) / _rx,\n (-py - cy) / _ry,\n );\n\n if (sweep === 0 && dtheta > 0) {\n dtheta -= 2 * PI;\n } else if (sweep === 1 && dtheta < 0) {\n dtheta += 2 * PI;\n }\n\n // Convert into cubic bezier segments <= 90deg\n const segments = Math.ceil(Math.abs((dtheta / PI) * 2)),\n result = [],\n mDelta = dtheta / segments,\n mT =\n ((8 / 3) * Math.sin(mDelta / 4) * Math.sin(mDelta / 4)) /\n Math.sin(mDelta / 2);\n let th3 = mTheta + mDelta;\n\n for (let i = 0; i < segments; i++) {\n result[i] = segmentToBezier(\n mTheta,\n th3,\n cosTh,\n sinTheta,\n _rx,\n _ry,\n cx1,\n cy1,\n mT,\n fromX,\n fromY,\n );\n fromX = result[i][5];\n fromY = result[i][6];\n mTheta = th3;\n th3 += mDelta;\n }\n return result;\n};\n\n/**\n * @private\n * Calculate the angle between two vectors\n * @param ux u endpoint x\n * @param uy u endpoint y\n * @param vx v endpoint x\n * @param vy v endpoint y\n */\nconst calcVectorAngle = (\n ux: number,\n uy: number,\n vx: number,\n vy: number,\n): TRadian => {\n const ta = Math.atan2(uy, ux),\n tb = Math.atan2(vy, vx);\n if (tb >= ta) {\n return tb - ta;\n } else {\n return 2 * Math.PI - (ta - tb);\n }\n};\n\n// functions for the Cubic beizer\n// taken from: https://github.com/konvajs/konva/blob/7.0.5/src/shapes/Path.ts#L350\nconst CB1 = (t: number) => t ** 3;\nconst CB2 = (t: number) => 3 * t ** 2 * (1 - t);\nconst CB3 = (t: number) => 3 * t * (1 - t) ** 2;\nconst CB4 = (t: number) => (1 - t) ** 3;\n\n/**\n * Calculate bounding box of a cubic Bezier curve\n * Taken from http://jsbin.com/ivomiq/56/edit (no credits available)\n * TODO: can we normalize this with the starting points set at 0 and then translated the bbox?\n * @param {number} begx starting point\n * @param {number} begy\n * @param {number} cp1x first control point\n * @param {number} cp1y\n * @param {number} cp2x second control point\n * @param {number} cp2y\n * @param {number} endx end of bezier\n * @param {number} endy\n * @return {TRectBounds} the rectangular bounds\n */\nexport function getBoundsOfCurve(\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n): TRectBounds {\n let argsString: string;\n if (config.cachesBoundsOfCurve) {\n // eslint-disable-next-line\n argsString = [...arguments].join();\n if (cache.boundsOfCurveCache[argsString]) {\n return cache.boundsOfCurveCache[argsString];\n }\n }\n\n const sqrt = Math.sqrt,\n abs = Math.abs,\n tvalues = [],\n bounds: [[x: number, y: number], [x: number, y: number]] = [\n [0, 0],\n [0, 0],\n ];\n\n let b = 6 * begx - 12 * cp1x + 6 * cp2x;\n let a = -3 * begx + 9 * cp1x - 9 * cp2x + 3 * endx;\n let c = 3 * cp1x - 3 * begx;\n\n for (let i = 0; i < 2; ++i) {\n if (i > 0) {\n b = 6 * begy - 12 * cp1y + 6 * cp2y;\n a = -3 * begy + 9 * cp1y - 9 * cp2y + 3 * endy;\n c = 3 * cp1y - 3 * begy;\n }\n\n if (abs(a) < 1e-12) {\n if (abs(b) < 1e-12) {\n continue;\n }\n const t = -c / b;\n if (0 < t && t < 1) {\n tvalues.push(t);\n }\n continue;\n }\n const b2ac = b * b - 4 * c * a;\n if (b2ac < 0) {\n continue;\n }\n const sqrtb2ac = sqrt(b2ac);\n const t1 = (-b + sqrtb2ac) / (2 * a);\n if (0 < t1 && t1 < 1) {\n tvalues.push(t1);\n }\n const t2 = (-b - sqrtb2ac) / (2 * a);\n if (0 < t2 && t2 < 1) {\n tvalues.push(t2);\n }\n }\n\n let j = tvalues.length;\n const jlen = j;\n const iterator = getPointOnCubicBezierIterator(\n begx,\n begy,\n cp1x,\n cp1y,\n cp2x,\n cp2y,\n endx,\n endy,\n );\n while (j--) {\n const { x, y } = iterator(tvalues[j]);\n bounds[0][j] = x;\n bounds[1][j] = y;\n }\n\n bounds[0][jlen] = begx;\n bounds[1][jlen] = begy;\n bounds[0][jlen + 1] = endx;\n bounds[1][jlen + 1] = endy;\n const result: TRectBounds = [\n new Point(Math.min(...bounds[0]), Math.min(...bounds[1])),\n new Point(Math.max(...bounds[0]), Math.max(...bounds[1])),\n ];\n if (config.cachesBoundsOfCurve) {\n cache.boundsOfCurveCache[argsString!] = result;\n }\n return result;\n}\n\n/**\n * Converts arc to a bunch of cubic Bezier curves\n * @param {number} fx starting point x\n * @param {number} fy starting point y\n * @param {TParsedArcCommand} coords Arc command\n */\nexport const fromArcToBeziers = (\n fx: number,\n fy: number,\n [_, rx, ry, rot, large, sweep, tx, ty]: TParsedArcCommand,\n): TParsedAbsoluteCubicCurveCommand[] => {\n const segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);\n\n for (let i = 0, len = segsNorm.length; i < len; i++) {\n segsNorm[i][1] += fx;\n segsNorm[i][2] += fy;\n segsNorm[i][3] += fx;\n segsNorm[i][4] += fy;\n segsNorm[i][5] += fx;\n segsNorm[i][6] += fy;\n }\n return segsNorm;\n};\n\n/**\n * This function takes a parsed SVG path and makes it simpler for fabricJS logic.\n * Simplification consist of:\n * - All commands converted to absolute (lowercase to uppercase)\n * - S converted to C\n * - T converted to Q\n * - A converted to C\n * @param {TComplexPathData} path the array of commands of a parsed SVG path for `Path`\n * @return {TSimplePathData} the simplified array of commands of a parsed SVG path for `Path`\n * TODO: figure out how to remove the type assertions in a nice way\n */\nexport const makePathSimpler = (path: TComplexPathData): TSimplePathData => {\n // x and y represent the last point of the path, AKA the previous command point.\n // we add them to each relative command to make it an absolute comment.\n // we also swap the v V h H with L, because are easier to transform.\n let x = 0,\n y = 0;\n // x1 and y1 represent the last point of the subpath. the subpath is started with\n // m or M command. When a z or Z command is drawn, x and y need to be resetted to\n // the last x1 and y1.\n let x1 = 0,\n y1 = 0;\n // previous will host the letter of the previous command, to handle S and T.\n // controlX and controlY will host the previous reflected control point\n const destinationPath: TSimplePathData = [];\n let previous,\n // placeholders\n controlX = 0,\n controlY = 0;\n for (const parsedCommand of path) {\n const current: TComplexParsedCommand = [...parsedCommand];\n let converted: TSimpleParsedCommand | undefined;\n switch (\n current[0] // first letter\n ) {\n case 'l': // lineto, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'L':\n x = current[1];\n y = current[2];\n converted = ['L', x, y];\n break;\n case 'h': // horizontal lineto, relative\n current[1] += x;\n // falls through\n case 'H':\n x = current[1];\n converted = ['L', x, y];\n break;\n case 'v': // vertical lineto, relative\n current[1] += y;\n // falls through\n case 'V':\n y = current[1];\n converted = ['L', x, y];\n break;\n case 'm': // moveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'M':\n x = current[1];\n y = current[2];\n x1 = current[1];\n y1 = current[2];\n converted = ['M', x, y];\n break;\n case 'c': // bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n current[5] += x;\n current[6] += y;\n // falls through\n case 'C':\n controlX = current[3];\n controlY = current[4];\n x = current[5];\n y = current[6];\n converted = ['C', current[1], current[2], controlX, controlY, x, y];\n break;\n case 's': // shorthand cubic bezierCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'S':\n // would be sScC but since we are swapping sSc for C, we check just that.\n if (previous === 'C') {\n // calculate reflection of previous control points\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a C, c, S, or s,\n // the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[3];\n y = current[4];\n converted = ['C', controlX, controlY, current[1], current[2], x, y];\n // converted[3] and converted[4] are NOW the second control point.\n // we keep it for the next reflection.\n controlX = converted[3];\n controlY = converted[4];\n break;\n case 'q': // quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n current[3] += x;\n current[4] += y;\n // falls through\n case 'Q':\n controlX = current[1];\n controlY = current[2];\n x = current[3];\n y = current[4];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 't': // shorthand quadraticCurveTo, relative\n current[1] += x;\n current[2] += y;\n // falls through\n case 'T':\n if (previous === 'Q') {\n // calculate reflection of previous control point\n controlX = 2 * x - controlX;\n controlY = 2 * y - controlY;\n } else {\n // If there is no previous command or if the previous command was not a Q, q, T or t,\n // assume the control point is coincident with the current point\n controlX = x;\n controlY = y;\n }\n x = current[1];\n y = current[2];\n converted = ['Q', controlX, controlY, x, y];\n break;\n case 'a':\n current[6] += x;\n current[7] += y;\n // falls through\n case 'A':\n fromArcToBeziers(x, y, current).forEach((b) => destinationPath.push(b));\n x = current[6];\n y = current[7];\n break;\n case 'z':\n case 'Z':\n x = x1;\n y = y1;\n converted = ['Z'];\n break;\n default:\n }\n if (converted) {\n destinationPath.push(converted);\n previous = converted[0];\n } else {\n previous = '';\n }\n }\n return destinationPath;\n};\n\n// todo verify if we can just use the point class here\n/**\n * Calc length from point x1,y1 to x2,y2\n * @param {number} x1 starting point x\n * @param {number} y1 starting point y\n * @param {number} x2 starting point x\n * @param {number} y2 starting point y\n * @return {number} length of segment\n */\nconst calcLineLength = (\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n): number => Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);\n\n/**\n * Get an iterator that takes a percentage and returns a point\n * @param {number} begx\n * @param {number} begy\n * @param {number} cp1x\n * @param {number} cp1y\n * @param {number} cp2x\n * @param {number} cp2y\n * @param {number} endx\n * @param {number} endy\n */\nconst getPointOnCubicBezierIterator =\n (\n begx: number,\n begy: number,\n cp1x: number,\n cp1y: number,\n cp2x: number,\n cp2y: number,\n endx: number,\n endy: number,\n ) =>\n (pct: number) => {\n const c1 = CB1(pct),\n c2 = CB2(pct),\n c3 = CB3(pct),\n c4 = CB4(pct);\n return new Point(\n endx * c1 + cp2x * c2 + cp1x * c3 + begx * c4,\n endy * c1 + cp2y * c2 + cp1y * c3 + begy * c4,\n );\n };\n\nconst QB1 = (t: number) => t ** 2;\nconst QB2 = (t: number) => 2 * t * (1 - t);\nconst QB3 = (t: number) => (1 - t) ** 2;\n\nconst getTangentCubicIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n p4x: number,\n p4y: number,\n ) =>\n (pct: number) => {\n const qb1 = QB1(pct),\n qb2 = QB2(pct),\n qb3 = QB3(pct),\n tangentX =\n 3 * (qb3 * (p2x - p1x) + qb2 * (p3x - p2x) + qb1 * (p4x - p3x)),\n tangentY =\n 3 * (qb3 * (p2y - p1y) + qb2 * (p3y - p2y) + qb1 * (p4y - p3y));\n return Math.atan2(tangentY, tangentX);\n };\n\nconst getPointOnQuadraticBezierIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const c1 = QB1(pct),\n c2 = QB2(pct),\n c3 = QB3(pct);\n return new Point(\n p3x * c1 + p2x * c2 + p1x * c3,\n p3y * c1 + p2y * c2 + p1y * c3,\n );\n };\n\nconst getTangentQuadraticIterator =\n (\n p1x: number,\n p1y: number,\n p2x: number,\n p2y: number,\n p3x: number,\n p3y: number,\n ) =>\n (pct: number) => {\n const invT = 1 - pct,\n tangentX = 2 * (invT * (p2x - p1x) + pct * (p3x - p2x)),\n tangentY = 2 * (invT * (p2y - p1y) + pct * (p3y - p2y));\n return Math.atan2(tangentY, tangentX);\n };\n\n// this will run over a path segment (a cubic or quadratic segment) and approximate it\n// with 100 segments. This will good enough to calculate the length of the curve\nconst pathIterator = (\n iterator: (pct: number) => Point,\n x1: number,\n y1: number,\n) => {\n let tempP = new Point(x1, y1),\n tmpLen = 0;\n for (let perc = 1; perc <= 100; perc += 1) {\n const p = iterator(perc / 100);\n tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y);\n tempP = p;\n }\n return tmpLen;\n};\n\n/**\n * Given a pathInfo, and a distance in pixels, find the percentage from 0 to 1\n * that correspond to that pixels run over the path.\n * The percentage will be then used to find the correct point on the canvas for the path.\n * @param {Array} segInfo fabricJS collection of information on a parsed path\n * @param {number} distance from starting point, in pixels.\n * @return {TPointAngle} info object with x and y ( the point on canvas ) and angle, the tangent on that point;\n */\nconst findPercentageForDistance = (\n segInfo: TCurveInfo<'Q' | 'C'>,\n distance: number,\n): TPointAngle => {\n let perc = 0,\n tmpLen = 0,\n tempP: XY = { x: segInfo.x, y: segInfo.y },\n p: XY = { ...tempP },\n nextLen: number,\n nextStep = 0.01,\n lastPerc = 0;\n // nextStep > 0.0001 covers 0.00015625 that 1/64th of 1/100\n // the path\n const iterator = segInfo.iterator,\n angleFinder = segInfo.angleFinder;\n while (tmpLen < distance && nextStep > 0.0001) {\n p = iterator(perc);\n lastPerc = perc;\n nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y);\n // compare tmpLen each cycle with distance, decide next perc to test.\n if (nextLen + tmpLen > distance) {\n // we discard this step and we make smaller steps.\n perc -= nextStep;\n nextStep /= 2;\n } else {\n tempP = p;\n perc += nextStep;\n tmpLen += nextLen;\n }\n }\n return { ...p, angle: angleFinder(lastPerc) };\n};\n\n/**\n * Run over a parsed and simplified path and extract some information (length of each command and starting point)\n * @param {TSimplePathData} path parsed path commands\n * @return {TPathSegmentInfo[]} path commands information\n */\nexport const getPathSegmentsInfo = (\n path: TSimplePathData,\n): TPathSegmentInfo[] => {\n let totalLength = 0,\n //x2 and y2 are the coords of segment start\n //x1 and y1 are the coords of the current point\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n iterator,\n tempInfo: TPathSegmentInfo;\n const info: TPathSegmentInfo[] = [];\n for (const current of path) {\n const basicInfo: TPathSegmentInfoCommon = {\n x: x1,\n y: y1,\n command: current[0],\n length: 0,\n };\n switch (\n current[0] //first letter\n ) {\n case 'M':\n tempInfo = >basicInfo;\n tempInfo.x = x2 = x1 = current[1];\n tempInfo.y = y2 = y1 = current[2];\n break;\n case 'L':\n tempInfo = >basicInfo;\n tempInfo.length = calcLineLength(x1, y1, current[1], current[2]);\n x1 = current[1];\n y1 = current[2];\n break;\n case 'C':\n iterator = getPointOnCubicBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentCubicIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n current[5],\n current[6],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n\n x1 = current[5];\n y1 = current[6];\n break;\n case 'Q':\n iterator = getPointOnQuadraticBezierIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo = >basicInfo;\n tempInfo.iterator = iterator;\n tempInfo.angleFinder = getTangentQuadraticIterator(\n x1,\n y1,\n current[1],\n current[2],\n current[3],\n current[4],\n );\n tempInfo.length = pathIterator(iterator, x1, y1);\n x1 = current[3];\n y1 = current[4];\n break;\n case 'Z':\n // we add those in order to ease calculations later\n tempInfo = basicInfo;\n tempInfo.destX = x2;\n tempInfo.destY = y2;\n tempInfo.length = calcLineLength(x1, y1, x2, y2);\n x1 = x2;\n y1 = y2;\n break;\n }\n totalLength += tempInfo.length;\n info.push(tempInfo);\n }\n info.push({ length: totalLength, x: x1, y: y1 });\n return info;\n};\n\n/**\n * Get the point on the path that is distance along the path\n * @param path\n * @param distance\n * @param infos\n */\nexport const getPointOnPath = (\n path: TSimplePathData,\n distance: number,\n infos: TPathSegmentInfo[] = getPathSegmentsInfo(path),\n): TPointAngle | undefined => {\n let i = 0;\n while (distance - infos[i].length > 0 && i < infos.length - 2) {\n distance -= infos[i].length;\n i++;\n }\n const segInfo = infos[i],\n segPercent = distance / segInfo.length,\n segment = path[i];\n\n switch (segInfo.command) {\n case 'M':\n return { x: segInfo.x, y: segInfo.y, angle: 0 };\n case 'Z':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segInfo.destX, segInfo.destY),\n segPercent,\n ),\n angle: Math.atan2(segInfo.destY - segInfo.y, segInfo.destX - segInfo.x),\n };\n case 'L':\n return {\n ...new Point(segInfo.x, segInfo.y).lerp(\n new Point(segment[1]!, segment[2]!),\n segPercent,\n ),\n angle: Math.atan2(segment[2]! - segInfo.y, segment[1]! - segInfo.x),\n };\n case 'C':\n return findPercentageForDistance(segInfo, distance);\n case 'Q':\n return findPercentageForDistance(segInfo, distance);\n default:\n // throw Error('Invalid command');\n }\n};\n\nconst rePathCmdAll = new RegExp(rePathCommand, 'gi');\nconst regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');\nconst reMyNum = new RegExp(reNum, 'gi');\nconst commandLengths = {\n m: 2,\n l: 2,\n h: 1,\n v: 1,\n c: 6,\n s: 4,\n q: 4,\n t: 2,\n a: 7,\n} as const;\n/**\n *\n * @param {string} pathString\n * @return {TComplexPathData} An array of SVG path commands\n * @example Usage\n * parsePath('M 3 4 Q 3 5 2 1 4 0 Q 9 12 2 1 4 0') === [\n * ['M', 3, 4],\n * ['Q', 3, 5, 2, 1, 4, 0],\n * ['Q', 9, 12, 2, 1, 4, 0],\n * ];\n */\nexport const parsePath = (pathString: string): TComplexPathData => {\n const chain: TComplexPathData = [];\n const all = pathString.match(rePathCmdAll) ?? [];\n for (const matchStr of all) {\n // take match string and save the first letter as the command\n const commandLetter = matchStr[0] as TComplexParsedCommandType;\n // in case of Z we have very little to do\n if (commandLetter === 'z' || commandLetter === 'Z') {\n chain.push([commandLetter]);\n continue;\n }\n const commandLength =\n commandLengths[\n commandLetter.toLowerCase() as keyof typeof commandLengths\n ];\n\n let paramArr = [];\n if (commandLetter === 'a' || commandLetter === 'A') {\n // the arc command ha some peculariaties that requires a special regex other than numbers\n // it is possible to avoid using a space between the sweep and large arc flags, making them either\n // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum\n // reset the regexp\n regExpArcCommandPoints.lastIndex = 0;\n for (let out = null; (out = regExpArcCommandPoints.exec(matchStr)); ) {\n paramArr.push(...out.slice(1));\n }\n } else {\n paramArr = matchStr.match(reMyNum) || [];\n }\n\n // inspect the length of paramArr, if is longer than commandLength\n // we are dealing with repeated commands\n for (let i = 0; i < paramArr.length; i += commandLength) {\n const newCommand = new Array(commandLength) as TComplexParsedCommand;\n const transformedCommand = repeatedCommands[commandLetter];\n newCommand[0] =\n i > 0 && transformedCommand ? transformedCommand : commandLetter;\n for (let j = 0; j < commandLength; j++) {\n newCommand[j + 1] = parseFloat(paramArr[i + j]);\n }\n chain.push(newCommand);\n }\n }\n return chain;\n};\n\n/**\n *\n * Converts points to a smooth SVG path\n * @param {XY[]} points Array of points\n * @param {number} [correction] Apply a correction to the path (usually we use `width / 1000`). If value is undefined 0 is used as the correction value.\n * @return {(string|number)[][]} An array of SVG path commands\n */\nexport const getSmoothPathFromPoints = (\n points: Point[],\n correction = 0,\n): TSimplePathData => {\n let p1 = new Point(points[0]),\n p2 = new Point(points[1]),\n multSignX = 1,\n multSignY = 0;\n const path: TSimplePathData = [],\n len = points.length,\n manyPoints = len > 2;\n\n if (manyPoints) {\n multSignX = points[2].x < p2.x ? -1 : points[2].x === p2.x ? 0 : 1;\n multSignY = points[2].y < p2.y ? -1 : points[2].y === p2.y ? 0 : 1;\n }\n path.push([\n 'M',\n p1.x - multSignX * correction,\n p1.y - multSignY * correction,\n ]);\n let i;\n for (i = 1; i < len; i++) {\n if (!p1.eq(p2)) {\n const midPoint = p1.midPointFrom(p2);\n // p1 is our bezier control point\n // midpoint is our endpoint\n // start point is p(i-1) value.\n path.push(['Q', p1.x, p1.y, midPoint.x, midPoint.y]);\n }\n p1 = points[i];\n if (i + 1 < points.length) {\n p2 = points[i + 1];\n }\n }\n if (manyPoints) {\n multSignX = p1.x > points[i - 2].x ? 1 : p1.x === points[i - 2].x ? 0 : -1;\n multSignY = p1.y > points[i - 2].y ? 1 : p1.y === points[i - 2].y ? 0 : -1;\n }\n path.push([\n 'L',\n p1.x + multSignX * correction,\n p1.y + multSignY * correction,\n ]);\n return path;\n};\n\n/**\n * Transform a path by transforming each segment.\n * it has to be a simplified path or it won't work.\n * WARNING: this depends from pathOffset for correct operation\n * @param {TSimplePathData} path fabricJS parsed and simplified path commands\n * @param {TMat2D} transform matrix that represent the transformation\n * @param {Point} [pathOffset] `Path.pathOffset`\n * @returns {TSimplePathData} the transformed path\n */\nexport const transformPath = (\n path: TSimplePathData,\n transform: TMat2D,\n pathOffset: Point,\n): TSimplePathData => {\n if (pathOffset) {\n transform = multiplyTransformMatrices(transform, [\n 1,\n 0,\n 0,\n 1,\n -pathOffset.x,\n -pathOffset.y,\n ]);\n }\n return path.map((pathSegment) => {\n const newSegment: TSimpleParsedCommand = [...pathSegment];\n for (let i = 1; i < pathSegment.length - 1; i += 2) {\n // TODO: is there a way to get around casting to any?\n const { x, y } = transformPoint(\n {\n x: pathSegment[i] as number,\n y: pathSegment[i + 1] as number,\n },\n transform,\n );\n newSegment[i] = x;\n newSegment[i + 1] = y;\n }\n return newSegment;\n });\n};\n\n/**\n * Returns an array of path commands to create a regular polygon\n * @param {number} numVertexes\n * @param {number} radius\n * @returns {TSimplePathData} An array of SVG path commands\n */\nexport const getRegularPolygonPath = (\n numVertexes: number,\n radius: number,\n): TSimplePathData => {\n const interiorAngle = (Math.PI * 2) / numVertexes;\n // rotationAdjustment rotates the path by 1/2 the interior angle so that the polygon always has a flat side on the bottom\n // This isn't strictly necessary, but it's how we tend to think of and expect polygons to be drawn\n let rotationAdjustment = -halfPI;\n if (numVertexes % 2 === 0) {\n rotationAdjustment += interiorAngle / 2;\n }\n const d = new Array(numVertexes + 1);\n for (let i = 0; i < numVertexes; i++) {\n const rad = i * interiorAngle + rotationAdjustment;\n const { x, y } = new Point(cos(rad), sin(rad)).scalarMultiply(radius);\n d[i] = [i === 0 ? 'M' : 'L', x, y];\n }\n d[numVertexes] = ['Z'];\n return d;\n};\n\n/**\n * Join path commands to go back to svg format\n * @param {TSimplePathData} pathData fabricJS parsed path commands\n * @param {number} fractionDigits number of fraction digits to \"leave\"\n * @return {String} joined path 'M 0 0 L 20 30'\n */\nexport const joinPath = (pathData: TSimplePathData, fractionDigits?: number) =>\n pathData\n .map((segment) => {\n return segment\n .map((arg, i) => {\n if (i === 0) return arg;\n return fractionDigits === undefined\n ? arg\n : toFixed(arg, fractionDigits);\n })\n .join(' ');\n })\n .join(' ');\n","// TODO this file needs to go away, cross browser style support is not fabricjs domain.\n\n/**\n * wrapper for setting element's style\n * @param {HTMLElement} element\n * @param {Object | string} styles\n */\nexport function setStyle(\n element: HTMLElement,\n styles: string | Record,\n) {\n const elementStyle = element.style;\n if (!elementStyle || !styles) {\n return;\n } else if (typeof styles === 'string') {\n elementStyle.cssText += ';' + styles;\n } else {\n Object.entries(styles).forEach(([property, value]) =>\n elementStyle.setProperty(property, value),\n );\n }\n}\n","import type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { sendObjectToPlane } from './planeChange';\nimport { Group } from '../../shapes/Group';\n/**\n * Merges 2 clip paths into one visually equal clip path\n *\n * **IMPORTANT**:\\\n * Does **NOT** clone the arguments, clone them proir if necessary.\n *\n * Creates a wrapper (group) that contains one clip path and is clipped by the other so content is kept where both overlap.\n * Use this method if both the clip paths may have nested clip paths of their own, so assigning one to the other's clip path property is not possible.\n *\n * In order to handle the `inverted` property we follow logic described in the following cases:\\\n * **(1)** both clip paths are inverted - the clip paths pass the inverted prop to the wrapper and loose it themselves.\\\n * **(2)** one is inverted and the other isn't - the wrapper shouldn't become inverted and the inverted clip path must clip the non inverted one to produce an identical visual effect.\\\n * **(3)** both clip paths are not inverted - wrapper and clip paths remain unchanged.\n *\n * @memberOf fabric.util\n * @param {fabric.Object} c1\n * @param {fabric.Object} c2\n * @returns {fabric.Object} merged clip path\n */\nexport const mergeClipPaths = (c1: FabricObject, c2: FabricObject) => {\n let a = c1,\n b = c2;\n if (a.inverted && !b.inverted) {\n // case (2)\n a = c2;\n b = c1;\n }\n // `b` becomes `a`'s clip path so we transform `b` to `a` coordinate plane\n sendObjectToPlane(b, b.group?.calcTransformMatrix(), a.calcTransformMatrix());\n // assign the `inverted` prop to the wrapping group\n const inverted = a.inverted && b.inverted;\n if (inverted) {\n // case (1)\n a.inverted = b.inverted = false;\n }\n return new Group([a], { clipPath: b, inverted });\n};\n","/**\n * Returns random number between 2 specified ones.\n * @param {Number} min lower limit\n * @param {Number} max upper limit\n * @return {Number} random value (between min and max)\n */\nexport const getRandomInt = (min: number, max: number): number =>\n Math.floor(Math.random() * (max - min + 1)) + min;\n","import { getFabricWindow } from '../../env';\nimport { noop } from '../../constants';\nimport type { Abortable } from '../../typedefs';\nimport { SignalAbortedError } from './console';\n\ntype requestOptions = Abortable & {\n onComplete?: (xhr: XMLHttpRequest) => void;\n};\n\n/**\n * Cross-browser abstraction for sending XMLHttpRequest\n * @deprecated this has to go away, we can use a modern browser method to do the same.\n * @param {String} url URL to send XMLHttpRequest to\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} options.onComplete Callback to invoke when request is completed\n * @return {XMLHttpRequest} request\n */\n\nexport function request(url: string, options: requestOptions = {}) {\n const onComplete = options.onComplete || noop,\n xhr = new (getFabricWindow().XMLHttpRequest)(),\n signal = options.signal,\n abort = function () {\n xhr.abort();\n },\n removeListener = function () {\n signal && signal.removeEventListener('abort', abort);\n xhr.onerror = xhr.ontimeout = noop;\n };\n\n if (signal && signal.aborted) {\n throw new SignalAbortedError('request');\n } else if (signal) {\n signal.addEventListener('abort', abort, { once: true });\n }\n\n /** @ignore */\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4) {\n removeListener();\n onComplete(xhr);\n xhr.onreadystatechange = noop;\n }\n };\n\n xhr.onerror = xhr.ontimeout = removeListener;\n\n xhr.open('get', url, true);\n\n xhr.send();\n return xhr;\n}\n","import { CENTER, SCALE_X, SCALE_Y } from '../constants';\nimport type { FabricImage } from '../shapes/Image';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { qrDecompose } from './misc/matrix';\n\ntype FabricObjectWithTransformMatrix = FabricObject & {\n transformMatrix?: TMat2D;\n};\n\n/**\n * This function is an helper for svg import. it decompose the transformMatrix\n * and assign properties to object.\n * untransformed coordinates\n * @private\n */\nconst _assignTransformMatrixProps = (\n object: FabricObjectWithTransformMatrix,\n) => {\n if (object.transformMatrix) {\n const { scaleX, scaleY, angle, skewX } = qrDecompose(\n object.transformMatrix,\n );\n object.flipX = false;\n object.flipY = false;\n object.set(SCALE_X, scaleX);\n object.set(SCALE_Y, scaleY);\n object.angle = angle;\n object.skewX = skewX;\n object.skewY = 0;\n }\n};\n\n/**\n * This function is an helper for svg import. it removes the transform matrix\n * and set to object properties that fabricjs can handle\n * @private\n * @param {Object} preserveAspectRatioOptions\n */\nexport const removeTransformMatrixForSvgParsing = (\n object: FabricObjectWithTransformMatrix,\n preserveAspectRatioOptions?: any,\n) => {\n let center = object._findCenterFromElement();\n if (object.transformMatrix) {\n _assignTransformMatrixProps(object);\n center = center.transform(object.transformMatrix);\n }\n delete object.transformMatrix;\n if (preserveAspectRatioOptions) {\n object.scaleX *= preserveAspectRatioOptions.scaleX;\n object.scaleY *= preserveAspectRatioOptions.scaleY;\n (object as FabricImage).cropX = preserveAspectRatioOptions.cropX;\n (object as FabricImage).cropY = preserveAspectRatioOptions.cropY;\n center.x += preserveAspectRatioOptions.offsetLeft;\n center.y += preserveAspectRatioOptions.offsetTop;\n object.width = preserveAspectRatioOptions.width;\n object.height = preserveAspectRatioOptions.height;\n }\n object.setPositionByOrigin(center, CENTER, CENTER);\n};\n","import { getEnv, getFabricDocument } from '../../env';\nimport type { TSize } from '../../typedefs';\nimport { createCanvasElement, setStyle } from '../../util';\nimport type { CSSDimensions } from './util';\nimport { makeElementUnselectable, setCSSDimensions } from './util';\nimport type { CanvasItem } from './StaticCanvasDOMManager';\nimport { StaticCanvasDOMManager } from './StaticCanvasDOMManager';\nimport { setCanvasDimensions } from './util';\nimport { NONE } from '../../constants';\n\nexport class CanvasDOMManager extends StaticCanvasDOMManager {\n upper: CanvasItem;\n container: HTMLDivElement;\n\n constructor(\n arg0?: string | HTMLCanvasElement,\n {\n allowTouchScrolling = false,\n containerClass = '',\n }: {\n allowTouchScrolling?: boolean;\n /**\n * @deprecated here only for backward compatibility\n */\n containerClass?: string;\n } = {},\n ) {\n super(arg0);\n const { el: lowerCanvasEl } = this.lower;\n const upperCanvasEl = this.createUpperCanvas();\n this.upper = { el: upperCanvasEl, ctx: upperCanvasEl.getContext('2d')! };\n this.applyCanvasStyle(lowerCanvasEl, {\n allowTouchScrolling,\n });\n this.applyCanvasStyle(upperCanvasEl, {\n allowTouchScrolling,\n styles: {\n position: 'absolute',\n left: '0',\n top: '0',\n },\n });\n const container = this.createContainerElement();\n container.classList.add(containerClass);\n if (lowerCanvasEl.parentNode) {\n lowerCanvasEl.parentNode.replaceChild(container, lowerCanvasEl);\n }\n container.append(lowerCanvasEl, upperCanvasEl);\n this.container = container;\n }\n\n protected createUpperCanvas() {\n const { el: lowerCanvasEl } = this.lower;\n const el = createCanvasElement();\n // we assign the same classname of the lowerCanvas\n el.className = lowerCanvasEl.className;\n // but then we remove the lower-canvas specific className\n el.classList.remove('lower-canvas');\n // we add the specific upper-canvas class\n el.classList.add('upper-canvas');\n el.setAttribute('data-fabric', 'top');\n el.style.cssText = lowerCanvasEl.style.cssText;\n el.setAttribute('draggable', 'true');\n return el;\n }\n\n protected createContainerElement() {\n const container = getFabricDocument().createElement('div');\n container.setAttribute('data-fabric', 'wrapper');\n setStyle(container, {\n position: 'relative',\n });\n makeElementUnselectable(container);\n return container;\n }\n\n /**\n * @private\n * @param {HTMLCanvasElement} element canvas element to apply styles on\n */\n protected applyCanvasStyle(\n element: HTMLCanvasElement,\n options: {\n allowTouchScrolling?: boolean;\n styles?: Record;\n },\n ) {\n const { styles, allowTouchScrolling } = options;\n setStyle(element, {\n ...styles,\n 'touch-action': allowTouchScrolling ? 'manipulation' : NONE,\n });\n makeElementUnselectable(element);\n }\n\n setDimensions(size: TSize, retinaScaling: number) {\n super.setDimensions(size, retinaScaling);\n const { el, ctx } = this.upper;\n setCanvasDimensions(el, ctx, size, retinaScaling);\n }\n\n setCSSDimensions(size: Partial): void {\n super.setCSSDimensions(size);\n setCSSDimensions(this.upper.el, size);\n setCSSDimensions(this.container, size);\n }\n\n cleanupDOM(size: TSize) {\n const container = this.container,\n { el: lowerCanvasEl } = this.lower,\n { el: upperCanvasEl } = this.upper;\n super.cleanupDOM(size);\n container.removeChild(upperCanvasEl);\n container.removeChild(lowerCanvasEl);\n if (container.parentNode) {\n container.parentNode.replaceChild(lowerCanvasEl, container);\n }\n }\n\n dispose() {\n super.dispose();\n getEnv().dispose(this.upper.el);\n // @ts-expect-error disposing\n delete this.upper;\n // @ts-expect-error disposing\n delete this.container;\n }\n}\n","import type { ModifierKey, TOptionalModifierKey } from '../EventTypeDefs';\nimport type { TOptions } from '../typedefs';\nimport type { StaticCanvasOptions } from './StaticCanvasOptions';\n\nexport interface CanvasTransformOptions {\n /**\n * When true, objects can be transformed by one side (unproportionately)\n * when dragged on the corners that normally would not do that.\n * @type Boolean\n * @default\n * @since fabric 4.0 // changed name and default value\n */\n uniformScaling: boolean;\n\n /**\n * Indicates which key switches uniform scaling.\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * totally wrong named. this sounds like `uniform scaling`\n * if Canvas.uniformScaling is true, pressing this will set it to false\n * and viceversa.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n uniScaleKey: TOptionalModifierKey;\n\n /**\n * When true, objects use center point as the origin of scale transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredScaling: boolean;\n\n /**\n * When true, objects use center point as the origin of rotate transformation.\n * Backwards incompatibility note: This property replaces \"centerTransform\" (Boolean).\n * @since 1.3.4\n * @type Boolean\n * @default\n */\n centeredRotation: boolean;\n\n /**\n * Indicates which key enable centered Transform\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n centeredKey: TOptionalModifierKey;\n\n /**\n * Indicates which key enable alternate action on corner\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled feature disabled.\n * @since 1.6.2\n * @type ModifierKey\n * @default\n */\n altActionKey: TOptionalModifierKey;\n}\n\nexport interface CanvasSelectionOptions {\n /**\n * Indicates whether group selection should be enabled\n * @type Boolean\n * @default\n */\n selection: boolean;\n\n /**\n * Indicates which key or keys enable multiple click selection\n * Pass value as a string or array of strings\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * If `null` or empty or containing any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.2\n * @type ModifierKey|ModifierKey[]\n * @default\n */\n selectionKey: TOptionalModifierKey | ModifierKey[];\n\n /**\n * Indicates which key enable alternative selection\n * in case of target overlapping with active object\n * values: 'altKey', 'shiftKey', 'ctrlKey'.\n * For a series of reason that come from the general expectations on how\n * things should work, this feature works only for preserveObjectStacking true.\n * If `null` or 'none' or any other string that is not a modifier key\n * feature is disabled.\n * @since 1.6.5\n * @type null|ModifierKey\n * @default\n */\n altSelectionKey: TOptionalModifierKey;\n\n /**\n * Color of selection\n * @type String\n * @default\n */\n selectionColor: string;\n\n /**\n * Default dash array pattern\n * If not empty the selection border is dashed\n * @type Array\n */\n selectionDashArray: number[];\n\n /**\n * Color of the border of selection (usually slightly darker than color of selection itself)\n * @type String\n * @default\n */\n selectionBorderColor: string;\n\n /**\n * Width of a line used in object/group selection\n * @type Number\n * @default\n */\n selectionLineWidth: number;\n\n /**\n * Select only shapes that are fully contained in the dragged selection rectangle.\n * @type Boolean\n * @default\n */\n selectionFullyContained: boolean;\n}\n\nexport interface CanvasCursorOptions {\n /**\n * Default cursor value used when hovering over an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n hoverCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used when moving an object on canvas\n * @type CSSStyleDeclaration['cursor']\n * @default move\n */\n moveCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Default cursor value used for the entire canvas\n * @type String\n * @default default\n */\n defaultCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used during free drawing\n * @type String\n * @default crosshair\n */\n freeDrawingCursor: CSSStyleDeclaration['cursor'];\n\n /**\n * Cursor value used for disabled elements ( corners with disabled action )\n * @type String\n * @since 2.0.0\n * @default not-allowed\n */\n notAllowedCursor: CSSStyleDeclaration['cursor'];\n}\n\nexport interface TargetFindOptions {\n /**\n * When true, object detection happens on per-pixel basis rather than on per-bounding-box\n * @type Boolean\n * @default\n */\n perPixelTargetFind: boolean;\n\n /**\n * Number of pixels around target pixel to tolerate (consider active) during object detection\n * @type Number\n * @default\n */\n targetFindTolerance: number;\n\n /**\n * When true, target detection is skipped. Target detection will return always undefined.\n * click selection won't work anymore, events will fire with no targets.\n * if something is selected before setting it to true, it will be deselected at the first click.\n * area selection will still work. check the `selection` property too.\n * if you deactivate both, you should look into staticCanvas.\n * @type Boolean\n * @default\n */\n skipTargetFind: boolean;\n}\n\nexport interface CanvasEventsOptions {\n /**\n * Indicates if the right click on canvas can output the context menu or not\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n stopContextMenu: boolean;\n\n /**\n * Indicates if the canvas can fire right click events\n * @type Boolean\n * @since 1.6.5\n * @default\n */\n fireRightClick: boolean;\n\n /**\n * Indicates if the canvas can fire middle click events\n * @type Boolean\n * @since 1.7.8\n * @default\n */\n fireMiddleClick: boolean;\n\n /**\n * When the option is enabled, PointerEvent is used instead of TPointerEvent.\n * @type Boolean\n * @default\n */\n enablePointerEvents: boolean;\n}\n\nexport interface CanvasOptions\n extends StaticCanvasOptions,\n CanvasTransformOptions,\n CanvasSelectionOptions,\n CanvasCursorOptions,\n TargetFindOptions,\n CanvasEventsOptions {\n /**\n * Default element class that's given to wrapper (div) element of canvas\n * @type String\n * @default\n * @deprecated customize {@link CanvasDOMManager} instead or access {@link elements} directly\n */\n containerClass: string;\n\n /**\n * Indicates whether objects should remain in current stack position when selected.\n * When false objects are brought to top and rendered as part of the selection group\n * @type Boolean\n * @default\n */\n preserveObjectStacking: boolean;\n}\n\nexport type TCanvasOptions = TOptions;\n\nexport const canvasDefaults: TOptions = {\n uniformScaling: true,\n uniScaleKey: 'shiftKey',\n centeredScaling: false,\n centeredRotation: false,\n centeredKey: 'altKey',\n altActionKey: 'shiftKey',\n\n selection: true,\n selectionKey: 'shiftKey',\n selectionColor: 'rgba(100, 100, 255, 0.3)',\n selectionDashArray: [],\n selectionBorderColor: 'rgba(255, 255, 255, 0.3)',\n selectionLineWidth: 1,\n selectionFullyContained: false,\n\n hoverCursor: 'move',\n moveCursor: 'move',\n defaultCursor: 'default',\n freeDrawingCursor: 'crosshair',\n notAllowedCursor: 'not-allowed',\n\n perPixelTargetFind: false,\n targetFindTolerance: 0,\n skipTargetFind: false,\n\n stopContextMenu: false,\n fireRightClick: false,\n fireMiddleClick: false,\n enablePointerEvents: false,\n\n containerClass: 'canvas-container',\n\n preserveObjectStacking: false,\n};\n","import { dragHandler } from '../controls/drag';\nimport { getActionFromCorner } from '../controls/util';\nimport { Point } from '../Point';\nimport { FabricObject } from '../shapes/Object/FabricObject';\nimport type {\n CanvasEvents,\n ModifierKey,\n TOptionalModifierKey,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport {\n addTransformToObject,\n saveObjectTransform,\n} from '../util/misc/objectTransforms';\nimport type { TCanvasSizeOptions } from './StaticCanvas';\nimport { StaticCanvas } from './StaticCanvas';\nimport { isCollection } from '../Collection';\nimport { isTransparent } from '../util/misc/isTransparent';\nimport type {\n TMat2D,\n TOriginX,\n TOriginY,\n TSize,\n TSVGReviver,\n} from '../typedefs';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { getPointer, isTouchEvent } from '../util/dom_event';\nimport type { IText } from '../shapes/IText/IText';\nimport type { BaseBrush } from '../brushes/BaseBrush';\nimport { pick } from '../util/misc/pick';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { cos, createCanvasElement, sin } from '../util';\nimport { CanvasDOMManager } from './DOMManagers/CanvasDOMManager';\nimport {\n BOTTOM,\n CENTER,\n LEFT,\n MODIFIED,\n RESIZING,\n RIGHT,\n ROTATE,\n SCALE,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CanvasOptions } from './CanvasOptions';\nimport { canvasDefaults } from './CanvasOptions';\nimport { Intersection } from '../Intersection';\nimport { isActiveSelection } from '../util/typeAssertions';\n\n/**\n * Canvas class\n * @class Canvas\n * @extends StaticCanvas\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#canvas}\n *\n * @fires object:modified at the end of a transform\n * @fires object:rotating while an object is being rotated from the control\n * @fires object:scaling while an object is being scaled by controls\n * @fires object:moving while an object is being dragged\n * @fires object:skewing while an object is being skewed from the controls\n *\n * @fires before:transform before a transform is is started\n * @fires before:selection:cleared\n * @fires selection:cleared\n * @fires selection:updated\n * @fires selection:created\n *\n * @fires path:created after a drawing operation ends and the path is added\n * @fires mouse:down\n * @fires mouse:move\n * @fires mouse:up\n * @fires mouse:down:before on mouse down, before the inner fabric logic runs\n * @fires mouse:move:before on mouse move, before the inner fabric logic runs\n * @fires mouse:up:before on mouse up, before the inner fabric logic runs\n * @fires mouse:over\n * @fires mouse:out\n * @fires mouse:dblclick whenever a native dbl click event fires on the canvas.\n *\n * @fires dragover\n * @fires dragenter\n * @fires dragleave\n * @fires drag:enter object drag enter\n * @fires drag:leave object drag leave\n * @fires drop:before before drop event. Prepare for the drop event (same native event).\n * @fires drop\n * @fires drop:after after drop event. Run logic on canvas after event has been accepted/declined (same native event).\n * @example\n * let a: fabric.Object, b: fabric.Object;\n * let flag = false;\n * canvas.add(a, b);\n * a.on('drop:before', opt => {\n * // we want a to accept the drop even though it's below b in the stack\n * flag = this.canDrop(opt.e);\n * });\n * b.canDrop = function(e) {\n * !flag && this.draggableTextDelegate.canDrop(e);\n * }\n * b.on('dragover', opt => b.set('fill', opt.dropTarget === b ? 'pink' : 'black'));\n * a.on('drop', opt => {\n * opt.e.defaultPrevented // drop occurred\n * opt.didDrop // drop occurred on canvas\n * opt.target // drop target\n * opt.target !== a && a.set('text', 'I lost');\n * });\n * canvas.on('drop:after', opt => {\n * // inform user who won\n * if(!opt.e.defaultPrevented) {\n * // no winners\n * }\n * else if(!opt.didDrop) {\n * // my objects didn't win, some other lucky object\n * }\n * else {\n * // we have a winner it's opt.target!!\n * }\n * })\n *\n * @fires after:render at the end of the render process, receives the context in the callback\n * @fires before:render at start the render process, receives the context in the callback\n *\n * @fires contextmenu:before\n * @fires contextmenu\n * @example\n * let handler;\n * targets.forEach(target => {\n * target.on('contextmenu:before', opt => {\n * // decide which target should handle the event before canvas hijacks it\n * if (someCaseHappens && opt.targets.includes(target)) {\n * handler = target;\n * }\n * });\n * target.on('contextmenu', opt => {\n * // do something fantastic\n * });\n * });\n * canvas.on('contextmenu', opt => {\n * if (!handler) {\n * // no one takes responsibility, it's always left to me\n * // let's show them how it's done!\n * }\n * });\n *\n */\nexport class SelectableCanvas\n extends StaticCanvas\n implements Omit\n{\n declare _objects: FabricObject[];\n\n // transform config\n declare uniformScaling: boolean;\n declare uniScaleKey: TOptionalModifierKey;\n declare centeredScaling: boolean;\n declare centeredRotation: boolean;\n declare centeredKey: TOptionalModifierKey;\n declare altActionKey: TOptionalModifierKey;\n\n // selection config\n declare selection: boolean;\n declare selectionKey: TOptionalModifierKey | ModifierKey[];\n declare altSelectionKey: TOptionalModifierKey;\n declare selectionColor: string;\n declare selectionDashArray: number[];\n declare selectionBorderColor: string;\n declare selectionLineWidth: number;\n declare selectionFullyContained: boolean;\n\n // cursors\n declare hoverCursor: CSSStyleDeclaration['cursor'];\n declare moveCursor: CSSStyleDeclaration['cursor'];\n declare defaultCursor: CSSStyleDeclaration['cursor'];\n declare freeDrawingCursor: CSSStyleDeclaration['cursor'];\n declare notAllowedCursor: CSSStyleDeclaration['cursor'];\n\n declare containerClass: string;\n\n // target find config\n declare perPixelTargetFind: boolean;\n declare targetFindTolerance: number;\n declare skipTargetFind: boolean;\n\n /**\n * When true, mouse events on canvas (mousedown/mousemove/mouseup) result in free drawing.\n * After mousedown, mousemove creates a shape,\n * and then mouseup finalizes it and adds an instance of `fabric.Path` onto canvas.\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-4#free_drawing}\n * @type Boolean\n * @default\n */\n declare isDrawingMode: boolean;\n\n declare preserveObjectStacking: boolean;\n\n // event config\n declare stopContextMenu: boolean;\n declare fireRightClick: boolean;\n declare fireMiddleClick: boolean;\n\n /**\n * Keep track of the subTargets for Mouse Events, ordered bottom up from innermost nested subTarget\n * @type FabricObject[]\n */\n targets: FabricObject[] = [];\n\n /**\n * Keep track of the hovered target\n * @type FabricObject | null\n * @private\n */\n declare _hoveredTarget?: FabricObject;\n\n /**\n * hold the list of nested targets hovered\n * @type FabricObject[]\n * @private\n */\n _hoveredTargets: FabricObject[] = [];\n\n /**\n * hold the list of objects to render\n * @type FabricObject[]\n * @private\n */\n _objectsToRender?: FabricObject[];\n\n /**\n * hold a reference to a data structure that contains information\n * on the current on going transform\n * @type\n * @private\n */\n _currentTransform: Transform | null = null;\n\n /**\n * hold a reference to a data structure used to track the selection\n * box on canvas drag\n * on the current on going transform\n * x, y, deltaX and deltaY are in scene plane\n * @type\n * @private\n */\n protected _groupSelector: {\n x: number;\n y: number;\n deltaX: number;\n deltaY: number;\n } | null = null;\n\n /**\n * internal flag used to understand if the context top requires a cleanup\n * in case this is true, the contextTop will be cleared at the next render\n * @type boolean\n * @private\n */\n contextTopDirty = false;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _absolutePointer holds a reference to the pointer in fabricCanvas/design coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _absolutePointer?: Point;\n\n /**\n * During a mouse event we may need the pointer multiple times in multiple functions.\n * _pointer holds a reference to the pointer in html coordinates that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * We do this because there are some HTML DOM inspection functions to get the actual pointer coordinates\n * @type {Point}\n */\n protected declare _pointer?: Point;\n\n /**\n * During a mouse event we may need the target multiple times in multiple functions.\n * _target holds a reference to the target that is valid for the event\n * lifespan. Every fabricJS mouse event create and delete the cache every time\n * @type {FabricObject}\n */\n protected declare _target?: FabricObject;\n\n static ownDefaults = canvasDefaults;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...SelectableCanvas.ownDefaults };\n }\n\n declare elements: CanvasDOMManager;\n get upperCanvasEl() {\n return this.elements.upper?.el;\n }\n get contextTop() {\n return this.elements.upper?.ctx;\n }\n get wrapperEl() {\n return this.elements.container;\n }\n private declare pixelFindCanvasEl: HTMLCanvasElement;\n private declare pixelFindContext: CanvasRenderingContext2D;\n\n protected declare _isCurrentlyDrawing: boolean;\n declare freeDrawingBrush?: BaseBrush;\n declare _activeObject?: FabricObject;\n\n protected initElements(el?: string | HTMLCanvasElement) {\n this.elements = new CanvasDOMManager(el, {\n allowTouchScrolling: this.allowTouchScrolling,\n containerClass: this.containerClass,\n });\n this._createCacheCanvas();\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was added\n */\n _onObjectAdded(obj: FabricObject) {\n this._objectsToRender = undefined;\n super._onObjectAdded(obj);\n }\n\n /**\n * @private\n * @param {FabricObject} obj Object that was removed\n */\n _onObjectRemoved(obj: FabricObject) {\n this._objectsToRender = undefined;\n // removing active object should fire \"selection:cleared\" events\n if (obj === this._activeObject) {\n this.fire('before:selection:cleared', { deselected: [obj] });\n this._discardActiveObject();\n this.fire('selection:cleared', { deselected: [obj] });\n obj.fire('deselected', {\n target: obj,\n });\n }\n if (obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n super._onObjectRemoved(obj);\n }\n\n _onStackOrderChanged() {\n this._objectsToRender = undefined;\n super._onStackOrderChanged();\n }\n\n /**\n * Divides objects in two groups, one to render immediately\n * and one to render as activeGroup.\n * @return {Array} objects to render immediately and pushes the other in the activeGroup.\n */\n _chooseObjectsToRender(): FabricObject[] {\n const activeObject = this._activeObject;\n return !this.preserveObjectStacking && activeObject\n ? this._objects\n .filter((object) => !object.group && object !== activeObject)\n .concat(activeObject)\n : this._objects;\n }\n\n /**\n * Renders both the top canvas and the secondary container canvas.\n */\n renderAll() {\n this.cancelRequestedRender();\n if (this.destroyed) {\n return;\n }\n if (this.contextTopDirty && !this._groupSelector && !this.isDrawingMode) {\n this.clearContext(this.contextTop);\n this.contextTopDirty = false;\n }\n if (this.hasLostContext) {\n this.renderTopLayer(this.contextTop);\n this.hasLostContext = false;\n }\n !this._objectsToRender &&\n (this._objectsToRender = this._chooseObjectsToRender());\n this.renderCanvas(this.getContext(), this._objectsToRender);\n }\n\n /**\n * text selection is rendered by the active text instance during the rendering cycle\n */\n renderTopLayer(ctx: CanvasRenderingContext2D): void {\n ctx.save();\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this.freeDrawingBrush && this.freeDrawingBrush._render();\n this.contextTopDirty = true;\n }\n // we render the top context - last object\n if (this.selection && this._groupSelector) {\n this._drawSelection(ctx);\n this.contextTopDirty = true;\n }\n ctx.restore();\n }\n\n /**\n * Method to render only the top canvas.\n * Also used to render the group selection box.\n * Does not render text selection.\n */\n renderTop() {\n const ctx = this.contextTop;\n this.clearContext(ctx);\n this.renderTopLayer(ctx);\n // todo: how do i know if the after:render is for the top or normal contex?\n this.fire('after:render', { ctx });\n }\n\n /**\n * Set the canvas tolerance value for pixel taret find.\n * Use only integer numbers.\n * @private\n */\n setTargetFindTolerance(value: number) {\n value = Math.round(value);\n this.targetFindTolerance = value;\n const retina = this.getRetinaScaling();\n const size = Math.ceil((value * 2 + 1) * retina);\n this.pixelFindCanvasEl.width = this.pixelFindCanvasEl.height = size;\n this.pixelFindContext.scale(retina, retina);\n }\n\n /**\n * Returns true if object is transparent at a certain location\n * Clarification: this is `is target transparent at location X or are controls there`\n * @TODO this seems dumb that we treat controls with transparency. we can find controls\n * programmatically without painting them, the cache canvas optimization is always valid\n * @param {FabricObject} target Object to check\n * @param {Number} x Left coordinate in viewport space\n * @param {Number} y Top coordinate in viewport space\n * @return {Boolean}\n */\n isTargetTransparent(target: FabricObject, x: number, y: number): boolean {\n const tolerance = this.targetFindTolerance;\n const ctx = this.pixelFindContext;\n this.clearContext(ctx);\n ctx.save();\n ctx.translate(-x + tolerance, -y + tolerance);\n ctx.transform(...this.viewportTransform);\n const selectionBgc = target.selectionBackgroundColor;\n target.selectionBackgroundColor = '';\n target.render(ctx);\n target.selectionBackgroundColor = selectionBgc;\n ctx.restore();\n // our canvas is square, and made around tolerance.\n // so tolerance in this case also represent the center of the canvas.\n const enhancedTolerance = Math.round(tolerance * this.getRetinaScaling());\n return isTransparent(\n ctx,\n enhancedTolerance,\n enhancedTolerance,\n enhancedTolerance,\n );\n }\n\n /**\n * takes an event and determines if selection key has been pressed\n * @private\n * @param {TPointerEvent} e Event object\n */\n _isSelectionKeyPressed(e: TPointerEvent): boolean {\n const sKey = this.selectionKey;\n if (!sKey) {\n return false;\n }\n if (Array.isArray(sKey)) {\n return !!sKey.find((key) => !!key && e[key] === true);\n } else {\n return e[sKey];\n }\n }\n\n /**\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target\n */\n _shouldClearSelection(\n e: TPointerEvent,\n target?: FabricObject,\n ): target is undefined {\n const activeObjects = this.getActiveObjects(),\n activeObject = this._activeObject;\n\n return !!(\n !target ||\n (target &&\n activeObject &&\n activeObjects.length > 1 &&\n activeObjects.indexOf(target) === -1 &&\n activeObject !== target &&\n !this._isSelectionKeyPressed(e)) ||\n (target && !target.evented) ||\n (target && !target.selectable && activeObject && activeObject !== target)\n );\n }\n\n /**\n * This method will take in consideration a modifier key pressed and the control we are\n * about to drag, and try to guess the anchor point ( origin ) of the transormation.\n * This should be really in the realm of controls, and we should remove specific code for legacy\n * embedded actions.\n * @TODO this probably deserve discussion/rediscovery and change/refactor\n * @private\n * @deprecated\n * @param {FabricObject} target\n * @param {string} action\n * @param {boolean} altKey\n * @returns {boolean} true if the transformation should be centered\n */\n private _shouldCenterTransform(\n target: FabricObject,\n action: string,\n modifierKeyPressed: boolean,\n ) {\n if (!target) {\n return;\n }\n\n let centerTransform;\n\n if (\n action === SCALE ||\n action === SCALE_X ||\n action === SCALE_Y ||\n action === RESIZING\n ) {\n centerTransform = this.centeredScaling || target.centeredScaling;\n } else if (action === ROTATE) {\n centerTransform = this.centeredRotation || target.centeredRotation;\n }\n\n return centerTransform ? !modifierKeyPressed : modifierKeyPressed;\n }\n\n /**\n * Given the control clicked, determine the origin of the transform.\n * This is bad because controls can totally have custom names\n * should disappear before release 4.0\n * @private\n * @deprecated\n */\n _getOriginFromCorner(\n target: FabricObject,\n controlName: string,\n ): { x: TOriginX; y: TOriginY } {\n const origin = {\n x: target.originX,\n y: target.originY,\n };\n\n if (!controlName) {\n return origin;\n }\n\n // is a left control ?\n if (['ml', 'tl', 'bl'].includes(controlName)) {\n origin.x = RIGHT;\n // is a right control ?\n } else if (['mr', 'tr', 'br'].includes(controlName)) {\n origin.x = LEFT;\n }\n // is a top control ?\n if (['tl', 'mt', 'tr'].includes(controlName)) {\n origin.y = BOTTOM;\n // is a bottom control ?\n } else if (['bl', 'mb', 'br'].includes(controlName)) {\n origin.y = TOP;\n }\n return origin;\n }\n\n /**\n * @private\n * @param {Event} e Event object\n * @param {FabricObject} target\n * @param {boolean} [alreadySelected] pass true to setup the active control\n */\n _setupCurrentTransform(\n e: TPointerEvent,\n target: FabricObject,\n alreadySelected: boolean,\n ): void {\n const pointer = target.group\n ? // transform pointer to target's containing coordinate plane\n sendPointToPlane(\n this.getScenePoint(e),\n undefined,\n target.group.calcTransformMatrix(),\n )\n : this.getScenePoint(e);\n const { key: corner = '', control } = target.getActiveControl() || {},\n actionHandler =\n alreadySelected && control\n ? control.getActionHandler(e, target, control)?.bind(control)\n : dragHandler,\n action = getActionFromCorner(alreadySelected, corner, e, target),\n altKey = e[this.centeredKey as ModifierKey],\n origin = this._shouldCenterTransform(target, action, altKey)\n ? ({ x: CENTER, y: CENTER } as const)\n : this._getOriginFromCorner(target, corner),\n /**\n * relative to target's containing coordinate plane\n * both agree on every point\n **/\n transform: Transform = {\n target: target,\n action,\n actionHandler,\n actionPerformed: false,\n corner,\n scaleX: target.scaleX,\n scaleY: target.scaleY,\n skewX: target.skewX,\n skewY: target.skewY,\n offsetX: pointer.x - target.left,\n offsetY: pointer.y - target.top,\n originX: origin.x,\n originY: origin.y,\n ex: pointer.x,\n ey: pointer.y,\n lastX: pointer.x,\n lastY: pointer.y,\n theta: degreesToRadians(target.angle),\n width: target.width,\n height: target.height,\n shiftKey: e.shiftKey,\n altKey,\n original: {\n ...saveObjectTransform(target),\n originX: origin.x,\n originY: origin.y,\n },\n };\n\n this._currentTransform = transform;\n\n this.fire('before:transform', {\n e,\n transform,\n });\n }\n\n /**\n * Set the cursor type of the canvas element\n * @param {String} value Cursor type of the canvas element.\n * @see http://www.w3.org/TR/css3-ui/#cursor\n */\n setCursor(value: CSSStyleDeclaration['cursor']): void {\n this.upperCanvasEl.style.cursor = value;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx to draw the selection on\n */\n _drawSelection(ctx: CanvasRenderingContext2D): void {\n const { x, y, deltaX, deltaY } = this._groupSelector!,\n start = new Point(x, y).transform(this.viewportTransform),\n extent = new Point(x + deltaX, y + deltaY).transform(\n this.viewportTransform,\n ),\n strokeOffset = this.selectionLineWidth / 2;\n let minX = Math.min(start.x, extent.x),\n minY = Math.min(start.y, extent.y),\n maxX = Math.max(start.x, extent.x),\n maxY = Math.max(start.y, extent.y);\n\n if (this.selectionColor) {\n ctx.fillStyle = this.selectionColor;\n ctx.fillRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n if (!this.selectionLineWidth || !this.selectionBorderColor) {\n return;\n }\n ctx.lineWidth = this.selectionLineWidth;\n ctx.strokeStyle = this.selectionBorderColor;\n\n minX += strokeOffset;\n minY += strokeOffset;\n maxX -= strokeOffset;\n maxY -= strokeOffset;\n // selection border\n // @TODO: is _setLineDash still necessary on modern canvas?\n FabricObject.prototype._setLineDash.call(\n this,\n ctx,\n this.selectionDashArray,\n );\n ctx.strokeRect(minX, minY, maxX - minX, maxY - minY);\n }\n\n /**\n * Method that determines what object we are clicking on\n * 11/09/2018 TODO: would be cool if findTarget could discern between being a full target\n * or the outside part of the corner.\n * @param {Event} e mouse event\n * @return {FabricObject | null} the target found\n */\n findTarget(e: TPointerEvent): FabricObject | undefined {\n if (this.skipTargetFind) {\n return undefined;\n }\n\n const pointer = this.getViewportPoint(e),\n activeObject = this._activeObject,\n aObjects = this.getActiveObjects();\n\n this.targets = [];\n\n if (activeObject && aObjects.length >= 1) {\n if (activeObject.findControl(pointer, isTouchEvent(e))) {\n // if we hit the corner of the active object, let's return that.\n return activeObject;\n } else if (\n aObjects.length > 1 &&\n // check pointer is over active selection and possibly perform `subTargetCheck`\n this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active selection does not select sub targets like normal groups\n return activeObject;\n } else if (\n activeObject === this.searchPossibleTargets([activeObject], pointer)\n ) {\n // active object is not an active selection\n if (!this.preserveObjectStacking) {\n return activeObject;\n } else {\n const subTargets = this.targets;\n this.targets = [];\n const target = this.searchPossibleTargets(this._objects, pointer);\n if (\n e[this.altSelectionKey as ModifierKey] &&\n target &&\n target !== activeObject\n ) {\n // alt selection: select active object even though it is not the top most target\n // restore targets\n this.targets = subTargets;\n return activeObject;\n }\n return target;\n }\n }\n }\n\n return this.searchPossibleTargets(this._objects, pointer);\n }\n\n /**\n * Checks if the point is inside the object selection area including padding\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point in scene coordinates\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n private _pointIsInObjectSelectionArea(obj: FabricObject, point: Point) {\n // getCoords will already take care of group de-nesting\n let coords = obj.getCoords();\n const viewportZoom = this.getZoom();\n const padding = obj.padding / viewportZoom;\n if (padding) {\n const [tl, tr, br, bl] = coords;\n // what is the angle of the object?\n // we could use getTotalAngle, but is way easier to look at it\n // from how coords are oriented, since if something went wrong\n // at least we are consistent.\n const angleRadians = Math.atan2(tr.y - tl.y, tr.x - tl.x),\n cosP = cos(angleRadians) * padding,\n sinP = sin(angleRadians) * padding,\n cosPSinP = cosP + sinP,\n cosPMinusSinP = cosP - sinP;\n\n coords = [\n new Point(tl.x - cosPMinusSinP, tl.y - cosPSinP),\n new Point(tr.x + cosPSinP, tr.y - cosPMinusSinP),\n new Point(br.x + cosPMinusSinP, br.y + cosPSinP),\n new Point(bl.x - cosPSinP, bl.y + cosPMinusSinP),\n ];\n // in case of padding we calculate the new coords on the fly.\n // otherwise we have to maintain 2 sets of coordinates for everything.\n // we can reiterate on storing them.\n // if this is slow, for now the semplification is large and doesn't impact\n // rendering.\n // the idea behind this is that outside target check we don't need ot know\n // where those coords are\n }\n return Intersection.isPointInPolygon(point, coords);\n }\n\n /**\n * Checks point is inside the object selection condition. Either area with padding\n * or over pixels if perPixelTargetFind is enabled\n * @param {FabricObject} obj Object to test against\n * @param {Object} [pointer] point from viewport.\n * @return {Boolean} true if point is contained within an area of given object\n * @private\n */\n _checkTarget(obj: FabricObject, pointer: Point): boolean {\n if (\n obj &&\n obj.visible &&\n obj.evented &&\n this._pointIsInObjectSelectionArea(\n obj,\n sendPointToPlane(pointer, undefined, this.viewportTransform),\n )\n ) {\n if (\n (this.perPixelTargetFind || obj.perPixelTargetFind) &&\n !(obj as unknown as IText).isEditing\n ) {\n if (!this.isTargetTransparent(obj, pointer.x, pointer.y)) {\n return true;\n }\n } else {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Internal Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @param {Array} [objects] objects array to look into\n * @param {Object} [pointer] x,y object of point coordinates we want to check.\n * @return {FabricObject} **top most object from given `objects`** that contains pointer\n * @private\n */\n _searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n // Cache all targets where their bounding box contains point.\n let i = objects.length;\n // Do not check for currently grouped objects, since we check the parent group itself.\n // until we call this function specifically to search inside the activeGroup\n while (i--) {\n const target = objects[i];\n if (this._checkTarget(target, pointer)) {\n if (isCollection(target) && target.subTargetCheck) {\n const subTarget = this._searchPossibleTargets(\n target._objects as FabricObject[],\n pointer,\n );\n subTarget && this.targets.push(subTarget);\n }\n return target;\n }\n }\n }\n\n /**\n * Function used to search inside objects an object that contains pointer in bounding box or that contains pointerOnCanvas when painted\n * @see {@link _searchPossibleTargets}\n * @param {FabricObject[]} [objects] objects array to look into\n * @param {Point} [pointer] coordinates from viewport to check.\n * @return {FabricObject} **top most object on screen** that contains pointer\n */\n searchPossibleTargets(\n objects: FabricObject[],\n pointer: Point,\n ): FabricObject | undefined {\n const target = this._searchPossibleTargets(objects, pointer);\n\n // if we found something in this.targets, and the group is interactive, return the innermost subTarget\n // that is still interactive\n // TODO: reverify why interactive. the target should be returned always, but selected only\n // if interactive.\n if (\n target &&\n isCollection(target) &&\n target.interactive &&\n this.targets[0]\n ) {\n /** targets[0] is the innermost nested target, but it could be inside non interactive groups and so not a selection target */\n const targets = this.targets;\n for (let i = targets.length - 1; i > 0; i--) {\n const t = targets[i];\n if (!(isCollection(t) && t.interactive)) {\n // one of the subtargets was not interactive. that is the last subtarget we can return.\n // we can't dig more deep;\n return t;\n }\n }\n return targets[0];\n }\n\n return target;\n }\n\n /**\n * @returns point existing in the same plane as the {@link HTMLCanvasElement},\n * `(0, 0)` being the top left corner of the {@link HTMLCanvasElement}.\n * This means that changes to the {@link viewportTransform} do not change the values of the point\n * and it remains unchanged from the viewer's perspective.\n *\n * @example\n * const scenePoint = sendPointToPlane(\n * this.getViewportPoint(e),\n * undefined,\n * canvas.viewportTransform\n * );\n *\n */\n getViewportPoint(e: TPointerEvent) {\n if (this._pointer) {\n return this._pointer;\n }\n return this.getPointer(e, true);\n }\n\n /**\n * @returns point existing in the scene (the same plane as the plane {@link FabricObject#getCenterPoint} exists in).\n * This means that changes to the {@link viewportTransform} do not change the values of the point,\n * however, from the viewer's perspective, the point is changed.\n *\n * @example\n * const viewportPoint = sendPointToPlane(\n * this.getScenePoint(e),\n * canvas.viewportTransform\n * );\n *\n */\n getScenePoint(e: TPointerEvent) {\n if (this._absolutePointer) {\n return this._absolutePointer;\n }\n return this.getPointer(e);\n }\n\n /**\n * Returns pointer relative to canvas.\n *\n * @deprecated This method is deprecated since v6 to protect you from misuse.\n * Use {@link getViewportPoint} or {@link getScenePoint} instead.\n *\n * @param {Event} e\n * @param {Boolean} [fromViewport] whether to return the point from the viewport or in the scene\n * @return {Point}\n */\n getPointer(e: TPointerEvent, fromViewport = false): Point {\n const upperCanvasEl = this.upperCanvasEl,\n bounds = upperCanvasEl.getBoundingClientRect();\n let pointer = getPointer(e),\n boundsWidth = bounds.width || 0,\n boundsHeight = bounds.height || 0;\n\n if (!boundsWidth || !boundsHeight) {\n if (TOP in bounds && BOTTOM in bounds) {\n boundsHeight = Math.abs(bounds.top - bounds.bottom);\n }\n if (RIGHT in bounds && LEFT in bounds) {\n boundsWidth = Math.abs(bounds.right - bounds.left);\n }\n }\n\n this.calcOffset();\n pointer.x = pointer.x - this._offset.left;\n pointer.y = pointer.y - this._offset.top;\n if (!fromViewport) {\n pointer = sendPointToPlane(pointer, undefined, this.viewportTransform);\n }\n\n const retinaScaling = this.getRetinaScaling();\n if (retinaScaling !== 1) {\n pointer.x /= retinaScaling;\n pointer.y /= retinaScaling;\n }\n\n // If bounds are not available (i.e. not visible), do not apply scale.\n const cssScale =\n boundsWidth === 0 || boundsHeight === 0\n ? new Point(1, 1)\n : new Point(\n upperCanvasEl.width / boundsWidth,\n upperCanvasEl.height / boundsHeight,\n );\n\n return pointer.multiply(cssScale);\n }\n\n /**\n * Internal use only\n * @protected\n */\n protected _setDimensionsImpl(\n dimensions: TSize,\n options?: TCanvasSizeOptions,\n ) {\n // @ts-expect-error this method exists in the subclass - should be moved or declared as abstract\n this._resetTransformEventData();\n super._setDimensionsImpl(dimensions, options);\n if (this._isCurrentlyDrawing) {\n this.freeDrawingBrush &&\n this.freeDrawingBrush._setBrushStyles(this.contextTop);\n }\n }\n\n protected _createCacheCanvas() {\n this.pixelFindCanvasEl = createCanvasElement();\n this.pixelFindContext = this.pixelFindCanvasEl.getContext('2d', {\n willReadFrequently: true,\n })!;\n this.setTargetFindTolerance(this.targetFindTolerance);\n }\n\n /**\n * Returns context of top canvas where interactions are drawn\n * @returns {CanvasRenderingContext2D}\n */\n getTopContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns context of canvas where object selection is drawn\n * @alias\n * @return {CanvasRenderingContext2D}\n */\n getSelectionContext(): CanvasRenderingContext2D {\n return this.elements.upper.ctx;\n }\n\n /**\n * Returns <canvas> element on which object selection is drawn\n * @return {HTMLCanvasElement}\n */\n getSelectionElement(): HTMLCanvasElement {\n return this.elements.upper.el;\n }\n\n /**\n * Returns currently active object\n * @return {FabricObject | null} active object\n */\n getActiveObject(): FabricObject | undefined {\n return this._activeObject;\n }\n\n /**\n * Returns an array with the current selected objects\n * @return {FabricObject[]} active objects array\n */\n getActiveObjects(): FabricObject[] {\n const active = this._activeObject;\n return isActiveSelection(active)\n ? active.getObjects()\n : active\n ? [active]\n : [];\n }\n\n /**\n * @private\n * Compares the old activeObject with the current one and fires correct events\n * @param {FabricObject[]} oldObjects old activeObject\n * @param {TPointerEvent} e mouse event triggering the selection events\n */\n _fireSelectionEvents(oldObjects: FabricObject[], e?: TPointerEvent) {\n let somethingChanged = false,\n invalidate = false;\n const objects = this.getActiveObjects(),\n added: FabricObject[] = [],\n removed: FabricObject[] = [];\n\n oldObjects.forEach((target) => {\n if (!objects.includes(target)) {\n somethingChanged = true;\n target.fire('deselected', {\n e,\n target,\n });\n removed.push(target);\n }\n });\n\n objects.forEach((target) => {\n if (!oldObjects.includes(target)) {\n somethingChanged = true;\n target.fire('selected', {\n e,\n target,\n });\n added.push(target);\n }\n });\n\n if (oldObjects.length > 0 && objects.length > 0) {\n invalidate = true;\n somethingChanged &&\n this.fire('selection:updated', {\n e,\n selected: added,\n deselected: removed,\n });\n } else if (objects.length > 0) {\n invalidate = true;\n this.fire('selection:created', {\n e,\n selected: added,\n });\n } else if (oldObjects.length > 0) {\n invalidate = true;\n this.fire('selection:cleared', {\n e,\n deselected: removed,\n });\n }\n invalidate && (this._objectsToRender = undefined);\n }\n\n /**\n * Sets given object as the only active object on canvas\n * @param {FabricObject} object Object to set as an active one\n * @param {TPointerEvent} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n setActiveObject(object: FabricObject, e?: TPointerEvent) {\n // we can't inline this, since _setActiveObject will change what getActiveObjects returns\n const currentActives = this.getActiveObjects();\n const selected = this._setActiveObject(object, e);\n this._fireSelectionEvents(currentActives, e);\n return selected;\n }\n\n /**\n * This is supposed to be equivalent to setActiveObject but without firing\n * any event. There is commitment to have this stay this way.\n * This is the functional part of setActiveObject.\n * @param {Object} object to set as active\n * @param {Event} [e] Event (passed along when firing \"object:selected\")\n * @return {Boolean} true if the object has been selected\n */\n _setActiveObject(object: FabricObject, e?: TPointerEvent) {\n const prevActiveObject = this._activeObject;\n if (prevActiveObject === object) {\n return false;\n }\n // after calling this._discardActiveObject, this,_activeObject could be undefined\n if (!this._discardActiveObject(e, object) && this._activeObject) {\n // refused to deselect\n return false;\n }\n if (object.onSelect({ e })) {\n return false;\n }\n\n this._activeObject = object;\n\n if (isActiveSelection(object) && prevActiveObject !== object) {\n object.set('canvas', this);\n }\n object.setCoords();\n\n return true;\n }\n\n /**\n * This is supposed to be equivalent to discardActiveObject but without firing\n * any selection events ( can still fire object transformation events ). There is commitment to have this stay this way.\n * This is the functional part of discardActiveObject.\n * @param {Event} [e] Event (passed along when firing \"object:deselected\")\n * @param {Object} object the next object to set as active, reason why we are discarding this\n * @return {Boolean} true if the active object has been discarded\n */\n _discardActiveObject(\n e?: TPointerEvent,\n object?: FabricObject,\n ): this is { _activeObject: undefined } {\n const obj = this._activeObject;\n if (obj) {\n // onDeselect return TRUE to cancel selection;\n if (obj.onDeselect({ e, object })) {\n return false;\n }\n if (this._currentTransform && this._currentTransform.target === obj) {\n this.endCurrentTransform(e);\n }\n if (isActiveSelection(obj) && obj === this._hoveredTarget) {\n this._hoveredTarget = undefined;\n }\n this._activeObject = undefined;\n return true;\n }\n return false;\n }\n\n /**\n * Discards currently active object and fire events. If the function is called by fabric\n * as a consequence of a mouse event, the event is passed as a parameter and\n * sent to the fire function for the custom events. When used as a method the\n * e param does not have any application.\n * @param {event} e\n * @return {Boolean} true if the active object has been discarded\n */\n discardActiveObject(e?: TPointerEvent): this is { _activeObject: undefined } {\n const currentActives = this.getActiveObjects(),\n activeObject = this.getActiveObject();\n if (currentActives.length) {\n this.fire('before:selection:cleared', {\n e,\n deselected: [activeObject!],\n });\n }\n const discarded = this._discardActiveObject(e);\n this._fireSelectionEvents(currentActives, e);\n return discarded;\n }\n\n /**\n * End the current transform.\n * You don't usually need to call this method unless you are interrupting a user initiated transform\n * because of some other event ( a press of key combination, or something that block the user UX )\n * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event\n */\n endCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform;\n this._finalizeCurrentTransform(e);\n if (transform && transform.target) {\n // this could probably go inside _finalizeCurrentTransform\n transform.target.isMoving = false;\n }\n this._currentTransform = null;\n }\n\n /**\n * @private\n * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event\n */\n _finalizeCurrentTransform(e?: TPointerEvent) {\n const transform = this._currentTransform!,\n target = transform.target,\n options = {\n e,\n target,\n transform,\n action: transform.action,\n };\n\n if (target._scaling) {\n target._scaling = false;\n }\n\n target.setCoords();\n\n if (transform.actionPerformed) {\n this.fire('object:modified', options);\n target.fire(MODIFIED, options);\n }\n }\n\n /**\n * Sets viewport transformation of this canvas instance\n * @param {Array} vpt a Canvas 2D API transform matrix\n */\n setViewportTransform(vpt: TMat2D) {\n super.setViewportTransform(vpt);\n const activeObject = this._activeObject;\n if (activeObject) {\n activeObject.setCoords();\n }\n }\n\n /**\n * @override clears active selection ref and interactive canvas elements and contexts\n */\n destroy() {\n // dispose of active selection\n const activeObject = this._activeObject;\n if (isActiveSelection(activeObject)) {\n activeObject.removeAll();\n activeObject.dispose();\n }\n\n delete this._activeObject;\n\n super.destroy();\n\n // free resources\n\n // pixel find canvas\n // @ts-expect-error disposing\n this.pixelFindContext = null;\n // @ts-expect-error disposing\n this.pixelFindCanvasEl = undefined;\n }\n\n /**\n * Clears all contexts (background, main, top) of an instance\n */\n clear() {\n // discard active object and fire events\n this.discardActiveObject();\n // make sure we clear the active object in case it refused to be discarded\n this._activeObject = undefined;\n this.clearContext(this.contextTop);\n super.clear();\n }\n\n /**\n * Draws objects' controls (borders/controls)\n * @param {CanvasRenderingContext2D} ctx Context to render controls on\n */\n drawControls(ctx: CanvasRenderingContext2D) {\n const activeObject = this._activeObject;\n\n if (activeObject) {\n activeObject._renderControls(ctx);\n }\n }\n\n /**\n * @private\n */\n protected _toObject(\n instance: FabricObject,\n methodName: 'toObject' | 'toDatalessObject',\n propertiesToInclude: string[],\n ): Record {\n // If the object is part of the current selection group, it should\n // be transformed appropriately\n // i.e. it should be serialised as it would appear if the selection group\n // were to be destroyed.\n const originalProperties = this._realizeGroupTransformOnObject(instance),\n object = super._toObject(instance, methodName, propertiesToInclude);\n //Undo the damage we did by changing all of its properties\n instance.set(originalProperties);\n return object;\n }\n\n /**\n * Realizes an object's group transformation on it\n * @private\n * @param {FabricObject} [instance] the object to transform (gets mutated)\n * @returns the original values of instance which were changed\n */\n private _realizeGroupTransformOnObject(\n instance: FabricObject,\n ): Partial {\n const { group } = instance;\n if (group && isActiveSelection(group) && this._activeObject === group) {\n const layoutProps = [\n 'angle',\n 'flipX',\n 'flipY',\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n ] as (keyof typeof instance)[];\n const originalValues = pick(instance, layoutProps);\n addTransformToObject(instance, group.calcOwnMatrix());\n return originalValues;\n } else {\n return {};\n }\n }\n\n /**\n * @private\n */\n _setSVGObject(\n markup: string[],\n instance: FabricObject,\n reviver?: TSVGReviver,\n ) {\n // If the object is in a selection group, simulate what would happen to that\n // object when the group is deselected\n const originalProperties = this._realizeGroupTransformOnObject(instance);\n super._setSVGObject(markup, instance, reviver);\n instance.set(originalProperties);\n }\n}\n","import type { TPointerEvent } from '../EventTypeDefs';\nimport type { ITextBehavior } from '../shapes/IText/ITextBehavior';\nimport { removeFromArray } from '../util/internals/removeFromArray';\nimport type { Canvas } from './Canvas';\n\n/**\n * In charge of synchronizing all interactive text instances of a canvas\n */\nexport class TextEditingManager {\n private targets: ITextBehavior[] = [];\n private declare target?: ITextBehavior;\n private __disposer: VoidFunction;\n\n constructor(canvas: Canvas) {\n const cb = () => {\n const { hiddenTextarea } =\n (canvas.getActiveObject() as ITextBehavior) || {};\n hiddenTextarea && hiddenTextarea.focus();\n };\n const el = canvas.upperCanvasEl;\n el.addEventListener('click', cb);\n this.__disposer = () => el.removeEventListener('click', cb);\n }\n\n exitTextEditing() {\n this.target = undefined;\n this.targets.forEach((target) => {\n if (target.isEditing) {\n target.exitEditing();\n }\n });\n }\n\n add(target: ITextBehavior) {\n this.targets.push(target);\n }\n\n remove(target: ITextBehavior) {\n this.unregister(target);\n removeFromArray(this.targets, target);\n }\n\n register(target: ITextBehavior) {\n this.target = target;\n }\n\n unregister(target: ITextBehavior) {\n if (target === this.target) {\n this.target = undefined;\n }\n }\n\n onMouseMove(e: TPointerEvent) {\n this.target?.isEditing && this.target.updateSelectionOnMouseMove(e);\n }\n\n clear() {\n this.targets = [];\n this.target = undefined;\n }\n\n dispose() {\n this.clear();\n this.__disposer();\n // @ts-expect-error disposing\n delete this.__disposer;\n }\n}\n","import { classRegistry } from '../ClassRegistry';\nimport { NONE } from '../constants';\nimport type {\n CanvasEvents,\n DragEventData,\n ObjectEvents,\n TPointerEvent,\n TPointerEventNames,\n Transform,\n} from '../EventTypeDefs';\nimport { Point } from '../Point';\nimport type { ActiveSelection } from '../shapes/ActiveSelection';\nimport type { Group } from '../shapes/Group';\nimport type { IText } from '../shapes/IText/IText';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { isTouchEvent, stopEvent } from '../util/dom_event';\nimport { getDocumentFromElement, getWindowFromElement } from '../util/dom_misc';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { isActiveSelection } from '../util/typeAssertions';\nimport type { CanvasOptions, TCanvasOptions } from './CanvasOptions';\nimport { SelectableCanvas } from './SelectableCanvas';\nimport { TextEditingManager } from './TextEditingManager';\n\nconst addEventOptions = { passive: false } as EventListenerOptions;\n\nconst getEventPoints = (canvas: Canvas, e: TPointerEvent) => {\n const viewportPoint = canvas.getViewportPoint(e);\n const scenePoint = canvas.getScenePoint(e);\n return {\n viewportPoint,\n scenePoint,\n pointer: viewportPoint,\n absolutePointer: scenePoint,\n };\n};\n\n// just to be clear, the utils are now deprecated and those are here exactly as minifier helpers\n// because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.\n// few bytes but why give it away.\nconst addListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.addEventListener(...args);\nconst removeListener = (\n el: HTMLElement | Document,\n ...args: Parameters\n) => el.removeEventListener(...args);\n\nconst syntheticEventConfig = {\n mouse: {\n in: 'over',\n out: 'out',\n targetIn: 'mouseover',\n targetOut: 'mouseout',\n canvasIn: 'mouse:over',\n canvasOut: 'mouse:out',\n },\n drag: {\n in: 'enter',\n out: 'leave',\n targetIn: 'dragenter',\n targetOut: 'dragleave',\n canvasIn: 'drag:enter',\n canvasOut: 'drag:leave',\n },\n} as const;\n\ntype TSyntheticEventContext = {\n mouse: { e: TPointerEvent };\n drag: DragEventData;\n};\n\nexport class Canvas extends SelectableCanvas implements CanvasOptions {\n /**\n * Contains the id of the touch event that owns the fabric transform\n * @type Number\n * @private\n */\n declare mainTouchId?: number;\n\n declare enablePointerEvents: boolean;\n\n /**\n * Holds a reference to a setTimeout timer for event synchronization\n * @type number\n * @private\n */\n private declare _willAddMouseDown: number;\n\n /**\n * Holds a reference to an object on the canvas that is receiving the drag over event.\n * @type FabricObject\n * @private\n */\n private declare _draggedoverTarget?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas from where the drag operation started\n * @type FabricObject\n * @private\n */\n private declare _dragSource?: FabricObject;\n\n /**\n * Holds a reference to an object on the canvas that is the current drop target\n * May differ from {@link _draggedoverTarget}\n * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow\n * @type FabricObject\n * @private\n */\n private declare _dropTarget: FabricObject | undefined;\n\n private _isClick: boolean;\n\n textEditingManager = new TextEditingManager(this);\n\n constructor(el?: string | HTMLCanvasElement, options: TCanvasOptions = {}) {\n super(el, options);\n // bind event handlers\n (\n [\n '_onMouseDown',\n '_onTouchStart',\n '_onMouseMove',\n '_onMouseUp',\n '_onTouchEnd',\n '_onResize',\n // '_onGesture',\n // '_onDrag',\n // '_onShake',\n // '_onLongPress',\n // '_onOrientationChange',\n '_onMouseWheel',\n '_onMouseOut',\n '_onMouseEnter',\n '_onContextMenu',\n '_onDoubleClick',\n '_onDragStart',\n '_onDragEnd',\n '_onDragProgress',\n '_onDragOver',\n '_onDragEnter',\n '_onDragLeave',\n '_onDrop',\n ] as (keyof this)[]\n ).forEach((eventHandler) => {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n this[eventHandler] = (this[eventHandler] as Function).bind(this);\n });\n // register event handlers\n this.addOrRemove(addListener, 'add');\n }\n\n /**\n * return an event prefix pointer or mouse.\n * @private\n */\n private _getEventPrefix() {\n return this.enablePointerEvents ? 'pointer' : 'mouse';\n }\n\n addOrRemove(functor: any, _eventjsFunctor: 'add' | 'remove') {\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n functor(getWindowFromElement(canvasElement), 'resize', this._onResize);\n functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);\n functor(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove,\n addEventOptions,\n );\n functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);\n functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);\n functor(canvasElement, 'wheel', this._onMouseWheel);\n functor(canvasElement, 'contextmenu', this._onContextMenu);\n functor(canvasElement, 'dblclick', this._onDoubleClick);\n functor(canvasElement, 'dragstart', this._onDragStart);\n functor(canvasElement, 'dragend', this._onDragEnd);\n functor(canvasElement, 'dragover', this._onDragOver);\n functor(canvasElement, 'dragenter', this._onDragEnter);\n functor(canvasElement, 'dragleave', this._onDragLeave);\n functor(canvasElement, 'drop', this._onDrop);\n if (!this.enablePointerEvents) {\n functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);\n }\n // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {\n // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);\n // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);\n // eventjs[eventjsFunctor](\n // canvasElement,\n // 'orientation',\n // this._onOrientationChange\n // );\n // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);\n // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);\n // }\n }\n\n /**\n * Removes all event listeners\n */\n removeListeners() {\n this.addOrRemove(removeListener, 'remove');\n // if you dispose on a mouseDown, before mouse up, you need to clean document to...\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} [e] Event object fired on wheel event\n */\n private _onMouseWheel(e: MouseEvent) {\n this.__onMouseWheel(e);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onMouseOut(e: TPointerEvent) {\n const target = this._hoveredTarget;\n const shared = {\n e,\n ...getEventPoints(this, e),\n };\n this.fire('mouse:out', { ...shared, target });\n this._hoveredTarget = undefined;\n target && target.fire('mouseout', { ...shared });\n this._hoveredTargets.forEach((nestedTarget) => {\n this.fire('mouse:out', { ...shared, target: nestedTarget });\n nestedTarget && nestedTarget.fire('mouseout', { ...shared });\n });\n this._hoveredTargets = [];\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseenter\n */\n private _onMouseEnter(e: TPointerEvent) {\n // This find target and consequent 'mouse:over' is used to\n // clear old instances on hovered target.\n // calling findTarget has the side effect of killing target.__corner.\n // as a short term fix we are not firing this if we are currently transforming.\n // as a long term fix we need to separate the action of finding a target with the\n // side effects we added to it.\n if (!this._currentTransform && !this.findTarget(e)) {\n this.fire('mouse:over', {\n e,\n ...getEventPoints(this, e),\n });\n this._hoveredTarget = undefined;\n this._hoveredTargets = [];\n }\n }\n\n /**\n * supports native like text dragging\n * @private\n * @param {DragEvent} e\n */\n private _onDragStart(e: DragEvent) {\n this._isClick = false;\n const activeObject = this.getActiveObject();\n if (activeObject && activeObject.onDragStart(e)) {\n this._dragSource = activeObject;\n const options = { e, target: activeObject };\n this.fire('dragstart', options);\n activeObject.fire('dragstart', options);\n addListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n return;\n }\n stopEvent(e);\n }\n\n /**\n * First we clear top context where the effects are being rendered.\n * Then we render the effects.\n * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.\n * @private\n */\n private _renderDragEffects(\n e: DragEvent,\n source?: FabricObject,\n target?: FabricObject,\n ) {\n let dirty = false;\n // clear top context\n const dropTarget = this._dropTarget;\n if (dropTarget && dropTarget !== source && dropTarget !== target) {\n dropTarget.clearContextTop();\n dirty = true;\n }\n source?.clearContextTop();\n target !== source && target?.clearContextTop();\n // render effects\n const ctx = this.contextTop;\n ctx.save();\n ctx.transform(...this.viewportTransform);\n if (source) {\n ctx.save();\n source.transform(ctx);\n source.renderDragSourceEffect(e);\n ctx.restore();\n dirty = true;\n }\n if (target) {\n ctx.save();\n target.transform(ctx);\n target.renderDropTargetEffect(e);\n ctx.restore();\n dirty = true;\n }\n ctx.restore();\n dirty && (this.contextTopDirty = true);\n }\n\n /**\n * supports native like text dragging\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n * @private\n * @param {DragEvent} e\n */\n private _onDragEnd(e: DragEvent) {\n const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== NONE,\n dropTarget = didDrop ? this._activeObject : undefined,\n options = {\n e,\n target: this._dragSource as FabricObject,\n subTargets: this.targets,\n dragSource: this._dragSource as FabricObject,\n didDrop,\n dropTarget: dropTarget as FabricObject,\n };\n removeListener(\n this.upperCanvasEl,\n 'drag',\n this._onDragProgress as EventListener,\n );\n this.fire('dragend', options);\n this._dragSource && this._dragSource.fire('dragend', options);\n delete this._dragSource;\n // we need to call mouse up synthetically because the browser won't\n this._onMouseUp(e);\n }\n\n /**\n * fire `drag` event on canvas and drag source\n * @private\n * @param {DragEvent} e\n */\n private _onDragProgress(e: DragEvent) {\n const options = {\n e,\n target: this._dragSource as FabricObject | undefined,\n dragSource: this._dragSource as FabricObject | undefined,\n dropTarget: this._draggedoverTarget as FabricObject,\n };\n this.fire('drag', options);\n this._dragSource && this._dragSource.fire('drag', options);\n }\n\n /**\n * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.\n * Override at will\n */\n protected findDragTargets(e: DragEvent) {\n this.targets = [];\n const target = this._searchPossibleTargets(\n this._objects,\n this.getViewportPoint(e),\n );\n return {\n target,\n targets: [...this.targets],\n };\n }\n\n /**\n * prevent default to allow drop event to be fired\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets\n * @private\n * @param {DragEvent} [e] Event object fired on Event.js shake\n */\n private _onDragOver(e: DragEvent) {\n const eventType = 'dragover';\n const { target, targets } = this.findDragTargets(e);\n const dragSource = this._dragSource as FabricObject;\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource,\n canDrop: false,\n dropTarget: undefined,\n };\n let dropTarget;\n // fire on canvas\n this.fire(eventType, options);\n // make sure we fire dragenter events before dragover\n // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it\n this._fireEnterLeaveEvents(target, options);\n if (target) {\n if (target.canDrop(e)) {\n dropTarget = target;\n }\n target.fire(eventType, options);\n }\n // propagate the event to subtargets\n for (let i = 0; i < targets.length; i++) {\n const subTarget = targets[i];\n // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)\n // TODO: verify if those should loop in inverse order then?\n // what is the order of subtargets?\n if (subTarget.canDrop(e)) {\n dropTarget = subTarget;\n }\n subTarget.fire(eventType, options);\n }\n // render drag effects now that relations between source and target is clear\n this._renderDragEffects(e, dragSource, dropTarget);\n this._dropTarget = dropTarget;\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragEnter(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n };\n this.fire('dragenter', options);\n // fire dragenter on targets\n this._fireEnterLeaveEvents(target, options);\n }\n\n /**\n * fire `dragleave` on `dragover` targets\n * @private\n * @param {Event} [e] Event object fired on Event.js shake\n */\n private _onDragLeave(e: DragEvent) {\n const options = {\n e,\n target: this._draggedoverTarget,\n subTargets: this.targets,\n dragSource: this._dragSource,\n };\n this.fire('dragleave', options);\n\n // fire dragleave on targets\n this._fireEnterLeaveEvents(undefined, options);\n this._renderDragEffects(e, this._dragSource);\n this._dropTarget = undefined;\n // clear targets\n this.targets = [];\n this._hoveredTargets = [];\n }\n\n /**\n * `drop:before` is a an event that allows you to schedule logic\n * before the `drop` event. Prefer `drop` event always, but if you need\n * to run some drop-disabling logic on an event, since there is no way\n * to handle event handlers ordering, use `drop:before`\n * @private\n * @param {Event} e\n */\n private _onDrop(e: DragEvent) {\n const { target, targets } = this.findDragTargets(e);\n const options = this._basicEventHandler('drop:before', {\n e,\n target,\n subTargets: targets,\n dragSource: this._dragSource,\n ...getEventPoints(this, e),\n });\n // will be set by the drop target\n options.didDrop = false;\n // will be set by the drop target, used in case options.target refuses the drop\n options.dropTarget = undefined;\n // fire `drop`\n this._basicEventHandler('drop', options);\n // inform canvas of the drop\n // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it\n // use for side effects\n this.fire('drop:after', options);\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onContextMenu(e: TPointerEvent): false {\n const target = this.findTarget(e),\n subTargets = this.targets || [];\n const options = this._basicEventHandler('contextmenu:before', {\n e,\n target,\n subTargets,\n });\n // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves\n this.stopContextMenu && stopEvent(e);\n this._basicEventHandler('contextmenu', options);\n return false;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n private _onDoubleClick(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'dblclick');\n this._resetTransformEventData();\n }\n\n /**\n * Return a the id of an event.\n * returns either the pointerId or the identifier or 0 for the mouse event\n * @private\n * @param {Event} evt Event object\n */\n getPointerId(evt: TouchEvent | PointerEvent): number {\n const changedTouches = (evt as TouchEvent).changedTouches;\n\n if (changedTouches) {\n return changedTouches[0] && changedTouches[0].identifier;\n }\n\n if (this.enablePointerEvents) {\n return (evt as PointerEvent).pointerId;\n }\n\n return -1;\n }\n\n /**\n * Determines if an event has the id of the event that is considered main\n * @private\n * @param {evt} event Event object\n */\n _isMainEvent(evt: TPointerEvent): boolean {\n if ((evt as PointerEvent).isPrimary === true) {\n return true;\n }\n if ((evt as PointerEvent).isPrimary === false) {\n return false;\n }\n if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {\n return true;\n }\n if ((evt as TouchEvent).changedTouches) {\n return (\n (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId\n );\n }\n return true;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchStart(e: TouchEvent) {\n e.preventDefault();\n if (this.mainTouchId === undefined) {\n this.mainTouchId = this.getPointerId(e);\n }\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(canvasElement);\n addListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n addListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n // Unbind mousedown to prevent double triggers from touch devices\n removeListener(\n canvasElement,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDown(e: TPointerEvent) {\n this.__onMouseDown(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n removeListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n const doc = getDocumentFromElement(canvasElement);\n addListener(doc, `${eventTypePrefix}up`, this._onMouseUp as EventListener);\n addListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onTouchEnd(e: TouchEvent) {\n if (e.touches.length > 0) {\n // if there are still touches stop here\n return;\n }\n this.__onMouseUp(e);\n this._resetTransformEventData();\n delete this.mainTouchId;\n const eventTypePrefix = this._getEventPrefix();\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n 'touchend',\n this._onTouchEnd as EventListener,\n addEventOptions,\n );\n removeListener(\n doc,\n 'touchmove',\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n if (this._willAddMouseDown) {\n clearTimeout(this._willAddMouseDown);\n }\n this._willAddMouseDown = setTimeout(() => {\n // Wait 400ms before rebinding mousedown to prevent double triggers\n // from touch devices\n addListener(\n this.upperCanvasEl,\n `${eventTypePrefix}down`,\n this._onMouseDown as EventListener,\n );\n this._willAddMouseDown = 0;\n }, 400) as unknown as number;\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUp(e: TPointerEvent) {\n this.__onMouseUp(e);\n this._resetTransformEventData();\n const canvasElement = this.upperCanvasEl,\n eventTypePrefix = this._getEventPrefix();\n if (this._isMainEvent(e)) {\n const doc = getDocumentFromElement(this.upperCanvasEl);\n removeListener(\n doc,\n `${eventTypePrefix}up`,\n this._onMouseUp as EventListener,\n );\n removeListener(\n doc,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n addListener(\n canvasElement,\n `${eventTypePrefix}move`,\n this._onMouseMove as EventListener,\n addEventOptions,\n );\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMove(e: TPointerEvent) {\n const activeObject = this.getActiveObject();\n !this.allowTouchScrolling &&\n (!activeObject ||\n // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before\n // we must not prevent the event's default behavior in order for the window to start dragging\n !activeObject.shouldStartDragging(e)) &&\n e.preventDefault &&\n e.preventDefault();\n this.__onMouseMove(e);\n }\n\n /**\n * @private\n */\n _onResize() {\n this.calcOffset();\n this._resetTransformEventData();\n }\n\n /**\n * Decides whether the canvas should be redrawn in mouseup and mousedown events.\n * @private\n * @param {Object} target\n */\n _shouldRender(target: FabricObject | undefined) {\n const activeObject = this.getActiveObject();\n // if just one of them is available or if they are both but are different objects\n // this covers: switch of target, from target to no target, selection of target\n // multiSelection with key and mouse\n return (\n !!activeObject !== !!target ||\n (activeObject && target && activeObject !== target)\n );\n }\n\n /**\n * Method that defines the actions when mouse is released on canvas.\n * The method resets the currentTransform parameters, store the image corner\n * position in the image object and render the canvas on top.\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseUp(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'up:before');\n\n const transform = this._currentTransform;\n const isClick = this._isClick;\n const target = this._target;\n\n // if right/middle click just fire events and return\n // target undefined will make the _handleEvent search the target\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'up');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode && this._isCurrentlyDrawing) {\n this._onMouseUpInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n let shouldRender = false;\n if (transform) {\n this._finalizeCurrentTransform(e);\n shouldRender = transform.actionPerformed;\n }\n if (!isClick) {\n const targetWasActive = target === this._activeObject;\n this.handleSelection(e);\n if (!shouldRender) {\n shouldRender =\n this._shouldRender(target) ||\n (!targetWasActive && target === this._activeObject);\n }\n }\n let pointer, corner;\n if (target) {\n const found = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n const { key, control } = found || {};\n corner = key;\n if (\n target.selectable &&\n target !== this._activeObject &&\n target.activeOn === 'up'\n ) {\n this.setActiveObject(target, e);\n shouldRender = true;\n } else if (control) {\n const mouseUpHandler = control.getMouseUpHandler(e, target, control);\n if (mouseUpHandler) {\n pointer = this.getScenePoint(e);\n mouseUpHandler.call(control, e, transform!, pointer.x, pointer.y);\n }\n }\n target.isMoving = false;\n }\n // if we are ending up a transform on a different control or a new object\n // fire the original mouse up from the corner that started the transform\n if (\n transform &&\n (transform.target !== target || transform.corner !== corner)\n ) {\n const originalControl =\n transform.target && transform.target.controls[transform.corner],\n originalMouseUpHandler =\n originalControl &&\n originalControl.getMouseUpHandler(\n e,\n transform.target,\n originalControl,\n );\n pointer = pointer || this.getScenePoint(e);\n originalMouseUpHandler &&\n originalMouseUpHandler.call(\n originalControl,\n e,\n transform,\n pointer.x,\n pointer.y,\n );\n }\n this._setCursorFromEvent(e, target);\n this._handleEvent(e, 'up');\n this._groupSelector = null;\n this._currentTransform = null;\n // reset the target information about which corner is selected\n target && (target.__corner = undefined);\n if (shouldRender) {\n this.requestRenderAll();\n } else if (!isClick && !(this._activeObject as IText)?.isEditing) {\n this.renderTop();\n }\n }\n\n _basicEventHandler(\n eventType: T,\n options: (CanvasEvents & ObjectEvents)[T],\n ) {\n const { target, subTargets = [] } = options as {\n target?: FabricObject;\n subTargets: FabricObject[];\n };\n this.fire(eventType, options);\n target && target.fire(eventType, options);\n for (let i = 0; i < subTargets.length; i++) {\n subTargets[i] !== target && subTargets[i].fire(eventType, options);\n }\n return options;\n }\n\n /**\n * @private\n * Handle event firing for target and subtargets\n * @param {TPointerEvent} e event from mouse\n * @param {TPointerEventNames} eventType\n */\n _handleEvent(e: TPointerEvent, eventType: T) {\n const target = this._target,\n targets = this.targets || [],\n options: CanvasEvents[`mouse:${T}`] = {\n e,\n target,\n subTargets: targets,\n ...getEventPoints(this, e),\n transform: this._currentTransform,\n ...(eventType === 'up:before' || eventType === 'up'\n ? {\n isClick: this._isClick,\n currentTarget: this.findTarget(e),\n // set by the preceding `findTarget` call\n currentSubTargets: this.targets,\n }\n : {}),\n } as CanvasEvents[`mouse:${T}`];\n this.fire(`mouse:${eventType}`, options);\n // this may be a little be more complicated of what we want to handle\n target && target.fire(`mouse${eventType}`, options);\n for (let i = 0; i < targets.length; i++) {\n targets[i] !== target && targets[i].fire(`mouse${eventType}`, options);\n }\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n _onMouseDownInDrawingMode(e: TPointerEvent) {\n this._isCurrentlyDrawing = true;\n if (this.getActiveObject()) {\n this.discardActiveObject(e);\n this.requestRenderAll();\n }\n // TODO: this is a scene point so it should be renamed\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });\n this._handleEvent(e, 'down');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n _onMouseMoveInDrawingMode(e: TPointerEvent) {\n if (this._isCurrentlyDrawing) {\n const pointer = this.getScenePoint(e);\n this.freeDrawingBrush &&\n this.freeDrawingBrush.onMouseMove(pointer, {\n e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n }\n this.setCursor(this.freeDrawingCursor);\n this._handleEvent(e, 'move');\n }\n\n /**\n * @private\n * @param {Event} e Event object fired on mouseup\n */\n _onMouseUpInDrawingMode(e: TPointerEvent) {\n const pointer = this.getScenePoint(e);\n if (this.freeDrawingBrush) {\n this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({\n e: e,\n // this is an absolute pointer, the naming is wrong\n pointer,\n });\n } else {\n this._isCurrentlyDrawing = false;\n }\n this._handleEvent(e, 'up');\n }\n\n /**\n * Method that defines the actions when mouse is clicked on canvas.\n * The method inits the currentTransform parameters and renders all the\n * canvas so the current image can be placed on the top canvas and the rest\n * in on the container one.\n * @private\n * @param {Event} e Event object fired on mousedown\n */\n __onMouseDown(e: TPointerEvent) {\n this._isClick = true;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'down:before');\n\n let target: FabricObject | undefined = this._target;\n\n // if right/middle click just fire events\n const { button } = e as MouseEvent;\n if (button) {\n ((this.fireMiddleClick && button === 1) ||\n (this.fireRightClick && button === 2)) &&\n this._handleEvent(e, 'down');\n this._resetTransformEventData();\n return;\n }\n\n if (this.isDrawingMode) {\n this._onMouseDownInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n // ignore if some object is being transformed at this moment\n if (this._currentTransform) {\n return;\n }\n\n let shouldRender = this._shouldRender(target);\n let grouped = false;\n if (this.handleMultiSelection(e, target)) {\n // active object might have changed while grouping\n target = this._activeObject;\n grouped = true;\n shouldRender = true;\n } else if (this._shouldClearSelection(e, target)) {\n this.discardActiveObject(e);\n }\n // we start a group selector rectangle if\n // selection is enabled\n // and there is no target, or the following 3 conditions are satisfied:\n // target is not selectable ( otherwise we selected it )\n // target is not editing\n // target is not already selected ( otherwise we drag )\n if (\n this.selection &&\n (!target ||\n (!target.selectable &&\n !(target as IText).isEditing &&\n target !== this._activeObject))\n ) {\n const p = this.getScenePoint(e);\n this._groupSelector = {\n x: p.x,\n y: p.y,\n deltaY: 0,\n deltaX: 0,\n };\n }\n\n if (target) {\n const alreadySelected = target === this._activeObject;\n if (target.selectable && target.activeOn === 'down') {\n this.setActiveObject(target, e);\n }\n const handle = target.findControl(\n this.getViewportPoint(e),\n isTouchEvent(e),\n );\n if (target === this._activeObject && (handle || !grouped)) {\n this._setupCurrentTransform(e, target, alreadySelected);\n const control = handle ? handle.control : undefined,\n pointer = this.getScenePoint(e),\n mouseDownHandler =\n control && control.getMouseDownHandler(e, target, control);\n mouseDownHandler &&\n mouseDownHandler.call(\n control,\n e,\n this._currentTransform!,\n pointer.x,\n pointer.y,\n );\n }\n }\n // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering\n // run before firing the `down` event to give the dev a chance to populate it themselves\n shouldRender && (this._objectsToRender = undefined);\n this._handleEvent(e, 'down');\n // we must renderAll so that we update the visuals\n shouldRender && this.requestRenderAll();\n }\n\n /**\n * reset cache form common information needed during event processing\n * @private\n */\n _resetTransformEventData() {\n this._target = undefined;\n this._pointer = undefined;\n this._absolutePointer = undefined;\n }\n\n /**\n * Cache common information needed during event processing\n * @private\n * @param {Event} e Event object fired on event\n */\n _cacheTransformEventData(e: TPointerEvent) {\n // reset in order to avoid stale caching\n this._resetTransformEventData();\n this._pointer = this.getViewportPoint(e);\n this._absolutePointer = sendPointToPlane(\n this._pointer,\n undefined,\n this.viewportTransform,\n );\n this._target = this._currentTransform\n ? this._currentTransform.target\n : this.findTarget(e);\n }\n\n /**\n * Method that defines the actions when mouse is hovering the canvas.\n * The currentTransform parameter will define whether the user is rotating/scaling/translating\n * an image or neither of them (only hovering). A group selection is also possible and would cancel\n * all any other type of action.\n * In case of an image transformation only the top canvas will be rendered.\n * @private\n * @param {Event} e Event object fired on mousemove\n */\n __onMouseMove(e: TPointerEvent) {\n this._isClick = false;\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'move:before');\n\n if (this.isDrawingMode) {\n this._onMouseMoveInDrawingMode(e);\n return;\n }\n\n if (!this._isMainEvent(e)) {\n return;\n }\n\n const groupSelector = this._groupSelector;\n\n // We initially clicked in an empty area, so we draw a box for multiple selection\n if (groupSelector) {\n const pointer = this.getScenePoint(e);\n\n groupSelector.deltaX = pointer.x - groupSelector.x;\n groupSelector.deltaY = pointer.y - groupSelector.y;\n\n this.renderTop();\n } else if (!this._currentTransform) {\n const target = this.findTarget(e);\n this._setCursorFromEvent(e, target);\n this._fireOverOutEvents(e, target);\n } else {\n this._transformObject(e);\n }\n this.textEditingManager.onMouseMove(e);\n this._handleEvent(e, 'move');\n this._resetTransformEventData();\n }\n\n /**\n * Manage the mouseout, mouseover events for the fabric object on the canvas\n * @param {Fabric.Object} target the target where the target from the mousemove event\n * @param {Event} e Event object fired on mousemove\n * @private\n */\n _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {\n const _hoveredTarget = this._hoveredTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target,\n oldTarget: _hoveredTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('mouse', {\n e,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._hoveredTarget = target;\n this._hoveredTargets = this.targets.concat();\n }\n\n /**\n * Manage the dragEnter, dragLeave events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the onDrag event\n * @param {Object} data Event object fired on dragover\n * @private\n */\n _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {\n const draggedoverTarget = this._draggedoverTarget,\n _hoveredTargets = this._hoveredTargets,\n targets = this.targets,\n length = Math.max(_hoveredTargets.length, targets.length);\n\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target,\n oldTarget: draggedoverTarget,\n fireCanvas: true,\n });\n for (let i = 0; i < length; i++) {\n this.fireSyntheticInOutEvents('drag', {\n ...data,\n target: targets[i],\n oldTarget: _hoveredTargets[i],\n });\n }\n this._draggedoverTarget = target;\n }\n\n /**\n * Manage the synthetic in/out events for the fabric objects on the canvas\n * @param {Fabric.Object} target the target where the target from the supported events\n * @param {Object} data Event object fired\n * @param {Object} config configuration for the function to work\n * @param {String} config.targetName property on the canvas where the old target is stored\n * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out\n * @param {String} config.evtOut name of the event to fire for out\n * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in\n * @param {String} config.evtIn name of the event to fire for in\n * @private\n */\n fireSyntheticInOutEvents(\n type: T,\n {\n target,\n oldTarget,\n fireCanvas,\n e,\n ...data\n }: TSyntheticEventContext[T] & {\n target?: FabricObject;\n oldTarget?: FabricObject;\n fireCanvas?: boolean;\n },\n ) {\n const { targetIn, targetOut, canvasIn, canvasOut } =\n syntheticEventConfig[type];\n const targetChanged = oldTarget !== target;\n\n if (oldTarget && targetChanged) {\n const outOpt: CanvasEvents[typeof canvasOut] = {\n ...data,\n e,\n target: oldTarget,\n nextTarget: target,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasOut, outOpt);\n oldTarget.fire(targetOut, outOpt);\n }\n if (target && targetChanged) {\n const inOpt: CanvasEvents[typeof canvasIn] = {\n ...data,\n e,\n target,\n previousTarget: oldTarget,\n ...getEventPoints(this, e),\n };\n fireCanvas && this.fire(canvasIn, inOpt);\n target.fire(targetIn, inOpt);\n }\n }\n\n /**\n * Method that defines actions when an Event Mouse Wheel\n * @param {Event} e Event object fired on mouseup\n */\n __onMouseWheel(e: TPointerEvent) {\n this._cacheTransformEventData(e);\n this._handleEvent(e, 'wheel');\n this._resetTransformEventData();\n }\n\n /**\n * @private\n * @param {Event} e Event fired on mousemove\n */\n _transformObject(e: TPointerEvent) {\n const scenePoint = this.getScenePoint(e),\n transform = this._currentTransform!,\n target = transform.target,\n // transform pointer to target's containing coordinate plane\n // both pointer and object should agree on every point\n localPointer = target.group\n ? sendPointToPlane(\n scenePoint,\n undefined,\n target.group.calcTransformMatrix(),\n )\n : scenePoint;\n transform.shiftKey = e.shiftKey;\n transform.altKey = !!this.centeredKey && e[this.centeredKey];\n\n this._performTransformAction(e, transform, localPointer);\n transform.actionPerformed && this.requestRenderAll();\n }\n\n /**\n * @private\n */\n _performTransformAction(\n e: TPointerEvent,\n transform: Transform,\n pointer: Point,\n ) {\n const { action, actionHandler, target } = transform;\n\n const actionPerformed =\n !!actionHandler && actionHandler(e, transform, pointer.x, pointer.y);\n actionPerformed && target.setCoords();\n\n // this object could be created from the function in the control handlers\n if (action === 'drag' && actionPerformed) {\n transform.target.isMoving = true;\n this.setCursor(transform.target.moveCursor || this.moveCursor);\n }\n transform.actionPerformed = transform.actionPerformed || actionPerformed;\n }\n\n /**\n * Sets the cursor depending on where the canvas is being hovered.\n * Note: very buggy in Opera\n * @param {Event} e Event object\n * @param {Object} target Object that the mouse is hovering, if so.\n */\n _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {\n if (!target) {\n this.setCursor(this.defaultCursor);\n return;\n }\n let hoverCursor = target.hoverCursor || this.hoverCursor;\n const activeSelection = isActiveSelection(this._activeObject)\n ? this._activeObject\n : null,\n // only show proper corner when group selection is not active\n corner =\n (!activeSelection || target.group !== activeSelection) &&\n // here we call findTargetCorner always with undefined for the touch parameter.\n // we assume that if you are using a cursor you do not need to interact with\n // the bigger touch area.\n target.findControl(this.getViewportPoint(e));\n\n if (!corner) {\n if ((target as Group).subTargetCheck) {\n // hoverCursor should come from top-most subTarget,\n // so we walk the array backwards\n this.targets\n .concat()\n .reverse()\n .map((_target) => {\n hoverCursor = _target.hoverCursor || hoverCursor;\n });\n }\n this.setCursor(hoverCursor);\n } else {\n const control = corner.control;\n this.setCursor(control.cursorStyleHandler(e, control, target));\n }\n }\n\n /**\n * ## Handles multiple selection\n * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)\n * - sets the active object in case it is not set or in case there is a single active object left under active selection.\n * ---\n * - If the active object is the active selection we add/remove `target` from it\n * - If not, add the active object and `target` to the active selection and make it the active object.\n * @private\n * @param {TPointerEvent} e Event object\n * @param {FabricObject} target target of event to select/deselect\n * @returns true if grouping occurred\n */\n protected handleMultiSelection(e: TPointerEvent, target?: FabricObject) {\n const activeObject = this._activeObject;\n const isAS = isActiveSelection(activeObject);\n if (\n // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.\n !!activeObject &&\n this._isSelectionKeyPressed(e) &&\n this.selection &&\n // on top of that the user also has to hit a target that is selectable.\n !!target &&\n target.selectable &&\n // group target and active object only if they are different objects\n // else we try to find a subtarget of `ActiveSelection`\n (activeObject !== target || isAS) &&\n // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`\n // if it is then we want to remove `target` from it\n (isAS ||\n (!target.isDescendantOf(activeObject) &&\n !activeObject.isDescendantOf(target))) &&\n // target accepts selection\n !target.onSelect({ e }) &&\n // make sure we are not on top of a control\n !activeObject.getActiveControl()\n ) {\n if (isAS) {\n const prevActiveObjects = activeObject.getObjects();\n if (target === activeObject) {\n const pointer = this.getViewportPoint(e);\n target =\n // first search active objects for a target to remove\n this.searchPossibleTargets(prevActiveObjects, pointer) ||\n // if not found, search under active selection for a target to add\n // `prevActiveObjects` will be searched but we already know they will not be found\n this.searchPossibleTargets(this._objects, pointer);\n // if nothing is found bail out\n if (!target || !target.selectable) {\n return false;\n }\n }\n if (target.group === activeObject) {\n // `target` is part of active selection => remove it\n activeObject.remove(target);\n this._hoveredTarget = target;\n this._hoveredTargets = [...this.targets];\n // if after removing an object we are left with one only...\n if (activeObject.size() === 1) {\n // activate last remaining object\n // deselecting the active selection will remove the remaining object from it\n this._setActiveObject(activeObject.item(0), e);\n }\n } else {\n // `target` isn't part of active selection => add it\n activeObject.multiSelectAdd(target);\n this._hoveredTarget = activeObject;\n this._hoveredTargets = [...this.targets];\n }\n this._fireSelectionEvents(prevActiveObjects, e);\n } else {\n (activeObject as IText).exitEditing &&\n (activeObject as IText).exitEditing();\n // add the active object and the target to the active selection and set it as the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n const newActiveSelection = new klass([], {\n /**\n * it is crucial to pass the canvas ref before calling {@link ActiveSelection#multiSelectAdd}\n * since it uses {@link FabricObject#isInFrontOf} which relies on the canvas ref\n */\n canvas: this,\n });\n newActiveSelection.multiSelectAdd(activeObject, target);\n this._hoveredTarget = newActiveSelection;\n // ISSUE 4115: should we consider subTargets here?\n // this._hoveredTargets = [];\n // this._hoveredTargets = this.targets.concat();\n this._setActiveObject(newActiveSelection, e);\n this._fireSelectionEvents([activeObject], e);\n }\n return true;\n }\n return false;\n }\n\n /**\n * ## Handles selection\n * - selects objects that are contained in (and possibly intersecting) the selection bounding box\n * - sets the active object\n * ---\n * runs on mouse up after a mouse move\n */\n protected handleSelection(e: TPointerEvent) {\n if (!this.selection || !this._groupSelector) {\n return false;\n }\n const { x, y, deltaX, deltaY } = this._groupSelector,\n point1 = new Point(x, y),\n point2 = point1.add(new Point(deltaX, deltaY)),\n tl = point1.min(point2),\n br = point1.max(point2),\n size = br.subtract(tl);\n\n const collectedObjects = this.collectObjects(\n {\n left: tl.x,\n top: tl.y,\n width: size.x,\n height: size.y,\n },\n { includeIntersecting: !this.selectionFullyContained },\n ) as FabricObject[];\n\n const objects =\n // though this method runs only after mouse move the pointer could do a mouse up on the same position as mouse down\n // should it be handled as is?\n point1.eq(point2)\n ? collectedObjects[0]\n ? [collectedObjects[0]]\n : []\n : collectedObjects.length > 1\n ? collectedObjects\n .filter((object) => !object.onSelect({ e }))\n .reverse()\n : // `setActiveObject` will call `onSelect(collectedObjects[0])` in this case\n collectedObjects;\n\n // set active object\n if (objects.length === 1) {\n // set as active object\n this.setActiveObject(objects[0], e);\n } else if (objects.length > 1) {\n // add to active selection and make it the active object\n const klass =\n classRegistry.getClass('ActiveSelection');\n this.setActiveObject(new klass(objects, { canvas: this }), e);\n }\n\n // cleanup\n this._groupSelector = null;\n return true;\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n clear() {\n this.textEditingManager.clear();\n super.clear();\n }\n\n /**\n * @override clear {@link textEditingManager}\n */\n destroy() {\n this.removeListeners();\n this.textEditingManager.dispose();\n super.destroy();\n }\n}\n","export const linearDefaultCoords = {\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n};\n\nexport const radialDefaultCoords = {\n ...linearDefaultCoords,\n r1: 0,\n r2: 0,\n};\n","/**\n *\n * @param value value to check if NaN\n * @param [valueIfNaN]\n * @returns `fallback` is `value is NaN\n */\nexport const ifNaN = (value: number, valueIfNaN?: number) => {\n return isNaN(value) && typeof valueIfNaN === 'number' ? valueIfNaN : value;\n};\n","import { ifNaN } from '../util/internals/ifNaN';\nimport { capValue } from '../util/misc/capValue';\n\nconst RE_PERCENT = /^(\\d+\\.\\d+)%|(\\d+)%$/;\n\nexport function isPercent(value: string | null) {\n return value && RE_PERCENT.test(value);\n}\n\n/**\n *\n * @param value\n * @param valueIfNaN\n * @returns ∈ [0, 1]\n */\nexport function parsePercent(\n value: string | number | null | undefined,\n valueIfNaN?: number,\n) {\n const parsed =\n typeof value === 'number'\n ? value\n : typeof value === 'string'\n ? parseFloat(value) / (isPercent(value) ? 100 : 1)\n : NaN;\n return capValue(0, ifNaN(parsed, valueIfNaN), 1);\n}\n","import { Color } from '../../color/Color';\nimport { parsePercent } from '../../parser/percent';\nimport { ifNaN } from '../../util/internals/ifNaN';\nimport type { ColorStop } from '../typedefs';\n\nconst RE_KEY_VALUE_PAIRS = /\\s*;\\s*/;\nconst RE_KEY_VALUE = /\\s*:\\s*/;\n\nfunction parseColorStop(el: SVGStopElement, multiplier: number) {\n let colorValue, opacity;\n const style = el.getAttribute('style');\n if (style) {\n const keyValuePairs = style.split(RE_KEY_VALUE_PAIRS);\n\n if (keyValuePairs[keyValuePairs.length - 1] === '') {\n keyValuePairs.pop();\n }\n\n for (let i = keyValuePairs.length; i--; ) {\n const [key, value] = keyValuePairs[i]\n .split(RE_KEY_VALUE)\n .map((s) => s.trim());\n if (key === 'stop-color') {\n colorValue = value;\n } else if (key === 'stop-opacity') {\n opacity = value;\n }\n }\n }\n\n const color = new Color(\n colorValue || el.getAttribute('stop-color') || 'rgb(0,0,0)',\n );\n\n return {\n offset: parsePercent(el.getAttribute('offset'), 0),\n color: color.toRgb(),\n opacity:\n ifNaN(parseFloat(opacity || el.getAttribute('stop-opacity') || ''), 1) *\n color.getAlpha() *\n multiplier,\n };\n}\n\nexport function parseColorStops(\n el: SVGGradientElement,\n opacityAttr: string | null,\n) {\n const colorStops: ColorStop[] = [],\n colorStopEls = el.getElementsByTagName('stop'),\n multiplier = parsePercent(opacityAttr, 1);\n for (let i = colorStopEls.length; i--; ) {\n colorStops.push(parseColorStop(colorStopEls[i], multiplier));\n }\n return colorStops;\n}\n","import type { GradientType, GradientUnits } from '../typedefs';\n\nexport function parseType(el: SVGGradientElement): GradientType {\n return el.nodeName === 'linearGradient' || el.nodeName === 'LINEARGRADIENT'\n ? 'linear'\n : 'radial';\n}\n\nexport function parseGradientUnits(el: SVGGradientElement): GradientUnits {\n return el.getAttribute('gradientUnits') === 'userSpaceOnUse'\n ? 'pixels'\n : 'percentage';\n}\n","import { isPercent } from '../../parser/percent';\nimport type { TSize } from '../../typedefs';\nimport type { GradientCoords, GradientType, GradientUnits } from '../typedefs';\nimport { parseGradientUnits, parseType } from './misc';\n\nfunction convertPercentUnitsToValues<\n T extends GradientType,\n K extends keyof GradientCoords,\n>(\n valuesToConvert: Record,\n { width, height, gradientUnits }: TSize & { gradientUnits: GradientUnits },\n) {\n let finalValue;\n return (Object.keys(valuesToConvert) as K[]).reduce(\n (acc, prop) => {\n const propValue = valuesToConvert[prop];\n if (propValue === 'Infinity') {\n finalValue = 1;\n } else if (propValue === '-Infinity') {\n finalValue = 0;\n } else {\n finalValue =\n typeof propValue === 'string' ? parseFloat(propValue) : propValue;\n if (typeof propValue === 'string' && isPercent(propValue)) {\n finalValue *= 0.01;\n if (gradientUnits === 'pixels') {\n // then we need to fix those percentages here in svg parsing\n if (prop === 'x1' || prop === 'x2' || prop === 'r2') {\n finalValue *= width;\n }\n if (prop === 'y1' || prop === 'y2') {\n finalValue *= height;\n }\n }\n }\n }\n acc[prop] = finalValue;\n return acc;\n },\n {} as Record,\n );\n}\n\nfunction getValue(el: SVGGradientElement, key: string) {\n return el.getAttribute(key);\n}\n\nexport function parseLinearCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'x1') || 0,\n y1: getValue(el, 'y1') || 0,\n x2: getValue(el, 'x2') || '100%',\n y2: getValue(el, 'y2') || 0,\n };\n}\n\nexport function parseRadialCoords(el: SVGGradientElement) {\n return {\n x1: getValue(el, 'fx') || getValue(el, 'cx') || '50%',\n y1: getValue(el, 'fy') || getValue(el, 'cy') || '50%',\n r1: 0,\n x2: getValue(el, 'cx') || '50%',\n y2: getValue(el, 'cy') || '50%',\n r2: getValue(el, 'r') || '50%',\n };\n}\n\nexport function parseCoords(el: SVGGradientElement, size: TSize) {\n return convertPercentUnitsToValues(\n parseType(el) === 'linear' ? parseLinearCoords(el) : parseRadialCoords(el),\n {\n ...size,\n gradientUnits: parseGradientUnits(el),\n },\n );\n}\n","import { Color } from '../color/Color';\nimport { iMatrix } from '../constants';\nimport { parseTransformAttribute } from '../parser/parseTransformAttribute';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport type { TMat2D } from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { pick } from '../util/misc/pick';\nimport { matrixToSVG } from '../util/misc/svgParsing';\nimport { linearDefaultCoords, radialDefaultCoords } from './constants';\nimport { parseColorStops } from './parser/parseColorStops';\nimport { parseCoords } from './parser/parseCoords';\nimport { parseType, parseGradientUnits } from './parser/misc';\nimport type {\n ColorStop,\n GradientCoords,\n GradientOptions,\n GradientType,\n GradientUnits,\n SVGOptions,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { isPath } from '../util/typeAssertions';\n\n/**\n * Gradient class\n * @class Gradient\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#gradients}\n */\nexport class Gradient<\n S,\n T extends GradientType = S extends GradientType ? S : 'linear',\n> {\n /**\n * Horizontal offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetX: number;\n\n /**\n * Vertical offset for aligning gradients coming from SVG when outside pathgroups\n * @type Number\n * @default 0\n */\n declare offsetY: number;\n\n /**\n * A transform matrix to apply to the gradient before painting.\n * Imported from svg gradients, is not applied with the current transform in the center.\n * Before this transform is applied, the origin point is at the top left corner of the object\n * plus the addition of offsetY and offsetX.\n * @type Number[]\n * @default null\n */\n declare gradientTransform?: TMat2D;\n\n /**\n * coordinates units for coords.\n * If `pixels`, the number of coords are in the same unit of width / height.\n * If set as `percentage` the coords are still a number, but 1 means 100% of width\n * for the X and 100% of the height for the y. It can be bigger than 1 and negative.\n * allowed values pixels or percentage.\n * @type GradientUnits\n * @default 'pixels'\n */\n declare gradientUnits: GradientUnits;\n\n /**\n * Gradient type linear or radial\n * @type GradientType\n * @default 'linear'\n */\n declare type: T;\n\n /**\n * Defines how the gradient is located in space and spread\n * @type GradientCoords\n */\n declare coords: GradientCoords;\n\n /**\n * Defines how many colors a gradient has and how they are located on the axis\n * defined by coords\n * @type GradientCoords\n */\n declare colorStops: ColorStop[];\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number | string\n */\n declare readonly id: string | number;\n\n static type = 'Gradient';\n\n constructor(options: GradientOptions) {\n const {\n type = 'linear' as T,\n gradientUnits = 'pixels',\n coords = {},\n colorStops = [],\n offsetX = 0,\n offsetY = 0,\n gradientTransform,\n id,\n } = options || {};\n Object.assign(this, {\n type,\n gradientUnits,\n coords: {\n ...(type === 'radial' ? radialDefaultCoords : linearDefaultCoords),\n ...coords,\n },\n colorStops,\n offsetX,\n offsetY,\n gradientTransform,\n id: id ? `${id}_${uid()}` : uid(),\n });\n }\n\n /**\n * Adds another colorStop\n * @param {Record} colorStop Object with offset and color\n * @return {Gradient} thisArg\n */\n addColorStop(colorStops: Record) {\n for (const position in colorStops) {\n const color = new Color(colorStops[position]);\n this.colorStops.push({\n offset: parseFloat(position),\n color: color.toRgb(),\n opacity: color.getAlpha(),\n });\n }\n return this;\n }\n\n /**\n * Returns object representation of a gradient\n * @param {string[]} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object}\n */\n toObject(propertiesToInclude?: (keyof this | string)[]) {\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: this.type,\n coords: { ...this.coords },\n colorStops: this.colorStops.map((colorStop) => ({ ...colorStop })),\n offsetX: this.offsetX,\n offsetY: this.offsetY,\n gradientUnits: this.gradientUnits,\n gradientTransform: this.gradientTransform\n ? [...this.gradientTransform]\n : undefined,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of an gradient\n * @param {FabricObject} object Object to create a gradient for\n * @return {String} SVG representation of an gradient (linear/radial)\n */\n toSVG(\n object: FabricObject,\n {\n additionalTransform: preTransform,\n }: { additionalTransform?: string } = {},\n ) {\n const markup = [],\n transform = (\n this.gradientTransform\n ? this.gradientTransform.concat()\n : iMatrix.concat()\n ) as TMat2D,\n gradientUnits =\n this.gradientUnits === 'pixels'\n ? 'userSpaceOnUse'\n : 'objectBoundingBox';\n // colorStops must be sorted ascending, and guarded against deep mutations\n const colorStops = this.colorStops\n .map((colorStop) => ({ ...colorStop }))\n .sort((a, b) => {\n return a.offset - b.offset;\n });\n\n let offsetX = -this.offsetX,\n offsetY = -this.offsetY;\n if (gradientUnits === 'objectBoundingBox') {\n offsetX /= object.width;\n offsetY /= object.height;\n } else {\n offsetX += object.width / 2;\n offsetY += object.height / 2;\n }\n // todo what about polygon/polyline?\n if (isPath(object) && this.gradientUnits !== 'percentage') {\n offsetX -= object.pathOffset.x;\n offsetY -= object.pathOffset.y;\n }\n transform[4] -= offsetX;\n transform[5] -= offsetY;\n\n const commonAttributes = [\n `id=\"SVGID_${this.id}\"`,\n `gradientUnits=\"${gradientUnits}\"`,\n `gradientTransform=\"${\n preTransform ? preTransform + ' ' : ''\n }${matrixToSVG(transform)}\"`,\n '',\n ].join(' ');\n\n if (this.type === 'linear') {\n const { x1, y1, x2, y2 } = this.coords;\n markup.push(\n '\\n',\n );\n } else if (this.type === 'radial') {\n const { x1, y1, x2, y2, r1, r2 } = this\n .coords as GradientCoords<'radial'>;\n const needsSwap = r1 > r2;\n // svg radial gradient has just 1 radius. the biggest.\n markup.push(\n '\\n',\n );\n if (needsSwap) {\n // svg goes from internal to external radius. if radius are inverted, swap color stops.\n colorStops.reverse(); // mutates array\n colorStops.forEach((colorStop) => {\n colorStop.offset = 1 - colorStop.offset;\n });\n }\n const minRadius = Math.min(r1, r2);\n if (minRadius > 0) {\n // i have to shift all colorStops and add new one in 0.\n const maxRadius = Math.max(r1, r2),\n percentageShift = minRadius / maxRadius;\n colorStops.forEach((colorStop) => {\n colorStop.offset += percentageShift * (1 - colorStop.offset);\n });\n }\n }\n\n colorStops.forEach(({ color, offset, opacity }) => {\n markup.push(\n '\\n',\n );\n });\n\n markup.push(\n this.type === 'linear' ? '' : '',\n '\\n',\n );\n\n return markup.join('');\n }\n /* _TO_SVG_END_ */\n\n /**\n * Returns an instance of CanvasGradient\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {CanvasGradient}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasGradient {\n const { x1, y1, x2, y2, r1, r2 } = this.coords as GradientCoords<'radial'>;\n const gradient =\n this.type === 'linear'\n ? ctx.createLinearGradient(x1, y1, x2, y2)\n : ctx.createRadialGradient(x1, y1, r1, x2, y2, r2);\n\n this.colorStops.forEach(({ color, opacity, offset }) => {\n gradient.addColorStop(\n offset,\n typeof opacity !== 'undefined'\n ? new Color(color).setAlpha(opacity).toRgba()\n : color,\n );\n });\n\n return gradient;\n }\n\n static async fromObject(\n options: GradientOptions<'linear'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'radial'>,\n ): Promise>;\n static async fromObject(\n options: GradientOptions<'linear'> | GradientOptions<'radial'>,\n ) {\n const { colorStops, gradientTransform } = options;\n return new this({\n ...options,\n colorStops: colorStops\n ? colorStops.map((colorStop) => ({ ...colorStop }))\n : undefined,\n gradientTransform: gradientTransform ? [...gradientTransform] : undefined,\n });\n }\n\n /* _FROM_SVG_START_ */\n /**\n * Returns {@link Gradient} instance from an SVG element\n * @static\n * @memberOf Gradient\n * @param {SVGGradientElement} el SVG gradient element\n * @param {FabricObject} instance\n * @param {String} opacity A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.\n * @param {SVGOptions} svgOptions an object containing the size of the SVG in order to parse correctly gradients\n * that uses gradientUnits as 'userSpaceOnUse' and percentages.\n * @return {Gradient} Gradient instance\n * @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement\n * @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement\n *\n * @example\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n * OR\n *\n * \n * \n * \n * \n * \n *\n */\n static fromElement(\n el: SVGGradientElement,\n instance: FabricObject,\n svgOptions: SVGOptions,\n ): Gradient {\n const gradientUnits = parseGradientUnits(el);\n const center = instance._findCenterFromElement();\n return new this({\n id: el.getAttribute('id') || undefined,\n type: parseType(el),\n coords: parseCoords(el, {\n width: svgOptions.viewBoxWidth || svgOptions.width,\n height: svgOptions.viewBoxHeight || svgOptions.height,\n }),\n colorStops: parseColorStops(el, svgOptions.opacity),\n gradientUnits,\n gradientTransform: parseTransformAttribute(\n el.getAttribute('gradientTransform') || '',\n ),\n ...(gradientUnits === 'pixels'\n ? {\n offsetX: instance.width / 2 - center.x,\n offsetY: instance.height / 2 - center.y,\n }\n : {\n offsetX: 0,\n offsetY: 0,\n }),\n });\n }\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Gradient, 'gradient');\nclassRegistry.setClass(Gradient, 'linear');\nclassRegistry.setClass(Gradient, 'radial');\n","import { config } from '../config';\nimport type { Abortable, TCrossOrigin, TMat2D, TSize } from '../typedefs';\nimport { ifNaN } from '../util/internals/ifNaN';\nimport { uid } from '../util/internals/uid';\nimport { loadImage } from '../util/misc/objectEnlive';\nimport { pick } from '../util/misc/pick';\nimport { toFixed } from '../util/misc/toFixed';\nimport { classRegistry } from '../ClassRegistry';\nimport type {\n PatternRepeat,\n PatternOptions,\n SerializedPatternOptions,\n} from './types';\nimport { log } from '../util/internals/console';\n\n/**\n * @see {@link http://fabricjs.com/patterns demo}\n * @see {@link http://fabricjs.com/dynamic-patterns demo}\n */\nexport class Pattern {\n static type = 'Pattern';\n\n /**\n * Legacy identifier of the class. Prefer using this.constructor.type 'Pattern'\n * or utils like isPattern, or instance of to indentify a pattern in your code.\n * Will be removed in future versiones\n * @TODO add sustainable warning message\n * @type string\n * @deprecated\n */\n get type() {\n return 'pattern';\n }\n\n set type(value) {\n log('warn', 'Setting type has no effect', value);\n }\n\n /**\n * @type PatternRepeat\n * @defaults\n */\n repeat: PatternRepeat = 'repeat';\n\n /**\n * Pattern horizontal offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetX = 0;\n\n /**\n * Pattern vertical offset from object's left/top corner\n * @type Number\n * @default\n */\n offsetY = 0;\n\n /**\n * @type TCrossOrigin\n * @default\n */\n crossOrigin: TCrossOrigin = '';\n\n /**\n * transform matrix to change the pattern, imported from svgs.\n * @todo verify if using the identity matrix as default makes the rest of the code more easy\n * @type Array\n * @default\n */\n declare patternTransform?: TMat2D;\n\n /**\n * The actual pixel source of the pattern\n */\n declare source: CanvasImageSource;\n\n /**\n * If true, this object will not be exported during the serialization of a canvas\n * @type boolean\n */\n declare excludeFromExport?: boolean;\n\n /**\n * ID used for SVG export functionalities\n * @type number\n */\n declare readonly id: number;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n * @param {option.source} [source] the pattern source, eventually empty or a drawable\n */\n constructor(options: PatternOptions) {\n this.id = uid();\n Object.assign(this, options);\n }\n\n /**\n * @returns true if {@link source} is an element\n */\n isImageSource(): this is { source: HTMLImageElement } {\n return (\n !!this.source && typeof (this.source as HTMLImageElement).src === 'string'\n );\n }\n\n /**\n * @returns true if {@link source} is a element\n */\n isCanvasSource(): this is { source: HTMLCanvasElement } {\n return !!this.source && !!(this.source as HTMLCanvasElement).toDataURL;\n }\n\n sourceToString(): string {\n return this.isImageSource()\n ? this.source.src\n : this.isCanvasSource()\n ? this.source.toDataURL()\n : '';\n }\n\n /**\n * Returns an instance of CanvasPattern\n * @param {CanvasRenderingContext2D} ctx Context to create pattern\n * @return {CanvasPattern}\n */\n toLive(ctx: CanvasRenderingContext2D): CanvasPattern | null {\n if (\n // if the image failed to load, return, and allow rest to continue loading\n !this.source ||\n // if an image\n (this.isImageSource() &&\n (!this.source.complete ||\n this.source.naturalWidth === 0 ||\n this.source.naturalHeight === 0))\n ) {\n return null;\n }\n\n return ctx.createPattern(this.source, this.repeat)!;\n }\n\n /**\n * Returns object representation of a pattern\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {object} Object representation of a pattern instance\n */\n toObject(propertiesToInclude: string[] = []): Record {\n const { repeat, crossOrigin } = this;\n return {\n ...pick(this, propertiesToInclude as (keyof this)[]),\n type: 'pattern',\n source: this.sourceToString(),\n repeat,\n crossOrigin,\n offsetX: toFixed(this.offsetX, config.NUM_FRACTION_DIGITS),\n offsetY: toFixed(this.offsetY, config.NUM_FRACTION_DIGITS),\n patternTransform: this.patternTransform\n ? [...this.patternTransform]\n : null,\n };\n }\n\n /* _TO_SVG_START_ */\n /**\n * Returns SVG representation of a pattern\n */\n toSVG({ width, height }: TSize): string {\n const { source: patternSource, repeat, id } = this,\n patternOffsetX = ifNaN(this.offsetX / width, 0),\n patternOffsetY = ifNaN(this.offsetY / height, 0),\n patternWidth =\n repeat === 'repeat-y' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetX || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).width as number) / width,\n 0,\n ),\n patternHeight =\n repeat === 'repeat-x' || repeat === 'no-repeat'\n ? 1 + Math.abs(patternOffsetY || 0)\n : ifNaN(\n ((patternSource as HTMLImageElement).height as number) / height,\n 0,\n );\n\n return [\n ``,\n ``,\n ``,\n '',\n ].join('\\n');\n }\n /* _TO_SVG_END_ */\n\n static async fromObject(\n {\n type,\n source,\n patternTransform,\n ...otherOptions\n }: SerializedPatternOptions,\n options?: Abortable,\n ): Promise {\n const img = await loadImage(source, {\n ...options,\n crossOrigin: otherOptions.crossOrigin,\n });\n return new this({\n ...otherOptions,\n patternTransform:\n patternTransform && (patternTransform.slice(0) as TMat2D),\n source: img,\n });\n }\n}\n\nclassRegistry.setClass(Pattern);\n// kept for compatibility reason\nclassRegistry.setClass(Pattern, 'pattern');\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport type { Shadow } from '../Shadow';\nimport type { Canvas } from '../canvas/Canvas';\nimport type { TBrushEventData } from './typedefs';\n\n/**\n * @see {@link http://fabricjs.com/freedrawing|Freedrawing demo}\n */\nexport abstract class BaseBrush {\n /**\n * Color of a brush\n * @type String\n * @default\n */\n color = 'rgb(0, 0, 0)';\n\n /**\n * Width of a brush, has to be a Number, no string literals\n * @type Number\n * @default\n */\n width = 1;\n\n /**\n * Shadow object representing shadow of this shape.\n * Backwards incompatibility note: This property replaces \"shadowColor\" (String), \"shadowOffsetX\" (Number),\n * \"shadowOffsetY\" (Number) and \"shadowBlur\" (Number) since v1.2.12\n * @type Shadow\n * @default\n */\n shadow: Shadow | null = null;\n\n /**\n * Line endings style of a brush (one of \"butt\", \"round\", \"square\")\n * @type String\n * @default\n */\n strokeLineCap: CanvasLineCap = 'round';\n\n /**\n * Corner style of a brush (one of \"bevel\", \"round\", \"miter\")\n * @type String\n * @default\n */\n strokeLineJoin: CanvasLineJoin = 'round';\n\n /**\n * Maximum miter length (used for strokeLineJoin = \"miter\") of a brush's\n * @type Number\n * @default\n */\n strokeMiterLimit = 10;\n\n /**\n * Stroke Dash Array.\n * @type Array\n * @default\n */\n strokeDashArray: number[] | null = null;\n\n /**\n * When `true`, the free drawing is limited to the whiteboard size. Default to false.\n * @type Boolean\n * @default false\n */\n\n limitedToCanvasSize = false;\n\n /**\n * @todo add type\n */\n declare canvas: Canvas;\n\n constructor(canvas: Canvas) {\n this.canvas = canvas;\n }\n\n abstract _render(): void;\n abstract onMouseDown(pointer: Point, ev: TBrushEventData): void;\n abstract onMouseMove(pointer: Point, ev: TBrushEventData): void;\n /**\n * @returns true if brush should continue blocking interaction\n */\n abstract onMouseUp(ev: TBrushEventData): boolean | void;\n\n /**\n * Sets brush styles\n * @private\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n ctx.strokeStyle = this.color;\n ctx.lineWidth = this.width;\n ctx.lineCap = this.strokeLineCap;\n ctx.miterLimit = this.strokeMiterLimit;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.setLineDash(this.strokeDashArray || []);\n }\n\n /**\n * Sets the transformation on given context\n * @param {CanvasRenderingContext2D} ctx context to render on\n * @private\n */\n protected _saveAndTransform(ctx: CanvasRenderingContext2D) {\n const v = this.canvas.viewportTransform;\n ctx.save();\n ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);\n }\n\n protected needsFullRender() {\n const color = new Color(this.color);\n return color.getAlpha() < 1 || !!this.shadow;\n }\n\n /**\n * Sets brush shadow styles\n * @private\n */\n protected _setShadow() {\n if (!this.shadow || !this.canvas) {\n return;\n }\n\n const canvas = this.canvas,\n shadow = this.shadow,\n ctx = canvas.contextTop,\n zoom = canvas.getZoom() * canvas.getRetinaScaling();\n\n ctx.shadowColor = shadow.color;\n ctx.shadowBlur = shadow.blur * zoom;\n ctx.shadowOffsetX = shadow.offsetX * zoom;\n ctx.shadowOffsetY = shadow.offsetY * zoom;\n }\n\n /**\n * Removes brush shadow styles\n * @private\n */\n protected _resetShadow() {\n const ctx = this.canvas.contextTop;\n\n ctx.shadowColor = '';\n ctx.shadowBlur = ctx.shadowOffsetX = ctx.shadowOffsetY = 0;\n }\n\n /**\n * Check is pointer is outside canvas boundaries\n * @param {Object} pointer\n * @private\n */\n protected _isOutSideCanvas(pointer: Point) {\n return (\n pointer.x < 0 ||\n pointer.x > this.canvas.getWidth() ||\n pointer.y < 0 ||\n pointer.y > this.canvas.getHeight()\n );\n }\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { toFixed } from '../util/misc/toFixed';\nimport {\n getBoundsOfCurve,\n joinPath,\n makePathSimpler,\n parsePath,\n} from '../util/path';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type {\n TComplexPathData,\n TPathSegmentInfo,\n TSimplePathData,\n} from '../util/path/typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type {\n TBBox,\n TClassProperties,\n TSVGReviver,\n TOptions,\n} from '../typedefs';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\ninterface UniquePathProps {\n sourcePath?: string;\n path?: TSimplePathData;\n}\n\nexport interface SerializedPathProps\n extends SerializedObjectProps,\n UniquePathProps {}\n\nexport interface PathProps extends FabricObjectProps, UniquePathProps {}\n\nexport interface IPathBBox extends TBBox {\n left: number;\n top: number;\n pathOffset: Point;\n}\n\nexport class Path<\n Props extends TOptions = Partial,\n SProps extends SerializedPathProps = SerializedPathProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Array of path points\n * @type Array\n * @default\n */\n declare path: TSimplePathData;\n\n declare pathOffset: Point;\n\n declare sourcePath?: string;\n\n declare segmentsInfo?: TPathSegmentInfo[];\n\n static type = 'Path';\n\n static cacheProperties = [...cacheProperties, 'path', 'fillRule'];\n\n /**\n * Constructor\n * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {Partial} [options] Options object\n * @return {Path} thisArg\n */\n constructor(\n path: TComplexPathData | string,\n // todo: evaluate this spread here\n { path: _, left, top, ...options }: Partial = {},\n ) {\n super();\n Object.assign(this, Path.ownDefaults);\n this.setOptions(options);\n this._setPath(path || [], true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding \"command\" tokens)\n * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box\n * @returns {Point} top left position of the bounding box, useful for complementary positioning\n */\n _setPath(path: TComplexPathData | string, adjustPosition?: boolean) {\n this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));\n this.setBoundingBox(adjustPosition);\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = this._calcBoundsFromPath();\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _renderPathCommands(ctx: CanvasRenderingContext2D) {\n const l = -this.pathOffset.x,\n t = -this.pathOffset.y;\n\n ctx.beginPath();\n\n for (const command of this.path) {\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n ctx.lineTo(command[1] + l, command[2] + t);\n break;\n\n case 'M': // moveTo, absolute\n ctx.moveTo(command[1] + l, command[2] + t);\n break;\n\n case 'C': // bezierCurveTo, absolute\n ctx.bezierCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n command[5] + l,\n command[6] + t,\n );\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n ctx.quadraticCurveTo(\n command[1] + l,\n command[2] + t,\n command[3] + l,\n command[4] + t,\n );\n break;\n\n case 'Z':\n ctx.closePath();\n break;\n }\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render path on\n */\n _render(ctx: CanvasRenderingContext2D) {\n this._renderPathCommands(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns string representation of an instance\n * @return {string} string representation of an instance\n */\n toString() {\n return `#`;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n path: this.path.map((pathCmd) => pathCmd.slice()),\n };\n }\n\n /**\n * Returns dataless object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toDatalessObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const o = this.toObject(propertiesToInclude);\n if (this.sourcePath) {\n delete o.path;\n o.sourcePath = this.sourcePath;\n }\n return o;\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const path = joinPath(this.path, config.NUM_FRACTION_DIGITS);\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @return the path command's translate transform attribute\n */\n _getOffsetTransform() {\n const digits = config.NUM_FRACTION_DIGITS;\n return ` translate(${toFixed(-this.pathOffset.x, digits)}, ${toFixed(\n -this.pathOffset.y,\n digits,\n )})`;\n }\n\n /**\n * Returns svg clipPath representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toClipPathSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return (\n '\\t' +\n this._createBaseClipPathSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n })\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @param {Function} [reviver] Method for further parsing of svg representation.\n * @return {string} svg representation of an instance\n */\n toSVG(reviver?: TSVGReviver): string {\n const additionalTransform = this._getOffsetTransform();\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n additionalTransform: additionalTransform,\n });\n }\n\n /**\n * Returns number representation of an instance complexity\n * @return {number} complexity of this instance\n */\n complexity() {\n return this.path.length;\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { width, height, pathOffset } = this._calcDimensions();\n this.set({ width, height, pathOffset });\n // using pathOffset because it match the use case.\n // if pathOffset change here we need to use left + width/2 , top + height/2\n adjustPosition && this.setPositionByOrigin(pathOffset, CENTER, CENTER);\n }\n\n _calcBoundsFromPath(): TBBox {\n const bounds: XY[] = [];\n let subpathStartX = 0,\n subpathStartY = 0,\n x = 0, // current x\n y = 0; // current y\n\n for (const command of this.path) {\n // current instruction\n switch (\n command[0] // first letter\n ) {\n case 'L': // lineto, absolute\n x = command[1];\n y = command[2];\n bounds.push({ x: subpathStartX, y: subpathStartY }, { x, y });\n break;\n\n case 'M': // moveTo, absolute\n x = command[1];\n y = command[2];\n subpathStartX = x;\n subpathStartY = y;\n break;\n\n case 'C': // bezierCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[3],\n command[4],\n command[5],\n command[6],\n ),\n );\n x = command[5];\n y = command[6];\n break;\n\n case 'Q': // quadraticCurveTo, absolute\n bounds.push(\n ...getBoundsOfCurve(\n x,\n y,\n command[1],\n command[2],\n command[1],\n command[2],\n command[3],\n command[4],\n ),\n );\n x = command[3];\n y = command[4];\n break;\n\n case 'Z':\n x = subpathStartX;\n y = subpathStartY;\n break;\n }\n }\n return makeBoundingBoxFromPoints(bounds);\n }\n\n /**\n * @private\n */\n _calcDimensions(): IPathBBox {\n const bbox = this._calcBoundsFromPath();\n\n return {\n ...bbox,\n pathOffset: new Point(\n bbox.left + bbox.width / 2,\n bbox.top + bbox.height / 2,\n ),\n };\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by `Path.fromElement`)\n * @static\n * @memberOf Path\n * @see http://www.w3.org/TR/SVG/paths.html#PathElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'd'];\n\n /**\n * Creates an instance of Path from an object\n * @static\n * @memberOf Path\n * @param {Object} object\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'path',\n });\n }\n\n /**\n * Creates an instance of Path from an SVG element\n * @static\n * @memberOf Path\n * @param {HTMLElement} element to parse\n * @param {Partial} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Partial,\n cssRules?: CSSRules,\n ) {\n const { d, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(d, {\n ...parsedAttributes,\n ...options,\n // we pass undefined to instruct the constructor to position the object using the bbox\n left: undefined,\n top: undefined,\n });\n }\n}\n\nclassRegistry.setClass(Path);\nclassRegistry.setSVGClass(Path);\n\n/* _FROM_SVG_START_ */\n","import type { ModifierKey, TEvent } from '../EventTypeDefs';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Path } from '../shapes/Path';\nimport { getSmoothPathFromPoints, joinPath } from '../util/path';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\n/**\n * @private\n * @param {TSimplePathData} pathData SVG path commands\n * @returns {boolean}\n */\nfunction isEmptySVGPath(pathData: TSimplePathData): boolean {\n return joinPath(pathData) === 'M 0 0 Q 0 0 0 0 L 0 0';\n}\n\nexport class PencilBrush extends BaseBrush {\n /**\n * Discard points that are less than `decimate` pixel distant from each other\n * @type Number\n * @default 0.4\n */\n decimate = 0.4;\n\n /**\n * Draws a straight line between last recorded point to current pointer\n * Used for `shift` functionality\n *\n * @type boolean\n * @default false\n */\n drawStraightLine = false;\n\n /**\n * The event modifier key that makes the brush draw a straight line.\n * If `null` or 'none' or any other string that is not a modifier key the feature is disabled.\n * @type {ModifierKey | undefined | null}\n */\n straightLineKey: ModifierKey | undefined | null = 'shiftKey';\n\n private declare _points: Point[];\n private declare _hasStraightLine: boolean;\n private declare oldEnd?: Point;\n\n constructor(canvas: Canvas) {\n super(canvas);\n this._points = [];\n this._hasStraightLine = false;\n }\n\n needsFullRender() {\n return super.needsFullRender() || this._hasStraightLine;\n }\n\n static drawSegment(ctx: CanvasRenderingContext2D, p1: Point, p2: Point) {\n const midPoint = p1.midPointFrom(p2);\n ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);\n return midPoint;\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n this._prepareForDrawing(pointer);\n // capture coordinates immediately\n // this allows to draw dots (when movement never occurs)\n this._addPoint(pointer);\n this._render();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point, { e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return;\n }\n this.drawStraightLine = !!this.straightLineKey && e[this.straightLineKey];\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this._addPoint(pointer) && this._points.length > 1) {\n if (this.needsFullRender()) {\n // redraw curve\n // clear top canvas\n this.canvas.clearContext(this.canvas.contextTop);\n this._render();\n } else {\n const points = this._points,\n length = points.length,\n ctx = this.canvas.contextTop;\n // draw the curve update\n this._saveAndTransform(ctx);\n if (this.oldEnd) {\n ctx.beginPath();\n ctx.moveTo(this.oldEnd.x, this.oldEnd.y);\n }\n this.oldEnd = PencilBrush.drawSegment(\n ctx,\n points[length - 2],\n points[length - 1],\n );\n ctx.stroke();\n ctx.restore();\n }\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp({ e }: TEvent) {\n if (!this.canvas._isMainEvent(e)) {\n return true;\n }\n this.drawStraightLine = false;\n this.oldEnd = undefined;\n this._finalizeAndAddPath();\n return false;\n }\n\n /**\n * @private\n * @param {Point} pointer Actual mouse position related to the canvas.\n */\n _prepareForDrawing(pointer: Point) {\n this._reset();\n this._addPoint(pointer);\n this.canvas.contextTop.moveTo(pointer.x, pointer.y);\n }\n\n /**\n * @private\n * @param {Point} point Point to be added to points array\n */\n _addPoint(point: Point) {\n if (\n this._points.length > 1 &&\n point.eq(this._points[this._points.length - 1])\n ) {\n return false;\n }\n if (this.drawStraightLine && this._points.length > 1) {\n this._hasStraightLine = true;\n this._points.pop();\n }\n this._points.push(point);\n return true;\n }\n\n /**\n * Clear points array and set contextTop canvas style.\n * @private\n */\n _reset() {\n this._points = [];\n this._setBrushStyles(this.canvas.contextTop);\n this._setShadow();\n this._hasStraightLine = false;\n }\n\n /**\n * Draw a smooth path on the topCanvas using quadraticCurveTo\n * @private\n * @param {CanvasRenderingContext2D} [ctx]\n */\n _render(ctx: CanvasRenderingContext2D = this.canvas.contextTop) {\n let p1 = this._points[0],\n p2 = this._points[1];\n this._saveAndTransform(ctx);\n ctx.beginPath();\n //if we only have 2 points in the path and they are the same\n //it means that the user only clicked the canvas without moving the mouse\n //then we should be drawing a dot. A path isn't drawn between two identical dots\n //that's why we set them apart a bit\n if (this._points.length === 2 && p1.x === p2.x && p1.y === p2.y) {\n const width = this.width / 1000;\n p1.x -= width;\n p2.x += width;\n }\n ctx.moveTo(p1.x, p1.y);\n\n for (let i = 1; i < this._points.length; i++) {\n // we pick the point between pi + 1 & pi + 2 as the\n // end point and p1 as our control point.\n PencilBrush.drawSegment(ctx, p1, p2);\n p1 = this._points[i];\n p2 = this._points[i + 1];\n }\n // Draw last line as a straight line while\n // we wait for the next point to be able to calculate\n // the bezier control point\n ctx.lineTo(p1.x, p1.y);\n ctx.stroke();\n ctx.restore();\n }\n\n /**\n * Converts points to SVG path\n * @param {Point[]} points Array of points\n * @return {TSimplePathData} SVG path commands\n */\n convertPointsToSVGPath(points: Point[]): TSimplePathData {\n const correction = this.width / 1000;\n return getSmoothPathFromPoints(points, correction);\n }\n\n /**\n * Creates a Path object to add on canvas\n * @param {TSimplePathData} pathData Path data\n * @return {Path} Path to add on canvas\n */\n createPath(pathData: TSimplePathData): Path {\n const path = new Path(pathData, {\n fill: null,\n stroke: this.color,\n strokeWidth: this.width,\n strokeLineCap: this.strokeLineCap,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeLineJoin: this.strokeLineJoin,\n strokeDashArray: this.strokeDashArray,\n });\n if (this.shadow) {\n this.shadow.affectStroke = true;\n path.shadow = new Shadow(this.shadow);\n }\n\n return path;\n }\n\n /**\n * Decimate points array with the decimate value\n */\n decimatePoints(points: Point[], distance: number) {\n if (points.length <= 2) {\n return points;\n }\n let lastPoint = points[0],\n cDistance;\n const zoom = this.canvas.getZoom(),\n adjustedDistance = Math.pow(distance / zoom, 2),\n l = points.length - 1,\n newPoints = [lastPoint];\n for (let i = 1; i < l - 1; i++) {\n cDistance =\n Math.pow(lastPoint.x - points[i].x, 2) +\n Math.pow(lastPoint.y - points[i].y, 2);\n if (cDistance >= adjustedDistance) {\n lastPoint = points[i];\n newPoints.push(lastPoint);\n }\n }\n // Add the last point from the original line to the end of the array.\n // This ensures decimate doesn't delete the last point on the line, and ensures the line is > 1 point.\n newPoints.push(points[l]);\n return newPoints;\n }\n\n /**\n * On mouseup after drawing the path on contextTop canvas\n * we use the points captured to create an new Path object\n * and add it to the canvas.\n */\n _finalizeAndAddPath() {\n const ctx = this.canvas.contextTop;\n ctx.closePath();\n if (this.decimate) {\n this._points = this.decimatePoints(this._points, this.decimate);\n }\n const pathData = this.convertPointsToSVGPath(this._points);\n if (isEmptySVGPath(pathData)) {\n // do not create 0 width/height paths, as they are\n // rendered inconsistently across browsers\n // Firefox 4, for example, renders a dot,\n // whereas Chrome 10 renders nothing\n this.canvas.requestRenderAll();\n return;\n }\n\n const path = this.createPath(pathData);\n this.canvas.clearContext(this.canvas.contextTop);\n this.canvas.fire('before:path:created', { path: path });\n this.canvas.add(path);\n this.canvas.requestRenderAll();\n path.setCoords();\n this._resetShadow();\n\n // fire event 'path' created\n this.canvas.fire('path:created', { path: path });\n }\n}\n","import type { ObjectEvents } from '../EventTypeDefs';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { cos } from '../util/misc/cos';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { sin } from '../util/misc/sin';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { CSSRules } from '../parser/typedefs';\nimport { SCALE_X, SCALE_Y } from '../constants';\n\ninterface UniqueCircleProps {\n /**\n * Radius of this circle\n * @type Number\n * @default 0\n */\n radius: number;\n\n /**\n * Angle for the start of the circle, in degrees.\n * @type TDegree 0 - 359\n * @default 0\n */\n startAngle: number;\n\n /**\n * Angle for the end of the circle, in degrees\n * @type TDegree 1 - 360\n * @default 360\n */\n endAngle: number;\n\n /**\n * Orientation for the direction of the circle.\n * Setting to true will switch the arc of the circle to traverse from startAngle to endAngle in a counter-clockwise direction.\n * Note: this will only change how the circle is drawn, and does not affect rotational transformation.\n * @default false\n */\n counterClockwise: boolean;\n}\n\nexport interface SerializedCircleProps\n extends SerializedObjectProps,\n UniqueCircleProps {}\n\nexport interface CircleProps extends FabricObjectProps, UniqueCircleProps {}\n\nconst CIRCLE_PROPS = [\n 'radius',\n 'startAngle',\n 'endAngle',\n 'counterClockwise',\n] as const;\n\nexport const circleDefaultValues: Partial> = {\n radius: 0,\n startAngle: 0,\n endAngle: 360,\n counterClockwise: false,\n};\n\nexport class Circle<\n Props extends TOptions = Partial,\n SProps extends SerializedCircleProps = SerializedCircleProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueCircleProps\n{\n declare radius: number;\n declare startAngle: number;\n declare endAngle: number;\n declare counterClockwise: boolean;\n\n static type = 'Circle';\n\n static cacheProperties = [...cacheProperties, ...CIRCLE_PROPS];\n\n static ownDefaults = circleDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Circle.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Circle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n\n if (key === 'radius') {\n this.setRadius(value);\n }\n\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.arc(\n 0,\n 0,\n this.radius,\n degreesToRadians(this.startAngle),\n degreesToRadians(this.endAngle),\n this.counterClockwise,\n );\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusX(): number {\n return this.get('radius') * this.get(SCALE_X);\n }\n\n /**\n * Returns vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRadiusY(): number {\n return this.get('radius') * this.get(SCALE_Y);\n }\n\n /**\n * Sets radius of an object (and updates width accordingly)\n */\n setRadius(value: number) {\n this.radius = value;\n this.set({ width: value * 2, height: value * 2 });\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...CIRCLE_PROPS, ...propertiesToInclude]);\n }\n\n /* _TO_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n const angle = (this.endAngle - this.startAngle) % 360;\n\n if (angle === 0) {\n return [\n '\\n',\n ];\n } else {\n const { radius } = this;\n const start = degreesToRadians(this.startAngle),\n end = degreesToRadians(this.endAngle),\n startX = cos(start) * radius,\n startY = sin(start) * radius,\n endX = cos(end) * radius,\n endY = sin(end) * radius,\n largeFlag = angle > 180 ? 1 : 0,\n sweepFlag = this.counterClockwise ? 0 : 1;\n return [\n `\\n',\n ];\n }\n }\n /* _TO_SVG_END_ */\n\n /* _FROM_SVG_START_ */\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Circle.fromElement})\n * @static\n * @memberOf Circle\n * @see: http://www.w3.org/TR/SVG/shapes.html#CircleElement\n */\n static ATTRIBUTE_NAMES = ['cx', 'cy', 'r', ...SHARED_ATTRIBUTES];\n\n /**\n * Returns {@link Circle} instance from an SVG element\n * @static\n * @memberOf Circle\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Partial Circle object to default missing properties on the element.\n * @throws {Error} If value of `r` attribute is missing or invalid\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ): Promise {\n const {\n left = 0,\n top = 0,\n radius = 0,\n ...otherParsedAttributes\n } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n ) as Partial;\n\n // this probably requires to be fixed for default origins not being top/left.\n\n return new this({\n ...otherParsedAttributes,\n radius,\n left: left - radius,\n top: top - radius,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * @todo how do we declare this??\n */\n static fromObject>(object: T) {\n return super._fromObject(object);\n }\n}\n\nclassRegistry.setClass(Circle);\nclassRegistry.setSVGClass(Circle);\n","import { Color } from '../color/Color';\nimport type { Point } from '../Point';\nimport { Shadow } from '../Shadow';\nimport { Circle } from '../shapes/Circle';\nimport { Group } from '../shapes/Group';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { CircleBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\nexport class CircleBrush extends BaseBrush {\n /**\n * Width of a brush\n * @type Number\n * @default\n */\n width = 10;\n\n declare points: CircleBrushPoint[];\n\n constructor(canvas: Canvas) {\n super(canvas);\n this.points = [];\n }\n\n /**\n * Invoked inside on mouse down and mouse move\n * @param {Point} pointer\n */\n drawDot(pointer: Point) {\n const point = this.addPoint(pointer),\n ctx = this.canvas.contextTop;\n this._saveAndTransform(ctx);\n this.dot(ctx, point);\n ctx.restore();\n }\n\n dot(ctx: CanvasRenderingContext2D, point: CircleBrushPoint) {\n ctx.fillStyle = point.fill;\n ctx.beginPath();\n ctx.arc(point.x, point.y, point.radius, 0, Math.PI * 2, false);\n ctx.closePath();\n ctx.fill();\n }\n\n /**\n * Invoked on mouse down\n */\n onMouseDown(pointer: Point) {\n this.points = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n this.drawDot(pointer);\n }\n\n /**\n * Render the full state of the brush\n * @private\n */\n _render() {\n const ctx = this.canvas.contextTop,\n points = this.points;\n this._saveAndTransform(ctx);\n for (let i = 0; i < points.length; i++) {\n this.dot(ctx, points[i]);\n }\n ctx.restore();\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n if (this.needsFullRender()) {\n this.canvas.clearContext(this.canvas.contextTop);\n this.addPoint(pointer);\n this._render();\n } else {\n this.drawDot(pointer);\n }\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const circles: Circle[] = [];\n\n for (let i = 0; i < this.points.length; i++) {\n const point = this.points[i],\n circle = new Circle({\n radius: point.radius,\n left: point.x,\n top: point.y,\n originX: CENTER,\n originY: CENTER,\n fill: point.fill,\n });\n\n this.shadow && (circle.shadow = new Shadow(this.shadow));\n\n circles.push(circle);\n }\n const group = new Group(circles, { canvas: this.canvas });\n\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n /**\n * @param {Object} pointer\n * @return {Point} Just added pointer point\n */\n addPoint({ x, y }: Point) {\n const pointerPoint: CircleBrushPoint = {\n x,\n y,\n radius: getRandomInt(Math.max(0, this.width - 20), this.width + 20) / 2,\n fill: new Color(this.color).setAlpha(getRandomInt(0, 100) / 100).toRgba(),\n };\n\n this.points.push(pointerPoint);\n\n return pointerPoint;\n }\n}\n","import type { Point } from '../Point';\nimport { Group } from '../shapes/Group';\nimport { Shadow } from '../Shadow';\nimport { Rect } from '../shapes/Rect';\nimport { getRandomInt } from '../util/internals/getRandomInt';\nimport type { Canvas } from '../canvas/Canvas';\nimport { BaseBrush } from './BaseBrush';\nimport type { SprayBrushPoint } from './typedefs';\nimport { CENTER } from '../constants';\n\n/**\n *\n * @param rects\n * @returns\n */\nfunction getUniqueRects(rects: Rect[]) {\n const uniqueRects: Record = {};\n const uniqueRectsArray: Rect[] = [];\n\n for (let i = 0, key: string; i < rects.length; i++) {\n key = `${rects[i].left}${rects[i].top}`;\n if (!uniqueRects[key]) {\n uniqueRects[key] = true;\n uniqueRectsArray.push(rects[i]);\n }\n }\n\n return uniqueRectsArray;\n}\n\nexport class SprayBrush extends BaseBrush {\n /**\n * Width of a spray\n * @type Number\n * @default\n */\n width = 10;\n\n /**\n * Density of a spray (number of dots per chunk)\n * @type Number\n * @default\n */\n density = 20;\n\n /**\n * Width of spray dots\n * @type Number\n * @default\n */\n dotWidth = 1;\n\n /**\n * Width variance of spray dots\n * @type Number\n * @default\n */\n dotWidthVariance = 1;\n\n /**\n * Whether opacity of a dot should be random\n * @type Boolean\n * @default\n */\n randomOpacity = false;\n\n /**\n * Whether overlapping dots (rectangles) should be removed (for performance reasons)\n * @type Boolean\n * @default\n */\n optimizeOverlapping = true;\n\n private declare sprayChunks: SprayBrushPoint[][];\n\n private declare sprayChunk: SprayBrushPoint[];\n\n /**\n * Constructor\n * @param {Canvas} canvas\n * @return {SprayBrush} Instance of a spray brush\n */\n constructor(canvas: Canvas) {\n super(canvas);\n this.sprayChunks = [];\n this.sprayChunk = [];\n }\n\n /**\n * Invoked on mouse down\n * @param {Point} pointer\n */\n onMouseDown(pointer: Point) {\n this.sprayChunks = [];\n this.canvas.clearContext(this.canvas.contextTop);\n this._setShadow();\n\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse move\n * @param {Point} pointer\n */\n onMouseMove(pointer: Point) {\n if (this.limitedToCanvasSize === true && this._isOutSideCanvas(pointer)) {\n return;\n }\n this.addSprayChunk(pointer);\n this.renderChunck(this.sprayChunk);\n }\n\n /**\n * Invoked on mouse up\n */\n onMouseUp() {\n const originalRenderOnAddRemove = this.canvas.renderOnAddRemove;\n this.canvas.renderOnAddRemove = false;\n\n const rects: Rect[] = [];\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n const sprayChunk = this.sprayChunks[i];\n for (let j = 0; j < sprayChunk.length; j++) {\n const chunck = sprayChunk[j];\n const rect = new Rect({\n width: chunck.width,\n height: chunck.width,\n left: chunck.x + 1,\n top: chunck.y + 1,\n originX: CENTER,\n originY: CENTER,\n fill: this.color,\n });\n rects.push(rect);\n }\n }\n\n const group = new Group(\n this.optimizeOverlapping ? getUniqueRects(rects) : rects,\n {\n objectCaching: true,\n subTargetCheck: false,\n interactive: false,\n },\n );\n this.shadow && group.set('shadow', new Shadow(this.shadow));\n this.canvas.fire('before:path:created', { path: group });\n this.canvas.add(group);\n this.canvas.fire('path:created', { path: group });\n\n this.canvas.clearContext(this.canvas.contextTop);\n this._resetShadow();\n this.canvas.renderOnAddRemove = originalRenderOnAddRemove;\n this.canvas.requestRenderAll();\n }\n\n renderChunck(sprayChunck: SprayBrushPoint[]) {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < sprayChunck.length; i++) {\n const point = sprayChunck[i];\n ctx.globalAlpha = point.opacity;\n ctx.fillRect(point.x, point.y, point.width, point.width);\n }\n\n ctx.restore();\n }\n\n /**\n * Render all spray chunks\n */\n _render() {\n const ctx = this.canvas.contextTop;\n ctx.fillStyle = this.color;\n\n this._saveAndTransform(ctx);\n\n for (let i = 0; i < this.sprayChunks.length; i++) {\n this.renderChunck(this.sprayChunks[i]);\n }\n ctx.restore();\n }\n\n /**\n * @param {Point} pointer\n */\n addSprayChunk(pointer: Point) {\n this.sprayChunk = [];\n const radius = this.width / 2;\n\n for (let i = 0; i < this.density; i++) {\n this.sprayChunk.push({\n x: getRandomInt(pointer.x - radius, pointer.x + radius),\n y: getRandomInt(pointer.y - radius, pointer.y + radius),\n width: this.dotWidthVariance\n ? getRandomInt(\n // bottom clamp width to 1\n Math.max(1, this.dotWidth - this.dotWidthVariance),\n this.dotWidth + this.dotWidthVariance,\n )\n : this.dotWidth,\n opacity: this.randomOpacity ? getRandomInt(0, 100) / 100 : 1,\n });\n }\n\n this.sprayChunks.push(this.sprayChunk);\n }\n}\n","import { Pattern } from '../Pattern';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { Canvas } from '../canvas/Canvas';\nimport { PencilBrush } from './PencilBrush';\nimport type { TSimplePathData } from '../util/path/typedefs';\n\nexport class PatternBrush extends PencilBrush {\n declare source?: CanvasImageSource;\n\n constructor(canvas: Canvas) {\n super(canvas);\n }\n\n getPatternSrc() {\n const dotWidth = 20,\n dotDistance = 5,\n patternCanvas = createCanvasElement(),\n patternCtx = patternCanvas.getContext('2d');\n\n patternCanvas.width = patternCanvas.height = dotWidth + dotDistance;\n if (patternCtx) {\n patternCtx.fillStyle = this.color;\n patternCtx.beginPath();\n patternCtx.arc(\n dotWidth / 2,\n dotWidth / 2,\n dotWidth / 2,\n 0,\n Math.PI * 2,\n false,\n );\n patternCtx.closePath();\n patternCtx.fill();\n }\n return patternCanvas;\n }\n\n /**\n * Creates \"pattern\" instance property\n * @param {CanvasRenderingContext2D} ctx\n */\n getPattern(ctx: CanvasRenderingContext2D) {\n return ctx.createPattern(this.source || this.getPatternSrc(), 'repeat');\n }\n\n /**\n * Sets brush styles\n * @param {CanvasRenderingContext2D} ctx\n */\n _setBrushStyles(ctx: CanvasRenderingContext2D) {\n super._setBrushStyles(ctx);\n const pattern = this.getPattern(ctx);\n pattern && (ctx.strokeStyle = pattern);\n }\n\n /**\n * Creates path\n */\n createPath(pathData: TSimplePathData) {\n const path = super.createPath(pathData),\n topLeft = path._getLeftTopCoords().scalarAdd(path.strokeWidth / 2);\n\n path.stroke = new Pattern({\n source: this.source || this.getPatternSrc(),\n offsetX: -topLeft.x,\n offsetY: -topLeft.y,\n });\n return path;\n }\n}\n","import { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport { Point } from '../Point';\nimport { isFiller } from '../util/typeAssertions';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { makeBoundingBoxFromPoints } from '../util';\nimport { CENTER, LEFT, TOP } from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\n// @TODO this code is terrible and Line should be a special case of polyline.\n\nconst coordProps = ['x1', 'x2', 'y1', 'y2'] as const;\n\ninterface UniqueLineProps {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n\nexport interface SerializedLineProps\n extends SerializedObjectProps,\n UniqueLineProps {}\n\nexport class Line<\n Props extends TOptions = Partial,\n SProps extends SerializedLineProps = SerializedLineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements UniqueLineProps\n{\n /**\n * x value or first line edge\n * @type number\n * @default\n */\n declare x1: number;\n\n /**\n * y value or first line edge\n * @type number\n * @default\n */\n declare y1: number;\n\n /**\n * x value or second line edge\n * @type number\n * @default\n */\n declare x2: number;\n\n /**\n * y value or second line edge\n * @type number\n * @default\n */\n declare y2: number;\n\n static type = 'Line';\n\n static cacheProperties = [...cacheProperties, ...coordProps];\n /**\n * Constructor\n * @param {Array} [points] Array of points\n * @param {Object} [options] Options object\n * @return {Line} thisArg\n */\n constructor([x1, y1, x2, y2] = [0, 0, 0, 0], options: Partial = {}) {\n super();\n Object.assign(this, Line.ownDefaults);\n this.setOptions(options);\n this.x1 = x1;\n this.x2 = x2;\n this.y1 = y1;\n this.y2 = y2;\n this._setWidthHeight();\n const { left, top } = options;\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n /**\n * @private\n * @param {Object} [options] Options\n */\n _setWidthHeight() {\n const { x1, y1, x2, y2 } = this;\n this.width = Math.abs(x2 - x1);\n this.height = Math.abs(y2 - y1);\n const { left, top, width, height } = makeBoundingBoxFromPoints([\n { x: x1, y: y1 },\n { x: x2, y: y2 },\n ]);\n const position = new Point(left + width / 2, top + height / 2);\n this.setPositionByOrigin(position, CENTER, CENTER);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n super._set(key, value);\n if (coordProps.includes(key as keyof UniqueLineProps)) {\n // this doesn't make sense very much, since setting x1 when top or left\n // are already set, is just going to show a strange result since the\n // line will move way more than the developer expect.\n // in fabric5 it worked only when the line didn't have extra transformations,\n // in fabric6 too. With extra transform they behave bad in different ways.\n // This needs probably a good rework or a tutorial if you have to create a dynamic line\n this._setWidthHeight();\n }\n return this;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n\n const p = this.calcLinePoints();\n ctx.moveTo(p.x1, p.y1);\n ctx.lineTo(p.x2, p.y2);\n\n ctx.lineWidth = this.strokeWidth;\n\n // TODO: test this\n // make sure setting \"fill\" changes color of a line\n // (by copying fillStyle to strokeStyle, since line is stroked, not filled)\n const origStrokeStyle = ctx.strokeStyle;\n if (isFiller(this.stroke)) {\n ctx.strokeStyle = this.stroke.toLive(ctx)!;\n } else {\n ctx.strokeStyle = this.stroke ?? ctx.fillStyle;\n }\n this.stroke && this._renderStroke(ctx);\n ctx.strokeStyle = origStrokeStyle;\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n return new Point((this.x1 + this.x2) / 2, (this.y1 + this.y2) / 2);\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n ...this.calcLinePoints(),\n };\n }\n\n /*\n * Calculate object dimensions from its properties\n * @private\n */\n _getNonTransformedDimensions(): Point {\n const dim = super._getNonTransformedDimensions();\n if (this.strokeLineCap === 'butt') {\n if (this.width === 0) {\n dim.y -= this.strokeWidth;\n }\n if (this.height === 0) {\n dim.x -= this.strokeWidth;\n }\n }\n return dim;\n }\n\n /**\n * Recalculates line points given width and height\n * Those points are simply placed around the center,\n * This is not useful outside internal render functions and svg output\n * Is not meant to be for the developer.\n * @private\n */\n calcLinePoints(): UniqueLineProps {\n const { x1: _x1, x2: _x2, y1: _y1, y2: _y2, width, height } = this;\n const xMult = _x1 <= _x2 ? -1 : 1,\n yMult = _y1 <= _y2 ? -1 : 1,\n x1 = (xMult * width) / 2,\n y1 = (yMult * height) / 2,\n x2 = (xMult * -width) / 2,\n y2 = (yMult * -height) / 2;\n\n return {\n x1,\n x2,\n y1,\n y2,\n };\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const { x1, x2, y1, y2 } = this.calcLinePoints();\n return [\n '\\n`,\n ];\n }\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})\n * @static\n * @memberOf Line\n * @see http://www.w3.org/TR/SVG/shapes.html#LineElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(coordProps);\n\n /**\n * Returns Line instance from an SVG element\n * @static\n * @memberOf Line\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {Function} [callback] callback function invoked after parsing\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const {\n x1 = 0,\n y1 = 0,\n x2 = 0,\n y2 = 0,\n ...parsedAttributes\n } = parseAttributes(element, this.ATTRIBUTE_NAMES, cssRules);\n return new this([x1, y1, x2, y2], parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Line instance from an object representation\n * @static\n * @memberOf Line\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>({\n x1,\n y1,\n x2,\n y2,\n ...object\n }: T) {\n return this._fromObject(\n {\n ...object,\n points: [x1, y1, x2, y2],\n },\n {\n extraParam: 'points',\n },\n );\n }\n}\n\nclassRegistry.setClass(Line);\nclassRegistry.setSVGClass(Line);\n","import { classRegistry } from '../ClassRegistry';\nimport { FabricObject } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { TClassProperties, TOptions } from '../typedefs';\nimport type { ObjectEvents } from '../EventTypeDefs';\n\nexport const triangleDefaultValues: Partial> = {\n width: 100,\n height: 100,\n};\n\nexport class Triangle<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements FabricObjectProps\n{\n static type = 'Triangle';\n\n static ownDefaults = triangleDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...Triangle.ownDefaults };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Triangle.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2;\n\n ctx.beginPath();\n ctx.moveTo(-widthBy2, heightBy2);\n ctx.lineTo(0, -heightBy2);\n ctx.lineTo(widthBy2, heightBy2);\n ctx.closePath();\n\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const widthBy2 = this.width / 2,\n heightBy2 = this.height / 2,\n points = `${-widthBy2} ${heightBy2},0 ${-heightBy2},${widthBy2} ${heightBy2}`;\n return [''];\n }\n}\n\nclassRegistry.setClass(Triangle);\nclassRegistry.setSVGClass(Triangle);\n","import { SCALE_X, SCALE_Y, twoMathPi } from '../constants';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const ellipseDefaultValues: Partial> = {\n rx: 0,\n ry: 0,\n};\n\ninterface UniqueEllipseProps {\n rx: number;\n ry: number;\n}\n\nexport interface SerializedEllipseProps\n extends SerializedObjectProps,\n UniqueEllipseProps {}\n\nexport interface EllipseProps extends FabricObjectProps, UniqueEllipseProps {}\n\nconst ELLIPSE_PROPS = ['rx', 'ry'] as const;\n\nexport class Ellipse<\n Props extends TOptions = Partial,\n SProps extends SerializedEllipseProps = SerializedEllipseProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements EllipseProps\n{\n /**\n * Horizontal radius\n * @type Number\n * @default\n */\n declare rx: number;\n\n /**\n * Vertical radius\n * @type Number\n * @default\n */\n declare ry: number;\n\n static type = 'Ellipse';\n\n static cacheProperties = [...cacheProperties, ...ELLIPSE_PROPS];\n\n static ownDefaults = ellipseDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Ellipse.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor(options?: Props) {\n super();\n Object.assign(this, Ellipse.ownDefaults);\n this.setOptions(options);\n }\n\n /**\n * @private\n * @param {String} key\n * @param {*} value\n * @return {Ellipse} thisArg\n */\n _set(key: string, value: any) {\n super._set(key, value);\n switch (key) {\n case 'rx':\n this.rx = value;\n this.set('width', value * 2);\n break;\n\n case 'ry':\n this.ry = value;\n this.set('height', value * 2);\n break;\n }\n return this;\n }\n\n /**\n * Returns horizontal radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRx() {\n return this.get('rx') * this.get(SCALE_X);\n }\n\n /**\n * Returns Vertical radius of an object (according to how an object is scaled)\n * @return {Number}\n */\n getRy() {\n return this.get('ry') * this.get(SCALE_Y);\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([...ELLIPSE_PROPS, ...propertiesToInclude]);\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG(): string[] {\n return [\n '\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.beginPath();\n ctx.save();\n ctx.transform(1, 0, 0, this.ry / this.rx, 0, 0);\n ctx.arc(0, 0, this.rx, 0, twoMathPi, false);\n ctx.restore();\n this._renderPaintInOrder(ctx);\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Ellipse.fromElement})\n * @static\n * @memberOf Ellipse\n * @see http://www.w3.org/TR/SVG/shapes.html#EllipseElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES, 'cx', 'cy', 'rx', 'ry'];\n\n /**\n * Returns {@link Ellipse} instance from an SVG element\n * @static\n * @memberOf Ellipse\n * @param {HTMLElement} element Element to parse\n * @return {Ellipse}\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;\n parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;\n return new this(parsedAttributes);\n }\n\n /* _FROM_SVG_END_ */\n}\n\nclassRegistry.setClass(Ellipse);\nclassRegistry.setSVGClass(Ellipse);\n","import type { XY } from '../Point';\n\n/**\n * Parses \"points\" attribute, returning an array of values\n * @static\n * @memberOf fabric\n * @param {String} points points attribute string\n * @return {Array} array of points\n */\nexport function parsePointsAttribute(points: string | null): XY[] {\n // points attribute is required and must not be empty\n if (!points) {\n return [];\n }\n\n // replace commas with whitespace and remove bookending whitespace\n const pointsSplit: string[] = points.replace(/,/g, ' ').trim().split(/\\s+/);\n\n const parsedPoints = [];\n\n for (let i = 0; i < pointsSplit.length; i += 2) {\n parsedPoints.push({\n x: parseFloat(pointsSplit[i]),\n y: parseFloat(pointsSplit[i + 1]),\n });\n }\n\n // odd number of points is an error\n // if (parsedPoints.length % 2 !== 0) {\n // return null;\n // }\n return parsedPoints;\n}\n","import { config } from '../config';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport { parsePointsAttribute } from '../parser/parsePointsAttribute';\nimport type { XY } from '../Point';\nimport { Point } from '../Point';\nimport type { Abortable, TClassProperties, TOptions } from '../typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { makeBoundingBoxFromPoints } from '../util/misc/boundingBoxFromPoints';\nimport { calcDimensionsMatrix, transformPoint } from '../util/misc/matrix';\nimport { projectStrokeOnPoints } from '../util/misc/projectStroke';\nimport type { TProjectStrokeOnPointsOptions } from '../util/misc/projectStroke/types';\nimport { degreesToRadians } from '../util/misc/radiansDegreesConversion';\nimport { toFixed } from '../util/misc/toFixed';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport {\n CENTER,\n LEFT,\n SCALE_X,\n SCALE_Y,\n SKEW_X,\n SKEW_Y,\n TOP,\n} from '../constants';\nimport type { CSSRules } from '../parser/typedefs';\n\nexport const polylineDefaultValues: Partial> = {\n /**\n * @deprecated transient option soon to be removed in favor of a different design\n */\n exactBoundingBox: false,\n};\n\nexport interface SerializedPolylineProps extends SerializedObjectProps {\n points: XY[];\n}\n\nexport class Polyline<\n Props extends TOptions = Partial,\n SProps extends SerializedPolylineProps = SerializedPolylineProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n /**\n * Points array\n * @type Array\n * @default\n */\n declare points: XY[];\n\n /**\n * WARNING: Feature in progress\n * Calculate the exact bounding box taking in account strokeWidth on acute angles\n * this will be turned to true by default on fabric 6.0\n * maybe will be left in as an optimization since calculations may be slow\n * @deprecated transient option soon to be removed in favor of a different design\n * @type Boolean\n * @default false\n */\n declare exactBoundingBox: boolean;\n\n private declare initialized: true | undefined;\n\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polyline';\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Polyline.ownDefaults,\n };\n }\n\n /**\n * A list of properties that if changed trigger a recalculation of dimensions\n * @todo check if you really need to recalculate for all cases\n */\n static layoutProperties: (keyof Polyline)[] = [\n SKEW_X,\n SKEW_Y,\n 'strokeLineCap',\n 'strokeLineJoin',\n 'strokeMiterLimit',\n 'strokeWidth',\n 'strokeUniform',\n 'points',\n ];\n\n declare pathOffset: Point;\n\n declare strokeOffset: Point;\n\n static cacheProperties = [...cacheProperties, 'points'];\n\n strokeDiff: Point;\n\n /**\n * Constructor\n * @param {Array} points Array of points (where each point is an object with x and y)\n * @param {Object} [options] Options object\n * @return {Polyline} thisArg\n * @example\n * var poly = new Polyline([\n * { x: 10, y: 10 },\n * { x: 50, y: 30 },\n * { x: 40, y: 70 },\n * { x: 60, y: 50 },\n * { x: 100, y: 150 },\n * { x: 40, y: 100 }\n * ], {\n * stroke: 'red',\n * left: 100,\n * top: 100\n * });\n */\n constructor(points: XY[] = [], options: Props = {} as Props) {\n super();\n Object.assign(this, Polyline.ownDefaults);\n this.setOptions(options);\n this.points = points;\n const { left, top } = options;\n this.initialized = true;\n this.setBoundingBox(true);\n typeof left === 'number' && this.set(LEFT, left);\n typeof top === 'number' && this.set(TOP, top);\n }\n\n protected isOpen() {\n return true;\n }\n\n private _projectStrokeOnPoints(options: TProjectStrokeOnPointsOptions) {\n return projectStrokeOnPoints(this.points, options, this.isOpen());\n }\n\n /**\n * Calculate the polygon bounding box\n * @private\n */\n _calcDimensions(options?: Partial) {\n options = {\n scaleX: this.scaleX,\n scaleY: this.scaleY,\n skewX: this.skewX,\n skewY: this.skewY,\n strokeLineCap: this.strokeLineCap,\n strokeLineJoin: this.strokeLineJoin,\n strokeMiterLimit: this.strokeMiterLimit,\n strokeUniform: this.strokeUniform,\n strokeWidth: this.strokeWidth,\n ...(options || {}),\n };\n const points = this.exactBoundingBox\n ? this._projectStrokeOnPoints(\n options as TProjectStrokeOnPointsOptions,\n ).map((projection) => projection.projectedPoint)\n : this.points;\n if (points.length === 0) {\n return {\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n pathOffset: new Point(),\n strokeOffset: new Point(),\n strokeDiff: new Point(),\n };\n }\n const bbox = makeBoundingBoxFromPoints(points),\n // Remove scale effect, since it's applied after\n matrix = calcDimensionsMatrix({ ...options, scaleX: 1, scaleY: 1 }),\n bboxNoStroke = makeBoundingBoxFromPoints(\n this.points.map((p) => transformPoint(p, matrix, true)),\n ),\n scale = new Point(this.scaleX, this.scaleY);\n let offsetX = bbox.left + bbox.width / 2,\n offsetY = bbox.top + bbox.height / 2;\n if (this.exactBoundingBox) {\n offsetX = offsetX - offsetY * Math.tan(degreesToRadians(this.skewX));\n // Order of those assignments is important.\n // offsetY relies on offsetX being already changed by the line above\n offsetY = offsetY - offsetX * Math.tan(degreesToRadians(this.skewY));\n }\n\n return {\n ...bbox,\n pathOffset: new Point(offsetX, offsetY),\n strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top)\n .subtract(new Point(bbox.left, bbox.top))\n .multiply(scale),\n strokeDiff: new Point(bbox.width, bbox.height)\n .subtract(new Point(bboxNoStroke.width, bboxNoStroke.height))\n .multiply(scale),\n };\n }\n\n /**\n * This function is an helper for svg import. it returns the center of the object in the svg\n * untransformed coordinates, by look at the polyline/polygon points.\n * @private\n * @return {Point} center point from element coordinates\n */\n _findCenterFromElement(): Point {\n const bbox = makeBoundingBoxFromPoints(this.points);\n return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);\n }\n\n setDimensions() {\n this.setBoundingBox();\n }\n\n setBoundingBox(adjustPosition?: boolean) {\n const { left, top, width, height, pathOffset, strokeOffset, strokeDiff } =\n this._calcDimensions();\n this.set({ width, height, pathOffset, strokeOffset, strokeDiff });\n adjustPosition &&\n this.setPositionByOrigin(\n new Point(left + width / 2, top + height / 2),\n CENTER,\n CENTER,\n );\n }\n\n /**\n * @deprecated intermidiate method to be removed, do not use\n */\n protected isStrokeAccountedForInDimensions() {\n return this.exactBoundingBox;\n }\n\n /**\n * @override stroke is taken in account in size\n */\n _getNonTransformedDimensions() {\n return this.exactBoundingBox\n ? // TODO: fix this\n new Point(this.width, this.height)\n : super._getNonTransformedDimensions();\n }\n\n /**\n * @override stroke and skewing are taken into account when projecting stroke on points,\n * therefore we don't want the default calculation to account for skewing as well.\n * Though it is possible to pass `width` and `height` in `options`, doing so is very strange, use with discretion.\n *\n * @private\n */\n _getTransformedDimensions(options: any = {}) {\n if (this.exactBoundingBox) {\n let size: Point;\n /* When `strokeUniform = true`, any changes to the properties require recalculating the `width` and `height` because\n the stroke projections are affected.\n When `strokeUniform = false`, we don't need to recalculate for scale transformations, as the effect of scale on\n projections follows a linear function (e.g. scaleX of 2 just multiply width by 2)*/\n if (\n Object.keys(options).some(\n (key) =>\n this.strokeUniform ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof TProjectStrokeOnPointsOptions,\n ),\n )\n ) {\n const { width, height } = this._calcDimensions(options);\n size = new Point(options.width ?? width, options.height ?? height);\n } else {\n size = new Point(\n options.width ?? this.width,\n options.height ?? this.height,\n );\n }\n return size.multiply(\n new Point(options.scaleX || this.scaleX, options.scaleY || this.scaleY),\n );\n } else {\n return super._getTransformedDimensions(options);\n }\n }\n\n /**\n * Recalculates dimensions when changing skew and scale\n * @private\n */\n _set(key: string, value: any) {\n const changed = this.initialized && this[key as keyof this] !== value;\n const output = super._set(key, value);\n if (\n this.exactBoundingBox &&\n changed &&\n (((key === SCALE_X || key === SCALE_Y) &&\n this.strokeUniform &&\n (this.constructor as typeof Polyline).layoutProperties.includes(\n 'strokeUniform',\n )) ||\n (this.constructor as typeof Polyline).layoutProperties.includes(\n key as keyof Polyline,\n ))\n ) {\n this.setDimensions();\n }\n return output;\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject(propertiesToInclude),\n points: this.points.map(({ x, y }) => ({ x, y })),\n };\n }\n\n /**\n * Returns svg representation of an instance\n * @return {Array} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const points = [],\n diffX = this.pathOffset.x,\n diffY = this.pathOffset.y,\n NUM_FRACTION_DIGITS = config.NUM_FRACTION_DIGITS;\n\n for (let i = 0, len = this.points.length; i < len; i++) {\n points.push(\n toFixed(this.points[i].x - diffX, NUM_FRACTION_DIGITS),\n ',',\n toFixed(this.points[i].y - diffY, NUM_FRACTION_DIGITS),\n ' ',\n );\n }\n return [\n `<${\n (this.constructor as typeof Polyline).type.toLowerCase() as\n | 'polyline'\n | 'polygon'\n } `,\n 'COMMON_PARTS',\n `points=\"${points.join('')}\" />\\n`,\n ];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const len = this.points.length,\n x = this.pathOffset.x,\n y = this.pathOffset.y;\n\n if (!len || isNaN(this.points[len - 1].y)) {\n // do not draw if no points or odd points\n // NaN comes from parseFloat of a empty string in parser\n return;\n }\n ctx.beginPath();\n ctx.moveTo(this.points[0].x - x, this.points[0].y - y);\n for (let i = 0; i < len; i++) {\n const point = this.points[i];\n ctx.lineTo(point.x - x, point.y - y);\n }\n !this.isOpen() && ctx.closePath();\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity of this instance\n */\n complexity(): number {\n return this.points.length;\n }\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link Polyline.fromElement})\n * @static\n * @memberOf Polyline\n * @see: http://www.w3.org/TR/SVG/shapes.html#PolylineElement\n */\n static ATTRIBUTE_NAMES = [...SHARED_ATTRIBUTES];\n\n /**\n * Returns Polyline instance from an SVG element\n * @static\n * @memberOf Polyline\n * @param {HTMLElement} element Element to parser\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const points = parsePointsAttribute(element.getAttribute('points')),\n // we omit left and top to instruct the constructor to position the object using the bbox\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n { left, top, ...parsedAttributes } = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return new this(points, {\n ...parsedAttributes,\n ...options,\n });\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns Polyline instance from an object representation\n * @static\n * @memberOf Polyline\n * @param {Object} object Object to create an instance from\n * @returns {Promise}\n */\n static fromObject>(object: T) {\n return this._fromObject(object, {\n extraParam: 'points',\n });\n }\n}\n\nclassRegistry.setClass(Polyline);\nclassRegistry.setSVGClass(Polyline);\n","import { classRegistry } from '../ClassRegistry';\nimport { Polyline, polylineDefaultValues } from './Polyline';\n\nexport class Polygon extends Polyline {\n static ownDefaults = polylineDefaultValues;\n\n static type = 'Polygon';\n\n protected isOpen() {\n return false;\n }\n}\n\nclassRegistry.setClass(Polygon);\nclassRegistry.setSVGClass(Polygon);\n","import { FILL, LEFT, STROKE, reNewline } from '../../constants';\nimport type { TClassProperties } from '../../typedefs';\nimport type { FabricText } from './Text';\n\nconst fontProperties = [\n 'fontSize',\n 'fontWeight',\n 'fontFamily',\n 'fontStyle',\n] as const;\n\nexport const textDecorationProperties = [\n 'underline',\n 'overline',\n 'linethrough',\n] as const;\n\nexport const textLayoutProperties: string[] = [\n ...fontProperties,\n 'lineHeight',\n 'text',\n 'charSpacing',\n 'textAlign',\n 'styles',\n 'path',\n 'pathStartOffset',\n 'pathSide',\n 'pathAlign',\n];\n\nexport const additionalProps = [\n ...textLayoutProperties,\n ...textDecorationProperties,\n 'textBackgroundColor',\n 'direction',\n] as const;\n\nexport type StylePropertiesType =\n | 'fill'\n | 'stroke'\n | 'strokeWidth'\n | 'fontSize'\n | 'fontFamily'\n | 'fontWeight'\n | 'fontStyle'\n | 'textBackgroundColor'\n | 'deltaY'\n | 'overline'\n | 'underline'\n | 'linethrough';\n\nexport const styleProperties: Readonly = [\n ...fontProperties,\n ...textDecorationProperties,\n STROKE,\n 'strokeWidth',\n FILL,\n 'deltaY',\n 'textBackgroundColor',\n] as const;\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textDefaultValues: Partial> = {\n _reNewline: reNewline,\n _reSpacesAndTabs: /[ \\t\\r]/g,\n _reSpaceAndTab: /[ \\t\\r]/,\n _reWords: /\\S+/g,\n fontSize: 40,\n fontWeight: 'normal',\n fontFamily: 'Times New Roman',\n underline: false,\n overline: false,\n linethrough: false,\n textAlign: LEFT,\n fontStyle: 'normal',\n lineHeight: 1.16,\n superscript: {\n size: 0.6, // fontSize factor\n baseline: -0.35, // baseline-shift factor (upwards)\n },\n subscript: {\n size: 0.6, // fontSize factor\n baseline: 0.11, // baseline-shift factor (downwards)\n },\n textBackgroundColor: '',\n stroke: null,\n shadow: null,\n path: undefined,\n pathStartOffset: 0,\n pathSide: LEFT,\n pathAlign: 'baseline',\n _fontSizeFraction: 0.222,\n offsets: {\n underline: 0.1,\n linethrough: -0.315,\n overline: -0.88,\n },\n _fontSizeMult: 1.13,\n charSpacing: 0,\n deltaY: 0,\n direction: 'ltr',\n CACHE_FONT_SIZE: 400,\n MIN_TEXT_WIDTH: 2,\n};\n\nexport const JUSTIFY = 'justify';\nexport const JUSTIFY_LEFT = 'justify-left';\nexport const JUSTIFY_RIGHT = 'justify-right';\nexport const JUSTIFY_CENTER = 'justify-center';\n","import type { ObjectEvents } from '../../EventTypeDefs';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { TOptions } from '../../typedefs';\nimport { FabricObject } from '../Object/FabricObject';\nimport { styleProperties } from './constants';\nimport type { StylePropertiesType } from './constants';\nimport type { FabricText } from './Text';\nimport { pick } from '../../util';\nimport { pickBy } from '../../util/misc/pick';\n\nexport type CompleteTextStyleDeclaration = Pick<\n FabricText,\n StylePropertiesType\n>;\n\nexport type TextStyleDeclaration = Partial;\n\nexport type TextStyle = {\n [line: number | string]: { [char: number | string]: TextStyleDeclaration };\n};\n\nexport abstract class StyledText<\n Props extends TOptions = Partial,\n SProps extends SerializedObjectProps = SerializedObjectProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n> extends FabricObject {\n declare abstract styles: TextStyle;\n protected declare abstract _textLines: string[][];\n protected declare _forceClearCache: boolean;\n static _styleProperties: Readonly = styleProperties;\n abstract get2DCursorLocation(\n selectionStart: number,\n skipWrapping?: boolean,\n ): { charIndex: number; lineIndex: number };\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex?: number): boolean {\n if (!this.styles) {\n return true;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return true;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n return true;\n }\n\n /**\n * Returns true if object has a style property or has it ina specified line\n * This function is used to detect if a text will use a particular property or not.\n * @param {String} property to check for\n * @param {Number} lineIndex to check the style on\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex?: number): boolean {\n if (!this.styles) {\n return false;\n }\n if (typeof lineIndex !== 'undefined' && !this.styles[lineIndex]) {\n return false;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { 0: this.styles[lineIndex] };\n // eslint-disable-next-line\n for (const p1 in obj) {\n // eslint-disable-next-line\n for (const p2 in obj[p1]) {\n if (typeof obj[p1][p2][property] !== 'undefined') {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Check if characters in a text have a value for a property\n * whose value matches the textbox's value for that property. If so,\n * the character-level property is deleted. If the character\n * has no other properties, then it is also deleted. Finally,\n * if the line containing that character has no other characters\n * then it also is deleted.\n *\n * @param {string} property The property to compare between characters and text.\n */\n cleanStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return false;\n }\n const obj = this.styles;\n let stylesCount = 0,\n letterCount,\n stylePropertyValue,\n allStyleObjectPropertiesMatch = true,\n graphemeCount = 0;\n for (const p1 in obj) {\n letterCount = 0;\n for (const p2 in obj[p1]) {\n const styleObject = obj[p1][p2] || {},\n stylePropertyHasBeenSet = styleObject[property] !== undefined;\n\n stylesCount++;\n\n if (stylePropertyHasBeenSet) {\n if (!stylePropertyValue) {\n stylePropertyValue = styleObject[property];\n } else if (styleObject[property] !== stylePropertyValue) {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (styleObject[property] === this[property as keyof this]) {\n delete styleObject[property];\n }\n } else {\n allStyleObjectPropertiesMatch = false;\n }\n\n if (Object.keys(styleObject).length !== 0) {\n letterCount++;\n } else {\n delete obj[p1][p2];\n }\n }\n\n if (letterCount === 0) {\n delete obj[p1];\n }\n }\n // if every grapheme has the same style set then\n // delete those styles and set it on the parent\n for (let i = 0; i < this._textLines.length; i++) {\n graphemeCount += this._textLines[i].length;\n }\n if (allStyleObjectPropertiesMatch && stylesCount === graphemeCount) {\n // @ts-expect-error conspiracy theory of TS\n this[property as keyof this] = stylePropertyValue;\n this.removeStyle(property);\n }\n }\n\n /**\n * Remove a style property or properties from all individual character styles\n * in a text object. Deletes the character style object if it contains no other style\n * props. Deletes a line style object if it contains no other character styles.\n *\n * @param {String} props The property to remove from character styles.\n */\n removeStyle(property: keyof TextStyleDeclaration) {\n if (!this.styles) {\n return;\n }\n const obj = this.styles;\n let line, lineNum, charNum;\n for (lineNum in obj) {\n line = obj[lineNum];\n for (charNum in line) {\n delete line[charNum][property];\n if (Object.keys(line[charNum]).length === 0) {\n delete line[charNum];\n }\n }\n if (Object.keys(line).length === 0) {\n delete obj[lineNum];\n }\n }\n }\n\n private _extendStyles(index: number, style: TextStyleDeclaration): void {\n const { lineIndex, charIndex } = this.get2DCursorLocation(index);\n\n if (!this._getLineStyle(lineIndex)) {\n this._setLineStyle(lineIndex);\n }\n\n const newStyle = pickBy(\n {\n // first create a new object that is a merge of existing and new\n ...this._getStyleDeclaration(lineIndex, charIndex),\n ...style,\n // use the predicate to discard undefined values\n },\n (value) => value !== undefined,\n );\n\n // finally assign to the old position the new style\n this._setStyleDeclaration(lineIndex, charIndex, newStyle);\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number,\n endIndex?: number,\n complete?: boolean,\n ): TextStyleDeclaration[] {\n const styles: TextStyleDeclaration[] = [];\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n styles.push(this.getStyleAtPosition(i, complete));\n }\n return styles;\n }\n\n /**\n * Gets style of a current selection/cursor position\n * @param {Number} position to get styles at\n * @param {Boolean} [complete] full style if true\n * @return {Object} style Style object at a specified index\n * @private\n */\n getStyleAtPosition(position: number, complete?: boolean) {\n const { lineIndex, charIndex } = this.get2DCursorLocation(position);\n return complete\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex)\n : this._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} styles Styles object\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified startIndex + 1\n */\n setSelectionStyles(styles: object, startIndex: number, endIndex?: number) {\n for (let i = startIndex; i < (endIndex || startIndex); i++) {\n this._extendStyles(i, styles);\n }\n /* not included in _extendStyles to avoid clearing cache more than once */\n this._forceClearCache = true;\n }\n\n /**\n * Get a reference, not a clone, to the style object for a given character,\n * if no style is set for a line or char, return a new empty object.\n * This is tricky and confusing because when you get an empty object you can't\n * determine if it is a reference or a new one.\n * @TODO this should always return a reference or always a clone or undefined when necessary.\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n const lineStyle = this.styles && this.styles[lineIndex];\n return lineStyle ? lineStyle[charIndex] ?? {} : {};\n }\n\n /**\n * return a new object that contains all the style property for a character\n * the object returned is newly created\n * @param {Number} lineIndex of the line where the character is\n * @param {Number} charIndex position of the character on the line\n * @return {Object} style object\n */\n getCompleteStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): CompleteTextStyleDeclaration {\n return {\n // @ts-expect-error readonly\n ...pick(this, (this.constructor as typeof StyledText)._styleProperties),\n ...this._getStyleDeclaration(lineIndex, charIndex),\n } as CompleteTextStyleDeclaration;\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n this.styles[lineIndex][charIndex] = style;\n }\n\n /**\n *\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n delete this.styles[lineIndex][charIndex];\n }\n\n /**\n * @param {Number} lineIndex\n * @return {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n return !!this.styles[lineIndex];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n this.styles[lineIndex] = {};\n }\n\n protected _deleteLineStyle(lineIndex: number) {\n delete this.styles[lineIndex];\n }\n}\n","import { config } from '../../config';\nimport type { TSVGReviver } from '../../typedefs';\nimport { escapeXml } from '../../util/lang_string';\nimport { colorPropToSVG, createSVGRect } from '../../util/misc/svgParsing';\nimport { hasStyleChanged } from '../../util/misc/textStyles';\nimport { toFixed } from '../../util/misc/toFixed';\nimport { FabricObjectSVGExportMixin } from '../Object/FabricObjectSVGExportMixin';\nimport { type TextStyleDeclaration } from './StyledText';\nimport { JUSTIFY } from '../Text/constants';\nimport type { FabricText } from './Text';\nimport { STROKE, FILL } from '../../constants';\n\nconst multipleSpacesRegex = / +/g;\nconst dblQuoteRegex = /\"/g;\n\nfunction createSVGInlineRect(\n color: string,\n left: number,\n top: number,\n width: number,\n height: number,\n) {\n return `\\t\\t${createSVGRect(color, { left, top, width, height })}\\n`;\n}\n\nexport class TextSVGExportMixin extends FabricObjectSVGExportMixin {\n _toSVG(this: TextSVGExportMixin & FabricText): string[] {\n const offsets = this._getSVGLeftTopOffsets(),\n textAndBg = this._getSVGTextAndBg(offsets.textTop, offsets.textLeft);\n return this._wrapSVGTextAndBg(textAndBg);\n }\n\n toSVG(this: TextSVGExportMixin & FabricText, reviver?: TSVGReviver): string {\n return this._createBaseSVGMarkup(this._toSVG(), {\n reviver,\n noStyle: true,\n withShadow: true,\n });\n }\n\n private _getSVGLeftTopOffsets(this: TextSVGExportMixin & FabricText) {\n return {\n textLeft: -this.width / 2,\n textTop: -this.height / 2,\n lineTop: this.getHeightOfLine(0),\n };\n }\n\n private _wrapSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n {\n textBgRects,\n textSpans,\n }: {\n textSpans: string[];\n textBgRects: string[];\n },\n ) {\n const noShadow = true,\n textDecoration = this.getSvgTextDecoration(this);\n return [\n textBgRects.join(''),\n '\\t\\t',\n textSpans.join(''),\n '\\n',\n ];\n }\n\n /**\n * @private\n * @param {Number} textTopOffset Text top offset\n * @param {Number} textLeftOffset Text left offset\n * @return {Object}\n */\n private _getSVGTextAndBg(\n this: TextSVGExportMixin & FabricText,\n textTopOffset: number,\n textLeftOffset: number,\n ) {\n const textSpans: string[] = [],\n textBgRects: string[] = [];\n let height = textTopOffset,\n lineOffset;\n\n // bounding-box background\n this.backgroundColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n this.backgroundColor,\n -this.width / 2,\n -this.height / 2,\n this.width,\n this.height,\n ),\n );\n\n // text and text-background\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineOffset = this._getLineLeftOffset(i);\n if (this.direction === 'rtl') {\n lineOffset += this.width;\n }\n if (this.textBackgroundColor || this.styleHas('textBackgroundColor', i)) {\n this._setSVGTextLineBg(\n textBgRects,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n }\n this._setSVGTextLineText(\n textSpans,\n i,\n textLeftOffset + lineOffset,\n height,\n );\n height += this.getHeightOfLine(i);\n }\n\n return {\n textSpans,\n textBgRects,\n };\n }\n\n private _createTextCharSpan(\n this: TextSVGExportMixin & FabricText,\n char: string,\n styleDecl: TextStyleDeclaration,\n left: number,\n top: number,\n ) {\n const styleProps = this.getSvgSpanStyles(\n styleDecl,\n char !== char.trim() || !!char.match(multipleSpacesRegex),\n ),\n fillStyles = styleProps ? `style=\"${styleProps}\"` : '',\n dy = styleDecl.deltaY,\n dySpan = dy ? ` dy=\"${toFixed(dy, config.NUM_FRACTION_DIGITS)}\" ` : '';\n\n return `${escapeXml(char)}`;\n }\n\n private _setSVGTextLineText(\n this: TextSVGExportMixin & FabricText,\n textSpans: string[],\n lineIndex: number,\n textLeftOffset: number,\n textTopOffset: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n line = this._textLines[lineIndex];\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n style,\n boxWidth = 0,\n timeToRender;\n\n textTopOffset +=\n (lineHeight * (1 - this._fontSizeFraction)) / this.lineHeight;\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i];\n if (boxWidth === 0) {\n textLeftOffset += charBox.kernedWidth - charBox.width;\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, true);\n }\n if (timeToRender) {\n style = this._getStyleDeclaration(lineIndex, i);\n textSpans.push(\n this._createTextCharSpan(\n charsToRender,\n style,\n textLeftOffset,\n textTopOffset,\n ),\n );\n charsToRender = '';\n actualStyle = nextStyle;\n if (this.direction === 'rtl') {\n textLeftOffset -= boxWidth;\n } else {\n textLeftOffset += boxWidth;\n }\n boxWidth = 0;\n }\n }\n }\n\n private _setSVGTextLineBg(\n this: TextSVGExportMixin & FabricText,\n textBgRects: (string | number)[],\n i: number,\n leftOffset: number,\n textTopOffset: number,\n ) {\n const line = this._textLines[i],\n heightOfLine = this.getHeightOfLine(i) / this.lineHeight;\n let boxWidth = 0,\n boxStart = 0,\n currentColor,\n lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < line.length; j++) {\n const { left, width, kernedWidth } = this.__charBounds[i][j];\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (currentColor !== lastColor) {\n lastColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n boxStart = left;\n boxWidth = width;\n lastColor = currentColor;\n } else {\n boxWidth += kernedWidth;\n }\n }\n currentColor &&\n textBgRects.push(\n ...createSVGInlineRect(\n lastColor,\n leftOffset + boxStart,\n textTopOffset,\n boxWidth,\n heightOfLine,\n ),\n );\n }\n\n /**\n * @deprecated unused\n */\n _getSVGLineTopOffset(\n this: TextSVGExportMixin & FabricText,\n lineIndex: number,\n ) {\n let lineTopOffset = 0,\n j;\n for (j = 0; j < lineIndex; j++) {\n lineTopOffset += this.getHeightOfLine(j);\n }\n const lastHeight = this.getHeightOfLine(j);\n return {\n lineTop: lineTopOffset,\n offset:\n ((this._fontSizeMult - this._fontSizeFraction) * lastHeight) /\n (this.lineHeight * this._fontSizeMult),\n };\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Boolean} skipShadow a boolean to skip shadow filter output\n * @return {String}\n */\n getSvgStyles(this: TextSVGExportMixin & FabricText, skipShadow?: boolean) {\n return `${super.getSvgStyles(skipShadow)} white-space: pre;`;\n }\n\n /**\n * Returns styles-string for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @param {Boolean} useWhiteSpace a boolean to include an additional attribute in the style.\n * @return {String}\n */\n getSvgSpanStyles(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n useWhiteSpace?: boolean,\n ) {\n const {\n fontFamily,\n strokeWidth,\n stroke,\n fill,\n fontSize,\n fontStyle,\n fontWeight,\n deltaY,\n } = style;\n\n const textDecoration = this.getSvgTextDecoration(style);\n\n return [\n stroke ? colorPropToSVG(STROKE, stroke) : '',\n strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',\n fontFamily\n ? `font-family: ${\n !fontFamily.includes(\"'\") && !fontFamily.includes('\"')\n ? `'${fontFamily}'`\n : fontFamily\n }; `\n : '',\n fontSize ? `font-size: ${fontSize}px; ` : '',\n fontStyle ? `font-style: ${fontStyle}; ` : '',\n fontWeight ? `font-weight: ${fontWeight}; ` : '',\n textDecoration ? `text-decoration: ${textDecoration}; ` : textDecoration,\n fill ? colorPropToSVG(FILL, fill) : '',\n deltaY ? `baseline-shift: ${-deltaY}; ` : '',\n useWhiteSpace ? 'white-space: pre; ' : '',\n ].join('');\n }\n\n /**\n * Returns text-decoration property for svg-export\n * @param {Object} style the object from which to retrieve style properties\n * @return {String}\n */\n getSvgTextDecoration(\n this: TextSVGExportMixin & FabricText,\n style: TextStyleDeclaration,\n ) {\n return (['overline', 'underline', 'line-through'] as const)\n .filter(\n (decoration) =>\n style[\n decoration.replace('-', '') as\n | 'overline'\n | 'underline'\n | 'linethrough'\n ],\n )\n .join(' ');\n }\n}\n","import { cache } from '../../cache';\nimport { DEFAULT_SVG_FONT_SIZE, FILL, STROKE } from '../../constants';\nimport type { ObjectEvents } from '../../EventTypeDefs';\nimport type {\n CompleteTextStyleDeclaration,\n TextStyle,\n TextStyleDeclaration,\n} from './StyledText';\nimport { StyledText } from './StyledText';\nimport { SHARED_ATTRIBUTES } from '../../parser/attributes';\nimport { parseAttributes } from '../../parser/parseAttributes';\nimport type {\n Abortable,\n TCacheCanvasDimensions,\n TClassProperties,\n TFiller,\n TOptions,\n} from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport { graphemeSplit } from '../../util/lang_string';\nimport { createCanvasElement } from '../../util/misc/dom';\nimport type { TextStyleArray } from '../../util/misc/textStyles';\nimport {\n hasStyleChanged,\n stylesFromArray,\n stylesToArray,\n} from '../../util/misc/textStyles';\nimport { getPathSegmentsInfo, getPointOnPath } from '../../util/path';\nimport { cacheProperties } from '../Object/FabricObject';\nimport type { Path } from '../Path';\nimport { TextSVGExportMixin } from './TextSVGExportMixin';\nimport { applyMixins } from '../../util/applyMixins';\nimport type { FabricObjectProps, SerializedObjectProps } from '../Object/types';\nimport type { StylePropertiesType } from './constants';\nimport {\n additionalProps,\n textDefaultValues,\n textLayoutProperties,\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from './constants';\nimport { CENTER, LEFT, RIGHT, TOP, BOTTOM } from '../../constants';\nimport { isFiller } from '../../util/typeAssertions';\nimport type { Gradient } from '../../gradient/Gradient';\nimport type { Pattern } from '../../Pattern';\nimport type { CSSRules } from '../../parser/typedefs';\n\nlet measuringContext: CanvasRenderingContext2D | null;\n\n/**\n * Return a context for measurement of text string.\n * if created it gets stored for reuse\n */\nfunction getMeasuringContext() {\n if (!measuringContext) {\n const canvas = createCanvasElement();\n canvas.width = canvas.height = 0;\n measuringContext = canvas.getContext('2d');\n }\n return measuringContext;\n}\n\nexport type TPathSide = 'left' | 'right';\n\nexport type TPathAlign = 'baseline' | 'center' | 'ascender' | 'descender';\n\nexport type TextLinesInfo = {\n lines: string[];\n graphemeLines: string[][];\n graphemeText: string[];\n _unwrappedLines: string[][];\n};\n\n/**\n * Measure and return the info of a single grapheme.\n * needs the the info of previous graphemes already filled\n * Override to customize measuring\n */\nexport type GraphemeBBox = {\n width: number;\n height: number;\n kernedWidth: number;\n left: number;\n deltaY: number;\n renderLeft?: number;\n renderTop?: number;\n angle?: number;\n};\n\n// @TODO this is not complete\ninterface UniqueTextProps {\n charSpacing: number;\n lineHeight: number;\n fontSize: number;\n fontWeight: string | number;\n fontFamily: string;\n fontStyle: string;\n pathSide: TPathSide;\n pathAlign: TPathAlign;\n underline: boolean;\n overline: boolean;\n linethrough: boolean;\n textAlign: string;\n direction: CanvasDirection;\n path?: Path;\n}\n\nexport interface SerializedTextProps\n extends SerializedObjectProps,\n UniqueTextProps {\n styles: TextStyleArray | TextStyle;\n}\n\nexport interface TextProps extends FabricObjectProps, UniqueTextProps {\n styles: TextStyle;\n}\n\n/**\n * Text class\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-2#text}\n */\nexport class FabricText<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends StyledText\n implements UniqueTextProps\n{\n /**\n * Properties that requires a text layout recalculation when changed\n * @type string[]\n * @protected\n */\n static textLayoutProperties: string[] = textLayoutProperties;\n\n /**\n * @private\n */\n declare _reNewline: RegExp;\n\n /**\n * Use this regular expression to filter for whitespaces that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpacesAndTabs: RegExp;\n\n /**\n * Use this regular expression to filter for whitespace that is not a new line.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reSpaceAndTab: RegExp;\n\n /**\n * Use this regular expression to filter consecutive groups of non spaces.\n * Mostly used when text is 'justify' aligned.\n * @private\n */\n declare _reWords: RegExp;\n\n declare text: string;\n\n /**\n * Font size (in pixels)\n * @type Number\n * @default\n */\n declare fontSize: number;\n\n /**\n * Font weight (e.g. bold, normal, 400, 600, 800)\n * @type {(Number|String)}\n * @default\n */\n declare fontWeight: string | number;\n\n /**\n * Font family\n * @type String\n * @default\n */\n declare fontFamily: string;\n\n /**\n * Text decoration underline.\n * @type Boolean\n * @default\n */\n declare underline: boolean;\n\n /**\n * Text decoration overline.\n * @type Boolean\n * @default\n */\n declare overline: boolean;\n\n /**\n * Text decoration linethrough.\n * @type Boolean\n * @default\n */\n declare linethrough: boolean;\n\n /**\n * Text alignment. Possible values: \"left\", \"center\", \"right\", \"justify\",\n * \"justify-left\", \"justify-center\" or \"justify-right\".\n * @type String\n * @default\n */\n declare textAlign: string;\n\n /**\n * Font style . Possible values: \"\", \"normal\", \"italic\" or \"oblique\".\n * @type String\n * @default\n */\n declare fontStyle: string;\n\n /**\n * Line height\n * @type Number\n * @default\n */\n declare lineHeight: number;\n\n /**\n * Superscript schema object (minimum overlap)\n */\n declare superscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (upwards)\n * @default -0.35\n */\n baseline: number;\n };\n\n /**\n * Subscript schema object (minimum overlap)\n */\n declare subscript: {\n /**\n * fontSize factor\n * @default 0.6\n */\n size: number;\n /**\n * baseline-shift factor (downwards)\n * @default 0.11\n */\n baseline: number;\n };\n\n /**\n * Background color of text lines\n * @type String\n * @default\n */\n declare textBackgroundColor: string;\n\n declare styles: TextStyle;\n\n /**\n * Path that the text should follow.\n * since 4.6.0 the path will be drawn automatically.\n * if you want to make the path visible, give it a stroke and strokeWidth or fill value\n * if you want it to be hidden, assign visible = false to the path.\n * This feature is in BETA, and SVG import/export is not yet supported.\n * @type Path\n * @example\n * const textPath = new Text('Text on a path', {\n * top: 150,\n * left: 150,\n * textAlign: 'center',\n * charSpacing: -50,\n * path: new Path('M 0 0 C 50 -100 150 -100 200 0', {\n * strokeWidth: 1,\n * visible: false\n * }),\n * pathSide: 'left',\n * pathStartOffset: 0\n * });\n * @default\n */\n declare path?: Path;\n\n /**\n * Offset amount for text path starting position\n * Only used when text has a path\n * @type Number\n * @default\n */\n declare pathStartOffset: number;\n\n /**\n * Which side of the path the text should be drawn on.\n * Only used when text has a path\n * @type {TPathSide} 'left|right'\n * @default\n */\n declare pathSide: TPathSide;\n\n /**\n * How text is aligned to the path. This property determines\n * the perpendicular position of each character relative to the path.\n * (one of \"baseline\", \"center\", \"ascender\", \"descender\")\n * This feature is in BETA, and its behavior may change\n * @type TPathAlign\n * @default\n */\n declare pathAlign: TPathAlign;\n\n /**\n * @private\n */\n declare _fontSizeFraction: number;\n\n /**\n * @private\n */\n declare offsets: { underline: number; linethrough: number; overline: number };\n\n /**\n * Text Line proportion to font Size (in pixels)\n * @type Number\n * @default\n */\n declare _fontSizeMult: number;\n\n /**\n * additional space between characters\n * expressed in thousands of em unit\n * @type Number\n * @default\n */\n declare charSpacing: number;\n\n /**\n * Baseline shift, styles only, keep at 0 for the main text object\n * @type {Number}\n * @default\n */\n declare deltaY: number;\n\n /**\n * WARNING: EXPERIMENTAL. NOT SUPPORTED YET\n * determine the direction of the text.\n * This has to be set manually together with textAlign and originX for proper\n * experience.\n * some interesting link for the future\n * https://www.w3.org/International/questions/qa-bidi-unicode-controls\n * @since 4.5.0\n * @type {CanvasDirection} 'ltr|rtl'\n * @default\n */\n declare direction: CanvasDirection;\n\n /**\n * contains characters bounding boxes\n * This variable is considered to be protected.\n * But for how mixins are implemented right now, we can't leave it private\n * @protected\n */\n __charBounds: GraphemeBBox[][] = [];\n\n /**\n * use this size when measuring text. To avoid IE11 rounding errors\n * @type {Number}\n * @default\n * @readonly\n * @private\n */\n declare CACHE_FONT_SIZE: number;\n\n /**\n * contains the min text width to avoid getting 0\n * @type {Number}\n * @default\n */\n declare MIN_TEXT_WIDTH: number;\n\n /**\n * contains the the text of the object, divided in lines as they are displayed\n * on screen. Wrapping will divide the text independently of line breaks\n * @type {string[]}\n * @default\n */\n declare textLines: string[];\n\n /**\n * same as textlines, but each line is an array of graphemes as split by splitByGrapheme\n * @type {string[]}\n * @default\n */\n declare _textLines: string[][];\n\n declare _unwrappedTextLines: string[][];\n declare _text: string[];\n declare cursorWidth: number;\n declare __lineHeights: number[];\n declare __lineWidths: number[];\n declare initialized?: true;\n\n static cacheProperties = [...cacheProperties, ...additionalProps];\n\n static ownDefaults = textDefaultValues;\n\n static type = 'Text';\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...FabricText.ownDefaults };\n }\n\n constructor(text: string, options?: Props) {\n super();\n Object.assign(this, FabricText.ownDefaults);\n this.setOptions(options);\n if (!this.styles) {\n this.styles = {};\n }\n this.text = text;\n this.initialized = true;\n if (this.path) {\n this.setPathInfo();\n }\n this.initDimensions();\n this.setCoords();\n }\n\n /**\n * If text has a path, it will add the extra information needed\n * for path and text calculations\n */\n setPathInfo() {\n const path = this.path;\n if (path) {\n path.segmentsInfo = getPathSegmentsInfo(path.path);\n }\n }\n\n /**\n * @private\n * Divides text into lines of text and lines of graphemes.\n */\n _splitText(): TextLinesInfo {\n const newLines = this._splitTextIntoLines(this.text);\n this.textLines = newLines.lines;\n this._textLines = newLines.graphemeLines;\n this._unwrappedTextLines = newLines._unwrappedLines;\n this._text = newLines.graphemeText;\n return newLines;\n }\n\n /**\n * Initialize or update text dimensions.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n */\n initDimensions() {\n this._splitText();\n this._clearCache();\n this.dirty = true;\n if (this.path) {\n this.width = this.path.width;\n this.height = this.path.height;\n } else {\n this.width =\n this.calcTextWidth() || this.cursorWidth || this.MIN_TEXT_WIDTH;\n this.height = this.calcTextHeight();\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n }\n\n /**\n * Enlarge space boxes and shift the others\n */\n enlargeSpaces() {\n let diffSpace,\n currentLineWidth,\n numberOfSpaces,\n accumulatedSpace,\n line,\n charBound,\n spaces;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n if (\n this.textAlign !== JUSTIFY &&\n (i === len - 1 || this.isEndOfWrapping(i))\n ) {\n continue;\n }\n accumulatedSpace = 0;\n line = this._textLines[i];\n currentLineWidth = this.getLineWidth(i);\n if (\n currentLineWidth < this.width &&\n (spaces = this.textLines[i].match(this._reSpacesAndTabs))\n ) {\n numberOfSpaces = spaces.length;\n diffSpace = (this.width - currentLineWidth) / numberOfSpaces;\n for (let j = 0; j <= line.length; j++) {\n charBound = this.__charBounds[i][j];\n if (this._reSpaceAndTab.test(line[j])) {\n charBound.width += diffSpace;\n charBound.kernedWidth += diffSpace;\n charBound.left += accumulatedSpace;\n accumulatedSpace += diffSpace;\n } else {\n charBound.left += accumulatedSpace;\n }\n }\n }\n }\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n return lineIndex === this._textLines.length - 1;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * It return always 1 for text and Itext. Textbox has its own implementation\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1;\n missingNewlineOffset(_lineIndex: number): 1 {\n return 1;\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor\n * @param {Number} selectionStart\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(selectionStart: number, skipWrapping?: boolean) {\n const lines = skipWrapping ? this._unwrappedTextLines : this._textLines;\n let i: number;\n for (i = 0; i < lines.length; i++) {\n if (selectionStart <= lines[i].length) {\n return {\n lineIndex: i,\n charIndex: selectionStart,\n };\n }\n selectionStart -=\n lines[i].length + this.missingNewlineOffset(i, skipWrapping);\n }\n return {\n lineIndex: i - 1,\n charIndex:\n lines[i - 1].length < selectionStart\n ? lines[i - 1].length\n : selectionStart,\n };\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of text object\n */\n toString(): string {\n return `#`;\n }\n\n /**\n * Return the dimension and the zoom level needed to create a cache canvas\n * big enough to host the object to be cached.\n * @private\n * @param {Object} dim.x width of object to be cached\n * @param {Object} dim.y height of object to be cached\n * @return {Object}.width width of canvas\n * @return {Object}.height height of canvas\n * @return {Object}.zoomX zoomX zoom value to unscale the canvas before drawing cache\n * @return {Object}.zoomY zoomY zoom value to unscale the canvas before drawing cache\n */\n _getCacheCanvasDimensions(): TCacheCanvasDimensions {\n const dims = super._getCacheCanvasDimensions();\n const fontSize = this.fontSize;\n dims.width += fontSize * dims.zoomX;\n dims.height += fontSize * dims.zoomY;\n return dims;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n const path = this.path;\n path && !path.isNotVisible() && path._render(ctx);\n this._setTextStyles(ctx);\n this._renderTextLinesBackground(ctx);\n this._renderTextDecoration(ctx, 'underline');\n this._renderText(ctx);\n this._renderTextDecoration(ctx, 'overline');\n this._renderTextDecoration(ctx, 'linethrough');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderText(ctx: CanvasRenderingContext2D) {\n if (this.paintFirst === STROKE) {\n this._renderTextStroke(ctx);\n this._renderTextFill(ctx);\n } else {\n this._renderTextFill(ctx);\n this._renderTextStroke(ctx);\n }\n }\n\n /**\n * Set the font parameter of the context with the object properties or with charStyle\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [charStyle] object with font style properties\n * @param {String} [charStyle.fontFamily] Font Family\n * @param {Number} [charStyle.fontSize] Font size in pixels. ( without px suffix )\n * @param {String} [charStyle.fontWeight] Font weight\n * @param {String} [charStyle.fontStyle] Font style (italic|normal)\n */\n _setTextStyles(\n ctx: CanvasRenderingContext2D,\n charStyle?: any,\n forMeasuring?: boolean,\n ) {\n ctx.textBaseline = 'alphabetic';\n if (this.path) {\n switch (this.pathAlign) {\n case CENTER:\n ctx.textBaseline = 'middle';\n break;\n case 'ascender':\n ctx.textBaseline = TOP;\n break;\n case 'descender':\n ctx.textBaseline = BOTTOM;\n break;\n }\n }\n ctx.font = this._getFontDeclaration(charStyle, forMeasuring);\n }\n\n /**\n * calculate and return the text Width measuring each line.\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @return {Number} Maximum width of Text object\n */\n calcTextWidth(): number {\n let maxWidth = this.getLineWidth(0);\n\n for (let i = 1, len = this._textLines.length; i < len; i++) {\n const currentLineWidth = this.getLineWidth(i);\n if (currentLineWidth > maxWidth) {\n maxWidth = currentLineWidth;\n }\n }\n return maxWidth;\n }\n\n /**\n * @private\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} line Text to render\n * @param {Number} left Left position of text\n * @param {Number} top Top position of text\n * @param {Number} lineIndex Index of a line in a text\n */\n _renderTextLine(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: string[],\n left: number,\n top: number,\n lineIndex: number,\n ) {\n this._renderChars(method, ctx, line, left, top, lineIndex);\n }\n\n /**\n * Renders the text background for lines, taking care of style\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextLinesBackground(ctx: CanvasRenderingContext2D) {\n if (!this.textBackgroundColor && !this.styleHas('textBackgroundColor')) {\n return;\n }\n const originalFill = ctx.fillStyle,\n leftOffset = this._getLeftOffset();\n let lineTopOffset = this._getTopOffset();\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (\n !this.textBackgroundColor &&\n !this.styleHas('textBackgroundColor', i)\n ) {\n lineTopOffset += heightOfLine;\n continue;\n }\n const jlen = this._textLines[i].length;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxWidth = 0;\n let boxStart = 0;\n let drawStart;\n let currentColor;\n let lastColor = this.getValueOfPropertyAt(i, 0, 'textBackgroundColor');\n for (let j = 0; j < jlen; j++) {\n // at this point charbox are either standard or full with pathInfo if there is a path.\n const charBox = this.__charBounds[i][j] as Required;\n currentColor = this.getValueOfPropertyAt(i, j, 'textBackgroundColor');\n if (this.path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillStyle = currentColor;\n currentColor &&\n ctx.fillRect(\n -charBox.width / 2,\n (-heightOfLine / this.lineHeight) * (1 - this._fontSizeFraction),\n charBox.width,\n heightOfLine / this.lineHeight,\n );\n ctx.restore();\n } else if (currentColor !== lastColor) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = lastColor;\n lastColor &&\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastColor = currentColor;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n if (currentColor && !this.path) {\n drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentColor;\n ctx.fillRect(\n drawStart,\n lineTopOffset,\n boxWidth,\n heightOfLine / this.lineHeight,\n );\n }\n lineTopOffset += heightOfLine;\n }\n ctx.fillStyle = originalFill;\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * measure and return the width of a single character.\n * possibly overridden to accommodate different measure logic or\n * to hook some external lib for character measurement\n * @private\n * @param {String} _char, char to be measured\n * @param {Object} charStyle style of char to be measured\n * @param {String} [previousChar] previous char\n * @param {Object} [prevCharStyle] style of previous char\n */\n _measureChar(\n _char: string,\n charStyle: CompleteTextStyleDeclaration,\n previousChar: string | undefined,\n prevCharStyle: CompleteTextStyleDeclaration | Record,\n ) {\n const fontCache = cache.getFontCache(charStyle),\n fontDeclaration = this._getFontDeclaration(charStyle),\n couple = previousChar + _char,\n stylesAreEqual =\n previousChar &&\n fontDeclaration === this._getFontDeclaration(prevCharStyle),\n fontMultiplier = charStyle.fontSize / this.CACHE_FONT_SIZE;\n let width: number | undefined,\n coupleWidth: number | undefined,\n previousWidth: number | undefined,\n kernedWidth: number | undefined;\n\n if (previousChar && fontCache[previousChar] !== undefined) {\n previousWidth = fontCache[previousChar];\n }\n if (fontCache[_char] !== undefined) {\n kernedWidth = width = fontCache[_char];\n }\n if (stylesAreEqual && fontCache[couple] !== undefined) {\n coupleWidth = fontCache[couple];\n kernedWidth = coupleWidth - previousWidth!;\n }\n if (\n width === undefined ||\n previousWidth === undefined ||\n coupleWidth === undefined\n ) {\n const ctx = getMeasuringContext()!;\n // send a TRUE to specify measuring font size CACHE_FONT_SIZE\n this._setTextStyles(ctx, charStyle, true);\n if (width === undefined) {\n kernedWidth = width = ctx.measureText(_char).width;\n fontCache[_char] = width;\n }\n if (previousWidth === undefined && stylesAreEqual && previousChar) {\n previousWidth = ctx.measureText(previousChar).width;\n fontCache[previousChar] = previousWidth;\n }\n if (stylesAreEqual && coupleWidth === undefined) {\n // we can measure the kerning couple and subtract the width of the previous character\n coupleWidth = ctx.measureText(couple).width;\n fontCache[couple] = coupleWidth;\n // safe to use the non-null since if undefined we defined it before.\n kernedWidth = coupleWidth - previousWidth!;\n }\n }\n return {\n width: width * fontMultiplier,\n kernedWidth: kernedWidth! * fontMultiplier,\n };\n }\n\n /**\n * Computes height of character at given position\n * @param {Number} line the line index number\n * @param {Number} _char the character index number\n * @return {Number} fontSize of the character\n */\n getHeightOfChar(line: number, _char: number): number {\n return this.getValueOfPropertyAt(line, _char, 'fontSize');\n }\n\n /**\n * measure a text line measuring all characters.\n * @param {Number} lineIndex line number\n */\n measureLine(lineIndex: number) {\n const lineInfo = this._measureLine(lineIndex);\n if (this.charSpacing !== 0) {\n lineInfo.width -= this._getWidthOfCharSpacing();\n }\n if (lineInfo.width < 0) {\n lineInfo.width = 0;\n }\n return lineInfo;\n }\n\n /**\n * measure every grapheme of a line, populating __charBounds\n * @param {Number} lineIndex\n * @return {Object} object.width total width of characters\n * @return {Object} object.numOfSpaces length of chars that match this._reSpacesAndTabs\n */\n _measureLine(lineIndex: number) {\n let width = 0,\n prevGrapheme: string | undefined,\n graphemeInfo: GraphemeBBox | undefined;\n\n const reverse = this.pathSide === RIGHT,\n path = this.path,\n line = this._textLines[lineIndex],\n llength = line.length,\n lineBounds = new Array(llength);\n\n this.__charBounds[lineIndex] = lineBounds;\n for (let i = 0; i < llength; i++) {\n const grapheme = line[i];\n graphemeInfo = this._getGraphemeBox(grapheme, lineIndex, i, prevGrapheme);\n lineBounds[i] = graphemeInfo;\n width += graphemeInfo.kernedWidth;\n prevGrapheme = grapheme;\n }\n // this latest bound box represent the last character of the line\n // to simplify cursor handling in interactive mode.\n lineBounds[llength] = {\n left: graphemeInfo ? graphemeInfo.left + graphemeInfo.width : 0,\n width: 0,\n kernedWidth: 0,\n height: this.fontSize,\n deltaY: 0,\n } as GraphemeBBox;\n if (path && path.segmentsInfo) {\n let positionInPath = 0;\n const totalPathLength =\n path.segmentsInfo[path.segmentsInfo.length - 1].length;\n switch (this.textAlign) {\n case LEFT:\n positionInPath = reverse ? totalPathLength - width : 0;\n break;\n case CENTER:\n positionInPath = (totalPathLength - width) / 2;\n break;\n case RIGHT:\n positionInPath = reverse ? 0 : totalPathLength - width;\n break;\n //todo - add support for justify\n }\n positionInPath += this.pathStartOffset * (reverse ? -1 : 1);\n for (\n let i = reverse ? llength - 1 : 0;\n reverse ? i >= 0 : i < llength;\n reverse ? i-- : i++\n ) {\n graphemeInfo = lineBounds[i];\n if (positionInPath > totalPathLength) {\n positionInPath %= totalPathLength;\n } else if (positionInPath < 0) {\n positionInPath += totalPathLength;\n }\n // it would probably much faster to send all the grapheme position for a line\n // and calculate path position/angle at once.\n this._setGraphemeOnPath(positionInPath, graphemeInfo);\n positionInPath += graphemeInfo.kernedWidth;\n }\n }\n return { width: width, numOfSpaces: 0 };\n }\n\n /**\n * Calculate the angle and the left,top position of the char that follow a path.\n * It appends it to graphemeInfo to be reused later at rendering\n * @private\n * @param {Number} positionInPath to be measured\n * @param {GraphemeBBox} graphemeInfo current grapheme box information\n * @param {Object} startingPoint position of the point\n */\n _setGraphemeOnPath(positionInPath: number, graphemeInfo: GraphemeBBox) {\n const centerPosition = positionInPath + graphemeInfo.kernedWidth / 2,\n path = this.path!;\n\n // we are at currentPositionOnPath. we want to know what point on the path is.\n const info = getPointOnPath(path.path, centerPosition, path.segmentsInfo)!;\n graphemeInfo.renderLeft = info.x - path.pathOffset.x;\n graphemeInfo.renderTop = info.y - path.pathOffset.y;\n graphemeInfo.angle = info.angle + (this.pathSide === RIGHT ? Math.PI : 0);\n }\n\n /**\n *\n * @param {String} grapheme to be measured\n * @param {Number} lineIndex index of the line where the char is\n * @param {Number} charIndex position in the line\n * @param {String} [prevGrapheme] character preceding the one to be measured\n * @returns {GraphemeBBox} grapheme bbox\n */\n _getGraphemeBox(\n grapheme: string,\n lineIndex: number,\n charIndex: number,\n prevGrapheme?: string,\n skipLeft?: boolean,\n ): GraphemeBBox {\n const style = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n prevStyle = prevGrapheme\n ? this.getCompleteStyleDeclaration(lineIndex, charIndex - 1)\n : {},\n info = this._measureChar(grapheme, style, prevGrapheme, prevStyle);\n let kernedWidth = info.kernedWidth,\n width = info.width,\n charSpacing;\n\n if (this.charSpacing !== 0) {\n charSpacing = this._getWidthOfCharSpacing();\n width += charSpacing;\n kernedWidth += charSpacing;\n }\n\n const box: GraphemeBBox = {\n width,\n left: 0,\n height: style.fontSize,\n kernedWidth,\n deltaY: style.deltaY,\n };\n if (charIndex > 0 && !skipLeft) {\n const previousBox = this.__charBounds[lineIndex][charIndex - 1];\n box.left =\n previousBox.left + previousBox.width + info.kernedWidth - info.width;\n }\n return box;\n }\n\n /**\n * Calculate height of line at 'lineIndex'\n * @param {Number} lineIndex index of line to calculate\n * @return {Number}\n */\n getHeightOfLine(lineIndex: number): number {\n if (this.__lineHeights[lineIndex]) {\n return this.__lineHeights[lineIndex];\n }\n\n // char 0 is measured before the line cycle because it needs to char\n // emptylines\n let maxHeight = this.getHeightOfChar(lineIndex, 0);\n for (let i = 1, len = this._textLines[lineIndex].length; i < len; i++) {\n maxHeight = Math.max(this.getHeightOfChar(lineIndex, i), maxHeight);\n }\n\n return (this.__lineHeights[lineIndex] =\n maxHeight * this.lineHeight * this._fontSizeMult);\n }\n\n /**\n * Calculate text box height\n */\n calcTextHeight() {\n let lineHeight,\n height = 0;\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n lineHeight = this.getHeightOfLine(i);\n height += i === len - 1 ? lineHeight / this.lineHeight : lineHeight;\n }\n return height;\n }\n\n /**\n * @private\n * @return {Number} Left offset\n */\n _getLeftOffset(): number {\n return this.direction === 'ltr' ? -this.width / 2 : this.width / 2;\n }\n\n /**\n * @private\n * @return {Number} Top offset\n */\n _getTopOffset(): number {\n return -this.height / 2;\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {String} method Method name (\"fillText\" or \"strokeText\")\n */\n _renderTextCommon(\n ctx: CanvasRenderingContext2D,\n method: 'fillText' | 'strokeText',\n ) {\n ctx.save();\n let lineHeights = 0;\n const left = this._getLeftOffset(),\n top = this._getTopOffset();\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i),\n maxHeight = heightOfLine / this.lineHeight,\n leftOffset = this._getLineLeftOffset(i);\n this._renderTextLine(\n method,\n ctx,\n this._textLines[i],\n left + leftOffset,\n top + lineHeights + maxHeight,\n i,\n );\n lineHeights += heightOfLine;\n }\n ctx.restore();\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextFill(ctx: CanvasRenderingContext2D) {\n if (!this.fill && !this.styleHas(FILL)) {\n return;\n }\n\n this._renderTextCommon(ctx, 'fillText');\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextStroke(ctx: CanvasRenderingContext2D) {\n if ((!this.stroke || this.strokeWidth === 0) && this.isEmptyStyles()) {\n return;\n }\n\n if (this.shadow && !this.shadow.affectStroke) {\n this._removeShadow(ctx);\n }\n\n ctx.save();\n this._setLineDash(ctx, this.strokeDashArray);\n ctx.beginPath();\n this._renderTextCommon(ctx, 'strokeText');\n ctx.closePath();\n ctx.restore();\n }\n\n /**\n * @private\n * @param {String} method fillText or strokeText.\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Array} line Content of the line, splitted in an array by grapheme\n * @param {Number} left\n * @param {Number} top\n * @param {Number} lineIndex\n */\n _renderChars(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n line: Array,\n left: number,\n top: number,\n lineIndex: number,\n ) {\n const lineHeight = this.getHeightOfLine(lineIndex),\n isJustify = this.textAlign.includes(JUSTIFY),\n path = this.path,\n shortCut =\n !isJustify &&\n this.charSpacing === 0 &&\n this.isEmptyStyles(lineIndex) &&\n !path,\n isLtr = this.direction === 'ltr',\n sign = this.direction === 'ltr' ? 1 : -1,\n // this was changed in the PR #7674\n // currentDirection = ctx.canvas.getAttribute('dir');\n currentDirection = ctx.direction;\n\n let actualStyle,\n nextStyle,\n charsToRender = '',\n charBox,\n boxWidth = 0,\n timeToRender,\n drawingLeft;\n\n ctx.save();\n if (currentDirection !== this.direction) {\n ctx.canvas.setAttribute('dir', isLtr ? 'ltr' : 'rtl');\n ctx.direction = isLtr ? 'ltr' : 'rtl';\n ctx.textAlign = isLtr ? LEFT : RIGHT;\n }\n top -= (lineHeight * this._fontSizeFraction) / this.lineHeight;\n if (shortCut) {\n // render all the line in one pass without checking\n // drawingLeft = isLtr ? left : left - this.getLineWidth(lineIndex);\n this._renderChar(method, ctx, lineIndex, 0, line.join(''), left, top);\n ctx.restore();\n return;\n }\n for (let i = 0, len = line.length - 1; i <= len; i++) {\n timeToRender = i === len || this.charSpacing || path;\n charsToRender += line[i];\n charBox = this.__charBounds[lineIndex][i] as Required;\n if (boxWidth === 0) {\n left += sign * (charBox.kernedWidth - charBox.width);\n boxWidth += charBox.width;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n if (isJustify && !timeToRender) {\n if (this._reSpaceAndTab.test(line[i])) {\n timeToRender = true;\n }\n }\n if (!timeToRender) {\n // if we have charSpacing, we render char by char\n actualStyle =\n actualStyle || this.getCompleteStyleDeclaration(lineIndex, i);\n nextStyle = this.getCompleteStyleDeclaration(lineIndex, i + 1);\n timeToRender = hasStyleChanged(actualStyle, nextStyle, false);\n }\n if (timeToRender) {\n if (path) {\n ctx.save();\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n -boxWidth / 2,\n 0,\n );\n ctx.restore();\n } else {\n drawingLeft = left;\n this._renderChar(\n method,\n ctx,\n lineIndex,\n i,\n charsToRender,\n drawingLeft,\n top,\n );\n }\n charsToRender = '';\n actualStyle = nextStyle;\n left += sign * boxWidth;\n boxWidth = 0;\n }\n }\n ctx.restore();\n }\n\n /**\n * This function try to patch the missing gradientTransform on canvas gradients.\n * transforming a context to transform the gradient, is going to transform the stroke too.\n * we want to transform the gradient but not the stroke operation, so we create\n * a transformed gradient on a pattern and then we use the pattern instead of the gradient.\n * this method has drawbacks: is slow, is in low resolution, needs a patch for when the size\n * is limited.\n * @private\n * @param {TFiller} filler a fabric gradient instance\n * @return {CanvasPattern} a pattern to use as fill/stroke style\n */\n _applyPatternGradientTransformText(filler: TFiller) {\n const pCanvas = createCanvasElement(),\n // TODO: verify compatibility with strokeUniform\n width = this.width + this.strokeWidth,\n height = this.height + this.strokeWidth,\n pCtx = pCanvas.getContext('2d')!;\n pCanvas.width = width;\n pCanvas.height = height;\n pCtx.beginPath();\n pCtx.moveTo(0, 0);\n pCtx.lineTo(width, 0);\n pCtx.lineTo(width, height);\n pCtx.lineTo(0, height);\n pCtx.closePath();\n pCtx.translate(width / 2, height / 2);\n pCtx.fillStyle = filler.toLive(pCtx)!;\n this._applyPatternGradientTransform(pCtx, filler);\n pCtx.fill();\n return pCtx.createPattern(pCanvas, 'no-repeat')!;\n }\n\n handleFiller(\n ctx: CanvasRenderingContext2D,\n property: `${T}Style`,\n filler: TFiller | string,\n ): { offsetX: number; offsetY: number } {\n let offsetX: number, offsetY: number;\n if (isFiller(filler)) {\n if (\n (filler as Gradient<'linear'>).gradientUnits === 'percentage' ||\n (filler as Gradient<'linear'>).gradientTransform ||\n (filler as Pattern).patternTransform\n ) {\n // need to transform gradient in a pattern.\n // this is a slow process. If you are hitting this codepath, and the object\n // is not using caching, you should consider switching it on.\n // we need a canvas as big as the current object caching canvas.\n offsetX = -this.width / 2;\n offsetY = -this.height / 2;\n ctx.translate(offsetX, offsetY);\n ctx[property] = this._applyPatternGradientTransformText(filler);\n return { offsetX, offsetY };\n } else {\n // is a simple gradient or pattern\n ctx[property] = filler.toLive(ctx)!;\n return this._applyPatternGradientTransform(ctx, filler);\n }\n } else {\n // is a color\n ctx[property] = filler;\n }\n return { offsetX: 0, offsetY: 0 };\n }\n\n /**\n * This function prepare the canvas for a stroke style, and stroke and strokeWidth\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with stroke and strokeWidth defined\n * @returns\n */\n _setStrokeStyles(\n ctx: CanvasRenderingContext2D,\n {\n stroke,\n strokeWidth,\n }: Pick,\n ) {\n ctx.lineWidth = strokeWidth;\n ctx.lineCap = this.strokeLineCap;\n ctx.lineDashOffset = this.strokeDashOffset;\n ctx.lineJoin = this.strokeLineJoin;\n ctx.miterLimit = this.strokeMiterLimit;\n return this.handleFiller(ctx, 'strokeStyle', stroke!);\n }\n\n /**\n * This function prepare the canvas for a ill style, and fill\n * need to be sent in as defined\n * @param {CanvasRenderingContext2D} ctx\n * @param {CompleteTextStyleDeclaration} style with ill defined\n * @returns\n */\n _setFillStyles(ctx: CanvasRenderingContext2D, { fill }: Pick) {\n return this.handleFiller(ctx, 'fillStyle', fill!);\n }\n\n /**\n * @private\n * @param {String} method\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {String} _char\n * @param {Number} left Left coordinate\n * @param {Number} top Top coordinate\n * @param {Number} lineHeight Height of the line\n */\n _renderChar(\n method: 'fillText' | 'strokeText',\n ctx: CanvasRenderingContext2D,\n lineIndex: number,\n charIndex: number,\n _char: string,\n left: number,\n top: number,\n ) {\n const decl = this._getStyleDeclaration(lineIndex, charIndex),\n fullDecl = this.getCompleteStyleDeclaration(lineIndex, charIndex),\n shouldFill = method === 'fillText' && fullDecl.fill,\n shouldStroke =\n method === 'strokeText' && fullDecl.stroke && fullDecl.strokeWidth;\n\n if (!shouldStroke && !shouldFill) {\n return;\n }\n ctx.save();\n\n ctx.font = this._getFontDeclaration(fullDecl);\n\n if (decl.textBackgroundColor) {\n this._removeShadow(ctx);\n }\n if (decl.deltaY) {\n top += decl.deltaY;\n }\n\n if (shouldFill) {\n const fillOffsets = this._setFillStyles(ctx, fullDecl);\n ctx.fillText(\n _char,\n left - fillOffsets.offsetX,\n top - fillOffsets.offsetY,\n );\n }\n\n if (shouldStroke) {\n const strokeOffsets = this._setStrokeStyles(ctx, fullDecl);\n ctx.strokeText(\n _char,\n left - strokeOffsets.offsetX,\n top - strokeOffsets.offsetY,\n );\n }\n\n ctx.restore();\n }\n\n /**\n * Turns the character into a 'superior figure' (i.e. 'superscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSuperscript(start: number, end: number) {\n this._setScript(start, end, this.superscript);\n }\n\n /**\n * Turns the character into an 'inferior figure' (i.e. 'subscript')\n * @param {Number} start selection start\n * @param {Number} end selection end\n */\n setSubscript(start: number, end: number) {\n this._setScript(start, end, this.subscript);\n }\n\n /**\n * Applies 'schema' at given position\n * @private\n * @param {Number} start selection start\n * @param {Number} end selection end\n * @param {Number} schema\n */\n protected _setScript(\n start: number,\n end: number,\n schema: {\n size: number;\n baseline: number;\n },\n ) {\n const loc = this.get2DCursorLocation(start, true),\n fontSize = this.getValueOfPropertyAt(\n loc.lineIndex,\n loc.charIndex,\n 'fontSize',\n ),\n dy = this.getValueOfPropertyAt(loc.lineIndex, loc.charIndex, 'deltaY'),\n style = {\n fontSize: fontSize * schema.size,\n deltaY: dy + fontSize * schema.baseline,\n };\n this.setSelectionStyles(style, start, end);\n }\n\n /**\n * @private\n * @param {Number} lineIndex index text line\n * @return {Number} Line left offset\n */\n _getLineLeftOffset(lineIndex: number): number {\n const lineWidth = this.getLineWidth(lineIndex),\n lineDiff = this.width - lineWidth,\n textAlign = this.textAlign,\n direction = this.direction,\n isEndOfWrapping = this.isEndOfWrapping(lineIndex);\n let leftOffset = 0;\n if (\n textAlign === JUSTIFY ||\n (textAlign === JUSTIFY_CENTER && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_RIGHT && !isEndOfWrapping) ||\n (textAlign === JUSTIFY_LEFT && !isEndOfWrapping)\n ) {\n return 0;\n }\n if (textAlign === CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === RIGHT) {\n leftOffset = lineDiff;\n }\n if (textAlign === JUSTIFY_CENTER) {\n leftOffset = lineDiff / 2;\n }\n if (textAlign === JUSTIFY_RIGHT) {\n leftOffset = lineDiff;\n }\n if (direction === 'rtl') {\n if (\n textAlign === RIGHT ||\n textAlign === JUSTIFY ||\n textAlign === JUSTIFY_RIGHT\n ) {\n leftOffset = 0;\n } else if (textAlign === LEFT || textAlign === JUSTIFY_LEFT) {\n leftOffset = -lineDiff;\n } else if (textAlign === CENTER || textAlign === JUSTIFY_CENTER) {\n leftOffset = -lineDiff / 2;\n }\n }\n return leftOffset;\n }\n\n /**\n * @private\n */\n _clearCache() {\n this._forceClearCache = false;\n this.__lineWidths = [];\n this.__lineHeights = [];\n this.__charBounds = [];\n }\n\n /**\n * Measure a single line given its index. Used to calculate the initial\n * text bounding box. The values are calculated and stored in __lineWidths cache.\n * @private\n * @param {Number} lineIndex line number\n * @return {Number} Line width\n */\n getLineWidth(lineIndex: number): number {\n if (this.__lineWidths[lineIndex] !== undefined) {\n return this.__lineWidths[lineIndex];\n }\n\n const { width } = this.measureLine(lineIndex);\n this.__lineWidths[lineIndex] = width;\n return width;\n }\n\n _getWidthOfCharSpacing() {\n if (this.charSpacing !== 0) {\n return (this.fontSize * this.charSpacing) / 1000;\n }\n return 0;\n }\n\n /**\n * Retrieves the value of property at given character position\n * @param {Number} lineIndex the line number\n * @param {Number} charIndex the character number\n * @param {String} property the property name\n * @returns the value of 'property'\n */\n getValueOfPropertyAt(\n lineIndex: number,\n charIndex: number,\n property: T,\n ): this[T] {\n const charStyle = this._getStyleDeclaration(lineIndex, charIndex);\n return (charStyle[property] ?? this[property]) as this[T];\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _renderTextDecoration(\n ctx: CanvasRenderingContext2D,\n type: 'underline' | 'linethrough' | 'overline',\n ) {\n if (!this[type] && !this.styleHas(type)) {\n return;\n }\n let topOffset = this._getTopOffset();\n const leftOffset = this._getLeftOffset(),\n path = this.path,\n charSpacing = this._getWidthOfCharSpacing(),\n offsetY = this.offsets[type];\n\n for (let i = 0, len = this._textLines.length; i < len; i++) {\n const heightOfLine = this.getHeightOfLine(i);\n if (!this[type] && !this.styleHas(type, i)) {\n topOffset += heightOfLine;\n continue;\n }\n const line = this._textLines[i];\n const maxHeight = heightOfLine / this.lineHeight;\n const lineLeftOffset = this._getLineLeftOffset(i);\n let boxStart = 0;\n let boxWidth = 0;\n let lastDecoration = this.getValueOfPropertyAt(i, 0, type);\n let lastFill = this.getValueOfPropertyAt(i, 0, FILL);\n let currentDecoration;\n let currentFill;\n const top = topOffset + maxHeight * (1 - this._fontSizeFraction);\n let size = this.getHeightOfChar(i, 0);\n let dy = this.getValueOfPropertyAt(i, 0, 'deltaY');\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n const charBox = this.__charBounds[i][j] as Required;\n currentDecoration = this.getValueOfPropertyAt(i, j, type);\n currentFill = this.getValueOfPropertyAt(i, j, FILL);\n const currentSize = this.getHeightOfChar(i, j);\n const currentDy = this.getValueOfPropertyAt(i, j, 'deltaY');\n if (path && currentDecoration && currentFill) {\n ctx.save();\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.translate(charBox.renderLeft, charBox.renderTop);\n ctx.rotate(charBox.angle);\n ctx.fillRect(\n -charBox.kernedWidth / 2,\n offsetY * currentSize + currentDy,\n charBox.kernedWidth,\n this.fontSize / 15,\n );\n ctx.restore();\n } else if (\n (currentDecoration !== lastDecoration ||\n currentFill !== lastFill ||\n currentSize !== size ||\n currentDy !== dy) &&\n boxWidth > 0\n ) {\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n if (lastDecoration && lastFill) {\n // bug? verify lastFill is a valid fill here.\n ctx.fillStyle = lastFill as string;\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth,\n this.fontSize / 15,\n );\n }\n boxStart = charBox.left;\n boxWidth = charBox.width;\n lastDecoration = currentDecoration;\n lastFill = currentFill;\n size = currentSize;\n dy = currentDy;\n } else {\n boxWidth += charBox.kernedWidth;\n }\n }\n let drawStart = leftOffset + lineLeftOffset + boxStart;\n if (this.direction === 'rtl') {\n drawStart = this.width - drawStart - boxWidth;\n }\n ctx.fillStyle = currentFill as string;\n currentDecoration &&\n currentFill &&\n ctx.fillRect(\n drawStart,\n top + offsetY * size + dy,\n boxWidth - charSpacing,\n this.fontSize / 15,\n );\n topOffset += heightOfLine;\n }\n // if there is text background color no\n // other shadows should be casted\n this._removeShadow(ctx);\n }\n\n /**\n * return font declaration string for canvas context\n * @param {Object} [styleObject] object\n * @returns {String} font declaration formatted for canvas context.\n */\n _getFontDeclaration(\n {\n fontFamily = this.fontFamily,\n fontStyle = this.fontStyle,\n fontWeight = this.fontWeight,\n fontSize = this.fontSize,\n }: Partial<\n Pick<\n TextStyleDeclaration,\n 'fontFamily' | 'fontStyle' | 'fontWeight' | 'fontSize'\n >\n > = {},\n forMeasuring?: boolean,\n ): string {\n const parsedFontFamily =\n fontFamily.includes(\"'\") ||\n fontFamily.includes('\"') ||\n fontFamily.includes(',') ||\n FabricText.genericFonts.includes(fontFamily.toLowerCase())\n ? fontFamily\n : `\"${fontFamily}\"`;\n return [\n fontStyle,\n fontWeight,\n `${forMeasuring ? this.CACHE_FONT_SIZE : fontSize}px`,\n parsedFontFamily,\n ].join(' ');\n }\n\n /**\n * Renders text instance on a specified context\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n if (!this.visible) {\n return;\n }\n if (\n this.canvas &&\n this.canvas.skipOffscreen &&\n !this.group &&\n !this.isOnScreen()\n ) {\n return;\n }\n if (this._forceClearCache) {\n this.initDimensions();\n }\n super.render(ctx);\n }\n\n /**\n * Override this method to customize grapheme splitting\n * @todo the util `graphemeSplit` needs to be injectable in some way.\n * is more comfortable to inject the correct util rather than having to override text\n * in the middle of the prototype chain\n * @param {string} value\n * @returns {string[]} array of graphemes\n */\n graphemeSplit(value: string): string[] {\n return graphemeSplit(value);\n }\n\n /**\n * Returns the text as an array of lines.\n * @param {String} text text to split\n * @returns Lines in the text\n */\n _splitTextIntoLines(text: string): TextLinesInfo {\n const lines = text.split(this._reNewline),\n newLines = new Array(lines.length),\n newLine = ['\\n'];\n let newText: string[] = [];\n for (let i = 0; i < lines.length; i++) {\n newLines[i] = this.graphemeSplit(lines[i]);\n newText = newText.concat(newLines[i], newLine);\n }\n newText.pop();\n return {\n _unwrappedLines: newLines,\n lines: lines,\n graphemeText: newText,\n graphemeLines: newLines,\n };\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return {\n ...super.toObject([...additionalProps, ...propertiesToInclude] as K[]),\n styles: stylesToArray(this.styles, this.text),\n ...(this.path ? { path: this.path.toObject() } : {}),\n };\n }\n\n set(key: string | any, value?: any) {\n const { textLayoutProperties } = this.constructor as typeof FabricText;\n super.set(key, value);\n let needsDims = false;\n let isAddingPath = false;\n if (typeof key === 'object') {\n for (const _key in key) {\n if (_key === 'path') {\n this.setPathInfo();\n }\n needsDims = needsDims || textLayoutProperties.includes(_key);\n isAddingPath = isAddingPath || _key === 'path';\n }\n } else {\n needsDims = textLayoutProperties.includes(key);\n isAddingPath = key === 'path';\n }\n if (isAddingPath) {\n this.setPathInfo();\n }\n if (needsDims && this.initialized) {\n this.initDimensions();\n this.setCoords();\n }\n return this;\n }\n\n /**\n * Returns complexity of an instance\n * @return {Number} complexity\n */\n complexity(): number {\n return 1;\n }\n\n static genericFonts = [\n 'sans-serif',\n 'serif',\n 'cursive',\n 'fantasy',\n 'monospace',\n ];\n\n /* _FROM_SVG_START_ */\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricText.fromElement})\n * @static\n * @memberOf Text\n * @see: http://www.w3.org/TR/SVG/text.html#TextElement\n */\n static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat(\n 'x',\n 'y',\n 'dx',\n 'dy',\n 'font-family',\n 'font-style',\n 'font-weight',\n 'font-size',\n 'letter-spacing',\n 'text-decoration',\n 'text-anchor',\n );\n\n /**\n * Returns FabricText instance from an SVG element (not yet implemented)\n * @static\n * @memberOf Text\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable,\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n FabricText.ATTRIBUTE_NAMES,\n cssRules,\n );\n\n const {\n textAnchor = LEFT as typeof LEFT | typeof CENTER | typeof RIGHT,\n textDecoration = '',\n dx = 0,\n dy = 0,\n top = 0,\n left = 0,\n fontSize = DEFAULT_SVG_FONT_SIZE,\n strokeWidth = 1,\n ...restOfOptions\n } = { ...options, ...parsedAttributes };\n\n const textContent = (element.textContent || '')\n .replace(/^\\s+|\\s+$|\\n+/g, '')\n .replace(/\\s+/g, ' ');\n\n // this code here is probably the usual issue for SVG center find\n // this can later looked at again and probably removed.\n\n const text = new this(textContent, {\n left: left + dx,\n top: top + dy,\n underline: textDecoration.includes('underline'),\n overline: textDecoration.includes('overline'),\n linethrough: textDecoration.includes('line-through'),\n // we initialize this as 0\n strokeWidth: 0,\n fontSize,\n ...restOfOptions,\n }),\n textHeightScaleFactor = text.getScaledHeight() / text.height,\n lineHeightDiff =\n (text.height + text.strokeWidth) * text.lineHeight - text.height,\n scaledDiff = lineHeightDiff * textHeightScaleFactor,\n textHeight = text.getScaledHeight() + scaledDiff;\n\n let offX = 0;\n /*\n Adjust positioning:\n x/y attributes in SVG correspond to the bottom-left corner of text bounding box\n fabric output by default at top, left.\n */\n if (textAnchor === CENTER) {\n offX = text.getScaledWidth() / 2;\n }\n if (textAnchor === RIGHT) {\n offX = text.getScaledWidth();\n }\n text.set({\n left: text.left - offX,\n top:\n text.top -\n (textHeight - text.fontSize * (0.07 + text._fontSizeFraction)) /\n text.lineHeight,\n strokeWidth,\n });\n return text;\n }\n\n /* _FROM_SVG_END_ */\n\n /**\n * Returns FabricText instance from an object representation\n * @param {Object} object plain js Object to create an instance from\n * @returns {Promise}\n */\n static fromObject<\n T extends TOptions,\n S extends FabricText,\n >(object: T) {\n return this._fromObject(\n {\n ...object,\n styles: stylesFromArray(object.styles || {}, object.text),\n },\n {\n extraParam: 'text',\n },\n );\n }\n}\n\napplyMixins(FabricText, [TextSVGExportMixin]);\nclassRegistry.setClass(FabricText);\nclassRegistry.setSVGClass(FabricText);\n","import type {\n DragEventData,\n DropEventData,\n TPointerEvent,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { IText } from './IText';\nimport { setStyle } from '../../util/dom_style';\nimport { cloneStyles } from '../../util/internals/cloneStyles';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, NONE } from '../../constants';\n\n/**\n * #### Dragging IText/Textbox Lifecycle\n * - {@link start} is called from `mousedown` {@link IText#_mouseDownHandler} and determines if dragging should start by testing {@link isPointerOverSelection}\n * - if true `mousedown` {@link IText#_mouseDownHandler} is blocked to keep selection\n * - if the pointer moves, canvas fires numerous mousemove {@link Canvas#_onMouseMove} that we make sure **aren't** prevented ({@link IText#shouldStartDragging}) in order for the window to start a drag session\n * - once/if the session starts canvas calls {@link onDragStart} on the active object to determine if dragging should occur\n * - canvas fires relevant drag events that are handled by the handlers defined in this scope\n * - {@link end} is called from `mouseup` {@link IText#mouseUpHandler}, blocking IText default click behavior\n * - in case the drag session didn't occur, {@link end} handles a click, since logic to do so was blocked during `mousedown`\n */\nexport class DraggableTextDelegate {\n readonly target: IText;\n private __mouseDownInPlace = false;\n private __dragStartFired = false;\n private __isDraggingOver = false;\n private __dragStartSelection?: {\n selectionStart: number;\n selectionEnd: number;\n };\n private __dragImageDisposer?: VoidFunction;\n private _dispose?: () => void;\n\n constructor(target: IText) {\n this.target = target;\n const disposers = [\n this.target.on('dragenter', this.dragEnterHandler.bind(this)),\n this.target.on('dragover', this.dragOverHandler.bind(this)),\n this.target.on('dragleave', this.dragLeaveHandler.bind(this)),\n this.target.on('dragend', this.dragEndHandler.bind(this)),\n this.target.on('drop', this.dropHandler.bind(this)),\n ];\n this._dispose = () => {\n disposers.forEach((d) => d());\n this._dispose = undefined;\n };\n }\n\n isPointerOverSelection(e: TPointerEvent) {\n const target = this.target;\n const newSelection = target.getSelectionStartFromPointer(e);\n return (\n target.isEditing &&\n newSelection >= target.selectionStart &&\n newSelection <= target.selectionEnd &&\n target.selectionStart < target.selectionEnd\n );\n }\n\n /**\n * @public override this method to disable dragging and default to mousedown logic\n */\n start(e: TPointerEvent) {\n return (this.__mouseDownInPlace = this.isPointerOverSelection(e));\n }\n\n /**\n * @public override this method to disable dragging without discarding selection\n */\n isActive() {\n return this.__mouseDownInPlace;\n }\n\n /**\n * Ends interaction and sets cursor in case of a click\n * @returns true if was active\n */\n end(e: TPointerEvent) {\n const active = this.isActive();\n if (active && !this.__dragStartFired) {\n // mousedown has been blocked since `active` is true => cursor has not been set.\n // `__dragStartFired` is false => dragging didn't occur, pointer didn't move and is over selection.\n // meaning this is actually a click, `active` is a false positive.\n this.target.setCursorByClick(e);\n this.target.initDelayedCursor(true);\n }\n this.__mouseDownInPlace = false;\n this.__dragStartFired = false;\n this.__isDraggingOver = false;\n return active;\n }\n\n getDragStartSelection() {\n return this.__dragStartSelection;\n }\n\n /**\n * Override to customize the drag image\n * https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage\n */\n setDragImage(\n e: DragEvent,\n {\n selectionStart,\n selectionEnd,\n }: {\n selectionStart: number;\n selectionEnd: number;\n },\n ) {\n const target = this.target;\n const canvas = target.canvas!;\n const flipFactor = new Point(target.flipX ? -1 : 1, target.flipY ? -1 : 1);\n const boundaries = target._getCursorBoundaries(selectionStart);\n const selectionPosition = new Point(\n boundaries.left + boundaries.leftOffset,\n boundaries.top + boundaries.topOffset,\n ).multiply(flipFactor);\n const pos = selectionPosition.transform(target.calcTransformMatrix());\n const pointer = canvas.getScenePoint(e);\n const diff = pointer.subtract(pos);\n const retinaScaling = target.getCanvasRetinaScaling();\n const bbox = target.getBoundingRect();\n const correction = pos.subtract(new Point(bbox.left, bbox.top));\n const vpt = canvas.viewportTransform;\n const offset = correction.add(diff).transform(vpt, true);\n // prepare instance for drag image snapshot by making all non selected text invisible\n const bgc = target.backgroundColor;\n const styles = cloneStyles(target.styles);\n target.backgroundColor = '';\n const styleOverride = {\n stroke: 'transparent',\n fill: 'transparent',\n textBackgroundColor: 'transparent',\n };\n target.setSelectionStyles(styleOverride, 0, selectionStart);\n target.setSelectionStyles(styleOverride, selectionEnd, target.text.length);\n target.dirty = true;\n const dragImage = target.toCanvasElement({\n enableRetinaScaling: canvas.enableRetinaScaling,\n viewportTransform: true,\n });\n // restore values\n target.backgroundColor = bgc;\n target.styles = styles;\n target.dirty = true;\n // position drag image offscreen\n setStyle(dragImage, {\n position: 'fixed',\n left: `${-dragImage.width}px`,\n border: NONE,\n width: `${dragImage.width / retinaScaling}px`,\n height: `${dragImage.height / retinaScaling}px`,\n });\n this.__dragImageDisposer && this.__dragImageDisposer();\n this.__dragImageDisposer = () => {\n dragImage.remove();\n };\n getDocumentFromElement(\n (e.target || this.target.hiddenTextarea)! as HTMLElement,\n ).body.appendChild(dragImage);\n e.dataTransfer?.setDragImage(dragImage, offset.x, offset.y);\n }\n\n /**\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drag source\n */\n onDragStart(e: DragEvent): boolean {\n this.__dragStartFired = true;\n const target = this.target;\n const active = this.isActive();\n if (active && e.dataTransfer) {\n const selection = (this.__dragStartSelection = {\n selectionStart: target.selectionStart,\n selectionEnd: target.selectionEnd,\n });\n const value = target._text\n .slice(selection.selectionStart, selection.selectionEnd)\n .join('');\n const data = { text: target.text, value, ...selection };\n e.dataTransfer.setData('text/plain', value);\n e.dataTransfer.setData(\n 'application/fabric',\n JSON.stringify({\n value: value,\n styles: target.getSelectionStyles(\n selection.selectionStart,\n selection.selectionEnd,\n true,\n ),\n }),\n );\n e.dataTransfer.effectAllowed = 'copyMove';\n this.setDragImage(e, data);\n }\n target.abortCursorAnimation();\n return active;\n }\n\n /**\n * use {@link targetCanDrop} to respect overriding\n * @returns {boolean} determines whether {@link target} should/shouldn't become a drop target\n */\n canDrop(e: DragEvent): boolean {\n if (\n this.target.editable &&\n !this.target.getActiveControl() &&\n !e.defaultPrevented\n ) {\n if (this.isActive() && this.__dragStartSelection) {\n // drag source trying to drop over itself\n // allow dropping only outside of drag start selection\n const index = this.target.getSelectionStartFromPointer(e);\n const dragStartSelection = this.__dragStartSelection;\n return (\n index < dragStartSelection.selectionStart ||\n index > dragStartSelection.selectionEnd\n );\n }\n return true;\n }\n return false;\n }\n\n /**\n * in order to respect overriding {@link IText#canDrop} we call that instead of calling {@link canDrop} directly\n */\n protected targetCanDrop(e: DragEvent) {\n return this.target.canDrop(e);\n }\n\n dragEnterHandler({ e }: DragEventData) {\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n }\n }\n\n dragOverHandler(ev: DragEventData) {\n const { e } = ev;\n const canDrop = this.targetCanDrop(e);\n if (!this.__isDraggingOver && canDrop) {\n this.__isDraggingOver = true;\n } else if (this.__isDraggingOver && !canDrop) {\n // drop state has changed\n this.__isDraggingOver = false;\n }\n if (this.__isDraggingOver) {\n // can be dropped, inform browser\n e.preventDefault();\n // inform event subscribers\n ev.canDrop = true;\n ev.dropTarget = this.target;\n }\n }\n\n dragLeaveHandler() {\n if (this.__isDraggingOver || this.isActive()) {\n this.__isDraggingOver = false;\n }\n }\n\n /**\n * Override the `text/plain | application/fabric` types of {@link DragEvent#dataTransfer}\n * in order to change the drop value or to customize styling respectively, by listening to the `drop:before` event\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#performing_a_drop\n */\n dropHandler(ev: DropEventData) {\n const { e } = ev;\n const didDrop = e.defaultPrevented;\n this.__isDraggingOver = false;\n // inform browser that the drop has been accepted\n e.preventDefault();\n let insert = e.dataTransfer?.getData('text/plain');\n if (insert && !didDrop) {\n const target = this.target;\n const canvas = target.canvas!;\n let insertAt = target.getSelectionStartFromPointer(e);\n const { styles } = (\n e.dataTransfer!.types.includes('application/fabric')\n ? JSON.parse(e.dataTransfer!.getData('application/fabric'))\n : {}\n ) as { styles: TextStyleDeclaration[] };\n const trailing = insert[Math.max(0, insert.length - 1)];\n const selectionStartOffset = 0;\n // drag and drop in same instance\n if (this.__dragStartSelection) {\n const selectionStart = this.__dragStartSelection.selectionStart;\n const selectionEnd = this.__dragStartSelection.selectionEnd;\n if (insertAt > selectionStart && insertAt <= selectionEnd) {\n insertAt = selectionStart;\n } else if (insertAt > selectionEnd) {\n insertAt -= selectionEnd - selectionStart;\n }\n target.removeChars(selectionStart, selectionEnd);\n // prevent `dragend` from handling event\n delete this.__dragStartSelection;\n }\n // remove redundant line break\n if (\n target._reNewline.test(trailing) &&\n (target._reNewline.test(target._text[insertAt]) ||\n insertAt === target._text.length)\n ) {\n insert = insert.trimEnd();\n }\n // inform subscribers\n ev.didDrop = true;\n ev.dropTarget = target;\n // finalize\n target.insertChars(insert, styles, insertAt);\n // can this part be moved in an outside event? andrea to check.\n canvas.setActiveObject(target);\n target.enterEditing(e);\n target.selectionStart = Math.min(\n insertAt + selectionStartOffset,\n target._text.length,\n );\n target.selectionEnd = Math.min(\n target.selectionStart + insert.length,\n target._text.length,\n );\n target.hiddenTextarea!.value = target.text;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n target.fire(CHANGED, {\n index: insertAt + selectionStartOffset,\n action: 'drop',\n });\n canvas.fire('text:changed', { target });\n canvas.contextTopDirty = true;\n canvas.requestRenderAll();\n }\n }\n\n /**\n * fired only on the drag source after drop (if occurred)\n * handle changes to the drag source in case of a drop on another object or a cancellation\n * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag\n */\n dragEndHandler({ e }: DragEventData) {\n if (this.isActive() && this.__dragStartFired) {\n // once the drop event finishes we check if we need to change the drag source\n // if the drag source received the drop we bail out since the drop handler has already handled logic\n if (this.__dragStartSelection) {\n const target = this.target;\n const canvas = this.target.canvas!;\n const { selectionStart, selectionEnd } = this.__dragStartSelection;\n const dropEffect = e.dataTransfer?.dropEffect || NONE;\n if (dropEffect === NONE) {\n // pointer is back over selection\n target.selectionStart = selectionStart;\n target.selectionEnd = selectionEnd;\n target._updateTextarea();\n target.hiddenTextarea!.focus();\n } else {\n target.clearContextTop();\n if (dropEffect === 'move') {\n target.removeChars(selectionStart, selectionEnd);\n target.selectionStart = target.selectionEnd = selectionStart;\n target.hiddenTextarea &&\n (target.hiddenTextarea.value = target.text);\n target._updateTextarea();\n target.fire(CHANGED, {\n index: selectionStart,\n action: 'dragend',\n });\n canvas.fire('text:changed', { target });\n canvas.requestRenderAll();\n }\n target.exitEditing();\n }\n }\n }\n\n this.__dragImageDisposer && this.__dragImageDisposer();\n delete this.__dragImageDisposer;\n delete this.__dragStartSelection;\n this.__isDraggingOver = false;\n }\n\n dispose() {\n this._dispose && this._dispose();\n }\n}\n","import type {\n ObjectEvents,\n TPointerEvent,\n TPointerEventInfo,\n} from '../../EventTypeDefs';\nimport { Point } from '../../Point';\nimport type { FabricObject } from '../Object/FabricObject';\nimport { FabricText } from '../Text/Text';\nimport { animate } from '../../util/animation/animate';\nimport type { TOnAnimationChangeCallback } from '../../util/animation/types';\nimport type { ValueAnimation } from '../../util/animation/ValueAnimation';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport type { TOptions } from '../../typedefs';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { LEFT, MODIFIED, RIGHT, reNewline } from '../../constants';\nimport type { IText } from './IText';\n\n/**\n * extend this regex to support non english languages\n *\n * - ` ` Matches a SPACE character (char code 32).\n * - `\\n` Matches a LINE FEED character (char code 10).\n * - `\\.` Matches a \".\" character (char code 46).\n * - `,` Matches a \",\" character (char code 44).\n * - `;` Matches a \";\" character (char code 59).\n * - `!` Matches a \"!\" character (char code 33).\n * - `\\?` Matches a \"?\" character (char code 63).\n * - `\\-` Matches a \"-\" character (char code 45).\n */\n// eslint-disable-next-line no-useless-escape\nconst reNonWord = /[ \\n\\.,;!\\?\\-]/;\n\nexport type ITextEvents = ObjectEvents & {\n 'selection:changed': never;\n changed: never | { index: number; action: string };\n tripleclick: TPointerEventInfo;\n 'editing:entered': never | { e: TPointerEvent };\n 'editing:exited': never;\n};\n\nexport abstract class ITextBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends FabricText {\n declare abstract isEditing: boolean;\n declare abstract cursorDelay: number;\n declare abstract selectionStart: number;\n declare abstract selectionEnd: number;\n declare abstract cursorDuration: number;\n declare abstract editable: boolean;\n declare abstract editingBorderColor: string;\n\n declare abstract compositionStart: number;\n declare abstract compositionEnd: number;\n\n declare abstract hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * Helps determining when the text is in composition, so that the cursor\n * rendering is altered.\n */\n protected declare inCompositionMode: boolean;\n\n protected declare _reSpace: RegExp;\n private declare _currentTickState?: ValueAnimation;\n private declare _currentTickCompleteState?: ValueAnimation;\n protected _currentCursorOpacity = 1;\n private declare _textBeforeEdit: string;\n protected declare __selectionStartOnMouseDown: number;\n\n protected declare selected: boolean;\n protected declare cursorOffsetCache: { left?: number; top?: number };\n protected declare _savedProps?: {\n hasControls: boolean;\n borderColor: string;\n lockMovementX: boolean;\n lockMovementY: boolean;\n selectable: boolean;\n hoverCursor: CSSStyleDeclaration['cursor'] | null;\n defaultCursor?: CSSStyleDeclaration['cursor'];\n moveCursor?: CSSStyleDeclaration['cursor'];\n };\n protected declare _selectionDirection: 'left' | 'right' | null;\n\n abstract initHiddenTextarea(): void;\n abstract _fireSelectionChanged(): void;\n abstract renderCursorOrSelection(): void;\n abstract getSelectionStartFromPointer(e: TPointerEvent): number;\n abstract _getCursorBoundaries(\n index: number,\n skipCaching?: boolean,\n ): {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n };\n\n /**\n * Initializes all the interactive behavior of IText\n */\n initBehavior() {\n this._tick = this._tick.bind(this);\n this._onTickComplete = this._onTickComplete.bind(this);\n this.updateSelectionOnMouseMove =\n this.updateSelectionOnMouseMove.bind(this);\n }\n\n onDeselect(options?: { e?: TPointerEvent; object?: FabricObject }) {\n this.isEditing && this.exitEditing();\n this.selected = false;\n return super.onDeselect(options);\n }\n\n /**\n * @private\n */\n _animateCursor({\n toValue,\n duration,\n delay,\n onComplete,\n }: {\n toValue: number;\n duration: number;\n delay?: number;\n onComplete?: TOnAnimationChangeCallback;\n }) {\n return animate({\n startValue: this._currentCursorOpacity,\n endValue: toValue,\n duration,\n delay,\n onComplete,\n abort: () =>\n !this.canvas ||\n // we do not want to animate a selection, only cursor\n this.selectionStart !== this.selectionEnd,\n onChange: (value) => {\n this._currentCursorOpacity = value;\n this.renderCursorOrSelection();\n },\n });\n }\n\n /**\n * changes the cursor from visible to invisible\n */\n private _tick(delay?: number) {\n this._currentTickState = this._animateCursor({\n toValue: 0,\n duration: this.cursorDuration / 2,\n delay: Math.max(delay || 0, 100),\n onComplete: this._onTickComplete,\n });\n }\n\n /**\n * Changes the cursor from invisible to visible\n */\n private _onTickComplete() {\n this._currentTickCompleteState?.abort();\n this._currentTickCompleteState = this._animateCursor({\n toValue: 1,\n duration: this.cursorDuration,\n onComplete: this._tick,\n });\n }\n\n /**\n * Initializes delayed cursor\n */\n initDelayedCursor(restart?: boolean) {\n this.abortCursorAnimation();\n this._tick(restart ? 0 : this.cursorDelay);\n }\n\n /**\n * Aborts cursor animation, clears all timeouts and clear textarea context if necessary\n */\n abortCursorAnimation() {\n let shouldClear = false;\n [this._currentTickState, this._currentTickCompleteState].forEach(\n (cursorAnimation) => {\n if (cursorAnimation && !cursorAnimation.isDone()) {\n shouldClear = true;\n cursorAnimation.abort();\n }\n },\n );\n\n this._currentCursorOpacity = 1;\n\n // make sure we clear context even if instance is not editing\n if (shouldClear) {\n this.clearContextTop();\n }\n }\n\n /**\n * Restart tue cursor animation if either is in complete state ( between animations )\n * or if it never started before\n */\n restartCursorIfNeeded() {\n if (\n [this._currentTickState, this._currentTickCompleteState].some(\n (cursorAnimation) => !cursorAnimation || cursorAnimation.isDone(),\n )\n ) {\n this.initDelayedCursor();\n }\n }\n\n /**\n * Selects entire text\n */\n selectAll() {\n this.selectionStart = 0;\n this.selectionEnd = this._text.length;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Returns selected text\n * @return {String}\n */\n getSelectedText(): string {\n return this._text.slice(this.selectionStart, this.selectionEnd).join('');\n }\n\n /**\n * Find new selection index representing start of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n // remove space before cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index--;\n }\n }\n while (/\\S/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current word according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findWordBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n // remove space after cursor first\n if (this._reSpace.test(this._text[index])) {\n while (this._reSpace.test(this._text[index])) {\n offset++;\n index++;\n }\n }\n while (/\\S/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Find new selection index representing start of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryLeft(startFrom: number): number {\n let offset = 0,\n index = startFrom - 1;\n\n while (!/\\n/.test(this._text[index]) && index > -1) {\n offset++;\n index--;\n }\n\n return startFrom - offset;\n }\n\n /**\n * Find new selection index representing end of current line according to current selection index\n * @param {Number} startFrom Current selection index\n * @return {Number} New selection index\n */\n findLineBoundaryRight(startFrom: number): number {\n let offset = 0,\n index = startFrom;\n\n while (!/\\n/.test(this._text[index]) && index < this._text.length) {\n offset++;\n index++;\n }\n\n return startFrom + offset;\n }\n\n /**\n * Finds index corresponding to beginning or end of a word\n * @param {Number} selectionStart Index of a character\n * @param {Number} direction 1 or -1\n * @return {Number} Index of the beginning or end of a word\n */\n searchWordBoundary(selectionStart: number, direction: 1 | -1): number {\n const text = this._text;\n // if we land on a space we move the cursor backwards\n // if we are searching boundary end we move the cursor backwards ONLY if we don't land on a line break\n let index =\n selectionStart > 0 &&\n this._reSpace.test(text[selectionStart]) &&\n (direction === -1 || !reNewline.test(text[selectionStart - 1]))\n ? selectionStart - 1\n : selectionStart,\n _char = text[index];\n while (index > 0 && index < text.length && !reNonWord.test(_char)) {\n index += direction;\n _char = text[index];\n }\n if (direction === -1 && reNonWord.test(_char)) {\n index++;\n }\n return index;\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a word based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectWord(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n // search backwards\n const newSelectionStart = this.searchWordBoundary(selectionStart, -1),\n // search forward\n newSelectionEnd = Math.max(\n newSelectionStart,\n this.searchWordBoundary(selectionStart, 1),\n );\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n\n /**\n * TODO fix: selectionStart set as 0 will be ignored?\n * Selects a line based on the index\n * @param {Number} selectionStart Index of a character\n */\n selectLine(selectionStart?: number) {\n selectionStart = selectionStart || this.selectionStart;\n const newSelectionStart = this.findLineBoundaryLeft(selectionStart),\n newSelectionEnd = this.findLineBoundaryRight(selectionStart);\n\n this.selectionStart = newSelectionStart;\n this.selectionEnd = newSelectionEnd;\n this._fireSelectionChanged();\n this._updateTextarea();\n return this;\n }\n\n /**\n * Enters editing state\n */\n enterEditing(e?: TPointerEvent) {\n if (this.isEditing || !this.editable) {\n return;\n }\n if (this.canvas) {\n this.canvas.calcOffset();\n this.canvas.textEditingManager.exitTextEditing();\n }\n\n this.isEditing = true;\n\n this.initHiddenTextarea();\n this.hiddenTextarea!.focus();\n this.hiddenTextarea!.value = this.text;\n this._updateTextarea();\n this._saveEditingProps();\n this._setEditingProps();\n this._textBeforeEdit = this.text;\n\n this._tick();\n this.fire('editing:entered', e ? { e } : undefined);\n this._fireSelectionChanged();\n if (this.canvas) {\n this.canvas.fire('text:editing:entered', {\n target: this as unknown as IText,\n e,\n });\n this.canvas.requestRenderAll();\n }\n }\n\n /**\n * called by {@link Canvas#textEditingManager}\n */\n updateSelectionOnMouseMove(e: TPointerEvent) {\n if (this.getActiveControl()) {\n return;\n }\n\n const el = this.hiddenTextarea!;\n // regain focus\n getDocumentFromElement(el).activeElement !== el && el.focus();\n\n const newSelectionStart = this.getSelectionStartFromPointer(e),\n currentStart = this.selectionStart,\n currentEnd = this.selectionEnd;\n if (\n (newSelectionStart !== this.__selectionStartOnMouseDown ||\n currentStart === currentEnd) &&\n (currentStart === newSelectionStart || currentEnd === newSelectionStart)\n ) {\n return;\n }\n if (newSelectionStart > this.__selectionStartOnMouseDown) {\n this.selectionStart = this.__selectionStartOnMouseDown;\n this.selectionEnd = newSelectionStart;\n } else {\n this.selectionStart = newSelectionStart;\n this.selectionEnd = this.__selectionStartOnMouseDown;\n }\n if (\n this.selectionStart !== currentStart ||\n this.selectionEnd !== currentEnd\n ) {\n this._fireSelectionChanged();\n this._updateTextarea();\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * @private\n */\n _setEditingProps() {\n this.hoverCursor = 'text';\n\n if (this.canvas) {\n this.canvas.defaultCursor = this.canvas.moveCursor = 'text';\n }\n\n this.borderColor = this.editingBorderColor;\n this.hasControls = this.selectable = false;\n this.lockMovementX = this.lockMovementY = true;\n }\n\n /**\n * convert from textarea to grapheme indexes\n */\n fromStringToGraphemeSelection(start: number, end: number, text: string) {\n const smallerTextStart = text.slice(0, start),\n graphemeStart = this.graphemeSplit(smallerTextStart).length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = text.slice(start, end),\n graphemeEnd = this.graphemeSplit(smallerTextEnd).length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * convert from fabric to textarea values\n */\n fromGraphemeToStringSelection(\n start: number,\n end: number,\n graphemes: string[],\n ) {\n const smallerTextStart = graphemes.slice(0, start),\n graphemeStart = smallerTextStart.join('').length;\n if (start === end) {\n return { selectionStart: graphemeStart, selectionEnd: graphemeStart };\n }\n const smallerTextEnd = graphemes.slice(start, end),\n graphemeEnd = smallerTextEnd.join('').length;\n return {\n selectionStart: graphemeStart,\n selectionEnd: graphemeStart + graphemeEnd,\n };\n }\n\n /**\n * @private\n */\n _updateTextarea() {\n this.cursorOffsetCache = {};\n if (!this.hiddenTextarea) {\n return;\n }\n if (!this.inCompositionMode) {\n const newSelection = this.fromGraphemeToStringSelection(\n this.selectionStart,\n this.selectionEnd,\n this._text,\n );\n this.hiddenTextarea.selectionStart = newSelection.selectionStart;\n this.hiddenTextarea.selectionEnd = newSelection.selectionEnd;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateFromTextArea() {\n if (!this.hiddenTextarea) {\n return;\n }\n this.cursorOffsetCache = {};\n const textarea = this.hiddenTextarea;\n this.text = textarea.value;\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n const newSelection = this.fromStringToGraphemeSelection(\n textarea.selectionStart,\n textarea.selectionEnd,\n textarea.value,\n );\n this.selectionEnd = this.selectionStart = newSelection.selectionEnd;\n if (!this.inCompositionMode) {\n this.selectionStart = newSelection.selectionStart;\n }\n this.updateTextareaPosition();\n }\n\n /**\n * @private\n */\n updateTextareaPosition() {\n if (this.selectionStart === this.selectionEnd) {\n const style = this._calcTextareaPosition();\n this.hiddenTextarea!.style.left = style.left;\n this.hiddenTextarea!.style.top = style.top;\n }\n }\n\n /**\n * @private\n * @return {Object} style contains style for hiddenTextarea\n */\n _calcTextareaPosition() {\n if (!this.canvas) {\n return { left: '1px', top: '1px' };\n }\n const desiredPosition = this.inCompositionMode\n ? this.compositionStart\n : this.selectionStart,\n boundaries = this._getCursorBoundaries(desiredPosition),\n cursorLocation = this.get2DCursorLocation(desiredPosition),\n lineIndex = cursorLocation.lineIndex,\n charIndex = cursorLocation.charIndex,\n charHeight =\n this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize') *\n this.lineHeight,\n leftOffset = boundaries.leftOffset,\n retinaScaling = this.getCanvasRetinaScaling(),\n upperCanvas = this.canvas.upperCanvasEl,\n upperCanvasWidth = upperCanvas.width / retinaScaling,\n upperCanvasHeight = upperCanvas.height / retinaScaling,\n maxWidth = upperCanvasWidth - charHeight,\n maxHeight = upperCanvasHeight - charHeight;\n\n const p = new Point(\n boundaries.left + leftOffset,\n boundaries.top + boundaries.topOffset + charHeight,\n )\n .transform(this.calcTransformMatrix())\n .transform(this.canvas.viewportTransform)\n .multiply(\n new Point(\n upperCanvas.clientWidth / upperCanvasWidth,\n upperCanvas.clientHeight / upperCanvasHeight,\n ),\n );\n\n if (p.x < 0) {\n p.x = 0;\n }\n if (p.x > maxWidth) {\n p.x = maxWidth;\n }\n if (p.y < 0) {\n p.y = 0;\n }\n if (p.y > maxHeight) {\n p.y = maxHeight;\n }\n\n // add canvas offset on document\n p.x += this.canvas._offset.left;\n p.y += this.canvas._offset.top;\n\n return {\n left: `${p.x}px`,\n top: `${p.y}px`,\n fontSize: `${charHeight}px`,\n charHeight: charHeight,\n };\n }\n\n /**\n * @private\n */\n _saveEditingProps() {\n this._savedProps = {\n hasControls: this.hasControls,\n borderColor: this.borderColor,\n lockMovementX: this.lockMovementX,\n lockMovementY: this.lockMovementY,\n hoverCursor: this.hoverCursor,\n selectable: this.selectable,\n defaultCursor: this.canvas && this.canvas.defaultCursor,\n moveCursor: this.canvas && this.canvas.moveCursor,\n };\n }\n\n /**\n * @private\n */\n _restoreEditingProps() {\n if (!this._savedProps) {\n return;\n }\n\n this.hoverCursor = this._savedProps.hoverCursor;\n this.hasControls = this._savedProps.hasControls;\n this.borderColor = this._savedProps.borderColor;\n this.selectable = this._savedProps.selectable;\n this.lockMovementX = this._savedProps.lockMovementX;\n this.lockMovementY = this._savedProps.lockMovementY;\n\n if (this.canvas) {\n this.canvas.defaultCursor =\n this._savedProps.defaultCursor || this.canvas.defaultCursor;\n this.canvas.moveCursor =\n this._savedProps.moveCursor || this.canvas.moveCursor;\n }\n\n delete this._savedProps;\n }\n\n /**\n * runs the actual logic that exits from editing state, see {@link exitEditing}\n */\n protected _exitEditing() {\n const hiddenTextarea = this.hiddenTextarea;\n this.selected = false;\n this.isEditing = false;\n\n if (hiddenTextarea) {\n hiddenTextarea.blur && hiddenTextarea.blur();\n hiddenTextarea.parentNode &&\n hiddenTextarea.parentNode.removeChild(hiddenTextarea);\n }\n this.hiddenTextarea = null;\n this.abortCursorAnimation();\n this.selectionStart !== this.selectionEnd && this.clearContextTop();\n }\n\n /**\n * Exits from editing state and fires relevant events\n */\n exitEditing() {\n const isTextChanged = this._textBeforeEdit !== this.text;\n this._exitEditing();\n this.selectionEnd = this.selectionStart;\n this._restoreEditingProps();\n if (this._forceClearCache) {\n this.initDimensions();\n this.setCoords();\n }\n this.fire('editing:exited');\n isTextChanged && this.fire(MODIFIED);\n if (this.canvas) {\n this.canvas.fire('text:editing:exited', {\n target: this as unknown as IText,\n });\n // todo: evaluate add an action to this event\n isTextChanged && this.canvas.fire('object:modified', { target: this });\n }\n return this;\n }\n\n /**\n * @private\n */\n _removeExtraneousStyles() {\n for (const prop in this.styles) {\n if (!this._textLines[prop as unknown as number]) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * remove and reflow a style block from start to end.\n * @param {Number} start linear start position for removal (included in removal)\n * @param {Number} end linear end position for removal ( excluded from removal )\n */\n removeStyleFromTo(start: number, end: number) {\n const { lineIndex: lineStart, charIndex: charStart } =\n this.get2DCursorLocation(start, true),\n { lineIndex: lineEnd, charIndex: charEnd } = this.get2DCursorLocation(\n end,\n true,\n );\n if (lineStart !== lineEnd) {\n // step1 remove the trailing of lineStart\n if (this.styles[lineStart]) {\n for (\n let i = charStart;\n i < this._unwrappedTextLines[lineStart].length;\n i++\n ) {\n delete this.styles[lineStart][i];\n }\n }\n // step2 move the trailing of lineEnd to lineStart if needed\n if (this.styles[lineEnd]) {\n for (\n let i = charEnd;\n i < this._unwrappedTextLines[lineEnd].length;\n i++\n ) {\n const styleObj = this.styles[lineEnd][i];\n if (styleObj) {\n this.styles[lineStart] || (this.styles[lineStart] = {});\n this.styles[lineStart][charStart + i - charEnd] = styleObj;\n }\n }\n }\n // step3 detects lines will be completely removed.\n for (let i = lineStart + 1; i <= lineEnd; i++) {\n delete this.styles[i];\n }\n // step4 shift remaining lines.\n this.shiftLineStyles(lineEnd, lineStart - lineEnd);\n } else {\n // remove and shift left on the same line\n if (this.styles[lineStart]) {\n const styleObj = this.styles[lineStart];\n const diff = charEnd - charStart;\n for (let i = charStart; i < charEnd; i++) {\n delete styleObj[i];\n }\n for (const char in this.styles[lineStart]) {\n const numericChar = parseInt(char, 10);\n if (numericChar >= charEnd) {\n styleObj[numericChar - diff] = styleObj[char];\n delete styleObj[char];\n }\n }\n }\n }\n }\n\n /**\n * Shifts line styles up or down\n * @param {Number} lineIndex Index of a line\n * @param {Number} offset Can any number?\n */\n shiftLineStyles(lineIndex: number, offset: number) {\n const clonedStyles = Object.assign({}, this.styles);\n for (const line in this.styles) {\n const numericLine = parseInt(line, 10);\n if (numericLine > lineIndex) {\n this.styles[numericLine + offset] = clonedStyles[numericLine];\n if (!clonedStyles[numericLine - offset]) {\n delete this.styles[numericLine];\n }\n }\n }\n }\n\n /**\n * Handle insertion of more consecutive style lines for when one or more\n * newlines gets added to the text. Since current style needs to be shifted\n * first we shift the current style of the number lines needed, then we add\n * new lines from the last to the first.\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} qty number of lines to add\n * @param {Array} copiedStyle Array of objects styles\n */\n insertNewlineStyleObject(\n lineIndex: number,\n charIndex: number,\n qty: number,\n copiedStyle?: { [index: number]: TextStyleDeclaration },\n ) {\n const newLineStyles: { [index: number]: TextStyleDeclaration } = {};\n const originalLineLength = this._unwrappedTextLines[lineIndex].length;\n const isEndOfLine = originalLineLength === charIndex;\n\n let someStyleIsCarryingOver = false;\n qty || (qty = 1);\n this.shiftLineStyles(lineIndex, qty);\n const currentCharStyle = this.styles[lineIndex]\n ? this.styles[lineIndex][charIndex === 0 ? charIndex : charIndex - 1]\n : undefined;\n\n // we clone styles of all chars\n // after cursor onto the current line\n for (const index in this.styles[lineIndex]) {\n const numIndex = parseInt(index, 10);\n if (numIndex >= charIndex) {\n someStyleIsCarryingOver = true;\n newLineStyles[numIndex - charIndex] = this.styles[lineIndex][index];\n // remove lines from the previous line since they're on a new line now\n if (!(isEndOfLine && charIndex === 0)) {\n delete this.styles[lineIndex][index];\n }\n }\n }\n let styleCarriedOver = false;\n if (someStyleIsCarryingOver && !isEndOfLine) {\n // if is end of line, the extra style we copied\n // is probably not something we want\n this.styles[lineIndex + qty] = newLineStyles;\n styleCarriedOver = true;\n }\n if (styleCarriedOver || originalLineLength > charIndex) {\n // skip the last line of since we already prepared it.\n // or contains text without style that we don't want to style\n // just because it changed lines\n qty--;\n }\n // for the all the lines or all the other lines\n // we clone current char style onto the next (otherwise empty) line\n while (qty > 0) {\n if (copiedStyle && copiedStyle[qty - 1]) {\n this.styles[lineIndex + qty] = {\n 0: { ...copiedStyle[qty - 1] },\n };\n } else if (currentCharStyle) {\n this.styles[lineIndex + qty] = {\n 0: { ...currentCharStyle },\n };\n } else {\n delete this.styles[lineIndex + qty];\n }\n qty--;\n }\n this._forceClearCache = true;\n }\n\n /**\n * Inserts style object for a given line/char index\n * @param {Number} lineIndex Index of a line\n * @param {Number} charIndex Index of a char\n * @param {Number} quantity number Style object to insert, if given\n * @param {Array} copiedStyle array of style objects\n */\n insertCharStyleObject(\n lineIndex: number,\n charIndex: number,\n quantity: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n if (!this.styles) {\n this.styles = {};\n }\n const currentLineStyles = this.styles[lineIndex],\n currentLineStylesCloned = currentLineStyles\n ? { ...currentLineStyles }\n : {};\n\n quantity || (quantity = 1);\n // shift all char styles by quantity forward\n // 0,1,2,3 -> (charIndex=2) -> 0,1,3,4 -> (insert 2) -> 0,1,2,3,4\n for (const index in currentLineStylesCloned) {\n const numericIndex = parseInt(index, 10);\n if (numericIndex >= charIndex) {\n currentLineStyles[numericIndex + quantity] =\n currentLineStylesCloned[numericIndex];\n // only delete the style if there was nothing moved there\n if (!currentLineStylesCloned[numericIndex - quantity]) {\n delete currentLineStyles[numericIndex];\n }\n }\n }\n this._forceClearCache = true;\n if (copiedStyle) {\n while (quantity--) {\n if (!Object.keys(copiedStyle[quantity]).length) {\n continue;\n }\n if (!this.styles[lineIndex]) {\n this.styles[lineIndex] = {};\n }\n this.styles[lineIndex][charIndex + quantity] = {\n ...copiedStyle[quantity],\n };\n }\n return;\n }\n if (!currentLineStyles) {\n return;\n }\n const newStyle = currentLineStyles[charIndex ? charIndex - 1 : 1];\n while (newStyle && quantity--) {\n this.styles[lineIndex][charIndex + quantity] = { ...newStyle };\n }\n }\n\n /**\n * Inserts style object(s)\n * @param {Array} insertedText Characters at the location where style is inserted\n * @param {Number} start cursor index for inserting style\n * @param {Array} [copiedStyle] array of style objects to insert.\n */\n insertNewStyleBlock(\n insertedText: string[],\n start: number,\n copiedStyle?: TextStyleDeclaration[],\n ) {\n const cursorLoc = this.get2DCursorLocation(start, true),\n addedLines = [0];\n let linesLength = 0;\n // get an array of how many char per lines are being added.\n for (let i = 0; i < insertedText.length; i++) {\n if (insertedText[i] === '\\n') {\n linesLength++;\n addedLines[linesLength] = 0;\n } else {\n addedLines[linesLength]++;\n }\n }\n // for the first line copy the style from the current char position.\n if (addedLines[0] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex,\n addedLines[0],\n copiedStyle,\n );\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[0] + 1);\n }\n linesLength &&\n this.insertNewlineStyleObject(\n cursorLoc.lineIndex,\n cursorLoc.charIndex + addedLines[0],\n linesLength,\n );\n let i;\n for (i = 1; i < linesLength; i++) {\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n } else if (copiedStyle) {\n // this test is required in order to close #6841\n // when a pasted buffer begins with a newline then\n // this.styles[cursorLoc.lineIndex + i] and copiedStyle[0]\n // may be undefined for some reason\n if (this.styles[cursorLoc.lineIndex + i] && copiedStyle[0]) {\n this.styles[cursorLoc.lineIndex + i][0] = copiedStyle[0];\n }\n }\n copiedStyle = copiedStyle && copiedStyle.slice(addedLines[i] + 1);\n }\n if (addedLines[i] > 0) {\n this.insertCharStyleObject(\n cursorLoc.lineIndex + i,\n 0,\n addedLines[i],\n copiedStyle,\n );\n }\n }\n\n /**\n * Removes characters from start/end\n * start/end ar per grapheme position in _text array.\n *\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n removeChars(start: number, end: number = start + 1) {\n this.removeStyleFromTo(start, end);\n this._text.splice(start, end - start);\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * insert characters at start position, before start position.\n * start equal 1 it means the text get inserted between actual grapheme 0 and 1\n * if style array is provided, it must be as the same length of text in graphemes\n * if end is provided and is bigger than start, old text is replaced.\n * start/end ar per grapheme position in _text array.\n *\n * @param {String} text text to insert\n * @param {Array} style array of style objects\n * @param {Number} start\n * @param {Number} end default to start + 1\n */\n insertChars(\n text: string,\n style: TextStyleDeclaration[] | undefined,\n start: number,\n end: number = start,\n ) {\n if (end > start) {\n this.removeStyleFromTo(start, end);\n }\n const graphemes = this.graphemeSplit(text);\n this.insertNewStyleBlock(graphemes, start, style);\n this._text = [\n ...this._text.slice(0, start),\n ...graphemes,\n ...this._text.slice(end),\n ];\n this.text = this._text.join('');\n this.set('dirty', true);\n this.initDimensions();\n this.setCoords();\n this._removeExtraneousStyles();\n }\n\n /**\n * Set the selectionStart and selectionEnd according to the new position of cursor\n * mimic the key - mouse navigation when shift is pressed.\n */\n setSelectionStartEndWithShift(\n start: number,\n end: number,\n newSelection: number,\n ) {\n if (newSelection <= start) {\n if (end === start) {\n this._selectionDirection = LEFT;\n } else if (this._selectionDirection === RIGHT) {\n this._selectionDirection = LEFT;\n this.selectionEnd = start;\n }\n this.selectionStart = newSelection;\n } else if (newSelection > start && newSelection < end) {\n if (this._selectionDirection === RIGHT) {\n this.selectionEnd = newSelection;\n } else {\n this.selectionStart = newSelection;\n }\n } else {\n // newSelection is > selection start and end\n if (end === start) {\n this._selectionDirection = RIGHT;\n } else if (this._selectionDirection === LEFT) {\n this._selectionDirection = RIGHT;\n this.selectionStart = end;\n }\n this.selectionEnd = newSelection;\n }\n }\n}\n","import { config } from '../../config';\nimport { getFabricDocument, getEnv } from '../../env';\nimport { capValue } from '../../util/misc/capValue';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextBehavior } from './ITextBehavior';\nimport type { TKeyMapIText } from './constants';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\nimport { getDocumentFromElement } from '../../util/dom_misc';\nimport { CHANGED, LEFT, RIGHT } from '../../constants';\nimport type { IText } from './IText';\nimport type { TextStyleDeclaration } from '../Text/StyledText';\n\nexport abstract class ITextKeyBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextBehavior {\n /**\n * For functionalities on keyDown\n * Map a special key to a function of the instance/prototype\n * If you need different behavior for ESC or TAB or arrows, you have to change\n * this map setting the name of a function that you build on the IText or\n * your prototype.\n * the map change will affect all Instances unless you need for only some text Instances\n * in that case you have to clone this object and assign your Instance.\n * this.keysMap = Object.assign({}, this.keysMap);\n * The function must be in IText.prototype.myFunction And will receive event as args[0]\n */\n declare keysMap: TKeyMapIText;\n\n declare keysMapRtl: TKeyMapIText;\n\n /**\n * For functionalities on keyUp + ctrl || cmd\n */\n declare ctrlKeysMapUp: TKeyMapIText;\n\n /**\n * For functionalities on keyDown + ctrl || cmd\n */\n declare ctrlKeysMapDown: TKeyMapIText;\n\n declare hiddenTextarea: HTMLTextAreaElement | null;\n\n /**\n * DOM container to append the hiddenTextarea.\n * An alternative to attaching to the document.body.\n * Useful to reduce laggish redraw of the full document.body tree and\n * also with modals event capturing that won't let the textarea take focus.\n * @type HTMLElement\n * @default\n */\n declare hiddenTextareaContainer?: HTMLElement | null;\n\n private declare _clickHandlerInitialized: boolean;\n private declare _copyDone: boolean;\n private declare fromPaste: boolean;\n\n /**\n * Initializes hidden textarea (needed to bring up keyboard in iOS)\n */\n initHiddenTextarea() {\n const doc =\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument();\n const textarea = doc.createElement('textarea');\n Object.entries({\n autocapitalize: 'off',\n autocorrect: 'off',\n autocomplete: 'off',\n spellcheck: 'false',\n 'data-fabric': 'textarea',\n wrap: 'off',\n }).map(([attribute, value]) => textarea.setAttribute(attribute, value));\n const { top, left, fontSize } = this._calcTextareaPosition();\n // line-height: 1px; was removed from the style to fix this:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=870966\n textarea.style.cssText = `position: absolute; top: ${top}; left: ${left}; z-index: -999; opacity: 0; width: 1px; height: 1px; font-size: 1px; padding-top: ${fontSize};`;\n\n (this.hiddenTextareaContainer || doc.body).appendChild(textarea);\n\n Object.entries({\n blur: 'blur',\n keydown: 'onKeyDown',\n keyup: 'onKeyUp',\n input: 'onInput',\n copy: 'copy',\n cut: 'copy',\n paste: 'paste',\n compositionstart: 'onCompositionStart',\n compositionupdate: 'onCompositionUpdate',\n compositionend: 'onCompositionEnd',\n } as Record).map(([eventName, handler]) =>\n textarea.addEventListener(\n eventName,\n (this[handler] as EventListener).bind(this),\n ),\n );\n this.hiddenTextarea = textarea;\n }\n\n /**\n * Override this method to customize cursor behavior on textbox blur\n */\n blur() {\n this.abortCursorAnimation();\n }\n\n /**\n * Handles keydown event\n * only used for arrows and combination of modifier keys.\n * @param {KeyboardEvent} e Event object\n */\n onKeyDown(e: KeyboardEvent) {\n if (!this.isEditing) {\n return;\n }\n const keyMap = this.direction === 'rtl' ? this.keysMapRtl : this.keysMap;\n if (e.keyCode in keyMap) {\n // @ts-expect-error legacy method calling pattern\n this[keyMap[e.keyCode]](e);\n } else if (e.keyCode in this.ctrlKeysMapDown && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapDown[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n if (e.keyCode >= 33 && e.keyCode <= 40) {\n // if i press an arrow key just update selection\n this.inCompositionMode = false;\n this.clearContextTop();\n this.renderCursorOrSelection();\n } else {\n this.canvas && this.canvas.requestRenderAll();\n }\n }\n\n /**\n * Handles keyup event\n * We handle KeyUp because ie11 and edge have difficulties copy/pasting\n * if a copy/cut event fired, keyup is dismissed\n * @param {KeyboardEvent} e Event object\n */\n onKeyUp(e: KeyboardEvent) {\n if (!this.isEditing || this._copyDone || this.inCompositionMode) {\n this._copyDone = false;\n return;\n }\n if (e.keyCode in this.ctrlKeysMapUp && (e.ctrlKey || e.metaKey)) {\n // @ts-expect-error legacy method calling pattern\n this[this.ctrlKeysMapUp[e.keyCode]](e);\n } else {\n return;\n }\n e.stopImmediatePropagation();\n e.preventDefault();\n this.canvas && this.canvas.requestRenderAll();\n }\n\n /**\n * Handles onInput event\n * @param {Event} e Event object\n */\n onInput(this: this & { hiddenTextarea: HTMLTextAreaElement }, e: Event) {\n const fromPaste = this.fromPaste;\n this.fromPaste = false;\n e && e.stopPropagation();\n if (!this.isEditing) {\n return;\n }\n const updateAndFire = () => {\n this.updateFromTextArea();\n this.fire(CHANGED);\n if (this.canvas) {\n this.canvas.fire('text:changed', { target: this as unknown as IText });\n this.canvas.requestRenderAll();\n }\n };\n if (this.hiddenTextarea.value === '') {\n this.styles = {};\n updateAndFire();\n return;\n }\n // decisions about style changes.\n const nextText = this._splitTextIntoLines(\n this.hiddenTextarea.value,\n ).graphemeText,\n charCount = this._text.length,\n nextCharCount = nextText.length,\n selectionStart = this.selectionStart,\n selectionEnd = this.selectionEnd,\n selection = selectionStart !== selectionEnd;\n let copiedStyle: TextStyleDeclaration[] | undefined,\n removedText,\n charDiff = nextCharCount - charCount,\n removeFrom,\n removeTo;\n\n const textareaSelection = this.fromStringToGraphemeSelection(\n this.hiddenTextarea.selectionStart,\n this.hiddenTextarea.selectionEnd,\n this.hiddenTextarea.value,\n );\n const backDelete = selectionStart > textareaSelection.selectionStart;\n\n if (selection) {\n removedText = this._text.slice(selectionStart, selectionEnd);\n charDiff += selectionEnd - selectionStart;\n } else if (nextCharCount < charCount) {\n if (backDelete) {\n removedText = this._text.slice(selectionEnd + charDiff, selectionEnd);\n } else {\n removedText = this._text.slice(\n selectionStart,\n selectionStart - charDiff,\n );\n }\n }\n const insertedText = nextText.slice(\n textareaSelection.selectionEnd - charDiff,\n textareaSelection.selectionEnd,\n );\n if (removedText && removedText.length) {\n if (insertedText.length) {\n // let's copy some style before deleting.\n // we want to copy the style before the cursor OR the style at the cursor if selection\n // is bigger than 0.\n copiedStyle = this.getSelectionStyles(\n selectionStart,\n selectionStart + 1,\n false,\n );\n // now duplicate the style one for each inserted text.\n copiedStyle = insertedText.map(\n () =>\n // this return an array of references, but that is fine since we are\n // copying the style later.\n copiedStyle![0],\n );\n }\n if (selection) {\n removeFrom = selectionStart;\n removeTo = selectionEnd;\n } else if (backDelete) {\n // detect differences between forwardDelete and backDelete\n removeFrom = selectionEnd - removedText.length;\n removeTo = selectionEnd;\n } else {\n removeFrom = selectionEnd;\n removeTo = selectionEnd + removedText.length;\n }\n this.removeStyleFromTo(removeFrom, removeTo);\n }\n if (insertedText.length) {\n const { copyPasteData } = getEnv();\n if (\n fromPaste &&\n insertedText.join('') === copyPasteData.copiedText &&\n !config.disableStyleCopyPaste\n ) {\n copiedStyle = copyPasteData.copiedTextStyle;\n }\n this.insertNewStyleBlock(insertedText, selectionStart, copiedStyle);\n }\n updateAndFire();\n }\n\n /**\n * Composition start\n */\n onCompositionStart() {\n this.inCompositionMode = true;\n }\n\n /**\n * Composition end\n */\n onCompositionEnd() {\n this.inCompositionMode = false;\n }\n\n onCompositionUpdate({ target }: CompositionEvent) {\n const { selectionStart, selectionEnd } = target as HTMLTextAreaElement;\n this.compositionStart = selectionStart;\n this.compositionEnd = selectionEnd;\n this.updateTextareaPosition();\n }\n\n /**\n * Copies selected text\n */\n copy() {\n if (this.selectionStart === this.selectionEnd) {\n //do not cut-copy if no selection\n return;\n }\n const { copyPasteData } = getEnv();\n copyPasteData.copiedText = this.getSelectedText();\n if (!config.disableStyleCopyPaste) {\n copyPasteData.copiedTextStyle = this.getSelectionStyles(\n this.selectionStart,\n this.selectionEnd,\n true,\n );\n } else {\n copyPasteData.copiedTextStyle = undefined;\n }\n this._copyDone = true;\n }\n\n /**\n * Pastes text\n */\n paste() {\n this.fromPaste = true;\n }\n\n /**\n * Finds the width in pixels before the cursor on the same line\n * @private\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {Number} widthBeforeCursor width before cursor\n */\n _getWidthBeforeCursor(lineIndex: number, charIndex: number): number {\n let widthBeforeCursor = this._getLineLeftOffset(lineIndex),\n bound;\n\n if (charIndex > 0) {\n bound = this.__charBounds[lineIndex][charIndex - 1];\n widthBeforeCursor += bound.left + bound.width;\n }\n return widthBeforeCursor;\n }\n\n /**\n * Gets start offset of a selection\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getDownCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n // if on last line, down cursor goes to end of line\n if (\n lineIndex === this._textLines.length - 1 ||\n e.metaKey ||\n e.keyCode === 34\n ) {\n // move to the end of a text\n return this._text.length - selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex + 1, widthBeforeCursor),\n textAfterCursor = this._textLines[lineIndex].slice(charIndex);\n return (\n textAfterCursor.length +\n indexOnOtherLine +\n 1 +\n this.missingNewlineOffset(lineIndex)\n );\n }\n\n /**\n * private\n * Helps finding if the offset should be counted from Start or End\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n _getSelectionForOffset(e: KeyboardEvent, isRight: boolean): number {\n if (e.shiftKey && this.selectionStart !== this.selectionEnd && isRight) {\n return this.selectionEnd;\n } else {\n return this.selectionStart;\n }\n }\n\n /**\n * @param {KeyboardEvent} e Event object\n * @param {Boolean} isRight\n * @return {Number}\n */\n getUpCursorOffset(e: KeyboardEvent, isRight: boolean): number {\n const selectionProp = this._getSelectionForOffset(e, isRight),\n cursorLocation = this.get2DCursorLocation(selectionProp),\n lineIndex = cursorLocation.lineIndex;\n if (lineIndex === 0 || e.metaKey || e.keyCode === 33) {\n // if on first line, up cursor goes to start of line\n return -selectionProp;\n }\n const charIndex = cursorLocation.charIndex,\n widthBeforeCursor = this._getWidthBeforeCursor(lineIndex, charIndex),\n indexOnOtherLine = this._getIndexOnLine(lineIndex - 1, widthBeforeCursor),\n textBeforeCursor = this._textLines[lineIndex].slice(0, charIndex),\n missingNewlineOffset = this.missingNewlineOffset(lineIndex - 1);\n // return a negative offset\n return (\n -this._textLines[lineIndex - 1].length +\n indexOnOtherLine -\n textBeforeCursor.length +\n (1 - missingNewlineOffset)\n );\n }\n\n /**\n * for a given width it founds the matching character.\n * @private\n */\n _getIndexOnLine(lineIndex: number, width: number) {\n const line = this._textLines[lineIndex],\n lineLeftOffset = this._getLineLeftOffset(lineIndex);\n let widthOfCharsOnLine = lineLeftOffset,\n indexOnLine = 0,\n charWidth,\n foundMatch;\n\n for (let j = 0, jlen = line.length; j < jlen; j++) {\n charWidth = this.__charBounds[lineIndex][j].width;\n widthOfCharsOnLine += charWidth;\n if (widthOfCharsOnLine > width) {\n foundMatch = true;\n const leftEdge = widthOfCharsOnLine - charWidth,\n rightEdge = widthOfCharsOnLine,\n offsetFromLeftEdge = Math.abs(leftEdge - width),\n offsetFromRightEdge = Math.abs(rightEdge - width);\n\n indexOnLine = offsetFromRightEdge < offsetFromLeftEdge ? j : j - 1;\n break;\n }\n }\n\n // reached end\n if (!foundMatch) {\n indexOnLine = line.length - 1;\n }\n\n return indexOnLine;\n }\n\n /**\n * Moves cursor down\n * @param {KeyboardEvent} e Event object\n */\n moveCursorDown(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorUpOrDown('Down', e);\n }\n\n /**\n * Moves cursor up\n * @param {KeyboardEvent} e Event object\n */\n moveCursorUp(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorUpOrDown('Up', e);\n }\n\n /**\n * Moves cursor up or down, fires the events\n * @param {String} direction 'Up' or 'Down'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorUpOrDown(direction: 'Up' | 'Down', e: KeyboardEvent) {\n const offset = this[`get${direction}CursorOffset`](\n e,\n this._selectionDirection === RIGHT,\n );\n if (e.shiftKey) {\n this.moveCursorWithShift(offset);\n } else {\n this.moveCursorWithoutShift(offset);\n }\n if (offset !== 0) {\n const max = this.text.length;\n this.selectionStart = capValue(0, this.selectionStart, max);\n this.selectionEnd = capValue(0, this.selectionEnd, max);\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor with shift\n * @param {Number} offset\n */\n moveCursorWithShift(offset: number) {\n const newSelection =\n this._selectionDirection === LEFT\n ? this.selectionStart + offset\n : this.selectionEnd + offset;\n this.setSelectionStartEndWithShift(\n this.selectionStart,\n this.selectionEnd,\n newSelection,\n );\n return offset !== 0;\n }\n\n /**\n * Moves cursor up without shift\n * @param {Number} offset\n */\n moveCursorWithoutShift(offset: number) {\n if (offset < 0) {\n this.selectionStart += offset;\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionEnd += offset;\n this.selectionStart = this.selectionEnd;\n }\n return offset !== 0;\n }\n\n /**\n * Moves cursor left\n * @param {KeyboardEvent} e Event object\n */\n moveCursorLeft(e: KeyboardEvent) {\n if (this.selectionStart === 0 && this.selectionEnd === 0) {\n return;\n }\n this._moveCursorLeftOrRight('Left', e);\n }\n\n /**\n * @private\n * @return {Boolean} true if a change happened\n *\n * @todo refactor not to use method name composition\n */\n _move(\n e: KeyboardEvent,\n prop: 'selectionStart' | 'selectionEnd',\n direction: 'Left' | 'Right',\n ): boolean {\n let newValue: number | undefined;\n if (e.altKey) {\n newValue = this[`findWordBoundary${direction}`](this[prop]);\n } else if (e.metaKey || e.keyCode === 35 || e.keyCode === 36) {\n newValue = this[`findLineBoundary${direction}`](this[prop]);\n } else {\n this[prop] += direction === 'Left' ? -1 : 1;\n return true;\n }\n if (typeof newValue !== 'undefined' && this[prop] !== newValue) {\n this[prop] = newValue;\n return true;\n }\n return false;\n }\n\n /**\n * @private\n */\n _moveLeft(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Left');\n }\n\n /**\n * @private\n */\n _moveRight(e: KeyboardEvent, prop: 'selectionStart' | 'selectionEnd') {\n return this._move(e, prop, 'Right');\n }\n\n /**\n * Moves cursor left without keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithoutShift(e: KeyboardEvent) {\n let change = true;\n this._selectionDirection = LEFT;\n\n // only move cursor when there is no selection,\n // otherwise we discard it, and leave cursor on same place\n if (\n this.selectionEnd === this.selectionStart &&\n this.selectionStart !== 0\n ) {\n change = this._moveLeft(e, 'selectionStart');\n }\n this.selectionEnd = this.selectionStart;\n return change;\n }\n\n /**\n * Moves cursor left while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorLeftWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === RIGHT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveLeft(e, 'selectionEnd');\n } else if (this.selectionStart !== 0) {\n this._selectionDirection = LEFT;\n return this._moveLeft(e, 'selectionStart');\n }\n }\n\n /**\n * Moves cursor right\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRight(e: KeyboardEvent) {\n if (\n this.selectionStart >= this._text.length &&\n this.selectionEnd >= this._text.length\n ) {\n return;\n }\n this._moveCursorLeftOrRight('Right', e);\n }\n\n /**\n * Moves cursor right or Left, fires event\n * @param {String} direction 'Left', 'Right'\n * @param {KeyboardEvent} e Event object\n */\n _moveCursorLeftOrRight(direction: 'Left' | 'Right', e: KeyboardEvent) {\n const actionName = `moveCursor${direction}${\n e.shiftKey ? 'WithShift' : 'WithoutShift'\n }` as const;\n this._currentCursorOpacity = 1;\n if (this[actionName](e)) {\n // TODO fix: abort and init should be an alternative depending\n // on selectionStart/End being equal or different\n this.abortCursorAnimation();\n this.initDelayedCursor();\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Moves cursor right while keeping selection\n * @param {KeyboardEvent} e\n */\n moveCursorRightWithShift(e: KeyboardEvent) {\n if (\n this._selectionDirection === LEFT &&\n this.selectionStart !== this.selectionEnd\n ) {\n return this._moveRight(e, 'selectionStart');\n } else if (this.selectionEnd !== this._text.length) {\n this._selectionDirection = RIGHT;\n return this._moveRight(e, 'selectionEnd');\n }\n }\n\n /**\n * Moves cursor right without keeping selection\n * @param {KeyboardEvent} e Event object\n */\n moveCursorRightWithoutShift(e: KeyboardEvent) {\n let changed = true;\n this._selectionDirection = RIGHT;\n\n if (this.selectionStart === this.selectionEnd) {\n changed = this._moveRight(e, 'selectionStart');\n this.selectionEnd = this.selectionStart;\n } else {\n this.selectionStart = this.selectionEnd;\n }\n return changed;\n }\n}\n","import type { TPointerEvent, TPointerEventInfo } from '../../EventTypeDefs';\nimport type { XY } from '../../Point';\nimport { Point } from '../../Point';\nimport { stopEvent } from '../../util/dom_event';\nimport { invertTransform } from '../../util/misc/matrix';\nimport { DraggableTextDelegate } from './DraggableTextDelegate';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextKeyBehavior } from './ITextKeyBehavior';\nimport type { TOptions } from '../../typedefs';\nimport type { TextProps, SerializedTextProps } from '../Text/Text';\n\n/**\n * `LEFT_CLICK === 0`\n */\nconst notALeftClick = (e: Event) => !!(e as MouseEvent).button;\n\nexport abstract class ITextClickBehavior<\n Props extends TOptions = Partial,\n SProps extends SerializedTextProps = SerializedTextProps,\n EventSpec extends ITextEvents = ITextEvents,\n> extends ITextKeyBehavior {\n private declare __lastSelected: boolean;\n private declare __lastClickTime: number;\n private declare __lastLastClickTime: number;\n private declare __lastPointer: XY | Record;\n private declare __newClickTime: number;\n\n protected draggableTextDelegate: DraggableTextDelegate;\n\n initBehavior() {\n // Initializes event handlers related to cursor or selection\n this.on('mousedown', this._mouseDownHandler);\n this.on('mousedown:before', this._mouseDownHandlerBefore);\n this.on('mouseup', this.mouseUpHandler);\n this.on('mousedblclick', this.doubleClickHandler);\n this.on('tripleclick', this.tripleClickHandler);\n\n // Initializes \"dbclick\" event handler\n this.__lastClickTime = +new Date();\n // for triple click\n this.__lastLastClickTime = +new Date();\n this.__lastPointer = {};\n this.on('mousedown', this.onMouseDown);\n\n // @ts-expect-error in reality it is an IText instance\n this.draggableTextDelegate = new DraggableTextDelegate(this);\n\n super.initBehavior();\n }\n\n /**\n * If this method returns true a mouse move operation over a text selection\n * will not prevent the native mouse event allowing the browser to start a drag operation.\n * shouldStartDragging can be read 'do not prevent default for mouse move event'\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns\n */\n shouldStartDragging() {\n return this.draggableTextDelegate.isActive();\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drag source,\n * @see also {@link DraggableTextDelegate#isActive}\n * To prevent drag and drop between objects both shouldStartDragging and onDragStart should return false\n * @returns {boolean} should handle event\n */\n onDragStart(e: DragEvent) {\n return this.draggableTextDelegate.onDragStart(e);\n }\n\n /**\n * @public override this method to control whether instance should/shouldn't become a drop target\n */\n canDrop(e: DragEvent) {\n return this.draggableTextDelegate.canDrop(e);\n }\n\n /**\n * Default event handler to simulate triple click\n * @private\n */\n onMouseDown(options: TPointerEventInfo) {\n if (!this.canvas) {\n return;\n }\n this.__newClickTime = +new Date();\n const newPointer = options.pointer;\n if (this.isTripleClick(newPointer)) {\n this.fire('tripleclick', options);\n stopEvent(options.e);\n }\n this.__lastLastClickTime = this.__lastClickTime;\n this.__lastClickTime = this.__newClickTime;\n this.__lastPointer = newPointer;\n this.__lastSelected = this.selected && !this.getActiveControl();\n }\n\n isTripleClick(newPointer: XY) {\n return (\n this.__newClickTime - this.__lastClickTime < 500 &&\n this.__lastClickTime - this.__lastLastClickTime < 500 &&\n this.__lastPointer.x === newPointer.x &&\n this.__lastPointer.y === newPointer.y\n );\n }\n\n /**\n * Default handler for double click, select a word\n */\n doubleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectWord(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default handler for triple click, select a line\n */\n tripleClickHandler(options: TPointerEventInfo) {\n if (!this.isEditing) {\n return;\n }\n this.selectLine(this.getSelectionStartFromPointer(options.e));\n }\n\n /**\n * Default event handler for the basic functionalities needed on _mouseDown\n * can be overridden to do something different.\n * Scope of this implementation is: find the click position, set selectionStart\n * find selectionEnd, initialize the drawing of either cursor or selection area\n * initializing a mousedDown on a text area will cancel fabricjs knowledge of\n * current compositionMode. It will be set to false.\n */\n _mouseDownHandler({ e }: TPointerEventInfo) {\n if (\n !this.canvas ||\n !this.editable ||\n notALeftClick(e) ||\n this.getActiveControl()\n ) {\n return;\n }\n\n if (this.draggableTextDelegate.start(e)) {\n return;\n }\n\n this.canvas.textEditingManager.register(this);\n\n if (this.selected) {\n this.inCompositionMode = false;\n this.setCursorByClick(e);\n }\n\n if (this.isEditing) {\n this.__selectionStartOnMouseDown = this.selectionStart;\n if (this.selectionStart === this.selectionEnd) {\n this.abortCursorAnimation();\n }\n this.renderCursorOrSelection();\n }\n }\n\n /**\n * Default event handler for the basic functionalities needed on mousedown:before\n * can be overridden to do something different.\n * Scope of this implementation is: verify the object is already selected when mousing down\n */\n _mouseDownHandlerBefore({ e }: TPointerEventInfo) {\n if (!this.canvas || !this.editable || notALeftClick(e)) {\n return;\n }\n // we want to avoid that an object that was selected and then becomes unselectable,\n // may trigger editing mode in some way.\n this.selected = this === this.canvas._activeObject;\n }\n\n /**\n * standard handler for mouse up, overridable\n * @private\n */\n mouseUpHandler({ e, transform }: TPointerEventInfo) {\n const didDrag = this.draggableTextDelegate.end(e);\n if (this.canvas) {\n this.canvas.textEditingManager.unregister(this);\n\n const activeObject = this.canvas._activeObject;\n if (activeObject && activeObject !== this) {\n // avoid running this logic when there is an active object\n // this because is possible with shift click and fast clicks,\n // to rapidly deselect and reselect this object and trigger an enterEdit\n return;\n }\n }\n if (\n !this.editable ||\n (this.group && !this.group.interactive) ||\n (transform && transform.actionPerformed) ||\n notALeftClick(e) ||\n didDrag\n ) {\n return;\n }\n\n if (this.__lastSelected && !this.getActiveControl()) {\n this.selected = false;\n this.__lastSelected = false;\n this.enterEditing(e);\n if (this.selectionStart === this.selectionEnd) {\n this.initDelayedCursor(true);\n } else {\n this.renderCursorOrSelection();\n }\n } else {\n this.selected = true;\n }\n }\n\n /**\n * Changes cursor location in a text depending on passed pointer (x/y) object\n * @param {TPointerEvent} e Event object\n */\n setCursorByClick(e: TPointerEvent) {\n const newSelection = this.getSelectionStartFromPointer(e),\n start = this.selectionStart,\n end = this.selectionEnd;\n if (e.shiftKey) {\n this.setSelectionStartEndWithShift(start, end, newSelection);\n } else {\n this.selectionStart = newSelection;\n this.selectionEnd = newSelection;\n }\n if (this.isEditing) {\n this._fireSelectionChanged();\n this._updateTextarea();\n }\n }\n\n /**\n * Returns index of a character corresponding to where an object was clicked\n * @param {TPointerEvent} e Event object\n * @return {Number} Index of a character\n */\n getSelectionStartFromPointer(e: TPointerEvent): number {\n const mouseOffset = this.canvas!.getScenePoint(e)\n .transform(invertTransform(this.calcTransformMatrix()))\n .add(new Point(-this._getLeftOffset(), -this._getTopOffset()));\n let height = 0,\n charIndex = 0,\n lineIndex = 0;\n\n for (let i = 0; i < this._textLines.length; i++) {\n if (height <= mouseOffset.y) {\n height += this.getHeightOfLine(i);\n lineIndex = i;\n if (i > 0) {\n charIndex +=\n this._textLines[i - 1].length + this.missingNewlineOffset(i - 1);\n }\n } else {\n break;\n }\n }\n const lineLeftOffset = Math.abs(this._getLineLeftOffset(lineIndex));\n let width = lineLeftOffset;\n const charLength = this._textLines[lineIndex].length;\n const chars = this.__charBounds[lineIndex];\n for (let j = 0; j < charLength; j++) {\n // i removed something about flipX here, check.\n const charWidth = chars[j].kernedWidth;\n const widthAfter = width + charWidth;\n if (mouseOffset.x <= widthAfter) {\n // if the pointer is closer to the end of the char we increment charIndex\n // in order to position the cursor after the char\n if (\n Math.abs(mouseOffset.x - widthAfter) <=\n Math.abs(mouseOffset.x - width)\n ) {\n charIndex++;\n }\n break;\n }\n width = widthAfter;\n charIndex++;\n }\n\n return Math.min(\n // if object is horizontally flipped, mirror cursor location from the end\n this.flipX ? charLength - charIndex : charIndex,\n this._text.length,\n );\n }\n}\n","export type TKeyMapIText = Record<\n KeyboardEvent['keyCode'],\n CursorHandlingMethods\n>;\n\nexport type CursorHandlingMethods =\n | 'moveCursorUp'\n | 'moveCursorDown'\n | 'moveCursorLeft'\n | 'moveCursorRight'\n | 'exitEditing'\n | 'copy'\n | 'cut'\n | 'selectAll';\n\nconst MOVE_CURSOR_UP: CursorHandlingMethods = 'moveCursorUp';\nconst MOVE_CURSOR_DOWN: CursorHandlingMethods = 'moveCursorDown';\nconst MOVE_CURSOR_LEFT: CursorHandlingMethods = 'moveCursorLeft';\nconst MOVE_CURSOR_RIGHT: CursorHandlingMethods = 'moveCursorRight';\nconst EXIT_EDITING: CursorHandlingMethods = 'exitEditing';\n\n// @TODO look into import { Key } from 'ts-key-enum';\n// and transition from keyCode to Key\n// also reduce string duplication\nexport const keysMap: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_RIGHT,\n 36: MOVE_CURSOR_LEFT,\n 37: MOVE_CURSOR_LEFT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_RIGHT,\n 40: MOVE_CURSOR_DOWN,\n};\n\nexport const keysMapRtl: TKeyMapIText = {\n 9: EXIT_EDITING,\n 27: EXIT_EDITING,\n 33: MOVE_CURSOR_UP,\n 34: MOVE_CURSOR_DOWN,\n 35: MOVE_CURSOR_LEFT,\n 36: MOVE_CURSOR_RIGHT,\n 37: MOVE_CURSOR_RIGHT,\n 38: MOVE_CURSOR_UP,\n 39: MOVE_CURSOR_LEFT,\n 40: MOVE_CURSOR_DOWN,\n};\n\n/**\n * For functionalities on keyUp + ctrl || cmd\n */\nexport const ctrlKeysMapUp: TKeyMapIText = {\n 67: 'copy',\n // there was a reason this wasn't deleted. for now leave it here\n 88: 'cut',\n};\n\n/**\n * For functionalities on keyDown + ctrl || cmd\n */\nexport const ctrlKeysMapDown: TKeyMapIText = {\n 65: 'selectAll',\n};\n","import { Canvas } from '../../canvas/Canvas';\nimport type { ITextEvents } from './ITextBehavior';\nimport { ITextClickBehavior } from './ITextClickBehavior';\nimport {\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n keysMap,\n keysMapRtl,\n} from './constants';\nimport type { TClassProperties, TFiller, TOptions } from '../../typedefs';\nimport { classRegistry } from '../../ClassRegistry';\nimport type { SerializedTextProps, TextProps } from '../Text/Text';\nimport {\n JUSTIFY,\n JUSTIFY_CENTER,\n JUSTIFY_LEFT,\n JUSTIFY_RIGHT,\n} from '../Text/constants';\nimport { CENTER, FILL, LEFT, RIGHT } from '../../constants';\nimport type { ObjectToCanvasElementOptions } from '../Object/Object';\n\ntype CursorBoundaries = {\n left: number;\n top: number;\n leftOffset: number;\n topOffset: number;\n};\n\n// Declare IText protected properties to workaround TS\nconst protectedDefaultValues = {\n _selectionDirection: null,\n _reSpace: /\\s|\\r?\\n/,\n inCompositionMode: false,\n};\n\nexport const iTextDefaultValues: Partial> = {\n selectionStart: 0,\n selectionEnd: 0,\n selectionColor: 'rgba(17,119,255,0.3)',\n isEditing: false,\n editable: true,\n editingBorderColor: 'rgba(102,153,255,0.25)',\n cursorWidth: 2,\n cursorColor: '',\n cursorDelay: 1000,\n cursorDuration: 600,\n caching: true,\n hiddenTextareaContainer: null,\n keysMap,\n keysMapRtl,\n ctrlKeysMapDown,\n ctrlKeysMapUp,\n ...protectedDefaultValues,\n};\n\n// @TODO this is not complete\ninterface UniqueITextProps {\n selectionStart: number;\n selectionEnd: number;\n}\n\nexport interface SerializedITextProps\n extends SerializedTextProps,\n UniqueITextProps {}\n\nexport interface ITextProps extends TextProps, UniqueITextProps {}\n\n/**\n * @fires changed\n * @fires selection:changed\n * @fires editing:entered\n * @fires editing:exited\n * @fires dragstart\n * @fires drag drag event firing on the drag source\n * @fires dragend\n * @fires copy\n * @fires cut\n * @fires paste\n *\n * #### Supported key combinations\n * ```\n * Move cursor: left, right, up, down\n * Select character: shift + left, shift + right\n * Select text vertically: shift + up, shift + down\n * Move cursor by word: alt + left, alt + right\n * Select words: shift + alt + left, shift + alt + right\n * Move cursor to line start/end: cmd + left, cmd + right or home, end\n * Select till start/end of line: cmd + shift + left, cmd + shift + right or shift + home, shift + end\n * Jump to start/end of text: cmd + up, cmd + down\n * Select till start/end of text: cmd + shift + up, cmd + shift + down or shift + pgUp, shift + pgDown\n * Delete character: backspace\n * Delete word: alt + backspace\n * Delete line: cmd + backspace\n * Forward delete: delete\n * Copy text: ctrl/cmd + c\n * Paste text: ctrl/cmd + v\n * Cut text: ctrl/cmd + x\n * Select entire text: ctrl/cmd + a\n * Quit editing tab or esc\n * ```\n *\n * #### Supported mouse/touch combination\n * ```\n * Position cursor: click/touch\n * Create selection: click/touch & drag\n * Create selection: click & shift + click\n * Select word: double click\n * Select line: triple click\n * ```\n */\nexport class IText<\n Props extends TOptions = Partial,\n SProps extends SerializedITextProps = SerializedITextProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends ITextClickBehavior\n implements UniqueITextProps\n{\n /**\n * Index where text selection starts (or where cursor is when there is no selection)\n * @type Number\n * @default\n */\n declare selectionStart: number;\n\n /**\n * Index where text selection ends\n * @type Number\n * @default\n */\n declare selectionEnd: number;\n\n declare compositionStart: number;\n\n declare compositionEnd: number;\n\n /**\n * Color of text selection\n * @type String\n * @default\n */\n declare selectionColor: string;\n\n /**\n * Indicates whether text is in editing mode\n * @type Boolean\n * @default\n */\n declare isEditing: boolean;\n\n /**\n * Indicates whether a text can be edited\n * @type Boolean\n * @default\n */\n declare editable: boolean;\n\n /**\n * Border color of text object while it's in editing mode\n * @type String\n * @default\n */\n declare editingBorderColor: string;\n\n /**\n * Width of cursor (in px)\n * @type Number\n * @default\n */\n declare cursorWidth: number;\n\n /**\n * Color of text cursor color in editing mode.\n * if not set (default) will take color from the text.\n * if set to a color value that fabric can understand, it will\n * be used instead of the color of the text at the current position.\n * @type String\n * @default\n */\n declare cursorColor: string;\n\n /**\n * Delay between cursor blink (in ms)\n * @type Number\n * @default\n */\n declare cursorDelay: number;\n\n /**\n * Duration of cursor fade in (in ms)\n * @type Number\n * @default\n */\n declare cursorDuration: number;\n\n declare compositionColor: string;\n\n /**\n * Indicates whether internal text char widths can be cached\n * @type Boolean\n * @default\n */\n declare caching: boolean;\n\n static ownDefaults = iTextDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...IText.ownDefaults };\n }\n\n static type = 'IText';\n\n get type() {\n const type = super.type;\n // backward compatibility\n return type === 'itext' ? 'i-text' : type;\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...IText.ownDefaults, ...options } as Props);\n this.initBehavior();\n }\n\n /**\n * While editing handle differently\n * @private\n * @param {string} key\n * @param {*} value\n */\n _set(key: string, value: any) {\n if (this.isEditing && this._savedProps && key in this._savedProps) {\n // @ts-expect-error irritating TS\n this._savedProps[key] = value;\n return this;\n }\n if (key === 'canvas') {\n this.canvas instanceof Canvas &&\n this.canvas.textEditingManager.remove(this);\n value instanceof Canvas && value.textEditingManager.add(this);\n }\n return super._set(key, value);\n }\n\n /**\n * Sets selection start (left boundary of a selection)\n * @param {Number} index Index to set selection start to\n */\n setSelectionStart(index: number) {\n index = Math.max(index, 0);\n this._updateAndFire('selectionStart', index);\n }\n\n /**\n * Sets selection end (right boundary of a selection)\n * @param {Number} index Index to set selection end to\n */\n setSelectionEnd(index: number) {\n index = Math.min(index, this.text.length);\n this._updateAndFire('selectionEnd', index);\n }\n\n /**\n * @private\n * @param {String} property 'selectionStart' or 'selectionEnd'\n * @param {Number} index new position of property\n */\n protected _updateAndFire(\n property: 'selectionStart' | 'selectionEnd',\n index: number,\n ) {\n if (this[property] !== index) {\n this._fireSelectionChanged();\n this[property] = index;\n }\n this._updateTextarea();\n }\n\n /**\n * Fires the even of selection changed\n * @private\n */\n _fireSelectionChanged() {\n this.fire('selection:changed');\n this.canvas && this.canvas.fire('text:selection:changed', { target: this });\n }\n\n /**\n * Initialize text dimensions. Render all text on given context\n * or on a offscreen canvas to get the text width with measureText.\n * Updates this.width and this.height with the proper values.\n * Does not return dimensions.\n * @private\n */\n initDimensions() {\n this.isEditing && this.initDelayedCursor();\n super.initDimensions();\n }\n\n /**\n * Gets style of a current selection/cursor (at the start position)\n * if startIndex or endIndex are not provided, selectionStart or selectionEnd will be used.\n * @param {Number} startIndex Start index to get styles at\n * @param {Number} endIndex End index to get styles at, if not specified selectionEnd or startIndex + 1\n * @param {Boolean} [complete] get full style or not\n * @return {Array} styles an array with one, zero or more Style objects\n */\n getSelectionStyles(\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n complete?: boolean,\n ) {\n return super.getSelectionStyles(startIndex, endIndex, complete);\n }\n\n /**\n * Sets style of a current selection, if no selection exist, do not set anything.\n * @param {Object} [styles] Styles object\n * @param {Number} [startIndex] Start index to get styles at\n * @param {Number} [endIndex] End index to get styles at, if not specified selectionEnd or startIndex + 1\n */\n setSelectionStyles(\n styles: object,\n startIndex: number = this.selectionStart || 0,\n endIndex: number = this.selectionEnd,\n ) {\n return super.setSelectionStyles(styles, startIndex, endIndex);\n }\n\n /**\n * Returns 2d representation (lineIndex and charIndex) of cursor (or selection start)\n * @param {Number} [selectionStart] Optional index. When not given, current selectionStart is used.\n * @param {Boolean} [skipWrapping] consider the location for unwrapped lines. useful to manage styles.\n */\n get2DCursorLocation(\n selectionStart = this.selectionStart,\n skipWrapping?: boolean,\n ) {\n return super.get2DCursorLocation(selectionStart, skipWrapping);\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n render(ctx: CanvasRenderingContext2D) {\n super.render(ctx);\n // clear the cursorOffsetCache, so we ensure to calculate once per renderCursor\n // the correct position but not at every cursor animation.\n this.cursorOffsetCache = {};\n this.renderCursorOrSelection();\n }\n\n /**\n * @override block cursor/selection logic while rendering the exported canvas\n * @todo this workaround should be replaced with a more robust solution\n */\n toCanvasElement(options?: ObjectToCanvasElementOptions): HTMLCanvasElement {\n const isEditing = this.isEditing;\n this.isEditing = false;\n const canvas = super.toCanvasElement(options);\n this.isEditing = isEditing;\n return canvas;\n }\n\n /**\n * Renders cursor or selection (depending on what exists)\n * it does on the contextTop. If contextTop is not available, do nothing.\n */\n renderCursorOrSelection() {\n if (!this.isEditing) {\n return;\n }\n const ctx = this.clearContextTop(true);\n if (!ctx) {\n return;\n }\n const boundaries = this._getCursorBoundaries();\n if (this.selectionStart === this.selectionEnd) {\n this.renderCursor(ctx, boundaries);\n } else {\n this.renderSelection(ctx, boundaries);\n }\n this.canvas!.contextTopDirty = true;\n ctx.restore();\n }\n\n /**\n * Returns cursor boundaries (left, top, leftOffset, topOffset)\n * left/top are left/top of entire text box\n * leftOffset/topOffset are offset from that left/top point of a text box\n * @private\n * @param {number} [index] index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundaries(\n index: number = this.selectionStart,\n skipCaching?: boolean,\n ): CursorBoundaries {\n const left = this._getLeftOffset(),\n top = this._getTopOffset(),\n offsets = this._getCursorBoundariesOffsets(index, skipCaching);\n return {\n left: left,\n top: top,\n leftOffset: offsets.left,\n topOffset: offsets.top,\n };\n }\n\n /**\n * Caches and returns cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n * @param {boolean} [skipCaching]\n */\n _getCursorBoundariesOffsets(\n index: number,\n skipCaching?: boolean,\n ): { left: number; top: number } {\n if (skipCaching) {\n return this.__getCursorBoundariesOffsets(index);\n }\n if (this.cursorOffsetCache && 'top' in this.cursorOffsetCache) {\n return this.cursorOffsetCache as { left: number; top: number };\n }\n return (this.cursorOffsetCache = this.__getCursorBoundariesOffsets(index));\n }\n\n /**\n * Calculates cursor left/top offset relative to instance's center point\n * @private\n * @param {number} index index from start\n */\n __getCursorBoundariesOffsets(index: number) {\n let topOffset = 0,\n leftOffset = 0;\n const { charIndex, lineIndex } = this.get2DCursorLocation(index);\n\n for (let i = 0; i < lineIndex; i++) {\n topOffset += this.getHeightOfLine(i);\n }\n const lineLeftOffset = this._getLineLeftOffset(lineIndex);\n const bound = this.__charBounds[lineIndex][charIndex];\n bound && (leftOffset = bound.left);\n if (\n this.charSpacing !== 0 &&\n charIndex === this._textLines[lineIndex].length\n ) {\n leftOffset -= this._getWidthOfCharSpacing();\n }\n const boundaries = {\n top: topOffset,\n left: lineLeftOffset + (leftOffset > 0 ? leftOffset : 0),\n };\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n boundaries.left *= -1;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n boundaries.left = lineLeftOffset - (leftOffset > 0 ? leftOffset : 0);\n }\n }\n return boundaries;\n }\n\n /**\n * Renders cursor on context Top, outside the animation cycle, on request\n * Used for the drag/drop effect.\n * If contextTop is not available, do nothing.\n */\n renderCursorAt(selectionStart: number) {\n const boundaries = this._getCursorBoundaries(selectionStart, true);\n this._renderCursor(this.canvas!.contextTop, boundaries, selectionStart);\n }\n\n /**\n * Renders cursor\n * @param {Object} boundaries\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderCursor(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n this._renderCursor(ctx, boundaries, this.selectionStart);\n }\n\n _renderCursor(\n ctx: CanvasRenderingContext2D,\n boundaries: CursorBoundaries,\n selectionStart: number,\n ) {\n const cursorLocation = this.get2DCursorLocation(selectionStart),\n lineIndex = cursorLocation.lineIndex,\n charIndex =\n cursorLocation.charIndex > 0 ? cursorLocation.charIndex - 1 : 0,\n charHeight = this.getValueOfPropertyAt(lineIndex, charIndex, 'fontSize'),\n multiplier = this.getObjectScaling().x * this.canvas!.getZoom(),\n cursorWidth = this.cursorWidth / multiplier,\n dy = this.getValueOfPropertyAt(lineIndex, charIndex, 'deltaY'),\n topOffset =\n boundaries.topOffset +\n ((1 - this._fontSizeFraction) * this.getHeightOfLine(lineIndex)) /\n this.lineHeight -\n charHeight * (1 - this._fontSizeFraction);\n\n if (this.inCompositionMode) {\n // TODO: investigate why there isn't a return inside the if,\n // and why can't happen at the top of the function\n this.renderSelection(ctx, boundaries);\n }\n ctx.fillStyle =\n this.cursorColor ||\n (this.getValueOfPropertyAt(lineIndex, charIndex, FILL) as string);\n ctx.globalAlpha = this._currentCursorOpacity;\n ctx.fillRect(\n boundaries.left + boundaries.leftOffset - cursorWidth / 2,\n topOffset + boundaries.top + dy,\n cursorWidth,\n charHeight,\n );\n }\n\n /**\n * Renders text selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n renderSelection(ctx: CanvasRenderingContext2D, boundaries: CursorBoundaries) {\n const selection = {\n selectionStart: this.inCompositionMode\n ? this.hiddenTextarea!.selectionStart\n : this.selectionStart,\n selectionEnd: this.inCompositionMode\n ? this.hiddenTextarea!.selectionEnd\n : this.selectionEnd,\n };\n this._renderSelection(ctx, selection, boundaries);\n }\n\n /**\n * Renders drag start text selection\n */\n renderDragSourceEffect() {\n const dragStartSelection =\n this.draggableTextDelegate.getDragStartSelection()!;\n this._renderSelection(\n this.canvas!.contextTop,\n dragStartSelection,\n this._getCursorBoundaries(dragStartSelection.selectionStart, true),\n );\n }\n\n renderDropTargetEffect(e: DragEvent) {\n const dragSelection = this.getSelectionStartFromPointer(e);\n this.renderCursorAt(dragSelection);\n }\n\n /**\n * Renders text selection\n * @private\n * @param {{ selectionStart: number, selectionEnd: number }} selection\n * @param {Object} boundaries Object with left/top/leftOffset/topOffset\n * @param {CanvasRenderingContext2D} ctx transformed context to draw on\n */\n _renderSelection(\n ctx: CanvasRenderingContext2D,\n selection: { selectionStart: number; selectionEnd: number },\n boundaries: CursorBoundaries,\n ) {\n const selectionStart = selection.selectionStart,\n selectionEnd = selection.selectionEnd,\n isJustify = this.textAlign.includes(JUSTIFY),\n start = this.get2DCursorLocation(selectionStart),\n end = this.get2DCursorLocation(selectionEnd),\n startLine = start.lineIndex,\n endLine = end.lineIndex,\n startChar = start.charIndex < 0 ? 0 : start.charIndex,\n endChar = end.charIndex < 0 ? 0 : end.charIndex;\n\n for (let i = startLine; i <= endLine; i++) {\n const lineOffset = this._getLineLeftOffset(i) || 0;\n let lineHeight = this.getHeightOfLine(i),\n realLineHeight = 0,\n boxStart = 0,\n boxEnd = 0;\n\n if (i === startLine) {\n boxStart = this.__charBounds[startLine][startChar].left;\n }\n if (i >= startLine && i < endLine) {\n boxEnd =\n isJustify && !this.isEndOfWrapping(i)\n ? this.width\n : this.getLineWidth(i) || 5; // WTF is this 5?\n } else if (i === endLine) {\n if (endChar === 0) {\n boxEnd = this.__charBounds[endLine][endChar].left;\n } else {\n const charSpacing = this._getWidthOfCharSpacing();\n boxEnd =\n this.__charBounds[endLine][endChar - 1].left +\n this.__charBounds[endLine][endChar - 1].width -\n charSpacing;\n }\n }\n realLineHeight = lineHeight;\n if (this.lineHeight < 1 || (i === endLine && this.lineHeight > 1)) {\n lineHeight /= this.lineHeight;\n }\n let drawStart = boundaries.left + lineOffset + boxStart,\n drawHeight = lineHeight,\n extraTop = 0;\n const drawWidth = boxEnd - boxStart;\n if (this.inCompositionMode) {\n ctx.fillStyle = this.compositionColor || 'black';\n drawHeight = 1;\n extraTop = lineHeight;\n } else {\n ctx.fillStyle = this.selectionColor;\n }\n if (this.direction === 'rtl') {\n if (\n this.textAlign === RIGHT ||\n this.textAlign === JUSTIFY ||\n this.textAlign === JUSTIFY_RIGHT\n ) {\n drawStart = this.width - drawStart - drawWidth;\n } else if (this.textAlign === LEFT || this.textAlign === JUSTIFY_LEFT) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n } else if (\n this.textAlign === CENTER ||\n this.textAlign === JUSTIFY_CENTER\n ) {\n drawStart = boundaries.left + lineOffset - boxEnd;\n }\n }\n ctx.fillRect(\n drawStart,\n boundaries.top + boundaries.topOffset + extraTop,\n drawWidth,\n drawHeight,\n );\n boundaries.topOffset += realLineHeight;\n }\n }\n\n /**\n * High level function to know the height of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns fontSize of char at the current cursor\n * Unused from the library, is for the end user\n * @return {Number} Character font size\n */\n getCurrentCharFontSize(): number {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, 'fontSize');\n }\n\n /**\n * High level function to know the color of the cursor.\n * the currentChar is the one that precedes the cursor\n * Returns color (fill) of char at the current cursor\n * if the text object has a pattern or gradient for filler, it will return that.\n * Unused by the library, is for the end user\n * @return {String | TFiller} Character color (fill)\n */\n getCurrentCharColor(): string | TFiller | null {\n const cp = this._getCurrentCharIndex();\n return this.getValueOfPropertyAt(cp.l, cp.c, FILL);\n }\n\n /**\n * Returns the cursor position for the getCurrent.. functions\n * @private\n */\n _getCurrentCharIndex() {\n const cursorPosition = this.get2DCursorLocation(this.selectionStart, true),\n charIndex =\n cursorPosition.charIndex > 0 ? cursorPosition.charIndex - 1 : 0;\n return { l: cursorPosition.lineIndex, c: charIndex };\n }\n\n dispose() {\n this._exitEditing();\n this.draggableTextDelegate.dispose();\n super.dispose();\n }\n}\n\nclassRegistry.setClass(IText);\n// legacy\nclassRegistry.setClass(IText, 'i-text');\n","import type { TClassProperties, TOptions } from '../typedefs';\nimport { IText } from './IText/IText';\nimport { classRegistry } from '../ClassRegistry';\nimport { createTextboxDefaultControls } from '../controls/commonControls';\nimport { JUSTIFY } from './Text/constants';\nimport type { TextStyleDeclaration } from './Text/StyledText';\nimport type { SerializedITextProps, ITextProps } from './IText/IText';\nimport type { ITextEvents } from './IText/ITextBehavior';\nimport type { TextLinesInfo } from './Text/Text';\nimport type { Control } from '../controls/Control';\n\n// @TODO: Many things here are configuration related and shouldn't be on the class nor prototype\n// regexes, list of properties that are not suppose to change by instances, magic consts.\n// this will be a separated effort\nexport const textboxDefaultValues: Partial> = {\n minWidth: 20,\n dynamicMinWidth: 2,\n lockScalingFlip: true,\n noScaleCache: false,\n _wordJoiners: /[ \\t\\r]/,\n splitByGrapheme: false,\n};\n\nexport type GraphemeData = {\n wordsData: {\n word: string[];\n width: number;\n }[][];\n largestWordWidth: number;\n};\n\nexport type StyleMap = Record;\n\n// @TODO this is not complete\ninterface UniqueTextboxProps {\n minWidth: number;\n splitByGrapheme: boolean;\n dynamicMinWidth: number;\n _wordJoiners: RegExp;\n}\n\nexport interface SerializedTextboxProps\n extends SerializedITextProps,\n Pick {}\n\nexport interface TextboxProps extends ITextProps, UniqueTextboxProps {}\n\n/**\n * Textbox class, based on IText, allows the user to resize the text rectangle\n * and wraps lines automatically. Textboxes have their Y scaling locked, the\n * user can only change width. Height is adjusted automatically based on the\n * wrapping of lines.\n */\nexport class Textbox<\n Props extends TOptions = Partial,\n SProps extends SerializedTextboxProps = SerializedTextboxProps,\n EventSpec extends ITextEvents = ITextEvents,\n >\n extends IText\n implements UniqueTextboxProps\n{\n /**\n * Minimum width of textbox, in pixels.\n * @type Number\n * @default\n */\n declare minWidth: number;\n\n /**\n * Minimum calculated width of a textbox, in pixels.\n * fixed to 2 so that an empty textbox cannot go to 0\n * and is still selectable without text.\n * @type Number\n * @default\n */\n declare dynamicMinWidth: number;\n\n /**\n * Use this boolean property in order to split strings that have no white space concept.\n * this is a cheap way to help with chinese/japanese\n * @type Boolean\n * @since 2.6.0\n */\n declare splitByGrapheme: boolean;\n\n declare _wordJoiners: RegExp;\n\n declare _styleMap: StyleMap;\n\n declare isWrapping: boolean;\n\n static type = 'Textbox';\n\n static textLayoutProperties = [...IText.textLayoutProperties, 'width'];\n\n static ownDefaults = textboxDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...Textbox.ownDefaults,\n };\n }\n\n /**\n * Constructor\n * @param {String} text Text string\n * @param {Object} [options] Options object\n */\n constructor(text: string, options?: Props) {\n super(text, { ...Textbox.ownDefaults, ...options } as Props);\n }\n\n /**\n * Creates the default control object.\n * If you prefer to have on instance of controls shared among all objects\n * make this function return an empty object and add controls to the ownDefaults object\n */\n static createControls(): { controls: Record } {\n return { controls: createTextboxDefaultControls() };\n }\n\n /**\n * Unlike superclass's version of this function, Textbox does not update\n * its width.\n * @private\n * @override\n */\n initDimensions() {\n if (!this.initialized) {\n return;\n }\n this.isEditing && this.initDelayedCursor();\n this._clearCache();\n // clear dynamicMinWidth as it will be different after we re-wrap line\n this.dynamicMinWidth = 0;\n // wrap lines\n this._styleMap = this._generateStyleMap(this._splitText());\n // if after wrapping, the width is smaller than dynamicMinWidth, change the width and re-wrap\n if (this.dynamicMinWidth > this.width) {\n this._set('width', this.dynamicMinWidth);\n }\n if (this.textAlign.includes(JUSTIFY)) {\n // once text is measured we need to make space fatter to make justified text.\n this.enlargeSpaces();\n }\n // clear cache and re-calculate height\n this.height = this.calcTextHeight();\n }\n\n /**\n * Generate an object that translates the style object so that it is\n * broken up by visual lines (new lines and automatic wrapping).\n * The original text styles object is broken up by actual lines (new lines only),\n * which is only sufficient for Text / IText\n * @private\n */\n _generateStyleMap(textInfo: TextLinesInfo): StyleMap {\n let realLineCount = 0,\n realLineCharCount = 0,\n charCount = 0;\n const map: StyleMap = {};\n\n for (let i = 0; i < textInfo.graphemeLines.length; i++) {\n if (textInfo.graphemeText[charCount] === '\\n' && i > 0) {\n realLineCharCount = 0;\n charCount++;\n realLineCount++;\n } else if (\n !this.splitByGrapheme &&\n this._reSpaceAndTab.test(textInfo.graphemeText[charCount]) &&\n i > 0\n ) {\n // this case deals with space's that are removed from end of lines when wrapping\n realLineCharCount++;\n charCount++;\n }\n\n map[i] = { line: realLineCount, offset: realLineCharCount };\n\n charCount += textInfo.graphemeLines[i].length;\n realLineCharCount += textInfo.graphemeLines[i].length;\n }\n\n return map;\n }\n\n /**\n * Returns true if object has a style property or has it on a specified line\n * @param {Number} lineIndex\n * @return {Boolean}\n */\n styleHas(property: keyof TextStyleDeclaration, lineIndex: number): boolean {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (map) {\n lineIndex = map.line;\n }\n }\n return super.styleHas(property, lineIndex);\n }\n\n /**\n * Returns true if object has no styling or no styling in a line\n * @param {Number} lineIndex , lineIndex is on wrapped lines.\n * @return {Boolean}\n */\n isEmptyStyles(lineIndex: number): boolean {\n if (!this.styles) {\n return true;\n }\n let offset = 0,\n nextLineIndex = lineIndex + 1,\n nextOffset: number,\n shouldLimit = false;\n const map = this._styleMap[lineIndex],\n mapNextLine = this._styleMap[lineIndex + 1];\n if (map) {\n lineIndex = map.line;\n offset = map.offset;\n }\n if (mapNextLine) {\n nextLineIndex = mapNextLine.line;\n shouldLimit = nextLineIndex === lineIndex;\n nextOffset = mapNextLine.offset;\n }\n const obj =\n typeof lineIndex === 'undefined'\n ? this.styles\n : { line: this.styles[lineIndex] };\n for (const p1 in obj) {\n for (const p2 in obj[p1]) {\n const p2Number = parseInt(p2, 10);\n if (p2Number >= offset && (!shouldLimit || p2Number < nextOffset!)) {\n // eslint-disable-next-line no-unused-vars\n for (const p3 in obj[p1][p2]) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n /**\n * @protected\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @return {TextStyleDeclaration} a style object reference to the existing one or a new empty object when undefined\n */\n _getStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n ): TextStyleDeclaration {\n if (this._styleMap && !this.isWrapping) {\n const map = this._styleMap[lineIndex];\n if (!map) {\n return {};\n }\n lineIndex = map.line;\n charIndex = map.offset + charIndex;\n }\n return super._getStyleDeclaration(lineIndex, charIndex);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @param {Object} style\n * @private\n */\n protected _setStyleDeclaration(\n lineIndex: number,\n charIndex: number,\n style: object,\n ) {\n const map = this._styleMap[lineIndex];\n super._setStyleDeclaration(map.line, map.offset + charIndex, style);\n }\n\n /**\n * @param {Number} lineIndex\n * @param {Number} charIndex\n * @private\n */\n protected _deleteStyleDeclaration(lineIndex: number, charIndex: number) {\n const map = this._styleMap[lineIndex];\n super._deleteStyleDeclaration(map.line, map.offset + charIndex);\n }\n\n /**\n * probably broken need a fix\n * Returns the real style line that correspond to the wrapped lineIndex line\n * Used just to verify if the line does exist or not.\n * @param {Number} lineIndex\n * @returns {Boolean} if the line exists or not\n * @private\n */\n protected _getLineStyle(lineIndex: number): boolean {\n const map = this._styleMap[lineIndex];\n return !!this.styles[map.line];\n }\n\n /**\n * Set the line style to an empty object so that is initialized\n * @param {Number} lineIndex\n * @param {Object} style\n * @private\n */\n protected _setLineStyle(lineIndex: number) {\n const map = this._styleMap[lineIndex];\n super._setLineStyle(map.line);\n }\n\n /**\n * Wraps text using the 'width' property of Textbox. First this function\n * splits text on newlines, so we preserve newlines entered by the user.\n * Then it wraps each line using the width of the Textbox by calling\n * _wrapLine().\n * @param {Array} lines The string array of text that is split into lines\n * @param {Number} desiredWidth width you want to wrap to\n * @returns {Array} Array of lines\n */\n _wrapText(lines: string[], desiredWidth: number): string[][] {\n this.isWrapping = true;\n // extract all thewords and the widths to optimally wrap lines.\n const data = this.getGraphemeDataForRender(lines);\n const wrapped: string[][] = [];\n for (let i = 0; i < data.wordsData.length; i++) {\n wrapped.push(...this._wrapLine(i, desiredWidth, data));\n }\n this.isWrapping = false;\n return wrapped;\n }\n\n /**\n * For each line of text terminated by an hard line stop,\n * measure each word width and extract the largest word from all.\n * The returned words here are the one that at the end will be rendered.\n * @param {string[]} lines the lines we need to measure\n *\n */\n getGraphemeDataForRender(lines: string[]): GraphemeData {\n const splitByGrapheme = this.splitByGrapheme,\n infix = splitByGrapheme ? '' : ' ';\n\n let largestWordWidth = 0;\n\n const data = lines.map((line, lineIndex) => {\n let offset = 0;\n const wordsOrGraphemes = splitByGrapheme\n ? this.graphemeSplit(line)\n : this.wordSplit(line);\n\n if (wordsOrGraphemes.length === 0) {\n return [{ word: [], width: 0 }];\n }\n\n return wordsOrGraphemes.map((word: string) => {\n // if using splitByGrapheme words are already in graphemes.\n const graphemeArray = splitByGrapheme\n ? [word]\n : this.graphemeSplit(word);\n const width = this._measureWord(graphemeArray, lineIndex, offset);\n largestWordWidth = Math.max(width, largestWordWidth);\n offset += graphemeArray.length + infix.length;\n return { word: graphemeArray, width };\n });\n });\n\n return {\n wordsData: data,\n largestWordWidth,\n };\n }\n\n /**\n * Helper function to measure a string of text, given its lineIndex and charIndex offset\n * It gets called when charBounds are not available yet.\n * Override if necessary\n * Use with {@link Textbox#wordSplit}\n *\n * @param {CanvasRenderingContext2D} ctx\n * @param {String} text\n * @param {number} lineIndex\n * @param {number} charOffset\n * @returns {number}\n */\n _measureWord(word: string[], lineIndex: number, charOffset = 0): number {\n let width = 0,\n prevGrapheme;\n const skipLeft = true;\n for (let i = 0, len = word.length; i < len; i++) {\n const box = this._getGraphemeBox(\n word[i],\n lineIndex,\n i + charOffset,\n prevGrapheme,\n skipLeft,\n );\n width += box.kernedWidth;\n prevGrapheme = word[i];\n }\n return width;\n }\n\n /**\n * Override this method to customize word splitting\n * Use with {@link Textbox#_measureWord}\n * @param {string} value\n * @returns {string[]} array of words\n */\n wordSplit(value: string): string[] {\n return value.split(this._wordJoiners);\n }\n\n /**\n * Wraps a line of text using the width of the Textbox as desiredWidth\n * and leveraging the known width o words from GraphemeData\n * @private\n * @param {Number} lineIndex\n * @param {Number} desiredWidth width you want to wrap the line to\n * @param {GraphemeData} graphemeData an object containing all the lines' words width.\n * @param {Number} reservedSpace space to remove from wrapping for custom functionalities\n * @returns {Array} Array of line(s) into which the given text is wrapped\n * to.\n */\n _wrapLine(\n lineIndex: number,\n desiredWidth: number,\n { largestWordWidth, wordsData }: GraphemeData,\n reservedSpace = 0,\n ): string[][] {\n const additionalSpace = this._getWidthOfCharSpacing(),\n splitByGrapheme = this.splitByGrapheme,\n graphemeLines = [],\n infix = splitByGrapheme ? '' : ' ';\n\n let lineWidth = 0,\n line: string[] = [],\n // spaces in different languages?\n offset = 0,\n infixWidth = 0,\n lineJustStarted = true;\n\n desiredWidth -= reservedSpace;\n\n const maxWidth = Math.max(\n desiredWidth,\n largestWordWidth,\n this.dynamicMinWidth,\n );\n // layout words\n const data = wordsData[lineIndex];\n offset = 0;\n let i;\n for (i = 0; i < data.length; i++) {\n const { word, width: wordWidth } = data[i];\n offset += word.length;\n\n lineWidth += infixWidth + wordWidth - additionalSpace;\n if (lineWidth > maxWidth && !lineJustStarted) {\n graphemeLines.push(line);\n line = [];\n lineWidth = wordWidth;\n lineJustStarted = true;\n } else {\n lineWidth += additionalSpace;\n }\n\n if (!lineJustStarted && !splitByGrapheme) {\n line.push(infix);\n }\n line = line.concat(word);\n\n infixWidth = splitByGrapheme\n ? 0\n : this._measureWord([infix], lineIndex, offset);\n offset++;\n lineJustStarted = false;\n }\n\n i && graphemeLines.push(line);\n\n // TODO: this code is probably not necessary anymore.\n // it can be moved out of this function since largestWordWidth is now\n // known in advance\n if (largestWordWidth + reservedSpace > this.dynamicMinWidth) {\n this.dynamicMinWidth = largestWordWidth - additionalSpace + reservedSpace;\n }\n return graphemeLines;\n }\n\n /**\n * Detect if the text line is ended with an hard break\n * text and itext do not have wrapping, return false\n * @param {Number} lineIndex text to split\n * @return {Boolean}\n */\n isEndOfWrapping(lineIndex: number): boolean {\n if (!this._styleMap[lineIndex + 1]) {\n // is last line, return true;\n return true;\n }\n if (this._styleMap[lineIndex + 1].line !== this._styleMap[lineIndex].line) {\n // this is last line before a line break, return true;\n return true;\n }\n return false;\n }\n\n /**\n * Detect if a line has a linebreak and so we need to account for it when moving\n * and counting style.\n * This is important only for splitByGrapheme at the end of wrapping.\n * If we are not wrapping the offset is always 1\n * @return Number\n */\n missingNewlineOffset(lineIndex: number, skipWrapping?: boolean): 0 | 1 {\n if (this.splitByGrapheme && !skipWrapping) {\n return this.isEndOfWrapping(lineIndex) ? 1 : 0;\n }\n return 1;\n }\n\n /**\n * Gets lines of text to render in the Textbox. This function calculates\n * text wrapping on the fly every time it is called.\n * @param {String} text text to split\n * @returns {Array} Array of lines in the Textbox.\n * @override\n */\n _splitTextIntoLines(text: string) {\n const newText = super._splitTextIntoLines(text),\n graphemeLines = this._wrapText(newText.lines, this.width),\n lines = new Array(graphemeLines.length);\n for (let i = 0; i < graphemeLines.length; i++) {\n lines[i] = graphemeLines[i].join('');\n }\n newText.lines = lines;\n newText.graphemeLines = graphemeLines;\n return newText;\n }\n\n getMinWidth() {\n return Math.max(this.minWidth, this.dynamicMinWidth);\n }\n\n _removeExtraneousStyles() {\n const linesToKeep = new Map();\n for (const prop in this._styleMap) {\n const propNumber = parseInt(prop, 10);\n if (this._textLines[propNumber]) {\n const lineIndex = this._styleMap[prop].line;\n linesToKeep.set(`${lineIndex}`, true);\n }\n }\n for (const prop in this.styles) {\n if (!linesToKeep.has(prop)) {\n delete this.styles[prop];\n }\n }\n }\n\n /**\n * Returns object representation of an instance\n * @method toObject\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n return super.toObject([\n 'minWidth',\n 'splitByGrapheme',\n ...propertiesToInclude,\n ] as K[]) as Pick & SProps;\n }\n}\n\nclassRegistry.setClass(Textbox);\n","import { Point } from '../../Point';\nimport type { FabricObject } from '../../shapes/Object/FabricObject';\nimport { makeBoundingBoxFromPoints } from '../../util/misc/boundingBoxFromPoints';\nimport { sendPointToPlane } from '../../util/misc/planeChange';\nimport type { LayoutStrategyResult, StrictLayoutContext } from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { getObjectBounds } from './utils';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will adjust the bounding box to match the clip path bounding box.\n */\nexport class ClipPathLayout extends LayoutStrategy {\n static readonly type = 'clip-path';\n\n shouldPerformLayout(context: StrictLayoutContext): boolean {\n return !!context.target.clipPath && super.shouldPerformLayout(context);\n }\n\n shouldLayoutClipPath() {\n return false;\n }\n\n calcLayoutResult(\n context: StrictLayoutContext,\n objects: FabricObject[],\n ): LayoutStrategyResult | undefined {\n const { target } = context;\n const { clipPath, group } = target;\n if (!clipPath || !this.shouldPerformLayout(context)) {\n return;\n }\n // TODO: remove stroke calculation from this case\n const { width, height } = makeBoundingBoxFromPoints(\n getObjectBounds(target, clipPath as FabricObject),\n );\n const size = new Point(width, height);\n if (clipPath.absolutePositioned) {\n // we want the center point to exist in group's containing plane\n const clipPathCenter = sendPointToPlane(\n clipPath.getRelativeCenterPoint(),\n undefined,\n group ? group.calcTransformMatrix() : undefined,\n );\n return {\n center: clipPathCenter,\n size,\n };\n } else {\n // we want the center point to exist in group's containing plane, so we send it upwards\n const clipPathCenter = clipPath\n .getRelativeCenterPoint()\n .transform(target.calcOwnMatrix(), true);\n if (this.shouldPerformLayout(context)) {\n // the clip path is positioned relative to the group's center which is affected by the bbox\n // so we first calculate the bbox\n const { center = new Point(), correction = new Point() } =\n this.calcBoundingBox(objects, context) || {};\n return {\n center: center.add(clipPathCenter),\n correction: correction.subtract(clipPathCenter),\n size,\n };\n } else {\n return {\n center: target.getRelativeCenterPoint().add(clipPathCenter),\n size,\n };\n }\n }\n }\n}\n\nclassRegistry.setClass(ClipPathLayout);\n","import { Point } from '../../Point';\nimport type {\n InitializationLayoutContext,\n LayoutStrategyResult,\n StrictLayoutContext,\n} from '../types';\nimport { LayoutStrategy } from './LayoutStrategy';\nimport { classRegistry } from '../../ClassRegistry';\n\n/**\n * Layout will keep target's initial size.\n */\nexport class FixedLayout extends LayoutStrategy {\n static readonly type = 'fixed';\n\n /**\n * @override respect target's initial size\n */\n getInitialSize(\n { target }: StrictLayoutContext & InitializationLayoutContext,\n { size }: Pick,\n ): Point {\n return new Point(target.width || size.x, target.height || size.y);\n }\n}\n\nclassRegistry.setClass(FixedLayout);\n","import { LayoutManager } from './LayoutManager';\nimport type { RegistrationContext, StrictLayoutContext } from './types';\nimport type { Group } from '../shapes/Group';\n\n/**\n * Today the LayoutManager class also takes care of subscribing event handlers\n * to update the group layout when the group is interactive and a transform is applied\n * to a child object.\n * The ActiveSelection is never interactive, but it could contain objects from\n * groups that are.\n * The standard LayoutManager would subscribe the children of the activeSelection to\n * perform layout changes to the active selection itself, what we need instead is that\n * the transformation applied to the active selection will trigger changes to the\n * original group of the children ( the one referenced under the parent property )\n * This subclass of the LayoutManager has a single duty to fill the gap of this difference.`\n */\nexport class ActiveSelectionLayoutManager extends LayoutManager {\n subscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n parent.layoutManager.subscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n\n /**\n * unsubscribe from parent only if all its children were deselected\n */\n unsubscribeTargets(\n context: RegistrationContext & Partial,\n ): void {\n const activeSelection = context.target;\n const selectedObjects = activeSelection.getObjects();\n const parents = context.targets.reduce((parents, target) => {\n target.parent && parents.add(target.parent);\n return parents;\n }, new Set());\n parents.forEach((parent) => {\n !selectedObjects.some((object) => object.parent === parent) &&\n parent.layoutManager.unsubscribeTargets({\n target: parent,\n targets: [activeSelection],\n });\n });\n }\n}\n","import type { ControlRenderingStyleOverride } from '../controls/controlRendering';\nimport { classRegistry } from '../ClassRegistry';\nimport type { GroupProps } from './Group';\nimport { Group } from './Group';\nimport type { FabricObject } from './Object/FabricObject';\nimport {\n LAYOUT_TYPE_ADDED,\n LAYOUT_TYPE_REMOVED,\n} from '../LayoutManager/constants';\nimport type { TClassProperties } from '../typedefs';\nimport { log } from '../util/internals/console';\nimport { ActiveSelectionLayoutManager } from '../LayoutManager/ActiveSelectionLayoutManager';\n\nexport type MultiSelectionStacking = 'canvas-stacking' | 'selection-order';\n\nexport interface ActiveSelectionOptions extends GroupProps {\n multiSelectionStacking: MultiSelectionStacking;\n}\n\nconst activeSelectionDefaultValues: Partial> =\n {\n multiSelectionStacking: 'canvas-stacking',\n };\n\n/**\n * Used by Canvas to manage selection.\n *\n * @example\n * class MyActiveSelection extends ActiveSelection {\n * ...\n * }\n *\n * // override the default `ActiveSelection` class\n * classRegistry.setClass(MyActiveSelection)\n */\nexport class ActiveSelection extends Group {\n static type = 'ActiveSelection';\n\n static ownDefaults: Record = activeSelectionDefaultValues;\n\n static getDefaults(): Record {\n return { ...super.getDefaults(), ...ActiveSelection.ownDefaults };\n }\n\n /**\n * The ActiveSelection needs to use the ActiveSelectionLayoutManager\n * or selections on interactive groups may be broken\n */\n declare layoutManager: ActiveSelectionLayoutManager;\n\n /**\n * controls how selected objects are added during a multiselection event\n * - `canvas-stacking` adds the selected object to the active selection while respecting canvas object stacking order\n * - `selection-order` adds the selected object to the top of the stack,\n * meaning that the stack is ordered by the order in which objects were selected\n * @default `canvas-stacking`\n */\n declare multiSelectionStacking: MultiSelectionStacking;\n\n constructor(\n objects: FabricObject[] = [],\n options: Partial = {},\n ) {\n super();\n Object.assign(this, ActiveSelection.ownDefaults);\n this.setOptions(options);\n const { left, top, layoutManager } = options;\n this.groupInit(objects, {\n left,\n top,\n layoutManager: layoutManager ?? new ActiveSelectionLayoutManager(),\n });\n }\n\n /**\n * @private\n */\n _shouldSetNestedCoords() {\n return true;\n }\n\n /**\n * @private\n * @override we don't want the selection monitor to be active\n */\n __objectSelectionMonitor() {\n // noop\n }\n\n /**\n * Adds objects with respect to {@link multiSelectionStacking}\n * @param targets object to add to selection\n */\n multiSelectAdd(...targets: FabricObject[]) {\n if (this.multiSelectionStacking === 'selection-order') {\n this.add(...targets);\n } else {\n // respect object stacking as it is on canvas\n // perf enhancement for large ActiveSelection: consider a binary search of `isInFrontOf`\n targets.forEach((target) => {\n const index = this._objects.findIndex((obj) => obj.isInFrontOf(target));\n const insertAt =\n index === -1\n ? // `target` is in front of all other objects\n this.size()\n : index;\n this.insertAt(insertAt, target);\n });\n }\n }\n\n /**\n * @override block ancestors/descendants of selected objects from being selected to prevent a circular object tree\n */\n canEnterGroup(object: FabricObject) {\n if (\n this.getObjects().some(\n (o) => o.isDescendantOf(object) || object.isDescendantOf(o),\n )\n ) {\n // prevent circular object tree\n log(\n 'error',\n 'ActiveSelection: circular object trees are not supported, this call has no effect',\n );\n return false;\n }\n\n return super.canEnterGroup(object);\n }\n\n /**\n * Change an object so that it can be part of an active selection.\n * this method is called by multiselectAdd from canvas code.\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object is in canvas coordinate plane\n */\n enterGroup(object: FabricObject, removeParentTransform?: boolean) {\n // This condition check that the object has currently a group, and the group\n // is also its parent, meaning that is not in an active selection, but is\n // in a normal group.\n if (object.parent && object.parent === object.group) {\n // Disconnect the object from the group functionalities, but keep the ref parent intact\n // for later re-enter\n object.parent._exitGroup(object);\n // in this case the object is probably inside an active selection.\n } else if (object.group && object.parent !== object.group) {\n // in this case group.remove will also clear the old parent reference.\n object.group.remove(object);\n }\n // enter the active selection from a render perspective\n // the object will be in the objects array of both the ActiveSelection and the Group\n // but referenced in the group's _activeObjects so that it won't be rendered twice.\n this._enterGroup(object, removeParentTransform);\n }\n\n /**\n * we want objects to retain their canvas ref when exiting instance\n * @private\n * @param {FabricObject} object\n * @param {boolean} [removeParentTransform] true if object should exit group without applying group's transform to it\n */\n exitGroup(object: FabricObject, removeParentTransform?: boolean) {\n this._exitGroup(object, removeParentTransform);\n // return to parent\n object.parent && object.parent._enterGroup(object, true);\n }\n\n /**\n * @private\n * @param {'added'|'removed'} type\n * @param {FabricObject[]} targets\n */\n _onAfterObjectsChange(type: 'added' | 'removed', targets: FabricObject[]) {\n super._onAfterObjectsChange(type, targets);\n const groups = new Set();\n targets.forEach((object) => {\n const { parent } = object;\n parent && groups.add(parent);\n });\n if (type === LAYOUT_TYPE_REMOVED) {\n // invalidate groups' layout and mark as dirty\n groups.forEach((group) => {\n group._onAfterObjectsChange(LAYOUT_TYPE_ADDED, targets);\n });\n } else {\n // mark groups as dirty\n groups.forEach((group) => {\n group._set('dirty', true);\n });\n }\n }\n\n /**\n * @override remove all objects\n */\n onDeselect() {\n this.removeAll();\n return false;\n }\n\n /**\n * Returns string representation of a group\n * @return {String}\n */\n toString() {\n return `#`;\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * objectCaching is a global flag, wins over everything\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * @return {Boolean}\n */\n shouldCache() {\n return false;\n }\n\n /**\n * Check if this group or its parent group are caching, recursively up\n * @return {Boolean}\n */\n isOnACache() {\n return false;\n }\n\n /**\n * Renders controls and borders for the object\n * @param {CanvasRenderingContext2D} ctx Context to render on\n * @param {Object} [styleOverride] properties to override the object style\n * @param {Object} [childrenOverride] properties to override the children overrides\n */\n _renderControls(\n ctx: CanvasRenderingContext2D,\n styleOverride?: ControlRenderingStyleOverride,\n childrenOverride?: ControlRenderingStyleOverride,\n ) {\n ctx.save();\n ctx.globalAlpha = this.isMoving ? this.borderOpacityWhenMoving : 1;\n const options = {\n hasControls: false,\n ...childrenOverride,\n forActiveSelection: true,\n };\n for (let i = 0; i < this._objects.length; i++) {\n this._objects[i]._renderControls(ctx, options);\n }\n super._renderControls(ctx, styleOverride);\n ctx.restore();\n }\n}\n\nclassRegistry.setClass(ActiveSelection);\nclassRegistry.setClass(ActiveSelection, 'activeSelection');\n","/**\n * Canvas 2D filter backend.\n */\nimport type { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TPipelineResources } from './typedefs';\n\nexport class Canvas2dFilterBackend {\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n /**\n * Apply a set of filters against a source image and draw the filtered output\n * to the provided destination canvas.\n *\n * @param {EnhancedFilter} filters The filter to apply.\n * @param {HTMLImageElement|HTMLCanvasElement} sourceElement The source to be filtered.\n * @param {Number} sourceWidth The width of the source input.\n * @param {Number} sourceHeight The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n */\n applyFilters(\n filters: BaseFilter>[],\n sourceElement: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n targetCanvas: HTMLCanvasElement,\n ): T2DPipelineState | void {\n const ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.drawImage(sourceElement, 0, 0, sourceWidth, sourceHeight);\n const imageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const originalImageData = ctx.getImageData(0, 0, sourceWidth, sourceHeight);\n const pipelineState: T2DPipelineState = {\n sourceWidth,\n sourceHeight,\n imageData,\n originalEl: sourceElement,\n originalImageData,\n canvasEl: targetCanvas,\n ctx,\n filterBackend: this,\n };\n filters.forEach((filter) => {\n filter.applyTo(pipelineState);\n });\n const { imageData: imageDataPostFilter } = pipelineState;\n if (\n imageDataPostFilter.width !== sourceWidth ||\n imageDataPostFilter.height !== sourceHeight\n ) {\n targetCanvas.width = imageDataPostFilter.width;\n targetCanvas.height = imageDataPostFilter.height;\n }\n ctx.putImageData(imageDataPostFilter, 0, 0);\n return pipelineState;\n }\n}\n","import { config } from '../config';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n TWebGLPipelineState,\n TProgramCache,\n TTextureCache,\n TPipelineResources,\n} from './typedefs';\nimport type { BaseFilter } from './BaseFilter';\n\nexport class WebGLFilterBackend {\n declare tileSize: number;\n\n /**\n * Define ...\n **/\n aPosition: Float32Array = new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]);\n\n /**\n * If GLPut data is the fastest operation, or if forced, this buffer will be used\n * to transfer the data back in the 2d logic\n **/\n declare imageBuffer?: ArrayBuffer;\n\n declare canvas: HTMLCanvasElement;\n\n /**\n * The Webgl context that will execute the operations for filtering\n **/\n declare gl: WebGLRenderingContext;\n\n /**\n * Keyed map for shader cache\n **/\n declare programCache: TProgramCache;\n\n /**\n * Keyed map for texture cache\n **/\n declare textureCache: TTextureCache;\n\n /**\n * Contains GPU info for debug\n **/\n declare gpuInfo: any;\n\n /**\n * Experimental. This object is a sort of repository of help layers used to avoid\n * of recreating them during frequent filtering. If you are previewing a filter with\n * a slider you probably do not want to create help layers every filter step.\n * in this object there will be appended some canvases, created once, resized sometimes\n * cleared never. Clearing is left to the developer.\n **/\n resources: TPipelineResources = {};\n\n constructor({ tileSize = config.textureSize } = {}) {\n this.tileSize = tileSize;\n this.setupGLContext(tileSize, tileSize);\n this.captureGPUInfo();\n }\n\n /**\n * Setup a WebGL context suitable for filtering, and bind any needed event handlers.\n */\n setupGLContext(width: number, height: number): void {\n this.dispose();\n this.createWebGLCanvas(width, height);\n }\n\n /**\n * Create a canvas element and associated WebGL context and attaches them as\n * class properties to the GLFilterBackend class.\n */\n createWebGLCanvas(width: number, height: number): void {\n const canvas = createCanvasElement();\n canvas.width = width;\n canvas.height = height;\n const glOptions = {\n alpha: true,\n premultipliedAlpha: false,\n depth: false,\n stencil: false,\n antialias: false,\n },\n gl = canvas.getContext('webgl', glOptions) as WebGLRenderingContext;\n\n if (!gl) {\n return;\n }\n gl.clearColor(0, 0, 0, 0);\n // this canvas can fire webglcontextlost and webglcontextrestored\n this.canvas = canvas;\n this.gl = gl;\n }\n\n /**\n * Attempts to apply the requested filters to the source provided, drawing the filtered output\n * to the provided target canvas.\n *\n * @param {Array} filters The filters to apply.\n * @param {TexImageSource} source The source to be filtered.\n * @param {Number} width The width of the source input.\n * @param {Number} height The height of the source input.\n * @param {HTMLCanvasElement} targetCanvas The destination for filtered output to be drawn.\n * @param {String|undefined} cacheKey A key used to cache resources related to the source. If\n * omitted, caching will be skipped.\n */\n applyFilters(\n filters: BaseFilter>[],\n source: TexImageSource,\n width: number,\n height: number,\n targetCanvas: HTMLCanvasElement,\n cacheKey?: string,\n ): TWebGLPipelineState | undefined {\n const gl = this.gl;\n const ctx = targetCanvas.getContext('2d');\n if (!gl || !ctx) {\n return;\n }\n let cachedTexture;\n if (cacheKey) {\n cachedTexture = this.getCachedTexture(cacheKey, source);\n }\n const pipelineState: TWebGLPipelineState = {\n originalWidth:\n (source as HTMLImageElement).width ||\n // @ts-expect-error is this a bug? should this be naturalWidth? or is this the pipeline state?\n (source as HTMLImageElement).originalWidth ||\n 0,\n originalHeight:\n (source as HTMLImageElement).height ||\n // @ts-expect-error is this a bug? should this be naturalHeight? or is this the pipeline state?\n (source as HTMLImageElement).originalHeight ||\n 0,\n sourceWidth: width,\n sourceHeight: height,\n destinationWidth: width,\n destinationHeight: height,\n context: gl,\n sourceTexture: this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n ),\n targetTexture: this.createTexture(gl, width, height),\n originalTexture:\n cachedTexture ||\n this.createTexture(\n gl,\n width,\n height,\n !cachedTexture ? source : undefined,\n )!,\n passes: filters.length,\n webgl: true,\n aPosition: this.aPosition,\n programCache: this.programCache,\n pass: 0,\n filterBackend: this,\n targetCanvas: targetCanvas,\n };\n const tempFbo = gl.createFramebuffer();\n gl.bindFramebuffer(gl.FRAMEBUFFER, tempFbo);\n filters.forEach((filter: any) => {\n filter && filter.applyTo(pipelineState);\n });\n resizeCanvasIfNeeded(pipelineState);\n this.copyGLTo2D(gl, pipelineState);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.deleteTexture(pipelineState.sourceTexture);\n gl.deleteTexture(pipelineState.targetTexture);\n gl.deleteFramebuffer(tempFbo);\n ctx.setTransform(1, 0, 0, 1, 0, 0);\n return pipelineState;\n }\n\n /**\n * Detach event listeners, remove references, and clean up caches.\n */\n dispose() {\n if (this.canvas) {\n // we are disposing, we don't care about the fact\n // that the canvas shouldn't be null.\n // @ts-expect-error disposing\n this.canvas = null;\n // @ts-expect-error disposing\n this.gl = null;\n }\n this.clearWebGLCaches();\n }\n\n /**\n * Wipe out WebGL-related caches.\n */\n clearWebGLCaches() {\n this.programCache = {};\n this.textureCache = {};\n }\n\n /**\n * Create a WebGL texture object.\n *\n * Accepts specific dimensions to initialize the texture to or a source image.\n *\n * @param {WebGLRenderingContext} gl The GL context to use for creating the texture.\n * @param {number} width The width to initialize the texture at.\n * @param {number} height The height to initialize the texture.\n * @param {TexImageSource} textureImageSource A source for the texture data.\n * @param {number} filter gl.NEAREST default or gl.LINEAR filters for the texture.\n * This filter is very useful for LUTs filters. If you need interpolation use gl.LINEAR\n * @returns {WebGLTexture}\n */\n createTexture(\n gl: WebGLRenderingContext,\n width: number,\n height: number,\n textureImageSource?: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ) {\n const {\n NEAREST,\n TEXTURE_2D,\n RGBA,\n UNSIGNED_BYTE,\n CLAMP_TO_EDGE,\n TEXTURE_MAG_FILTER,\n TEXTURE_MIN_FILTER,\n TEXTURE_WRAP_S,\n TEXTURE_WRAP_T,\n } = gl;\n const texture = gl.createTexture();\n gl.bindTexture(TEXTURE_2D, texture);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, filter || NEAREST);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n if (textureImageSource) {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n RGBA,\n UNSIGNED_BYTE,\n textureImageSource,\n );\n } else {\n gl.texImage2D(\n TEXTURE_2D,\n 0,\n RGBA,\n width,\n height,\n 0,\n RGBA,\n UNSIGNED_BYTE,\n null,\n );\n }\n return texture;\n }\n\n /**\n * Can be optionally used to get a texture from the cache array\n *\n * If an existing texture is not found, a new texture is created and cached.\n *\n * @param {String} uniqueId A cache key to use to find an existing texture.\n * @param {HTMLImageElement|HTMLCanvasElement} textureImageSource A source to use to create the\n * texture cache entry if one does not already exist.\n */\n getCachedTexture(\n uniqueId: string,\n textureImageSource: TexImageSource,\n filter?:\n | WebGLRenderingContextBase['NEAREST']\n | WebGLRenderingContextBase['LINEAR'],\n ): WebGLTexture | null {\n const { textureCache } = this;\n if (textureCache[uniqueId]) {\n return textureCache[uniqueId];\n } else {\n const texture = this.createTexture(\n this.gl,\n (textureImageSource as HTMLImageElement).width,\n (textureImageSource as HTMLImageElement).height,\n textureImageSource,\n filter,\n );\n if (texture) {\n textureCache[uniqueId] = texture;\n }\n return texture;\n }\n }\n\n /**\n * Clear out cached resources related to a source image that has been\n * filtered previously.\n *\n * @param {String} cacheKey The cache key provided when the source image was filtered.\n */\n evictCachesForKey(cacheKey: string) {\n if (this.textureCache[cacheKey]) {\n this.gl.deleteTexture(this.textureCache[cacheKey]);\n delete this.textureCache[cacheKey];\n }\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas.\n *\n * The WebGL canvas is assumed to be upside down, with the top-left pixel of the\n * desired output image appearing in the bottom-left corner of the WebGL canvas.\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2D(gl: WebGLRenderingContext, pipelineState: TWebGLPipelineState) {\n const glCanvas = gl.canvas,\n targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d');\n if (!ctx) {\n return;\n }\n ctx.translate(0, targetCanvas.height); // move it down again\n ctx.scale(1, -1); // vertical flip\n // where is my image on the big glcanvas?\n const sourceY = glCanvas.height - targetCanvas.height;\n ctx.drawImage(\n glCanvas,\n 0,\n sourceY,\n targetCanvas.width,\n targetCanvas.height,\n 0,\n 0,\n targetCanvas.width,\n targetCanvas.height,\n );\n }\n\n /**\n * Copy an input WebGL canvas on to an output 2D canvas using 2d canvas' putImageData\n * API. Measurably faster than using ctx.drawImage in Firefox (version 54 on OSX Sierra).\n *\n * @param {WebGLRenderingContext} sourceContext The WebGL context to copy from.\n * @param {HTMLCanvasElement} targetCanvas The 2D target canvas to copy on to.\n * @param {Object} pipelineState The 2D target canvas to copy on to.\n */\n copyGLTo2DPutImageData(\n this: Required,\n gl: WebGLRenderingContext,\n pipelineState: TWebGLPipelineState,\n ) {\n const targetCanvas = pipelineState.targetCanvas,\n ctx = targetCanvas.getContext('2d'),\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight,\n numBytes = dWidth * dHeight * 4;\n if (!ctx) {\n return;\n }\n const u8 = new Uint8Array(this.imageBuffer, 0, numBytes);\n const u8Clamped = new Uint8ClampedArray(this.imageBuffer, 0, numBytes);\n\n gl.readPixels(0, 0, dWidth, dHeight, gl.RGBA, gl.UNSIGNED_BYTE, u8);\n const imgData = new ImageData(u8Clamped, dWidth, dHeight);\n ctx.putImageData(imgData, 0, 0);\n }\n\n /**\n * Attempt to extract GPU information strings from a WebGL context.\n *\n * Useful information when debugging or blacklisting specific GPUs.\n *\n * @returns {Object} A GPU info object with renderer and vendor strings.\n */\n captureGPUInfo() {\n if (this.gpuInfo) {\n return this.gpuInfo;\n }\n const gl = this.gl,\n gpuInfo = { renderer: '', vendor: '' };\n if (!gl) {\n return gpuInfo;\n }\n const ext = gl.getExtension('WEBGL_debug_renderer_info');\n if (ext) {\n const renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);\n const vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);\n if (renderer) {\n gpuInfo.renderer = renderer.toLowerCase();\n }\n if (vendor) {\n gpuInfo.vendor = vendor.toLowerCase();\n }\n }\n this.gpuInfo = gpuInfo;\n return gpuInfo;\n }\n}\n\nfunction resizeCanvasIfNeeded(pipelineState: TWebGLPipelineState): void {\n const targetCanvas = pipelineState.targetCanvas,\n width = targetCanvas.width,\n height = targetCanvas.height,\n dWidth = pipelineState.destinationWidth,\n dHeight = pipelineState.destinationHeight;\n\n if (width !== dWidth || height !== dHeight) {\n targetCanvas.width = dWidth;\n targetCanvas.height = dHeight;\n }\n}\n","import { config } from '../config';\nimport { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { Canvas2dFilterBackend } from './Canvas2dFilterBackend';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\n\nexport type FilterBackend = WebGLFilterBackend | Canvas2dFilterBackend;\n\nlet filterBackend: FilterBackend;\n\n/**\n * Verifies if it is possible to initialize webgl or fallback on a canvas2d filtering backend\n */\nexport function initFilterBackend(): FilterBackend {\n const { WebGLProbe } = getEnv();\n WebGLProbe.queryWebGL(createCanvasElement());\n if (config.enableGLFiltering && WebGLProbe.isSupported(config.textureSize)) {\n return new WebGLFilterBackend({ tileSize: config.textureSize });\n } else {\n return new Canvas2dFilterBackend();\n }\n}\n\n/**\n * Get the current fabricJS filter backend or initialize one if not available yet\n * @param [strict] pass `true` to create the backend if it wasn't created yet (default behavior),\n * pass `false` to get the backend ref without mutating it\n */\nexport function getFilterBackend(strict = true): FilterBackend {\n if (!filterBackend && strict) {\n filterBackend = initFilterBackend();\n }\n return filterBackend;\n}\n\nexport function setFilterBackend(backend: FilterBackend) {\n filterBackend = backend;\n}\n","import { getFabricDocument, getEnv } from '../env';\nimport type { BaseFilter } from '../filters/BaseFilter';\nimport { getFilterBackend } from '../filters/FilterBackend';\nimport { SHARED_ATTRIBUTES } from '../parser/attributes';\nimport { parseAttributes } from '../parser/parseAttributes';\nimport type {\n TClassProperties,\n TCrossOrigin,\n TSize,\n Abortable,\n TOptions,\n} from '../typedefs';\nimport { uid } from '../util/internals/uid';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { findScaleToCover, findScaleToFit } from '../util/misc/findScaleTo';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport {\n enlivenObjectEnlivables,\n enlivenObjects,\n loadImage,\n} from '../util/misc/objectEnlive';\nimport { parsePreserveAspectRatioAttribute } from '../util/misc/svgParsing';\nimport { classRegistry } from '../ClassRegistry';\nimport { FabricObject, cacheProperties } from './Object/FabricObject';\nimport type { FabricObjectProps, SerializedObjectProps } from './Object/types';\nimport type { ObjectEvents } from '../EventTypeDefs';\nimport { WebGLFilterBackend } from '../filters/WebGLFilterBackend';\nimport { FILL, NONE } from '../constants';\nimport { getDocumentFromElement } from '../util/dom_misc';\nimport type { CSSRules } from '../parser/typedefs';\nimport type { Resize } from '../filters/Resize';\nimport type { TCachedFabricObject } from './Object/Object';\nimport { log } from '../util/internals/console';\n\n// @todo Would be nice to have filtering code not imported directly.\n\nexport type ImageSource =\n | HTMLImageElement\n | HTMLVideoElement\n | HTMLCanvasElement;\n\ninterface UniqueImageProps {\n srcFromAttribute: boolean;\n minimumScaleTrigger: number;\n cropX: number;\n cropY: number;\n imageSmoothing: boolean;\n filters: BaseFilter>[];\n resizeFilter?: Resize;\n}\n\nexport const imageDefaultValues: Partial> = {\n strokeWidth: 0,\n srcFromAttribute: false,\n minimumScaleTrigger: 0.5,\n cropX: 0,\n cropY: 0,\n imageSmoothing: true,\n};\n\nexport interface SerializedImageProps extends SerializedObjectProps {\n src: string;\n crossOrigin: TCrossOrigin;\n filters: any[];\n resizeFilter?: any;\n cropX: number;\n cropY: number;\n}\n\nexport interface ImageProps extends FabricObjectProps, UniqueImageProps {}\n\nconst IMAGE_PROPS = ['cropX', 'cropY'] as const;\n\n/**\n * @tutorial {@link http://fabricjs.com/fabric-intro-part-1#images}\n */\nexport class FabricImage<\n Props extends TOptions = Partial,\n SProps extends SerializedImageProps = SerializedImageProps,\n EventSpec extends ObjectEvents = ObjectEvents,\n >\n extends FabricObject\n implements ImageProps\n{\n /**\n * When calling {@link FabricImage.getSrc}, return value from element src with `element.getAttribute('src')`.\n * This allows for relative urls as image src.\n * @since 2.7.0\n * @type Boolean\n * @default false\n */\n declare srcFromAttribute: boolean;\n\n /**\n * private\n * contains last value of scaleX to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleX = 1;\n\n /**\n * private\n * contains last value of scaleY to detect\n * if the Image got resized after the last Render\n * @type Number\n */\n protected _lastScaleY = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingX = 1;\n\n /**\n * private\n * contains last value of scaling applied by the apply filter chain\n * @type Number\n */\n protected _filterScalingY = 1;\n\n /**\n * minimum scale factor under which any resizeFilter is triggered to resize the image\n * 0 will disable the automatic resize. 1 will trigger automatically always.\n * number bigger than 1 are not implemented yet.\n * @type Number\n */\n declare minimumScaleTrigger: number;\n\n /**\n * key used to retrieve the texture representing this image\n * @since 2.0.0\n * @type String\n * @default\n */\n declare cacheKey: string;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropX: number;\n\n /**\n * Image crop in pixels from original image size.\n * @since 2.0.0\n * @type Number\n * @default\n */\n declare cropY: number;\n\n /**\n * Indicates whether this canvas will use image smoothing when painting this image.\n * Also influence if the cacheCanvas for this image uses imageSmoothing\n * @since 4.0.0-beta.11\n * @type Boolean\n * @default\n */\n declare imageSmoothing: boolean;\n\n declare preserveAspectRatio: string;\n\n protected declare src: string;\n\n declare filters: BaseFilter>[];\n declare resizeFilter: Resize;\n\n declare _element: ImageSource;\n declare _filteredEl?: HTMLCanvasElement;\n declare _originalElement: ImageSource;\n\n static type = 'Image';\n\n static cacheProperties = [...cacheProperties, ...IMAGE_PROPS];\n\n static ownDefaults = imageDefaultValues;\n\n static getDefaults(): Record {\n return {\n ...super.getDefaults(),\n ...FabricImage.ownDefaults,\n };\n }\n /**\n * Constructor\n * Image can be initialized with any canvas drawable or a string.\n * The string should be a url and will be loaded as an image.\n * Canvas and Image element work out of the box, while videos require extra code to work.\n * Please check video element events for seeking.\n * @param {ImageSource | string} element Image element\n * @param {Object} [options] Options object\n */\n constructor(elementId: string, options?: Props);\n constructor(element: ImageSource, options?: Props);\n constructor(arg0: ImageSource | string, options?: Props) {\n super();\n this.filters = [];\n Object.assign(this, FabricImage.ownDefaults);\n this.setOptions(options);\n this.cacheKey = `texture${uid()}`;\n this.setElement(\n typeof arg0 === 'string'\n ? ((\n (this.canvas && getDocumentFromElement(this.canvas.getElement())) ||\n getFabricDocument()\n ).getElementById(arg0) as ImageSource)\n : arg0,\n options,\n );\n }\n\n /**\n * Returns image element which this instance if based on\n */\n getElement() {\n return this._element;\n }\n\n /**\n * Sets image element for this instance to a specified one.\n * If filters defined they are applied to new image.\n * You might need to call `canvas.renderAll` and `object.setCoords` after replacing, to render new image and update controls area.\n * @param {HTMLImageElement} element\n * @param {Partial} [size] Options object\n */\n setElement(element: ImageSource, size: Partial = {}) {\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._element = element;\n this._originalElement = element;\n this._setWidthHeight(size);\n element.classList.add(FabricImage.CSS_CANVAS);\n if (this.filters.length !== 0) {\n this.applyFilters();\n }\n // resizeFilters work on the already filtered copy.\n // we need to apply resizeFilters AFTER normal filters.\n // applyResizeFilters is run more often than normal filters\n // and is triggered by user interactions rather than dev code\n if (this.resizeFilter) {\n this.applyResizeFilters();\n }\n }\n\n /**\n * Delete a single texture if in webgl mode\n */\n removeTexture(key: string) {\n const backend = getFilterBackend(false);\n if (backend instanceof WebGLFilterBackend) {\n backend.evictCachesForKey(key);\n }\n }\n\n /**\n * Delete textures, reference to elements and eventually JSDOM cleanup\n */\n dispose() {\n super.dispose();\n this.removeTexture(this.cacheKey);\n this.removeTexture(`${this.cacheKey}_filtered`);\n this._cacheContext = null;\n (\n ['_originalElement', '_element', '_filteredEl', '_cacheCanvas'] as const\n ).forEach((elementKey) => {\n const el = this[elementKey];\n el && getEnv().dispose(el);\n // @ts-expect-error disposing\n this[elementKey] = undefined;\n });\n }\n\n /**\n * Get the crossOrigin value (of the corresponding image element)\n */\n getCrossOrigin(): string | null {\n return (\n this._originalElement &&\n ((this._originalElement as any).crossOrigin || null)\n );\n }\n\n /**\n * Returns original size of an image\n */\n getOriginalSize() {\n const element = this.getElement() as any;\n if (!element) {\n return {\n width: 0,\n height: 0,\n };\n }\n return {\n width: element.naturalWidth || element.width,\n height: element.naturalHeight || element.height,\n };\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _stroke(ctx: CanvasRenderingContext2D) {\n if (!this.stroke || this.strokeWidth === 0) {\n return;\n }\n const w = this.width / 2,\n h = this.height / 2;\n ctx.beginPath();\n ctx.moveTo(-w, -h);\n ctx.lineTo(w, -h);\n ctx.lineTo(w, h);\n ctx.lineTo(-w, h);\n ctx.lineTo(-w, -h);\n ctx.closePath();\n }\n\n /**\n * Returns object representation of an instance\n * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output\n * @return {Object} Object representation of an instance\n */\n toObject<\n T extends Omit, keyof SProps>,\n K extends keyof T = never,\n >(propertiesToInclude: K[] = []): Pick & SProps {\n const filters: Record[] = [];\n this.filters.forEach((filterObj) => {\n filterObj && filters.push(filterObj.toObject());\n });\n return {\n ...super.toObject([...IMAGE_PROPS, ...propertiesToInclude]),\n src: this.getSrc(),\n crossOrigin: this.getCrossOrigin(),\n filters,\n ...(this.resizeFilter\n ? { resizeFilter: this.resizeFilter.toObject() }\n : {}),\n };\n }\n\n /**\n * Returns true if an image has crop applied, inspecting values of cropX,cropY,width,height.\n * @return {Boolean}\n */\n hasCrop() {\n return (\n !!this.cropX ||\n !!this.cropY ||\n this.width < this._element.width ||\n this.height < this._element.height\n );\n }\n\n /**\n * Returns svg representation of an instance\n * @return {string[]} an array of strings with the specific svg representation\n * of the instance\n */\n _toSVG() {\n const imageMarkup: string[] = [],\n element = this._element,\n x = -this.width / 2,\n y = -this.height / 2;\n let svgString: string[] = [],\n strokeSvg: string[] = [],\n clipPath = '',\n imageRendering = '';\n if (!element) {\n return [];\n }\n if (this.hasCrop()) {\n const clipPathId = uid();\n svgString.push(\n '\\n',\n '\\t\\n',\n '\\n',\n );\n clipPath = ' clip-path=\"url(#imageCrop_' + clipPathId + ')\" ';\n }\n if (!this.imageSmoothing) {\n imageRendering = ' image-rendering=\"optimizeSpeed\"';\n }\n imageMarkup.push(\n '\\t element with actual transformation, then offsetting object to the top/left\n // so that object's center aligns with container's left/top\n }\" width=\"${\n element.width || (element as HTMLImageElement).naturalWidth\n }\" height=\"${\n element.height || (element as HTMLImageElement).naturalHeight\n }\"${imageRendering}${clipPath}>\\n`,\n );\n\n if (this.stroke || this.strokeDashArray) {\n const origFill = this.fill;\n this.fill = null;\n strokeSvg = [\n `\\t\\n`,\n ];\n this.fill = origFill;\n }\n if (this.paintFirst !== FILL) {\n svgString = svgString.concat(strokeSvg, imageMarkup);\n } else {\n svgString = svgString.concat(imageMarkup, strokeSvg);\n }\n return svgString;\n }\n\n /**\n * Returns source of an image\n * @param {Boolean} filtered indicates if the src is needed for svg\n * @return {String} Source of an image\n */\n getSrc(filtered?: boolean): string {\n const element = filtered ? this._element : this._originalElement;\n if (element) {\n if ((element as HTMLCanvasElement).toDataURL) {\n return (element as HTMLCanvasElement).toDataURL();\n }\n\n if (this.srcFromAttribute) {\n return element.getAttribute('src') || '';\n } else {\n return (element as HTMLImageElement).src;\n }\n } else {\n return this.src || '';\n }\n }\n\n /**\n * Alias for getSrc\n * @param filtered\n * @deprecated\n */\n getSvgSrc(filtered?: boolean) {\n return this.getSrc(filtered);\n }\n\n /**\n * Loads and sets source of an image\\\n * **IMPORTANT**: It is recommended to abort loading tasks before calling this method to prevent race conditions and unnecessary networking\n * @param {String} src Source string (URL)\n * @param {LoadImageOptions} [options] Options object\n */\n setSrc(src: string, { crossOrigin, signal }: LoadImageOptions = {}) {\n return loadImage(src, { crossOrigin, signal }).then((img) => {\n typeof crossOrigin !== 'undefined' && this.set({ crossOrigin });\n this.setElement(img);\n });\n }\n\n /**\n * Returns string representation of an instance\n * @return {String} String representation of an instance\n */\n toString() {\n return `#`;\n }\n\n applyResizeFilters() {\n const filter = this.resizeFilter,\n minimumScale = this.minimumScaleTrigger,\n objectScale = this.getTotalObjectScaling(),\n scaleX = objectScale.x,\n scaleY = objectScale.y,\n elementToFilter = this._filteredEl || this._originalElement;\n if (this.group) {\n this.set('dirty', true);\n }\n if (!filter || (scaleX > minimumScale && scaleY > minimumScale)) {\n this._element = elementToFilter;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n this._lastScaleX = scaleX;\n this._lastScaleY = scaleY;\n return;\n }\n const canvasEl = createCanvasElement(),\n sourceWidth = elementToFilter.width,\n sourceHeight = elementToFilter.height;\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._lastScaleX = filter.scaleX = scaleX;\n this._lastScaleY = filter.scaleY = scaleY;\n getFilterBackend().applyFilters(\n [filter],\n elementToFilter,\n sourceWidth,\n sourceHeight,\n this._element,\n );\n this._filterScalingX = canvasEl.width / this._originalElement.width;\n this._filterScalingY = canvasEl.height / this._originalElement.height;\n }\n\n /**\n * Applies filters assigned to this image (from \"filters\" array) or from filter param\n * @method applyFilters\n * @param {Array} filters to be applied\n * @param {Boolean} forResizing specify if the filter operation is a resize operation\n */\n applyFilters(\n filters: BaseFilter>[] = this.filters || [],\n ) {\n filters = filters.filter((filter) => filter && !filter.isNeutralState());\n this.set('dirty', true);\n\n // needs to clear out or WEBGL will not resize correctly\n this.removeTexture(`${this.cacheKey}_filtered`);\n\n if (filters.length === 0) {\n this._element = this._originalElement;\n // this is unsafe and needs to be rethinkend\n this._filteredEl = undefined;\n this._filterScalingX = 1;\n this._filterScalingY = 1;\n return;\n }\n\n const imgElement = this._originalElement,\n sourceWidth =\n (imgElement as HTMLImageElement).naturalWidth || imgElement.width,\n sourceHeight =\n (imgElement as HTMLImageElement).naturalHeight || imgElement.height;\n\n if (this._element === this._originalElement) {\n // if the _element a reference to _originalElement\n // we need to create a new element to host the filtered pixels\n const canvasEl = createCanvasElement();\n canvasEl.width = sourceWidth;\n canvasEl.height = sourceHeight;\n this._element = canvasEl;\n this._filteredEl = canvasEl;\n } else if (this._filteredEl) {\n // if the _element is it own element,\n // and we also have a _filteredEl, then we clean up _filteredEl\n // and we assign it to _element.\n // in this way we invalidate the eventual old resize filtered element\n this._element = this._filteredEl;\n this._filteredEl\n .getContext('2d')!\n .clearRect(0, 0, sourceWidth, sourceHeight);\n // we also need to resize again at next renderAll, so remove saved _lastScaleX/Y\n this._lastScaleX = 1;\n this._lastScaleY = 1;\n }\n getFilterBackend().applyFilters(\n filters,\n this._originalElement,\n sourceWidth,\n sourceHeight,\n this._element as HTMLCanvasElement,\n );\n if (\n this._originalElement.width !== this._element.width ||\n this._originalElement.height !== this._element.height\n ) {\n this._filterScalingX = this._element.width / this._originalElement.width;\n this._filterScalingY =\n this._element.height / this._originalElement.height;\n }\n }\n\n /**\n * @private\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n _render(ctx: CanvasRenderingContext2D) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n if (this.isMoving !== true && this.resizeFilter && this._needsResize()) {\n this.applyResizeFilters();\n }\n this._stroke(ctx);\n this._renderPaintInOrder(ctx);\n }\n\n /**\n * Paint the cached copy of the object on the target context.\n * it will set the imageSmoothing for the draw operation\n * @param {CanvasRenderingContext2D} ctx Context to render on\n */\n drawCacheOnCanvas(\n this: TCachedFabricObject,\n ctx: CanvasRenderingContext2D,\n ) {\n ctx.imageSmoothingEnabled = this.imageSmoothing;\n super.drawCacheOnCanvas(ctx);\n }\n\n /**\n * Decide if the object should cache or not. Create its own cache level\n * needsItsOwnCache should be used when the object drawing method requires\n * a cache step. None of the fabric classes requires it.\n * Generally you do not cache objects in groups because the group outside is cached.\n * This is the special image version where we would like to avoid caching where possible.\n * Essentially images do not benefit from caching. They may require caching, and in that\n * case we do it. Also caching an image usually ends in a loss of details.\n * A full performance audit should be done.\n * @return {Boolean}\n */\n shouldCache() {\n return this.needsItsOwnCache();\n }\n\n _renderFill(ctx: CanvasRenderingContext2D) {\n const elementToDraw = this._element;\n if (!elementToDraw) {\n return;\n }\n const scaleX = this._filterScalingX,\n scaleY = this._filterScalingY,\n w = this.width,\n h = this.height,\n // crop values cannot be lesser than 0.\n cropX = Math.max(this.cropX, 0),\n cropY = Math.max(this.cropY, 0),\n elWidth =\n (elementToDraw as HTMLImageElement).naturalWidth || elementToDraw.width,\n elHeight =\n (elementToDraw as HTMLImageElement).naturalHeight ||\n elementToDraw.height,\n sX = cropX * scaleX,\n sY = cropY * scaleY,\n // the width height cannot exceed element width/height, starting from the crop offset.\n sW = Math.min(w * scaleX, elWidth - sX),\n sH = Math.min(h * scaleY, elHeight - sY),\n x = -w / 2,\n y = -h / 2,\n maxDestW = Math.min(w, elWidth / scaleX - cropX),\n maxDestH = Math.min(h, elHeight / scaleY - cropY);\n\n elementToDraw &&\n ctx.drawImage(elementToDraw, sX, sY, sW, sH, x, y, maxDestW, maxDestH);\n }\n\n /**\n * needed to check if image needs resize\n * @private\n */\n _needsResize() {\n const scale = this.getTotalObjectScaling();\n return scale.x !== this._lastScaleX || scale.y !== this._lastScaleY;\n }\n\n /**\n * @private\n * @deprecated unused\n */\n _resetWidthHeight() {\n this.set(this.getOriginalSize());\n }\n\n /**\n * @private\n * Set the width and the height of the image object, using the element or the\n * options.\n */\n _setWidthHeight({ width, height }: Partial = {}) {\n const size = this.getOriginalSize();\n this.width = width || size.width;\n this.height = height || size.height;\n }\n\n /**\n * Calculate offset for center and scale factor for the image in order to respect\n * the preserveAspectRatio attribute\n * @private\n */\n parsePreserveAspectRatioAttribute() {\n const pAR = parsePreserveAspectRatioAttribute(\n this.preserveAspectRatio || '',\n ),\n pWidth = this.width,\n pHeight = this.height,\n parsedAttributes = { width: pWidth, height: pHeight };\n let rWidth = this._element.width,\n rHeight = this._element.height,\n scaleX = 1,\n scaleY = 1,\n offsetLeft = 0,\n offsetTop = 0,\n cropX = 0,\n cropY = 0,\n offset;\n\n if (pAR && (pAR.alignX !== NONE || pAR.alignY !== NONE)) {\n if (pAR.meetOrSlice === 'meet') {\n scaleX = scaleY = findScaleToFit(this._element, parsedAttributes);\n offset = (pWidth - rWidth * scaleX) / 2;\n if (pAR.alignX === 'Min') {\n offsetLeft = -offset;\n }\n if (pAR.alignX === 'Max') {\n offsetLeft = offset;\n }\n offset = (pHeight - rHeight * scaleY) / 2;\n if (pAR.alignY === 'Min') {\n offsetTop = -offset;\n }\n if (pAR.alignY === 'Max') {\n offsetTop = offset;\n }\n }\n if (pAR.meetOrSlice === 'slice') {\n scaleX = scaleY = findScaleToCover(this._element, parsedAttributes);\n offset = rWidth - pWidth / scaleX;\n if (pAR.alignX === 'Mid') {\n cropX = offset / 2;\n }\n if (pAR.alignX === 'Max') {\n cropX = offset;\n }\n offset = rHeight - pHeight / scaleY;\n if (pAR.alignY === 'Mid') {\n cropY = offset / 2;\n }\n if (pAR.alignY === 'Max') {\n cropY = offset;\n }\n rWidth = pWidth / scaleX;\n rHeight = pHeight / scaleY;\n }\n } else {\n scaleX = pWidth / rWidth;\n scaleY = pHeight / rHeight;\n }\n return {\n width: rWidth,\n height: rHeight,\n scaleX,\n scaleY,\n offsetLeft,\n offsetTop,\n cropX,\n cropY,\n };\n }\n\n /**\n * Default CSS class name for canvas\n * @static\n * @type String\n * @default\n */\n static CSS_CANVAS = 'canvas-img';\n\n /**\n * List of attribute names to account for when parsing SVG element (used by {@link FabricImage.fromElement})\n * @static\n * @see {@link http://www.w3.org/TR/SVG/struct.html#ImageElement}\n */\n static ATTRIBUTE_NAMES = [\n ...SHARED_ATTRIBUTES,\n 'x',\n 'y',\n 'width',\n 'height',\n 'preserveAspectRatio',\n 'xlink:href',\n 'crossOrigin',\n 'image-rendering',\n ];\n\n /**\n * Creates an instance of FabricImage from its object representation\n * @static\n * @param {Object} object Object to create an instance from\n * @param {object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject>(\n { filters: f, resizeFilter: rf, src, crossOrigin, type, ...object }: T,\n options?: Abortable,\n ) {\n return Promise.all([\n loadImage(src!, { ...options, crossOrigin }),\n f && enlivenObjects>(f, options),\n // TODO: redundant - handled by enlivenObjectEnlivables\n rf && enlivenObjects>([rf], options),\n enlivenObjectEnlivables(object, options),\n ]).then(([el, filters = [], [resizeFilter] = [], hydratedProps = {}]) => {\n return new this(el, {\n ...object,\n // TODO: this creates a difference between image creation and restoring from JSON\n src,\n filters,\n resizeFilter,\n ...hydratedProps,\n });\n });\n }\n\n /**\n * Creates an instance of Image from an URL string\n * @static\n * @param {String} url URL to create an image from\n * @param {LoadImageOptions} [options] Options object\n * @returns {Promise}\n */\n static fromURL>(\n url: string,\n { crossOrigin = null, signal }: LoadImageOptions = {},\n imageOptions?: T,\n ): Promise {\n return loadImage(url, { crossOrigin, signal }).then(\n (img) => new this(img, imageOptions),\n );\n }\n\n /**\n * Returns {@link FabricImage} instance from an SVG element\n * @static\n * @param {HTMLElement} element Element to parse\n * @param {Object} [options] Options object\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @param {Function} callback Callback to execute when Image object is created\n */\n static async fromElement(\n element: HTMLElement,\n options: Abortable = {},\n cssRules?: CSSRules,\n ) {\n const parsedAttributes = parseAttributes(\n element,\n this.ATTRIBUTE_NAMES,\n cssRules,\n );\n return this.fromURL(\n parsedAttributes['xlink:href'],\n options,\n parsedAttributes,\n ).catch((err) => {\n log('log', 'Unable to parse Image', err);\n return null;\n });\n }\n}\n\nclassRegistry.setClass(FabricImage);\nclassRegistry.setSVGClass(FabricImage);\n","import { svgNS } from './constants';\nimport {\n parsePreserveAspectRatioAttribute,\n parseUnit,\n} from '../util/misc/svgParsing';\nimport { svgViewBoxElementsRegEx, reViewBoxAttrValue } from './constants';\nimport { NONE } from '../constants';\n\nexport type ParsedViewboxTransform = Partial<{\n width: number;\n height: number;\n minX: number;\n minY: number;\n viewBoxWidth: number;\n viewBoxHeight: number;\n}>;\n\n/**\n * Add a element that envelop all child elements and makes the viewbox transformMatrix descend on all elements\n */\nexport function applyViewboxTransform(\n element: Element,\n): ParsedViewboxTransform {\n if (!svgViewBoxElementsRegEx.test(element.nodeName)) {\n return {};\n }\n const viewBoxAttr: string | null = element.getAttribute('viewBox');\n let scaleX = 1;\n let scaleY = 1;\n let minX = 0;\n let minY = 0;\n let matrix;\n let el;\n const widthAttr = element.getAttribute('width');\n const heightAttr = element.getAttribute('height');\n const x = element.getAttribute('x') || 0;\n const y = element.getAttribute('y') || 0;\n const goodViewbox = viewBoxAttr && reViewBoxAttrValue.test(viewBoxAttr);\n const missingViewBox = !goodViewbox;\n const missingDimAttr =\n !widthAttr || !heightAttr || widthAttr === '100%' || heightAttr === '100%';\n\n let translateMatrix = '';\n let widthDiff = 0;\n let heightDiff = 0;\n\n if (missingViewBox) {\n if (\n (x || y) &&\n element.parentNode &&\n element.parentNode.nodeName !== '#document'\n ) {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n matrix = (element.getAttribute('transform') || '') + translateMatrix;\n element.setAttribute('transform', matrix);\n element.removeAttribute('x');\n element.removeAttribute('y');\n }\n }\n\n if (missingViewBox && missingDimAttr) {\n return {\n width: 0,\n height: 0,\n };\n }\n\n const parsedDim: ParsedViewboxTransform = {\n width: 0,\n height: 0,\n };\n\n if (missingViewBox) {\n parsedDim.width = parseUnit(widthAttr!);\n parsedDim.height = parseUnit(heightAttr!);\n // set a transform for elements that have x y and are inner(only) SVGs\n return parsedDim;\n }\n\n const pasedViewBox = viewBoxAttr.match(reViewBoxAttrValue)!;\n minX = -parseFloat(pasedViewBox[1]);\n minY = -parseFloat(pasedViewBox[2]);\n const viewBoxWidth = parseFloat(pasedViewBox[3]);\n const viewBoxHeight = parseFloat(pasedViewBox[4]);\n parsedDim.minX = minX;\n parsedDim.minY = minY;\n parsedDim.viewBoxWidth = viewBoxWidth;\n parsedDim.viewBoxHeight = viewBoxHeight;\n if (!missingDimAttr) {\n parsedDim.width = parseUnit(widthAttr);\n parsedDim.height = parseUnit(heightAttr);\n scaleX = parsedDim.width / viewBoxWidth;\n scaleY = parsedDim.height / viewBoxHeight;\n } else {\n parsedDim.width = viewBoxWidth;\n parsedDim.height = viewBoxHeight;\n }\n\n // default is to preserve aspect ratio\n const preserveAspectRatio = parsePreserveAspectRatioAttribute(\n element.getAttribute('preserveAspectRatio') || '',\n );\n if (preserveAspectRatio.alignX !== NONE) {\n //translate all container for the effect of Mid, Min, Max\n if (preserveAspectRatio.meetOrSlice === 'meet') {\n scaleY = scaleX = scaleX > scaleY ? scaleY : scaleX;\n // calculate additional translation to move the viewbox\n }\n if (preserveAspectRatio.meetOrSlice === 'slice') {\n scaleY = scaleX = scaleX > scaleY ? scaleX : scaleY;\n // calculate additional translation to move the viewbox\n }\n widthDiff = parsedDim.width - viewBoxWidth * scaleX;\n heightDiff = parsedDim.height - viewBoxHeight * scaleX;\n if (preserveAspectRatio.alignX === 'Mid') {\n widthDiff /= 2;\n }\n if (preserveAspectRatio.alignY === 'Mid') {\n heightDiff /= 2;\n }\n if (preserveAspectRatio.alignX === 'Min') {\n widthDiff = 0;\n }\n if (preserveAspectRatio.alignY === 'Min') {\n heightDiff = 0;\n }\n }\n\n if (\n scaleX === 1 &&\n scaleY === 1 &&\n minX === 0 &&\n minY === 0 &&\n x === 0 &&\n y === 0\n ) {\n return parsedDim;\n }\n if ((x || y) && element.parentNode!.nodeName !== '#document') {\n translateMatrix =\n ' translate(' + parseUnit(x || '0') + ' ' + parseUnit(y || '0') + ') ';\n }\n\n matrix =\n translateMatrix +\n ' matrix(' +\n scaleX +\n ' 0' +\n ' 0 ' +\n scaleY +\n ' ' +\n (minX * scaleX + widthDiff) +\n ' ' +\n (minY * scaleY + heightDiff) +\n ') ';\n // seems unused.\n // parsedDim.viewboxTransform = parseTransformAttribute(matrix);\n if (element.nodeName === 'svg') {\n el = element.ownerDocument.createElementNS(svgNS, 'g');\n // element.firstChild != null\n while (element.firstChild) {\n el.appendChild(element.firstChild);\n }\n element.appendChild(el);\n } else {\n el = element;\n el.removeAttribute('x');\n el.removeAttribute('y');\n matrix = el.getAttribute('transform') + matrix;\n }\n el.setAttribute('transform', matrix);\n return parsedDim;\n}\n","export const getTagName = (node: Element) => node.tagName.replace('svg:', '');\n","import { svgInvalidAncestors } from './constants';\nimport { getSvgRegex } from './getSvgRegex';\nimport { getTagName } from './getTagName';\n\nconst svgInvalidAncestorsRegEx = getSvgRegex(svgInvalidAncestors);\n\nexport function hasInvalidAncestor(element: Element) {\n let _element: Element | null = element;\n while (_element && (_element = _element.parentElement)) {\n if (\n _element &&\n _element.nodeName &&\n svgInvalidAncestorsRegEx.test(getTagName(_element)) &&\n !_element.getAttribute('instantiated_by_use')\n ) {\n return true;\n }\n }\n return false;\n}\n","export function getMultipleNodes(\n doc: Document,\n nodeNames: string[],\n): Element[] {\n let nodeName,\n nodeArray: Element[] = [],\n nodeList,\n i,\n len;\n for (i = 0, len = nodeNames.length; i < len; i++) {\n nodeName = nodeNames[i];\n nodeList = doc.getElementsByTagNameNS(\n 'http://www.w3.org/2000/svg',\n nodeName,\n );\n nodeArray = nodeArray.concat(Array.from(nodeList));\n }\n return nodeArray;\n}\n","import { svgNS } from './constants';\nimport { getMultipleNodes } from './getMultipleNodes';\nimport { applyViewboxTransform } from './applyViewboxTransform';\nimport { parseStyleString } from './parseStyleString';\n\nexport function parseUseDirectives(doc: Document) {\n const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);\n const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];\n\n for (const useElement of nodelist) {\n const useAttributes: NamedNodeMap = useElement.attributes;\n\n const useAttrMap: Record = {};\n for (const attr of useAttributes) {\n attr.value && (useAttrMap[attr.name] = attr.value);\n }\n\n const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);\n\n if (xlink === '') {\n return;\n }\n const referencedElement = doc.getElementById(xlink);\n if (referencedElement === null) {\n // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink\n return;\n }\n let clonedOriginal = referencedElement.cloneNode(true) as Element;\n\n const originalAttributes: NamedNodeMap = clonedOriginal.attributes;\n\n const originalAttrMap: Record = {};\n for (const attr of originalAttributes) {\n attr.value && (originalAttrMap[attr.name] = attr.value);\n }\n\n // Transform attribute needs to be merged in a particular way\n const { x = 0, y = 0, transform = '' } = useAttrMap;\n const currentTrans = `${transform} ${\n originalAttrMap.transform || ''\n } translate(${x}, ${y})`;\n\n applyViewboxTransform(clonedOriginal);\n\n if (/^svg$/i.test(clonedOriginal.nodeName)) {\n // if is an SVG, create a group and apply all the attributes on top of it\n const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');\n Object.entries(originalAttrMap).forEach(([name, value]) =>\n el3.setAttributeNS(svgNS, name, value),\n );\n el3.append(...clonedOriginal.childNodes);\n clonedOriginal = el3;\n }\n\n for (const attr of useAttributes) {\n if (!attr) {\n continue;\n }\n const { name, value } = attr;\n if (skipAttributes.includes(name)) {\n continue;\n }\n\n if (name === 'style') {\n // when use has a style, merge the two styles, with the ref being priority (not use)\n // priority is by feature. an attribute for fill on the original element\n // will overwrite the fill in style or attribute for tha use\n const styleRecord: Record = {};\n parseStyleString(value!, styleRecord);\n // cleanup styleRecord from attributes of original\n Object.entries(originalAttrMap).forEach(([name, value]) => {\n styleRecord[name] = value;\n });\n // now we can put in the style of the original that will overwrite the original attributes\n parseStyleString(originalAttrMap.style || '', styleRecord);\n const mergedStyles = Object.entries(styleRecord)\n .map((entry) => entry.join(':'))\n .join(';');\n clonedOriginal.setAttribute(name, mergedStyles);\n } else {\n // set the attribute from use element only if the original does not have it already\n !originalAttrMap[name] && clonedOriginal.setAttribute(name, value!);\n }\n }\n\n clonedOriginal.setAttribute('transform', currentTrans);\n clonedOriginal.setAttribute('instantiated_by_use', '1');\n clonedOriginal.removeAttribute('id');\n useElement.parentNode!.replaceChild(clonedOriginal, useElement);\n }\n}\n","const gradientsAttrs = [\n 'gradientTransform',\n 'x1',\n 'x2',\n 'y1',\n 'y2',\n 'gradientUnits',\n 'cx',\n 'cy',\n 'r',\n 'fx',\n 'fy',\n];\nconst xlinkAttr = 'xlink:href';\n\nexport function recursivelyParseGradientsXlink(\n doc: Document,\n gradient: Element,\n) {\n const xLink = gradient.getAttribute(xlinkAttr)?.slice(1) || '',\n referencedGradient = doc.getElementById(xLink);\n if (referencedGradient && referencedGradient.getAttribute(xlinkAttr)) {\n recursivelyParseGradientsXlink(doc, referencedGradient as Element);\n }\n if (referencedGradient) {\n gradientsAttrs.forEach((attr) => {\n const value = referencedGradient.getAttribute(attr);\n if (!gradient.hasAttribute(attr) && value) {\n gradient.setAttribute(attr, value);\n }\n });\n if (!gradient.children.length) {\n const referenceClone = referencedGradient.cloneNode(true);\n while (referenceClone.firstChild) {\n gradient.appendChild(referenceClone.firstChild);\n }\n }\n }\n gradient.removeAttribute(xlinkAttr);\n}\n","import { getMultipleNodes } from './getMultipleNodes';\nimport { recursivelyParseGradientsXlink } from './recursivelyParseGradientsXlink';\n\nconst tagArray = [\n 'linearGradient',\n 'radialGradient',\n 'svg:linearGradient',\n 'svg:radialGradient',\n];\n\n/**\n * Parses an SVG document, returning all of the gradient declarations found in it\n * @param {SVGDocument} doc SVG document to parse\n * @return {Object} Gradient definitions; key corresponds to element id, value -- to gradient definition element\n */\nexport function getGradientDefs(\n doc: Document,\n): Record {\n const elList = getMultipleNodes(doc, tagArray);\n const gradientDefs: Record = {};\n let j = elList.length;\n while (j--) {\n const el = elList[j];\n if (el.getAttribute('xlink:href')) {\n recursivelyParseGradientsXlink(doc, el);\n }\n const id = el.getAttribute('id');\n if (id) {\n gradientDefs[id] = el as SVGGradientElement;\n }\n }\n return gradientDefs;\n}\n","import type { CSSRules } from './typedefs';\n\n/**\n * Returns CSS rules for a given SVG document\n * @param {HTMLElement} doc SVG document to parse\n * @return {Object} CSS rules of this document\n */\nexport function getCSSRules(doc: Document) {\n const styles = doc.getElementsByTagName('style');\n let i;\n let len;\n const allRules: CSSRules = {};\n\n // very crude parsing of style contents\n for (i = 0, len = styles.length; i < len; i++) {\n const styleContents = (styles[i].textContent || '').replace(\n // remove comments\n /\\/\\*[\\s\\S]*?\\*\\//g,\n '',\n );\n\n if (styleContents.trim() === '') {\n continue;\n }\n // recovers all the rule in this form `body { style code... }`\n // rules = styleContents.match(/[^{]*\\{[\\s\\S]*?\\}/g);\n styleContents\n .split('}')\n // remove empty rules and remove everything if we didn't split in at least 2 pieces\n .filter((rule, index, array) => array.length > 1 && rule.trim())\n // at this point we have hopefully an array of rules `body { style code... `\n .forEach((rule) => {\n // if there is more than one opening bracket and the rule starts with '@', it is likely\n // a nested at-rule like @media, @supports, @scope, etc. Ignore these as the code below\n // can not handle it.\n if (\n (rule.match(/{/g) || []).length > 1 &&\n rule.trim().startsWith('@')\n ) {\n return;\n }\n\n const match = rule.split('{'),\n ruleObj: Record = {},\n declaration = match[1].trim(),\n propertyValuePairs = declaration.split(';').filter(function (pair) {\n return pair.trim();\n });\n\n for (i = 0, len = propertyValuePairs.length; i < len; i++) {\n const pair = propertyValuePairs[i].split(':'),\n property = pair[0].trim(),\n value = pair[1].trim();\n ruleObj[property] = value;\n }\n rule = match[0].trim();\n rule.split(',').forEach((_rule) => {\n _rule = _rule.replace(/^svg/i, '').trim();\n if (_rule === '') {\n return;\n }\n allRules[_rule] = {\n ...(allRules[_rule] || {}),\n ...ruleObj,\n };\n });\n });\n }\n return allRules;\n}\n","import { Gradient } from '../gradient/Gradient';\nimport { Group } from '../shapes/Group';\nimport { FabricImage } from '../shapes/Image';\nimport { classRegistry } from '../ClassRegistry';\nimport {\n invertTransform,\n multiplyTransformMatrices,\n qrDecompose,\n} from '../util/misc/matrix';\nimport { removeTransformMatrixForSvgParsing } from '../util/transform_matrix_removal';\nimport type { FabricObject } from '../shapes/Object/FabricObject';\nimport { Point } from '../Point';\nimport { CENTER, FILL, STROKE } from '../constants';\nimport { getGradientDefs } from './getGradientDefs';\nimport { getCSSRules } from './getCSSRules';\nimport type { LoadImageOptions } from '../util';\nimport type { CSSRules, TSvgReviverCallback } from './typedefs';\nimport type { ParsedViewboxTransform } from './applyViewboxTransform';\nimport type { SVGOptions } from '../gradient';\nimport { getTagName } from './getTagName';\nimport { parseTransformAttribute } from './parseTransformAttribute';\n\nconst findTag = (el: Element) =>\n classRegistry.getSVGClass(getTagName(el).toLowerCase());\n\ntype StorageType = {\n fill: SVGGradientElement;\n stroke: SVGGradientElement;\n clipPath: Element[];\n};\n\ntype NotParsedFabricObject = FabricObject & {\n fill: string;\n stroke: string;\n clipPath?: string;\n clipRule?: CanvasFillRule;\n};\n\nexport class ElementsParser {\n declare elements: Element[];\n declare options: LoadImageOptions & ParsedViewboxTransform;\n declare reviver?: TSvgReviverCallback;\n declare regexUrl: RegExp;\n declare doc: Document;\n declare clipPaths: Record;\n declare gradientDefs: Record;\n declare cssRules: CSSRules;\n\n constructor(\n elements: Element[],\n options: LoadImageOptions & ParsedViewboxTransform,\n reviver: TSvgReviverCallback | undefined,\n doc: Document,\n clipPaths: Record,\n ) {\n this.elements = elements;\n this.options = options;\n this.reviver = reviver;\n this.regexUrl = /^url\\(['\"]?#([^'\"]+)['\"]?\\)/g;\n this.doc = doc;\n this.clipPaths = clipPaths;\n this.gradientDefs = getGradientDefs(doc);\n this.cssRules = getCSSRules(doc);\n }\n\n parse(): Promise> {\n return Promise.all(\n this.elements.map((element) => this.createObject(element)),\n );\n }\n\n async createObject(el: Element): Promise {\n const klass = findTag(el);\n if (klass) {\n const obj: NotParsedFabricObject = await klass.fromElement(\n el,\n this.options,\n this.cssRules,\n );\n this.resolveGradient(obj, el, FILL);\n this.resolveGradient(obj, el, STROKE);\n if (obj instanceof FabricImage && obj._originalElement) {\n removeTransformMatrixForSvgParsing(\n obj,\n obj.parsePreserveAspectRatioAttribute(),\n );\n } else {\n removeTransformMatrixForSvgParsing(obj);\n }\n await this.resolveClipPath(obj, el);\n this.reviver && this.reviver(el, obj);\n return obj;\n }\n return null;\n }\n\n extractPropertyDefinition(\n obj: NotParsedFabricObject,\n property: 'fill' | 'stroke' | 'clipPath',\n storage: Record,\n ): StorageType[typeof property] | undefined {\n const value = obj[property]!,\n regex = this.regexUrl;\n if (!regex.test(value)) {\n return undefined;\n }\n // verify: can we remove the 'g' flag? and remove lastIndex changes?\n regex.lastIndex = 0;\n // we passed the regex test, so we know is not null;\n const id = regex.exec(value)![1];\n regex.lastIndex = 0;\n // @todo fix this\n return storage[id];\n }\n\n resolveGradient(\n obj: NotParsedFabricObject,\n el: Element,\n property: 'fill' | 'stroke',\n ) {\n const gradientDef = this.extractPropertyDefinition(\n obj,\n property,\n this.gradientDefs,\n ) as SVGGradientElement;\n if (gradientDef) {\n const opacityAttr = el.getAttribute(property + '-opacity');\n const gradient = Gradient.fromElement(gradientDef, obj, {\n ...this.options,\n opacity: opacityAttr,\n } as SVGOptions);\n obj.set(property, gradient);\n }\n }\n\n // TODO: resolveClipPath could be run once per clippath with minor work per object.\n // is a refactor that i m not sure is worth on this code\n async resolveClipPath(obj: NotParsedFabricObject, usingElement: Element) {\n const clipPathElements = this.extractPropertyDefinition(\n obj,\n 'clipPath',\n this.clipPaths,\n ) as Element[];\n if (clipPathElements) {\n const objTransformInv = invertTransform(obj.calcTransformMatrix());\n const clipPathTag = clipPathElements[0].parentElement!;\n let clipPathOwner = usingElement;\n while (\n clipPathOwner.parentElement &&\n clipPathOwner.getAttribute('clip-path') !== obj.clipPath\n ) {\n clipPathOwner = clipPathOwner.parentElement;\n }\n // move the clipPath tag as sibling to the real element that is using it\n clipPathOwner.parentElement!.appendChild(clipPathTag!);\n\n // this multiplication order could be opposite.\n // but i don't have an svg to test it\n // at the first SVG that has a transform on both places and is misplaced\n // try to invert this multiplication order\n const finalTransform = parseTransformAttribute(\n `${clipPathOwner.getAttribute('transform') || ''} ${\n clipPathTag.getAttribute('originalTransform') || ''\n }`,\n );\n\n clipPathTag.setAttribute(\n 'transform',\n `matrix(${finalTransform.join(',')})`,\n );\n\n const container = await Promise.all(\n clipPathElements.map((clipPathElement) => {\n return findTag(clipPathElement)\n .fromElement(clipPathElement, this.options, this.cssRules)\n .then((enlivedClippath: NotParsedFabricObject) => {\n removeTransformMatrixForSvgParsing(enlivedClippath);\n enlivedClippath.fillRule = enlivedClippath.clipRule!;\n delete enlivedClippath.clipRule;\n return enlivedClippath;\n });\n }),\n );\n const clipPath =\n container.length === 1 ? container[0] : new Group(container);\n const gTransform = multiplyTransformMatrices(\n objTransformInv,\n clipPath.calcTransformMatrix(),\n );\n if (clipPath.clipPath) {\n await this.resolveClipPath(clipPath, clipPathOwner);\n }\n const { scaleX, scaleY, angle, skewX, translateX, translateY } =\n qrDecompose(gTransform);\n clipPath.set({\n flipX: false,\n flipY: false,\n });\n clipPath.set({\n scaleX,\n scaleY,\n angle,\n skewX,\n skewY: 0,\n });\n clipPath.setPositionByOrigin(\n new Point(translateX, translateY),\n CENTER,\n CENTER,\n );\n obj.clipPath = clipPath;\n } else {\n // if clip-path does not resolve to any element, delete the property.\n delete obj.clipPath;\n return;\n }\n }\n}\n","import { applyViewboxTransform } from './applyViewboxTransform';\nimport { svgValidTagNamesRegEx } from './constants';\nimport { hasInvalidAncestor } from './hasInvalidAncestor';\nimport { parseUseDirectives } from './parseUseDirectives';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { ElementsParser } from './elements_parser';\nimport { log, SignalAbortedError } from '../util/internals/console';\nimport { getTagName } from './getTagName';\n\nconst isValidSvgTag = (el: Element) =>\n svgValidTagNamesRegEx.test(getTagName(el));\n\nexport const createEmptyResponse = (): SVGParsingOutput => ({\n objects: [],\n elements: [],\n options: {},\n allElements: [],\n});\n\n/**\n * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback\n * @static\n * @function\n * @memberOf fabric\n * @param {HTMLElement} doc SVG document to parse\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @return {SVGParsingOutput}\n * {@link SVGParsingOutput} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n */\nexport async function parseSVGDocument(\n doc: Document,\n reviver?: TSvgReviverCallback,\n { crossOrigin, signal }: LoadImageOptions = {},\n): Promise {\n if (signal && signal.aborted) {\n log('log', new SignalAbortedError('parseSVGDocument'));\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n }\n const documentElement = doc.documentElement;\n parseUseDirectives(doc);\n\n const descendants = Array.from(documentElement.getElementsByTagName('*')),\n options = {\n ...applyViewboxTransform(documentElement),\n crossOrigin,\n signal,\n };\n\n const elements = descendants.filter((el) => {\n applyViewboxTransform(el);\n return isValidSvgTag(el) && !hasInvalidAncestor(el); // http://www.w3.org/TR/SVG/struct.html#DefsElement\n });\n if (!elements || (elements && !elements.length)) {\n return {\n ...createEmptyResponse(),\n options,\n allElements: descendants,\n };\n }\n const localClipPaths: Record = {};\n descendants\n .filter((el) => getTagName(el) === 'clipPath')\n .forEach((el) => {\n el.setAttribute('originalTransform', el.getAttribute('transform') || '');\n const id = el.getAttribute('id')!;\n localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(\n (el) => isValidSvgTag(el),\n );\n });\n\n // Precedence of rules: style > class > attribute\n const elementParser = new ElementsParser(\n elements,\n options,\n reviver,\n doc,\n localClipPaths,\n );\n\n const instances = await elementParser.parse();\n\n return {\n objects: instances,\n elements,\n options,\n allElements: descendants,\n };\n}\n","import { getFabricWindow } from '../env';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\nimport { parseSVGDocument } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\n\n/**\n * Takes string corresponding to an SVG document, and parses it into a set of fabric objects\n * @memberOf fabric\n * @param {String} string representing the svg\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromString(\n string: string,\n reviver?: TSvgReviverCallback,\n options?: LoadImageOptions,\n): Promise {\n const parser = new (getFabricWindow().DOMParser)(),\n // should we use `image/svg+xml` here?\n doc = parser.parseFromString(string.trim(), 'text/xml');\n return parseSVGDocument(doc, reviver, options);\n}\n","import { request } from '../util/internals/dom_request';\nimport { parseSVGDocument, createEmptyResponse } from './parseSVGDocument';\nimport type { SVGParsingOutput, TSvgReviverCallback } from './typedefs';\nimport type { LoadImageOptions } from '../util/misc/objectEnlive';\n\n/**\n * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.\n * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)\n * @memberOf fabric\n * @param {string} url where the SVG is\n * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.\n * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.\n * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )\n * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.\n * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,\n * or extra custom manipulation\n * @param {Object} [options] Object containing options for parsing\n * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources\n * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n */\nexport function loadSVGFromURL(\n url: string,\n reviver?: TSvgReviverCallback,\n options: LoadImageOptions = {},\n): Promise {\n // need to handle error properly\n return new Promise((resolve, reject) => {\n const onComplete = (r: XMLHttpRequest) => {\n const xml = r.responseXML;\n if (xml) {\n resolve(xml);\n }\n reject();\n };\n\n request(url.replace(/^\\n\\s*/, '').trim(), {\n onComplete,\n signal: options.signal,\n });\n })\n .then((parsedDoc) => parseSVGDocument(parsedDoc, reviver, options))\n .catch(() => {\n // this is an unhappy path, we dont care about speed\n return createEmptyResponse();\n });\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Polyline } from '../shapes/Polyline';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n TransformActionHandler,\n} from '../EventTypeDefs';\nimport { wrapWithFireEvent } from './wrapWithFireEvent';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport { MODIFY_POLY } from '../constants';\n\nconst ACTION_NAME: TModificationEvents = MODIFY_POLY;\n\ntype TTransformAnchor = Transform & { pointIndex: number };\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nexport const createPolyPositionHandler = (pointIndex: number) => {\n return function (dim: Point, finalMatrix: TMat2D, polyObject: Polyline) {\n const { points, pathOffset } = polyObject;\n return new Point(points[pointIndex])\n .subtract(pathOffset)\n .transform(\n multiplyTransformMatrices(\n polyObject.getViewportTransform(),\n polyObject.calcTransformMatrix(),\n ),\n );\n };\n};\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nexport const polyActionHandler = (\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) => {\n const { target, pointIndex } = transform;\n const poly = target as Polyline;\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n poly.calcOwnMatrix(),\n );\n\n poly.points[pointIndex] = mouseLocalPosition.add(poly.pathOffset);\n poly.setDimensions();\n\n return true;\n};\n\n/**\n * Keep the polygon in the same position when we change its `width`/`height`/`top`/`left`.\n */\nexport const factoryPolyActionHandler = (\n pointIndex: number,\n fn: TransformActionHandler,\n) => {\n return function (\n eventData: TPointerEvent,\n transform: Transform,\n x: number,\n y: number,\n ) {\n const poly = transform.target as Polyline,\n anchorPoint = new Point(\n poly.points[(pointIndex > 0 ? pointIndex : poly.points.length) - 1],\n ),\n anchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix()),\n actionPerformed = fn(eventData, { ...transform, pointIndex }, x, y);\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(poly.pathOffset)\n .transform(poly.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n poly.left -= diff.x;\n poly.top -= diff.y;\n\n return actionPerformed;\n };\n};\n\nexport const createPolyActionHandler = (pointIndex: number) =>\n wrapWithFireEvent(\n ACTION_NAME,\n factoryPolyActionHandler(pointIndex, polyActionHandler),\n );\n\nexport function createPolyControls(\n poly: Polyline,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n numOfControls: number,\n options?: Partial,\n): Record;\nexport function createPolyControls(\n arg0: number | Polyline,\n options: Partial = {},\n) {\n const controls = {} as Record;\n for (\n let idx = 0;\n idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length);\n idx++\n ) {\n controls[`p${idx}`] = new Control({\n actionName: ACTION_NAME,\n positionHandler: createPolyPositionHandler(idx),\n actionHandler: createPolyActionHandler(idx),\n ...options,\n });\n }\n return controls;\n}\n","import { Point } from '../Point';\nimport { Control } from './Control';\nimport type { TMat2D } from '../typedefs';\nimport type { Path } from '../shapes/Path';\nimport { multiplyTransformMatrices } from '../util/misc/matrix';\nimport type {\n TModificationEvents,\n TPointerEvent,\n Transform,\n} from '../EventTypeDefs';\nimport { sendPointToPlane } from '../util/misc/planeChange';\nimport type { TSimpleParseCommandType } from '../util/path/typedefs';\nimport type { ControlRenderingStyleOverride } from './controlRendering';\nimport { fireEvent } from './fireEvent';\nimport { commonEventInfo } from './util';\n\nconst ACTION_NAME: TModificationEvents = 'modifyPath' as const;\n\ntype TTransformAnchor = Transform;\n\nexport type PathPointControlStyle = {\n controlFill?: string;\n controlStroke?: string;\n connectionDashArray?: number[];\n};\n\nconst calcPathPointPosition = (\n pathObject: Path,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n const command = path[commandIndex];\n return new Point(\n (command[pointIndex] as number) - pathOffset.x,\n (command[pointIndex + 1] as number) - pathOffset.y,\n ).transform(\n multiplyTransformMatrices(\n pathObject.getViewportTransform(),\n pathObject.calcTransformMatrix(),\n ),\n );\n};\n\nconst movePathPoint = (\n pathObject: Path,\n x: number,\n y: number,\n commandIndex: number,\n pointIndex: number,\n) => {\n const { path, pathOffset } = pathObject;\n\n const anchorCommand =\n path[(commandIndex > 0 ? commandIndex : path.length) - 1];\n const anchorPoint = new Point(\n anchorCommand[pointIndex] as number,\n anchorCommand[pointIndex + 1] as number,\n );\n\n const anchorPointInParentPlane = anchorPoint\n .subtract(pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const mouseLocalPosition = sendPointToPlane(\n new Point(x, y),\n undefined,\n pathObject.calcOwnMatrix(),\n );\n\n path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;\n path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;\n pathObject.setDimensions();\n\n const newAnchorPointInParentPlane = anchorPoint\n .subtract(pathObject.pathOffset)\n .transform(pathObject.calcOwnMatrix());\n\n const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);\n pathObject.left -= diff.x;\n pathObject.top -= diff.y;\n pathObject.set('dirty', true);\n return true;\n};\n\n/**\n * This function locates the controls.\n * It'll be used both for drawing and for interaction.\n */\nfunction pathPositionHandler(\n this: PathPointControl,\n dim: Point,\n finalMatrix: TMat2D,\n pathObject: Path,\n) {\n const { commandIndex, pointIndex } = this;\n return calcPathPointPosition(pathObject, commandIndex, pointIndex);\n}\n\n/**\n * This function defines what the control does.\n * It'll be called on every mouse move after a control has been clicked and is being dragged.\n * The function receives as argument the mouse event, the current transform object\n * and the current position in canvas coordinate `transform.target` is a reference to the\n * current object being transformed.\n */\nfunction pathActionHandler(\n this: PathPointControl,\n eventData: TPointerEvent,\n transform: TTransformAnchor,\n x: number,\n y: number,\n) {\n const { target } = transform;\n const { commandIndex, pointIndex } = this;\n const actionPerformed = movePathPoint(\n target as Path,\n x,\n y,\n commandIndex,\n pointIndex,\n );\n if (actionPerformed) {\n fireEvent(this.actionName as TModificationEvents, {\n ...commonEventInfo(eventData, transform, x, y),\n commandIndex,\n pointIndex,\n });\n }\n return actionPerformed;\n}\n\nconst indexFromPrevCommand = (previousCommandType: TSimpleParseCommandType) =>\n previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;\n\nclass PathPointControl extends Control {\n declare commandIndex: number;\n declare pointIndex: number;\n declare controlFill: string;\n declare controlStroke: string;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const overrides: ControlRenderingStyleOverride = {\n ...styleOverride,\n cornerColor: this.controlFill,\n cornerStrokeColor: this.controlStroke,\n transparentCorners: !this.controlFill,\n };\n super.render(ctx, left, top, overrides, fabricObject);\n }\n}\n\nclass PathControlPointControl extends PathPointControl {\n declare connectionDashArray?: number[];\n declare connectToCommandIndex: number;\n declare connectToPointIndex: number;\n constructor(options?: Partial) {\n super(options);\n }\n\n render(\n this: PathControlPointControl,\n ctx: CanvasRenderingContext2D,\n left: number,\n top: number,\n styleOverride: ControlRenderingStyleOverride | undefined,\n fabricObject: Path,\n ) {\n const { path } = fabricObject;\n const {\n commandIndex,\n pointIndex,\n connectToCommandIndex,\n connectToPointIndex,\n } = this;\n ctx.save();\n ctx.strokeStyle = this.controlStroke;\n if (this.connectionDashArray) {\n ctx.setLineDash(this.connectionDashArray);\n }\n const [commandType] = path[commandIndex];\n const point = calcPathPointPosition(\n fabricObject,\n connectToCommandIndex,\n connectToPointIndex,\n );\n\n if (commandType === 'Q') {\n // one control point connects to 2 points\n const point2 = calcPathPointPosition(\n fabricObject,\n commandIndex,\n pointIndex + 2,\n );\n ctx.moveTo(point2.x, point2.y);\n ctx.lineTo(left, top);\n } else {\n ctx.moveTo(left, top);\n }\n ctx.lineTo(point.x, point.y);\n ctx.stroke();\n ctx.restore();\n\n super.render(ctx, left, top, styleOverride, fabricObject);\n }\n}\n\nconst createControl = (\n commandIndexPos: number,\n pointIndexPos: number,\n isControlPoint: boolean,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n },\n connectToCommandIndex?: number,\n connectToPointIndex?: number,\n) =>\n new (isControlPoint ? PathControlPointControl : PathPointControl)({\n commandIndex: commandIndexPos,\n pointIndex: pointIndexPos,\n actionName: ACTION_NAME,\n positionHandler: pathPositionHandler,\n actionHandler: pathActionHandler,\n connectToCommandIndex,\n connectToPointIndex,\n ...options,\n ...(isControlPoint ? options.controlPointStyle : options.pointStyle),\n } as Partial);\n\nexport function createPathControls(\n path: Path,\n options: Partial & {\n controlPointStyle?: PathPointControlStyle;\n pointStyle?: PathPointControlStyle;\n } = {},\n): Record {\n const controls = {} as Record;\n let previousCommandType: TSimpleParseCommandType = 'M';\n path.path.forEach((command, commandIndex) => {\n const commandType = command[0];\n\n if (commandType !== 'Z') {\n controls[`c_${commandIndex}_${commandType}`] = createControl(\n commandIndex,\n command.length - 2,\n false,\n options,\n );\n }\n switch (commandType) {\n case 'C':\n controls[`c_${commandIndex}_C_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex - 1,\n indexFromPrevCommand(previousCommandType),\n );\n controls[`c_${commandIndex}_C_CP_2`] = createControl(\n commandIndex,\n 3,\n true,\n options,\n commandIndex,\n 5,\n );\n break;\n case 'Q':\n controls[`c_${commandIndex}_Q_CP_1`] = createControl(\n commandIndex,\n 1,\n true,\n options,\n commandIndex,\n 3,\n );\n break;\n }\n previousCommandType = commandType;\n });\n return controls;\n}\n","import { getFabricWindow } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { WebGLFilterBackend } from './WebGLFilterBackend';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\n\nexport const isWebGLPipelineState = (\n options: TWebGLPipelineState | T2DPipelineState,\n): options is TWebGLPipelineState => {\n return (options as TWebGLPipelineState).webgl !== undefined;\n};\n\n/**\n * Pick a method to copy data from GL context to 2d canvas. In some browsers using\n * drawImage should be faster, but is also bugged for a small combination of old hardware\n * and drivers.\n * putImageData is faster than drawImage for that specific operation.\n */\nexport const isPutImageFaster = (width: number, height: number): boolean => {\n const targetCanvas = createCanvasElement();\n const sourceCanvas = createCanvasElement();\n const gl = sourceCanvas.getContext('webgl')!;\n // eslint-disable-next-line no-undef\n const imageBuffer = new ArrayBuffer(width * height * 4);\n\n const testContext = {\n imageBuffer: imageBuffer,\n } as unknown as Required;\n const testPipelineState = {\n destinationWidth: width,\n destinationHeight: height,\n targetCanvas: targetCanvas,\n } as unknown as TWebGLPipelineState;\n let startTime;\n targetCanvas.width = width;\n targetCanvas.height = height;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2D.call(\n testContext,\n gl,\n testPipelineState,\n );\n const drawImageTime = getFabricWindow().performance.now() - startTime;\n\n startTime = getFabricWindow().performance.now();\n WebGLFilterBackend.prototype.copyGLTo2DPutImageData.call(\n testContext,\n gl,\n testPipelineState,\n );\n const putImageDataTime = getFabricWindow().performance.now() - startTime;\n\n return drawImageTime > putImageDataTime;\n};\n","export const highPsourceCode = `precision highp float`;\n\nexport const identityFragmentShader = `\n ${highPsourceCode};\n varying vec2 vTexCoord;\n uniform sampler2D uTexture;\n void main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n }`;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n void main() {\n vTexCoord = aPosition;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }`;\n","import { getEnv } from '../env';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type {\n T2DPipelineState,\n TWebGLAttributeLocationMap,\n TWebGLPipelineState,\n TWebGLProgramCacheItem,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport {\n highPsourceCode,\n identityFragmentShader,\n vertexSource,\n} from './shaders/baseFilter';\nimport type { Abortable } from '../typedefs';\nimport { FabricError } from '../util/internals/console';\n\nconst regex = new RegExp(highPsourceCode, 'g');\n\nexport class BaseFilter<\n Name extends string,\n OwnProps extends Record = object,\n> {\n /**\n * Filter type\n * @param {String} type\n * @default\n */\n get type(): Name {\n return (this.constructor as typeof BaseFilter).type as Name;\n }\n\n /**\n * The class type. Used to identify which class this is.\n * This is used for serialization purposes and internally it can be used\n * to identify classes. As a developer you could use `instance of Class`\n * but to avoid importing all the code and blocking tree shaking we try\n * to avoid doing that.\n */\n static type = 'BaseFilter';\n\n /**\n * Contains the uniform locations for the fragment shader.\n * uStepW and uStepH are handled by the BaseFilter, each filter class\n * needs to specify all the one that are needed\n */\n static uniformLocations: string[] = [];\n\n declare static defaults: Record;\n\n /**\n * Constructor\n * @param {Object} [options] Options object\n */\n constructor({\n type,\n ...options\n }: { type?: never } & Partial & Record = {}) {\n Object.assign(\n this,\n (this.constructor as typeof BaseFilter).defaults,\n options,\n );\n }\n\n protected getFragmentSource(): string {\n return identityFragmentShader;\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n /**\n * Compile this filter's shader program.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context to use for shader compilation.\n * @param {String} fragmentSource fragmentShader source for compilation\n * @param {String} vertexSource vertexShader source for compilation\n */\n createProgram(\n gl: WebGLRenderingContext,\n fragmentSource: string = this.getFragmentSource(),\n vertexSource: string = this.getVertexSource(),\n ) {\n const {\n WebGLProbe: { GLPrecision = 'highp' },\n } = getEnv();\n if (GLPrecision !== 'highp') {\n fragmentSource = fragmentSource.replace(\n regex,\n highPsourceCode.replace('highp', GLPrecision),\n );\n }\n const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n const program = gl.createProgram();\n\n if (!vertexShader || !fragmentShader || !program) {\n throw new FabricError(\n 'Vertex, fragment shader or program creation error',\n );\n }\n gl.shaderSource(vertexShader, vertexSource);\n gl.compileShader(vertexShader);\n if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n vertexShader,\n )}`,\n );\n }\n\n gl.shaderSource(fragmentShader, fragmentSource);\n gl.compileShader(fragmentShader);\n if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n throw new FabricError(\n `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n fragmentShader,\n )}`,\n );\n }\n\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new FabricError(\n `Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}`,\n );\n }\n\n const uniformLocations = this.getUniformLocations(gl, program) || {};\n uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n\n return {\n program,\n attributeLocations: this.getAttributeLocations(gl, program),\n uniformLocations,\n };\n }\n\n /**\n * Return a map of attribute names to WebGLAttributeLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.\n * @returns {Object} A map of attribute names to attribute locations.\n */\n getAttributeLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLAttributeLocationMap {\n return {\n aPosition: gl.getAttribLocation(program, 'aPosition'),\n };\n }\n\n /**\n * Return a map of uniform names to WebGLUniformLocation objects.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {WebGLShaderProgram} program The shader program from which to take uniform locations.\n * @returns {Object} A map of uniform names to uniform locations.\n */\n getUniformLocations(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): TWebGLUniformLocationMap {\n const locations = (this.constructor as unknown as typeof BaseFilter)\n .uniformLocations;\n\n const uniformLocations: Record = {};\n for (let i = 0; i < locations.length; i++) {\n uniformLocations[locations[i]] = gl.getUniformLocation(\n program,\n locations[i],\n );\n }\n return uniformLocations;\n }\n\n /**\n * Send attribute data from this filter to its shader program on the GPU.\n *\n * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.\n * @param {Object} attributeLocations A map of shader attribute names to their locations.\n */\n sendAttributeData(\n gl: WebGLRenderingContext,\n attributeLocations: Record,\n aPositionData: Float32Array,\n ) {\n const attributeLocation = attributeLocations.aPosition;\n const buffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.enableVertexAttribArray(attributeLocation);\n gl.vertexAttribPointer(attributeLocation, 2, gl.FLOAT, false, 0, 0);\n gl.bufferData(gl.ARRAY_BUFFER, aPositionData, gl.STATIC_DRAW);\n }\n\n _setupFrameBuffer(options: TWebGLPipelineState) {\n const gl = options.context;\n if (options.passes > 1) {\n const width = options.destinationWidth;\n const height = options.destinationHeight;\n if (options.sourceWidth !== width || options.sourceHeight !== height) {\n gl.deleteTexture(options.targetTexture);\n options.targetTexture = options.filterBackend.createTexture(\n gl,\n width,\n height,\n );\n }\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n options.targetTexture,\n 0,\n );\n } else {\n // draw last filter on canvas and not to framebuffer.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.finish();\n }\n }\n\n _swapTextures(options: TWebGLPipelineState) {\n options.passes--;\n options.pass++;\n const temp = options.targetTexture;\n options.targetTexture = options.sourceTexture;\n options.sourceTexture = temp;\n }\n\n /**\n * Generic isNeutral implementation for one parameter based filters.\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * Other filters may need their own version ( ColorMatrix, HueRotation, gamma, ComposedFilter )\n * @param {Object} options\n **/\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n isNeutralState(options?: any): boolean {\n return false;\n }\n\n /**\n * Apply this filter to the input image data provided.\n *\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n this._setupFrameBuffer(options);\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(_options: T2DPipelineState): void {\n // override by subclass\n }\n\n /**\n * Returns a string that represent the current selected shader code for the filter.\n * Used to force recompilation when parameters change or to retrieve the shader from cache\n * @type string\n **/\n getCacheKey(): string {\n return this.type;\n }\n\n /**\n * Retrieves the cached shader.\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n * @return {WebGLProgram} the compiled program shader\n */\n retrieveShader(options: TWebGLPipelineState): TWebGLProgramCacheItem {\n const key = this.getCacheKey();\n if (!options.programCache[key]) {\n options.programCache[key] = this.createProgram(options.context);\n }\n return options.programCache[key];\n }\n\n /**\n * Apply this filter using webgl.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.originalTexture The texture of the original input image.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context;\n const shader = this.retrieveShader(options);\n if (options.pass === 0 && options.originalTexture) {\n gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);\n } else {\n gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);\n }\n gl.useProgram(shader.program);\n this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);\n\n gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);\n gl.uniform1f(shader.uniformLocations.uStepH, 1 / options.sourceHeight);\n\n this.sendUniformData(gl, shader.uniformLocations);\n gl.viewport(0, 0, options.destinationWidth, options.destinationHeight);\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n }\n\n bindAdditionalTexture(\n gl: WebGLRenderingContext,\n texture: WebGLTexture,\n textureUnit: number,\n ) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, texture);\n // reset active texture to 0 as usual\n gl.activeTexture(gl.TEXTURE0);\n }\n\n unbindAdditionalTexture(gl: WebGLRenderingContext, textureUnit: number) {\n gl.activeTexture(textureUnit);\n gl.bindTexture(gl.TEXTURE_2D, null);\n gl.activeTexture(gl.TEXTURE0);\n }\n\n /**\n * Send uniform data from this filter to its shader program on the GPU.\n *\n * Intended to be overridden by subclasses.\n *\n * @param {WebGLRenderingContext} _gl The canvas context used to compile the shader program.\n * @param {Object} _uniformLocations A map of shader uniform names to their locations.\n */\n sendUniformData(\n _gl: WebGLRenderingContext,\n _uniformLocations: TWebGLUniformLocationMap,\n ): void {\n // override by subclass\n }\n\n /**\n * If needed by a 2d filter, this functions can create an helper canvas to be used\n * remember that options.targetCanvas is available for use till end of chain.\n */\n createHelpLayer(options: T2DPipelineState) {\n if (!options.helpLayer) {\n const helpLayer = createCanvasElement();\n helpLayer.width = options.sourceWidth;\n helpLayer.height = options.sourceHeight;\n options.helpLayer = helpLayer;\n }\n }\n\n /**\n * Returns object representation of an instance\n * It will automatically export the default values of a filter,\n * stored in the static defaults property.\n * @return {Object} Object representation of an instance\n */\n toObject(): { type: Name } & OwnProps {\n const defaultKeys = Object.keys(\n (this.constructor as typeof BaseFilter).defaults || {},\n ) as (keyof OwnProps)[];\n\n return {\n type: this.type,\n ...defaultKeys.reduce((acc, key) => {\n acc[key] = this[\n key as keyof this\n ] as unknown as (typeof acc)[typeof key];\n return acc;\n }, {} as OwnProps),\n };\n }\n\n /**\n * Returns a JSON representation of an instance\n * @return {Object} JSON\n */\n toJSON() {\n // delegate, not alias\n return this.toObject();\n }\n\n static async fromObject(\n { type, ...filterOptions }: Record,\n _options: Abortable,\n ): Promise> {\n return new this(filterOptions);\n }\n}\n","export const blendColorFragmentSource = {\n multiply: 'gl_FragColor.rgb *= uColor.rgb;\\n',\n screen:\n 'gl_FragColor.rgb = 1.0 - (1.0 - gl_FragColor.rgb) * (1.0 - uColor.rgb);\\n',\n add: 'gl_FragColor.rgb += uColor.rgb;\\n',\n difference: 'gl_FragColor.rgb = abs(gl_FragColor.rgb - uColor.rgb);\\n',\n subtract: 'gl_FragColor.rgb -= uColor.rgb;\\n',\n lighten: 'gl_FragColor.rgb = max(gl_FragColor.rgb, uColor.rgb);\\n',\n darken: 'gl_FragColor.rgb = min(gl_FragColor.rgb, uColor.rgb);\\n',\n exclusion:\n 'gl_FragColor.rgb += uColor.rgb - 2.0 * (uColor.rgb * gl_FragColor.rgb);\\n',\n overlay: `\n if (uColor.r < 0.5) {\n gl_FragColor.r *= 2.0 * uColor.r;\n } else {\n gl_FragColor.r = 1.0 - 2.0 * (1.0 - gl_FragColor.r) * (1.0 - uColor.r);\n }\n if (uColor.g < 0.5) {\n gl_FragColor.g *= 2.0 * uColor.g;\n } else {\n gl_FragColor.g = 1.0 - 2.0 * (1.0 - gl_FragColor.g) * (1.0 - uColor.g);\n }\n if (uColor.b < 0.5) {\n gl_FragColor.b *= 2.0 * uColor.b;\n } else {\n gl_FragColor.b = 1.0 - 2.0 * (1.0 - gl_FragColor.b) * (1.0 - uColor.b);\n }\n `,\n tint: `\n gl_FragColor.rgb *= (1.0 - uColor.a);\n gl_FragColor.rgb += uColor.rgb;\n `,\n} as const;\n","import { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { blendColorFragmentSource } from './shaders/blendColor';\n\nexport type TBlendMode =\n | 'multiply'\n | 'add'\n | 'difference'\n | 'screen'\n | 'subtract'\n | 'darken'\n | 'lighten'\n | 'overlay'\n | 'exclusion'\n | 'tint';\n\ntype BlendColorOwnProps = {\n color: string;\n mode: TBlendMode;\n alpha: number;\n};\n\nexport const blendColorDefaultValues: BlendColorOwnProps = {\n color: '#F95C63',\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Color Blend filter class\n * @example\n * const filter = new BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendColor extends BaseFilter<'BlendColor', BlendColorOwnProps> {\n /**\n * Color to make the blend operation with. default to a reddish color since black or white\n * gives always strong result.\n * @type String\n * @default\n **/\n declare color: BlendColorOwnProps['color'];\n\n /**\n * Blend mode for the filter: one of multiply, add, difference, screen, subtract,\n * darken, lighten, overlay, exclusion, tint.\n * @type String\n * @default\n **/\n declare mode: BlendColorOwnProps['mode'];\n /**\n * alpha value. represent the strength of the blend color operation.\n * @type Number\n * @default\n **/\n declare alpha: BlendColorOwnProps['alpha'];\n\n static defaults = blendColorDefaultValues;\n\n static type = 'BlendColor';\n\n static uniformLocations = ['uColor'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n protected getFragmentSource(): string {\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n gl_FragColor = color;\n if (color.a > 0.0) {\n ${blendColorFragmentSource[this.mode]}\n }\n }\n `;\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const source = new Color(this.color).getSource();\n const tr = source[0] * this.alpha;\n const tg = source[1] * this.alpha;\n const tb = source[2] * this.alpha;\n const alpha1 = 1 - this.alpha;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n break;\n case 'screen':\n data[i] = 255 - ((255 - r) * (255 - tr)) / 255;\n data[i + 1] = 255 - ((255 - g) * (255 - tg)) / 255;\n data[i + 2] = 255 - ((255 - b) * (255 - tb)) / 255;\n break;\n case 'add':\n data[i] = r + tr;\n data[i + 1] = g + tg;\n data[i + 2] = b + tb;\n break;\n case 'difference':\n data[i] = Math.abs(r - tr);\n data[i + 1] = Math.abs(g - tg);\n data[i + 2] = Math.abs(b - tb);\n break;\n case 'subtract':\n data[i] = r - tr;\n data[i + 1] = g - tg;\n data[i + 2] = b - tb;\n break;\n case 'darken':\n data[i] = Math.min(r, tr);\n data[i + 1] = Math.min(g, tg);\n data[i + 2] = Math.min(b, tb);\n break;\n case 'lighten':\n data[i] = Math.max(r, tr);\n data[i + 1] = Math.max(g, tg);\n data[i + 2] = Math.max(b, tb);\n break;\n case 'overlay':\n data[i] =\n tr < 128\n ? (2 * r * tr) / 255\n : 255 - (2 * (255 - r) * (255 - tr)) / 255;\n data[i + 1] =\n tg < 128\n ? (2 * g * tg) / 255\n : 255 - (2 * (255 - g) * (255 - tg)) / 255;\n data[i + 2] =\n tb < 128\n ? (2 * b * tb) / 255\n : 255 - (2 * (255 - b) * (255 - tb)) / 255;\n break;\n case 'exclusion':\n data[i] = tr + r - (2 * tr * r) / 255;\n data[i + 1] = tg + g - (2 * tg * g) / 255;\n data[i + 2] = tb + b - (2 * tb * b) / 255;\n break;\n case 'tint':\n data[i] = tr + r * alpha1;\n data[i + 1] = tg + g * alpha1;\n data[i + 2] = tb + b * alpha1;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource();\n source[0] = (this.alpha * source[0]) / 255;\n source[1] = (this.alpha * source[1]) / 255;\n source[2] = (this.alpha * source[2]) / 255;\n source[3] = this.alpha;\n gl.uniform4fv(uniformLocations.uColor, source);\n }\n}\n\nclassRegistry.setClass(BlendColor);\n","import type { TBlendImageMode } from '../BlendImage';\n\nexport const fragmentSource: Record = {\n multiply: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.rgba *= color2.rgba;\n gl_FragColor = color;\n }\n `,\n mask: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform sampler2D uImage;\n uniform vec4 uColor;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec4 color2 = texture2D(uImage, vTexCoord2);\n color.a = color2.a;\n gl_FragColor = color;\n }\n `,\n} as const;\n\nexport const vertexSource = `\n attribute vec2 aPosition;\n varying vec2 vTexCoord;\n varying vec2 vTexCoord2;\n uniform mat3 uTransformMatrix;\n void main() {\n vTexCoord = aPosition;\n vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n }\n ` as const;\n","import { FabricImage } from '../shapes/Image';\nimport { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport type { WebGLFilterBackend } from './WebGLFilterBackend';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource, vertexSource } from './shaders/blendImage';\n\nexport type TBlendImageMode = 'multiply' | 'mask';\n\ntype BlendImageOwnProps = {\n mode: TBlendImageMode;\n alpha: number;\n};\n\nexport const blendImageDefaultValues: BlendImageOwnProps = {\n mode: 'multiply',\n alpha: 1,\n};\n\n/**\n * Image Blend filter class\n * @example\n * const filter = new filters.BlendColor({\n * color: '#000',\n * mode: 'multiply'\n * });\n *\n * const filter = new BlendImage({\n * image: fabricImageObject,\n * mode: 'multiply'\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class BlendImage extends BaseFilter<'BlendImage', BlendImageOwnProps> {\n /**\n * Image to make the blend operation with.\n **/\n declare image: FabricImage;\n\n /**\n * Blend mode for the filter: either 'multiply' or 'mask'. 'multiply' will\n * multiply the values of each channel (R, G, B, and A) of the filter image by\n * their corresponding values in the base image. 'mask' will only look at the\n * alpha channel of the filter image, and apply those values to the base\n * image's alpha channel.\n * @type String\n * @default\n **/\n declare mode: BlendImageOwnProps['mode'];\n\n /**\n * alpha value. represent the strength of the blend image operation.\n * not implemented.\n **/\n declare alpha: BlendImageOwnProps['alpha'];\n\n static type = 'BlendImage';\n\n static defaults = blendImageDefaultValues;\n\n static uniformLocations = ['uTransformMatrix', 'uImage'];\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource(): string {\n return fragmentSource[this.mode];\n }\n\n getVertexSource(): string {\n return vertexSource;\n }\n\n applyToWebGL(options: TWebGLPipelineState) {\n const gl = options.context,\n texture = this.createTexture(options.filterBackend, this.image);\n this.bindAdditionalTexture(gl, texture!, gl.TEXTURE1);\n super.applyToWebGL(options);\n this.unbindAdditionalTexture(gl, gl.TEXTURE1);\n }\n\n createTexture(backend: WebGLFilterBackend, image: FabricImage) {\n return backend.getCachedTexture(image.cacheKey, image.getElement());\n }\n\n /**\n * Calculate a transformMatrix to adapt the image to blend over\n * @param {Object} options\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n calculateMatrix() {\n const image = this.image,\n { width, height } = image.getElement();\n return [\n 1 / image.scaleX,\n 0,\n 0,\n 0,\n 1 / image.scaleY,\n 0,\n -image.left / width,\n -image.top / height,\n 1,\n ];\n }\n\n /**\n * Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({\n imageData: { data, width, height },\n filterBackend: { resources },\n }: T2DPipelineState) {\n const image = this.image;\n if (!resources.blendImage) {\n resources.blendImage = createCanvasElement();\n }\n const canvas1 = resources.blendImage;\n const context = canvas1.getContext('2d')!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas1.width = width;\n canvas1.height = height;\n } else {\n context.clearRect(0, 0, width, height);\n }\n context.setTransform(\n image.scaleX,\n 0,\n 0,\n image.scaleY,\n image.left,\n image.top,\n );\n context.drawImage(image.getElement(), 0, 0, width, height);\n const blendData = context.getImageData(0, 0, width, height).data;\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n const a = data[i + 3];\n\n const tr = blendData[i];\n const tg = blendData[i + 1];\n const tb = blendData[i + 2];\n const ta = blendData[i + 3];\n\n switch (this.mode) {\n case 'multiply':\n data[i] = (r * tr) / 255;\n data[i + 1] = (g * tg) / 255;\n data[i + 2] = (b * tb) / 255;\n data[i + 3] = (a * ta) / 255;\n break;\n case 'mask':\n data[i + 3] = ta;\n break;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const matrix = this.calculateMatrix();\n gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.\n gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);\n }\n\n /**\n * Returns object representation of an instance\n * TODO: Handle the possibility of missing image better.\n * As of now a BlendImage filter without image can't be used with fromObject\n * @return {Object} Object representation of an instance\n */\n toObject(): {\n type: 'BlendImage';\n image: ReturnType;\n } & BlendImageOwnProps {\n return {\n ...super.toObject(),\n image: this.image && this.image.toObject(),\n };\n }\n\n /**\n * Create filter instance from an object representation\n * @static\n * @param {object} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting image loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static async fromObject(\n { type, image, ...filterOptions }: Record,\n options: { signal: AbortSignal },\n ): Promise> {\n return FabricImage.fromObject(image, options).then(\n (enlivedImage) =>\n new this({ ...filterOptions, image: enlivedImage }) as BlendImage,\n );\n }\n}\n\nclassRegistry.setClass(BlendImage);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n const float nSamples = 15.0;\n vec3 v3offset = vec3(12.9898, 78.233, 151.7182);\n float random(vec3 scale) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz, scale)) * 43758.5453);\n }\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n float offset = random(v3offset);\n for (float t = -nSamples; t <= nSamples; t++) {\n float percent = (t + offset - 0.5) / nSamples;\n float weight = 1.0 - abs(percent);\n color += texture2D(uTexture, vTexCoord + uDelta * percent) * weight;\n total += weight;\n }\n gl_FragColor = color / total;\n }\n ` as const;\n","import { createCanvasElement } from '../util/misc/dom';\nimport { BaseFilter } from './BaseFilter';\nimport type {\n TWebGLPipelineState,\n T2DPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/blur';\n\ntype BlurOwnProps = {\n blur: number;\n};\n\nexport const blurDefaultValues: BlurOwnProps = {\n blur: 0,\n};\n\n/**\n * Blur filter class\n * @example\n * const filter = new Blur({\n * blur: 0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Blur extends BaseFilter<'Blur', BlurOwnProps> {\n /**\n * blur value, in percentage of image dimensions.\n * specific to keep the image blur constant at different resolutions\n * range between 0 and 1.\n * @type Number\n * @default\n */\n declare blur: BlurOwnProps['blur'];\n\n declare horizontal: boolean;\n declare aspectRatio: number;\n\n static type = 'Blur';\n\n static defaults = blurDefaultValues;\n\n static uniformLocations = ['uDelta'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n // this aspectRatio is used to give the same blur to vertical and horizontal\n this.aspectRatio = options.sourceWidth / options.sourceHeight;\n options.passes++;\n this._setupFrameBuffer(options);\n this.horizontal = true;\n this.applyToWebGL(options);\n this._swapTextures(options);\n this._setupFrameBuffer(options);\n this.horizontal = false;\n this.applyToWebGL(options);\n this._swapTextures(options);\n } else {\n this.applyTo2d(options);\n }\n }\n\n applyTo2d(options: T2DPipelineState) {\n options.imageData = this.simpleBlur(options);\n }\n\n simpleBlur({\n ctx,\n imageData,\n filterBackend: { resources },\n }: T2DPipelineState) {\n const { width, height } = imageData;\n if (!resources.blurLayer1) {\n resources.blurLayer1 = createCanvasElement();\n resources.blurLayer2 = createCanvasElement();\n }\n const canvas1 = resources.blurLayer1!;\n const canvas2 = resources.blurLayer2!;\n if (canvas1.width !== width || canvas1.height !== height) {\n canvas2.width = canvas1.width = width;\n canvas2.height = canvas1.height = height;\n }\n const ctx1 = canvas1.getContext('2d')!,\n ctx2 = canvas2.getContext('2d')!,\n nSamples = 15,\n blur = this.blur * 0.06 * 0.5;\n let random, percent, j, i;\n\n // load first canvas\n ctx1.putImageData(imageData, 0, 0);\n ctx2.clearRect(0, 0, width, height);\n\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * width + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, j, random);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n for (i = -nSamples; i <= nSamples; i++) {\n random = (Math.random() - 0.5) / 4;\n percent = i / nSamples;\n j = blur * percent * height + random;\n ctx2.globalAlpha = 1 - Math.abs(percent);\n ctx2.drawImage(canvas1, random, j);\n ctx1.drawImage(canvas2, 0, 0);\n ctx2.globalAlpha = 1;\n ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n }\n ctx.drawImage(canvas1, 0, 0);\n const newImageData = ctx.getImageData(0, 0, canvas1.width, canvas1.height);\n ctx1.globalAlpha = 1;\n ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n return newImageData;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const delta = this.chooseRightDelta();\n gl.uniform2fv(uniformLocations.uDelta, delta);\n }\n\n isNeutralState() {\n return this.blur === 0;\n }\n\n /**\n * choose right value of image percentage to blur with\n * @returns {Array} a numeric array with delta values\n */\n chooseRightDelta() {\n let blurScale = 1;\n const delta = [0, 0];\n if (this.horizontal) {\n if (this.aspectRatio > 1) {\n // image is wide, i want to shrink radius horizontal\n blurScale = 1 / this.aspectRatio;\n }\n } else {\n if (this.aspectRatio < 1) {\n // image is tall, i want to shrink radius vertical\n blurScale = this.aspectRatio;\n }\n }\n const blur = blurScale * this.blur * 0.12;\n if (this.horizontal) {\n delta[0] = blur;\n } else {\n delta[1] = blur;\n }\n return delta;\n }\n}\n\nclassRegistry.setClass(Blur);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBrightness;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += uBrightness;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/brightness';\n\ntype BrightnessOwnProps = {\n brightness: number;\n};\n\nexport const brightnessDefaultValues: BrightnessOwnProps = {\n brightness: 0,\n};\n\n/**\n * Brightness filter class\n * @example\n * const filter = new Brightness({\n * brightness: 0.05\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Brightness extends BaseFilter<'Brightness', BrightnessOwnProps> {\n /**\n * Brightness value, from -1 to 1.\n * translated to -255 to 255 for 2d\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Number} brightness\n * @default\n */\n declare brightness: BrightnessOwnProps['brightness'];\n\n static type = 'Brightness';\n\n static defaults = brightnessDefaultValues;\n\n static uniformLocations = ['uBrightness'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const brightness = Math.round(this.brightness * 255);\n for (let i = 0; i < data.length; i += 4) {\n data[i] = data[i] + brightness;\n data[i + 1] = data[i + 1] + brightness;\n data[i + 2] = data[i + 2] + brightness;\n }\n }\n\n isNeutralState() {\n return this.brightness === 0;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBrightness, this.brightness);\n }\n}\n\nclassRegistry.setClass(Brightness);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n uniform mat4 uColorMatrix;\n uniform vec4 uConstants;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color *= uColorMatrix;\n color += uConstants;\n gl_FragColor = color;\n }`;\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TMatColorMatrix,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/colorMatrix';\n\ntype ColorMatrixOwnProps = {\n matrix: TMatColorMatrix;\n colorsOnly: boolean;\n};\n\nexport const colorMatrixDefaultValues: ColorMatrixOwnProps = {\n matrix: [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0],\n colorsOnly: true,\n};\n\n/**\n * Color Matrix filter class\n * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}\n * @see {@Link http://phoboslab.org/log/2013/11/fast-image-filters-with-webgl demo}\n * @example Kodachrome filter\n * const filter = new ColorMatrix({\n * matrix: [\n 1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502,\n -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203,\n -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946,\n 0, 0, 0, 1, 0\n ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class ColorMatrix<\n Name extends string = 'ColorMatrix',\n OwnProps extends object = ColorMatrixOwnProps,\n> extends BaseFilter {\n /**\n * Colormatrix for pixels.\n * array of 20 floats. Numbers in positions 4, 9, 14, 19 loose meaning\n * outside the -1, 1 range.\n * 0.0039215686 is the part of 1 that get translated to 1 in 2d\n * @param {Array} matrix array of 20 numbers.\n * @default\n */\n declare matrix: ColorMatrixOwnProps['matrix'];\n\n /**\n * Lock the colormatrix on the color part, skipping alpha, mainly for non webgl scenario\n * to save some calculation\n * @type Boolean\n * @default true\n */\n declare colorsOnly: ColorMatrixOwnProps['colorsOnly'];\n\n static type = 'ColorMatrix';\n\n static defaults = colorMatrixDefaultValues;\n\n static uniformLocations = ['uColorMatrix', 'uConstants'];\n\n getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Apply the ColorMatrix operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n m = this.matrix,\n colorsOnly = this.colorsOnly;\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n if (colorsOnly) {\n data[i] = r * m[0] + g * m[1] + b * m[2] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + m[9] * 255;\n data[i + 2] = r * m[10] + g * m[11] + b * m[12] + m[14] * 255;\n } else {\n const a = data[i + 3];\n data[i] = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4] * 255;\n data[i + 1] = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9] * 255;\n data[i + 2] =\n r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14] * 255;\n data[i + 3] =\n r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19] * 255;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const m = this.matrix,\n matrix = [\n m[0],\n m[1],\n m[2],\n m[3],\n m[5],\n m[6],\n m[7],\n m[8],\n m[10],\n m[11],\n m[12],\n m[13],\n m[15],\n m[16],\n m[17],\n m[18],\n ],\n constants = [m[4], m[9], m[14], m[19]];\n gl.uniformMatrix4fv(uniformLocations.uColorMatrix, false, matrix);\n gl.uniform4fv(uniformLocations.uConstants, constants);\n }\n\n toObject() {\n return {\n ...super.toObject(),\n matrix: [...this.matrix] as TMatColorMatrix,\n };\n }\n}\n\nclassRegistry.setClass(ColorMatrix);\n","import { ColorMatrix } from './ColorMatrix';\nimport { classRegistry } from '../ClassRegistry';\nimport type { TMatColorMatrix } from './typedefs';\n\ntype FixedFiltersOwnProps = {\n colorsOnly: boolean;\n};\n\nexport function createColorMatrixFilter(key: string, matrix: TMatColorMatrix) {\n const newClass = class extends ColorMatrix {\n static type = key;\n\n static defaults = {\n colorsOnly: false,\n matrix,\n };\n\n //@ts-expect-error TS wants matrix to be exported.\n toObject(): { type: string } & FixedFiltersOwnProps {\n return { type: this.type, colorsOnly: this.colorsOnly };\n }\n };\n classRegistry.setClass(newClass, key);\n return newClass as typeof ColorMatrix;\n}\n\nexport const Brownie = createColorMatrixFilter(\n 'Brownie',\n [\n 0.5997, 0.34553, -0.27082, 0, 0.186, -0.0377, 0.86095, 0.15059, 0, -0.1449,\n 0.24113, -0.07441, 0.44972, 0, -0.02965, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Vintage = createColorMatrixFilter(\n 'Vintage',\n [\n 0.62793, 0.32021, -0.03965, 0, 0.03784, 0.02578, 0.64411, 0.03259, 0,\n 0.02926, 0.0466, -0.08512, 0.52416, 0, 0.02023, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Kodachrome = createColorMatrixFilter(\n 'Kodachrome',\n [\n 1.12855, -0.39673, -0.03992, 0, 0.24991, -0.16404, 1.08352, -0.05498, 0,\n 0.09698, -0.16786, -0.56034, 1.60148, 0, 0.13972, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Technicolor = createColorMatrixFilter(\n 'Technicolor',\n [\n 1.91252, -0.85453, -0.09155, 0, 0.04624, -0.30878, 1.76589, -0.10601, 0,\n -0.27589, -0.2311, -0.75018, 1.84759, 0, 0.12137, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Polaroid = createColorMatrixFilter(\n 'Polaroid',\n [\n 1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016,\n 1.483, 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const Sepia = createColorMatrixFilter(\n 'Sepia',\n [\n 0.393, 0.769, 0.189, 0, 0, 0.349, 0.686, 0.168, 0, 0, 0.272, 0.534, 0.131,\n 0, 0, 0, 0, 0, 1, 0,\n ],\n);\n\nexport const BlackWhite = createColorMatrixFilter(\n 'BlackWhite',\n [\n 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 1.5, 1.5, 1.5, 0, -1, 0, 0, 0,\n 1, 0,\n ],\n);\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLPipelineState } from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\n\ntype ComposedOwnProps = {\n subFilters: BaseFilter[];\n};\n\n/**\n * A container class that knows how to apply a sequence of filters to an input image.\n */\nexport class Composed extends BaseFilter<'Composed', ComposedOwnProps> {\n /**\n * A non sparse array of filters to apply\n */\n declare subFilters: ComposedOwnProps['subFilters'];\n\n static type = 'Composed';\n\n constructor(\n options: { subFilters?: BaseFilter[] } & Record<\n string,\n any\n > = {},\n ) {\n super(options);\n this.subFilters = options.subFilters || [];\n }\n\n /**\n * Apply this container's filters to the input image provided.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be applied.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n options.passes += this.subFilters.length - 1;\n }\n this.subFilters.forEach((filter) => {\n filter.applyTo(options);\n });\n }\n\n /**\n * Serialize this filter into JSON.\n * @returns {Object} A JSON representation of this filter.\n */\n //@ts-expect-error TS doesn't like this toObject\n toObject(): {\n type: 'Composed';\n subFilters: ReturnType['toObject']>[];\n } {\n return {\n type: this.type,\n subFilters: this.subFilters.map((filter) => filter.toObject()),\n };\n }\n\n isNeutralState() {\n return !this.subFilters.some((filter) => !filter.isNeutralState());\n }\n\n /**\n * Deserialize a JSON definition of a ComposedFilter into a concrete instance.\n * @static\n * @param {oject} object Object to create an instance from\n * @param {object} [options]\n * @param {AbortSignal} [options.signal] handle aborting `BlendImage` filter loading, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal\n * @returns {Promise}\n */\n static fromObject(\n object: Record,\n options: { signal: AbortSignal },\n ): Promise {\n return Promise.all(\n ((object.subFilters || []) as BaseFilter[]).map(\n (filter) =>\n classRegistry\n .getClass(filter.type)\n .fromObject(filter, options),\n ),\n ).then(\n (enlivedFilters) => new this({ subFilters: enlivedFilters }) as Composed,\n );\n }\n}\n\nclassRegistry.setClass(Composed);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uContrast;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float contrastF = 1.015 * (uContrast + 1.0) / (1.0 * (1.015 - uContrast));\n color.rgb = contrastF * (color.rgb - 0.5) + 0.5;\n gl_FragColor = color;\n }`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/constrast';\n\ntype ContrastOwnProps = {\n contrast: number;\n};\n\nexport const contrastDefaultValues: ContrastOwnProps = {\n contrast: 0,\n};\n\n/**\n * Contrast filter class\n * @example\n * const filter = new Contrast({\n * contrast: 0.25\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Contrast extends BaseFilter<'Contrast', ContrastOwnProps> {\n /**\n * contrast value, range from -1 to 1.\n * @param {Number} contrast\n * @default 0\n */\n declare contrast: ContrastOwnProps['contrast'];\n\n static type = 'Contrast';\n\n static defaults = contrastDefaultValues;\n\n static uniformLocations = ['uContrast'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n isNeutralState() {\n return this.contrast === 0;\n }\n\n /**\n * Apply the Contrast operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const contrast = Math.floor(this.contrast * 255),\n contrastF = (259 * (contrast + 255)) / (255 * (259 - contrast));\n\n for (let i = 0; i < data.length; i += 4) {\n data[i] = contrastF * (data[i] - 128) + 128;\n data[i + 1] = contrastF * (data[i + 1] - 128) + 128;\n data[i + 2] = contrastF * (data[i + 2] - 128) + 128;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uContrast, this.contrast);\n }\n}\n\nclassRegistry.setClass(Contrast);\n","export const fragmentSource = {\n Convolute_3_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1), uStepH * (h - 1));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 3.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_3_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[9];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 3.0; h+=1.0) {\n for (float w = 0.0; w < 3.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 1.0), uStepH * (h - 1.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 3.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_5_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 5.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_5_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[25];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 5.0; h+=1.0) {\n for (float w = 0.0; w < 5.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 2.0), uStepH * (h - 2.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 5.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_7_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 7.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_7_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[49];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 7.0; h+=1.0) {\n for (float w = 0.0; w < 7.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 3.0), uStepH * (h - 3.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 7.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n Convolute_9_1: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 0);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color += texture2D(uTexture, vTexCoord + matrixPos) * uMatrix[int(h * 9.0 + w)];\n }\n }\n gl_FragColor = color;\n }\n `,\n Convolute_9_0: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uMatrix[81];\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = vec4(0, 0, 0, 1);\n for (float h = 0.0; h < 9.0; h+=1.0) {\n for (float w = 0.0; w < 9.0; w+=1.0) {\n vec2 matrixPos = vec2(uStepW * (w - 4.0), uStepH * (h - 4.0));\n color.rgb += texture2D(uTexture, vTexCoord + matrixPos).rgb * uMatrix[int(h * 9.0 + w)];\n }\n }\n float alpha = texture2D(uTexture, vTexCoord).a;\n gl_FragColor = color;\n gl_FragColor.a = alpha;\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/convolute';\n\nexport type ConvoluteOwnProps = {\n opaque: boolean;\n matrix: number[];\n};\n\nexport const convoluteDefaultValues: ConvoluteOwnProps = {\n opaque: false,\n matrix: [0, 0, 0, 0, 1, 0, 0, 0, 0],\n};\n\n/**\n * Adapted from html5rocks article\n * @example Sharpen filter\n * const filter = new Convolute({\n * matrix: [ 0, -1, 0,\n * -1, 5, -1,\n * 0, -1, 0 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Blur filter\n * const filter = new Convolute({\n * matrix: [ 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9,\n * 1/9, 1/9, 1/9 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter\n * const filter = new Convolute({\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n * @example Emboss filter with opaqueness\n * const filter = new Convolute({\n * opaque: true,\n * matrix: [ 1, 1, 1,\n * 1, 0.7, -1,\n * -1, -1, -1 ]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Convolute extends BaseFilter<'Convolute', ConvoluteOwnProps> {\n /*\n * Opaque value (true/false)\n */\n declare opaque: ConvoluteOwnProps['opaque'];\n\n /*\n * matrix for the filter, max 9x9\n */\n declare matrix: ConvoluteOwnProps['matrix'];\n\n static type = 'Convolute';\n\n static defaults = convoluteDefaultValues;\n\n static uniformLocations = ['uMatrix', 'uOpaque', 'uHalfSize', 'uSize'];\n\n getCacheKey() {\n return `${this.type}_${Math.sqrt(this.matrix.length)}_${\n this.opaque ? 1 : 0\n }` as keyof typeof fragmentSource;\n }\n\n getFragmentSource() {\n return fragmentSource[this.getCacheKey()];\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d(options: T2DPipelineState) {\n const imageData = options.imageData,\n data = imageData.data,\n weights = this.matrix,\n side = Math.round(Math.sqrt(weights.length)),\n halfSide = Math.floor(side / 2),\n sw = imageData.width,\n sh = imageData.height,\n output = options.ctx.createImageData(sw, sh),\n dst = output.data,\n // go through the destination image pixels\n alphaFac = this.opaque ? 1 : 0;\n let r, g, b, a, dstOff, scx, scy, srcOff, wt, x, y, cx, cy;\n\n for (y = 0; y < sh; y++) {\n for (x = 0; x < sw; x++) {\n dstOff = (y * sw + x) * 4;\n // calculate the weighed sum of the source image pixels that\n // fall under the convolution matrix\n r = 0;\n g = 0;\n b = 0;\n a = 0;\n\n for (cy = 0; cy < side; cy++) {\n for (cx = 0; cx < side; cx++) {\n scy = y + cy - halfSide;\n scx = x + cx - halfSide;\n\n // eslint-disable-next-line max-depth\n if (scy < 0 || scy >= sh || scx < 0 || scx >= sw) {\n continue;\n }\n\n srcOff = (scy * sw + scx) * 4;\n wt = weights[cy * side + cx];\n\n r += data[srcOff] * wt;\n g += data[srcOff + 1] * wt;\n b += data[srcOff + 2] * wt;\n // eslint-disable-next-line max-depth\n if (!alphaFac) {\n a += data[srcOff + 3] * wt;\n }\n }\n }\n dst[dstOff] = r;\n dst[dstOff + 1] = g;\n dst[dstOff + 2] = b;\n if (!alphaFac) {\n dst[dstOff + 3] = a;\n } else {\n dst[dstOff + 3] = data[dstOff + 3];\n }\n }\n }\n options.imageData = output;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1fv(uniformLocations.uMatrix, this.matrix);\n }\n\n /**\n * Returns object representation of an instance\n * @return {Object} Object representation of an instance\n */\n toObject() {\n return {\n ...super.toObject(),\n opaque: this.opaque,\n matrix: [...this.matrix],\n };\n }\n}\n\nclassRegistry.setClass(Convolute);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec3 uGamma;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n vec3 correction = (1.0 / uGamma);\n color.r = pow(color.r, correction.r);\n color.g = pow(color.g, correction.g);\n color.b = pow(color.b, correction.b);\n gl_FragColor = color;\n gl_FragColor.rgb *= color.a;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/gamma';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nconst GAMMA = 'Gamma' as const;\n\nexport type GammaInput = [number, number, number];\n\nexport type GammaOwnProps = {\n gamma: GammaInput;\n};\n\nexport const gammaDefaultValues: GammaOwnProps = {\n gamma: [1, 1, 1],\n};\n\n/**\n * Gamma filter class\n * @example\n * const filter = new Gamma({\n * gamma: [1, 0.5, 2.1]\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Gamma extends BaseFilter {\n /**\n * Gamma array value, from 0.01 to 2.2.\n * @param {Array} gamma\n * @default\n */\n declare gamma: GammaOwnProps['gamma'];\n declare rgbValues?: {\n r: Uint8Array;\n g: Uint8Array;\n b: Uint8Array;\n };\n\n static type = GAMMA;\n\n static defaults = gammaDefaultValues;\n\n static uniformLocations = ['uGamma'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n constructor(options: { gamma?: GammaInput } = {}) {\n super(options);\n this.gamma =\n options.gamma ||\n ((\n this.constructor as typeof Gamma\n ).defaults.gamma.concat() as GammaInput);\n }\n\n /**\n * Apply the Gamma operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const gamma = this.gamma,\n rInv = 1 / gamma[0],\n gInv = 1 / gamma[1],\n bInv = 1 / gamma[2];\n\n if (!this.rgbValues) {\n this.rgbValues = {\n r: new Uint8Array(256),\n g: new Uint8Array(256),\n b: new Uint8Array(256),\n };\n }\n\n // This is an optimization - pre-compute a look-up table for each color channel\n // instead of performing these pow calls for each pixel in the image.\n const rgb = this.rgbValues;\n for (let i = 0; i < 256; i++) {\n rgb.r[i] = Math.pow(i / 255, rInv) * 255;\n rgb.g[i] = Math.pow(i / 255, gInv) * 255;\n rgb.b[i] = Math.pow(i / 255, bInv) * 255;\n }\n for (let i = 0; i < data.length; i += 4) {\n data[i] = rgb.r[data[i]];\n data[i + 1] = rgb.g[data[i + 1]];\n data[i + 2] = rgb.b[data[i + 2]];\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform3fv(uniformLocations.uGamma, this.gamma);\n }\n\n isNeutralState() {\n const { gamma } = this;\n return gamma[0] === 1 && gamma[1] === 1 && gamma[2] === 1;\n }\n\n toObject(): { type: typeof GAMMA; gamma: GammaInput } {\n return {\n type: GAMMA,\n gamma: this.gamma.concat() as GammaInput,\n };\n }\n}\n\nclassRegistry.setClass(Gamma);\n","import type { TGrayscaleMode } from '../Grayscale';\n\nexport const fragmentSource: Record = {\n average: `\n precision highp float;\n uniform sampler2D uTexture;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float average = (color.r + color.b + color.g) / 3.0;\n gl_FragColor = vec4(average, average, average, color.a);\n }\n `,\n lightness: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = (max(max(col.r, col.g),col.b) + min(min(col.r, col.g),col.b)) / 2.0;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n luminosity: `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uMode;\n varying vec2 vTexCoord;\n void main() {\n vec4 col = texture2D(uTexture, vTexCoord);\n float average = 0.21 * col.r + 0.72 * col.g + 0.07 * col.b;\n gl_FragColor = vec4(average, average, average, col.a);\n }\n `,\n};\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/grayscale';\n\nexport type TGrayscaleMode = 'average' | 'lightness' | 'luminosity';\n\ntype GrayscaleOwnProps = {\n mode: TGrayscaleMode;\n};\n\nexport const grayscaleDefaultValues: GrayscaleOwnProps = {\n mode: 'average',\n};\n\n/**\n * Grayscale image filter class\n * @example\n * const filter = new Grayscale();\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Grayscale extends BaseFilter<'Grayscale', GrayscaleOwnProps> {\n declare mode: TGrayscaleMode;\n\n static type = 'Grayscale';\n\n static defaults = grayscaleDefaultValues;\n\n static uniformLocations = ['uMode'];\n\n /**\n * Apply the Grayscale operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0, value: number; i < data.length; i += 4) {\n switch (this.mode) {\n case 'average':\n value = (data[i] + data[i + 1] + data[i + 2]) / 3;\n break;\n case 'lightness':\n value =\n (Math.min(data[i], data[i + 1], data[i + 2]) +\n Math.max(data[i], data[i + 1], data[i + 2])) /\n 2;\n break;\n case 'luminosity':\n value = 0.21 * data[i] + 0.72 * data[i + 1] + 0.07 * data[i + 2];\n break;\n }\n\n data[i] = value;\n data[i + 1] = value;\n data[i + 2] = value;\n }\n }\n\n getCacheKey() {\n return `${this.type}_${this.mode}`;\n }\n\n getFragmentSource() {\n return fragmentSource[this.mode];\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const mode = 1;\n gl.uniform1i(uniformLocations.uMode, mode);\n }\n\n /**\n * Grayscale filter isNeutralState implementation\n * The filter is never neutral\n * on the image\n **/\n isNeutralState() {\n return false;\n }\n}\n\nclassRegistry.setClass(Grayscale);\n","import { cos } from '../util/misc/cos';\nimport { sin } from '../util/misc/sin';\nimport { ColorMatrix } from './ColorMatrix';\nimport type { TWebGLPipelineState, T2DPipelineState } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\n\nexport type HueRotationOwnProps = {\n rotation: number;\n};\n\nexport const hueRotationDefaultValues: HueRotationOwnProps = {\n rotation: 0,\n};\n\n/**\n * HueRotation filter class\n * @example\n * const filter = new HueRotation({\n * rotation: -0.5\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class HueRotation extends ColorMatrix<\n 'HueRotation',\n HueRotationOwnProps\n> {\n /**\n * HueRotation value, from -1 to 1.\n */\n declare rotation: HueRotationOwnProps['rotation'];\n\n static type = 'HueRotation';\n\n static defaults = hueRotationDefaultValues;\n\n calculateMatrix() {\n const rad = this.rotation * Math.PI,\n cosine = cos(rad),\n sine = sin(rad),\n aThird = 1 / 3,\n aThirdSqtSin = Math.sqrt(aThird) * sine,\n OneMinusCos = 1 - cosine;\n this.matrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];\n this.matrix[0] = cosine + OneMinusCos / 3;\n this.matrix[1] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[2] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[5] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[6] = cosine + aThird * OneMinusCos;\n this.matrix[7] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[10] = aThird * OneMinusCos - aThirdSqtSin;\n this.matrix[11] = aThird * OneMinusCos + aThirdSqtSin;\n this.matrix[12] = cosine + aThird * OneMinusCos;\n }\n\n isNeutralState() {\n return this.rotation === 0;\n }\n\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n this.calculateMatrix();\n super.applyTo(options);\n }\n\n //@ts-expect-error TS and classes with different methods\n toObject(): { type: 'HueRotation'; rotation: number } {\n return {\n type: this.type,\n rotation: this.rotation,\n };\n }\n}\n\nclassRegistry.setClass(HueRotation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform int uInvert;\n uniform int uAlpha;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n if (uInvert == 1) {\n if (uAlpha == 1) {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,1.0 -color.a);\n } else {\n gl_FragColor = vec4(1.0 - color.r,1.0 -color.g,1.0 -color.b,color.a);\n }\n } else {\n gl_FragColor = color;\n }\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/invert';\n\nexport type InvertOwnProps = {\n alpha: boolean;\n invert: boolean;\n};\n\nexport const invertDefaultValues: InvertOwnProps = {\n alpha: false,\n invert: true,\n};\n\n/**\n * @example\n * const filter = new Invert();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Invert extends BaseFilter<'Invert', InvertOwnProps> {\n /**\n * Invert also alpha.\n * @param {Boolean} alpha\n * @default\n **/\n declare alpha: InvertOwnProps['alpha'];\n\n /**\n * Filter invert. if false, does nothing\n * @param {Boolean} invert\n * @default\n */\n declare invert: InvertOwnProps['invert'];\n\n static type = 'Invert';\n\n static defaults = invertDefaultValues;\n\n static uniformLocations = ['uInvert', 'uAlpha'];\n\n /**\n * Apply the Invert operation to a Uint8Array representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8Array to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n for (let i = 0; i < data.length; i += 4) {\n data[i] = 255 - data[i];\n data[i + 1] = 255 - data[i + 1];\n data[i + 2] = 255 - data[i + 2];\n\n if (this.alpha) {\n data[i + 3] = 255 - data[i + 3];\n }\n }\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Invert filter isNeutralState implementation\n * Used only in image applyFilters to discard filters that will not have an effect\n * on the image\n * @param {Object} options\n **/\n isNeutralState() {\n return !this.invert;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1i(uniformLocations.uInvert, Number(this.invert));\n gl.uniform1i(uniformLocations.uAlpha, Number(this.alpha));\n }\n}\n\nclassRegistry.setClass(Invert);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uStepH;\n uniform float uNoise;\n uniform float uSeed;\n varying vec2 vTexCoord;\n float rand(vec2 co, float seed, float vScale) {\n return fract(sin(dot(co.xy * vScale ,vec2(12.9898 , 78.233))) * 43758.5453 * (seed + 0.01) / 2.0);\n }\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n color.rgb += (0.5 - rand(vTexCoord, uSeed, 0.1 / uStepH)) * uNoise;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/noise';\n\nexport type NoiseOwnProps = {\n noise: number;\n};\n\nexport const noiseDefaultValues: NoiseOwnProps = {\n noise: 0,\n};\n\n/**\n * Noise filter class\n * @example\n * const filter = new Noise({\n * noise: 700\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class Noise extends BaseFilter<'Noise', NoiseOwnProps> {\n /**\n * Noise value, from\n * @param {Number} noise\n * @default\n */\n declare noise: NoiseOwnProps['noise'];\n\n static type = 'Noise';\n\n static defaults = noiseDefaultValues;\n\n static uniformLocations = ['uNoise', 'uSeed'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Brightness operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const noise = this.noise;\n for (let i = 0; i < data.length; i += 4) {\n const rand = (0.5 - Math.random()) * noise;\n data[i] += rand;\n data[i + 1] += rand;\n data[i + 2] += rand;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uNoise, this.noise / 255);\n gl.uniform1f(uniformLocations.uSeed, Math.random());\n }\n\n isNeutralState() {\n return this.noise === 0;\n }\n}\n\nclassRegistry.setClass(Noise);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uBlocksize;\n uniform float uStepW;\n uniform float uStepH;\n varying vec2 vTexCoord;\n void main() {\n float blockW = uBlocksize * uStepW;\n float blockH = uBlocksize * uStepH;\n int posX = int(vTexCoord.x / blockW);\n int posY = int(vTexCoord.y / blockH);\n float fposX = float(posX);\n float fposY = float(posY);\n vec2 squareCoords = vec2(fposX * blockW, fposY * blockH);\n vec4 color = texture2D(uTexture, squareCoords);\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/pixelate';\n\nexport type PixelateOwnProps = {\n blocksize: number;\n};\n\nexport const pixelateDefaultValues: PixelateOwnProps = {\n blocksize: 4,\n};\n\n/**\n * Pixelate filter class\n * @example\n * const filter = new Pixelate({\n * blocksize: 8\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Pixelate extends BaseFilter<'Pixelate', PixelateOwnProps> {\n declare blocksize: PixelateOwnProps['blocksize'];\n\n static type = 'Pixelate';\n\n static defaults = pixelateDefaultValues;\n\n static uniformLocations = ['uBlocksize'];\n\n /**\n * Apply the Pixelate operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data, width, height } }: T2DPipelineState) {\n for (let i = 0; i < height; i += this.blocksize) {\n for (let j = 0; j < width; j += this.blocksize) {\n const index = i * 4 * width + j * 4;\n const r = data[index];\n const g = data[index + 1];\n const b = data[index + 2];\n const a = data[index + 3];\n\n for (let _i = i; _i < Math.min(i + this.blocksize, height); _i++) {\n for (let _j = j; _j < Math.min(j + this.blocksize, width); _j++) {\n const index = _i * 4 * width + _j * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = a;\n }\n }\n }\n }\n }\n\n /**\n * Indicate when the filter is not gonna apply changes to the image\n **/\n isNeutralState() {\n return this.blocksize === 1;\n }\n\n protected getFragmentSource(): string {\n return fragmentSource;\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uBlocksize, this.blocksize);\n }\n}\n\nclassRegistry.setClass(Pixelate);\n","export const fragmentShader = `\nprecision highp float;\nuniform sampler2D uTexture;\nuniform vec4 uLow;\nuniform vec4 uHigh;\nvarying vec2 vTexCoord;\nvoid main() {\n gl_FragColor = texture2D(uTexture, vTexCoord);\n if(all(greaterThan(gl_FragColor.rgb,uLow.rgb)) && all(greaterThan(uHigh.rgb,gl_FragColor.rgb))) {\n gl_FragColor.a = 0.0;\n }\n}\n`;\n","import { classRegistry } from '../ClassRegistry';\nimport { Color } from '../color/Color';\nimport { BaseFilter } from './BaseFilter';\nimport { fragmentShader } from './shaders/removeColor';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\n\nexport type RemoveColorOwnProps = {\n color: string;\n distance: number;\n useAlpha: boolean;\n};\n\nexport const removeColorDefaultValues: RemoveColorOwnProps = {\n color: '#FFFFFF',\n distance: 0.02,\n useAlpha: false,\n};\n\n/**\n * Remove white filter class\n * @example\n * const filter = new RemoveColor({\n * threshold: 0.2,\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n * canvas.renderAll();\n */\nexport class RemoveColor extends BaseFilter<\n 'RemoveColor',\n RemoveColorOwnProps\n> {\n /**\n * Color to remove, in any format understood by {@link Color}.\n * @param {String} type\n * @default\n */\n declare color: RemoveColorOwnProps['color'];\n\n /**\n * distance to actual color, as value up or down from each r,g,b\n * between 0 and 1\n **/\n declare distance: RemoveColorOwnProps['distance'];\n\n /**\n * For color to remove inside distance, use alpha channel for a smoother deletion\n * NOT IMPLEMENTED YET\n **/\n declare useAlpha: RemoveColorOwnProps['useAlpha'];\n\n static type = 'RemoveColor';\n\n static defaults = removeColorDefaultValues;\n\n static uniformLocations = ['uLow', 'uHigh'];\n\n getFragmentSource() {\n return fragmentShader;\n }\n\n /**\n * Applies filter to canvas element\n * @param {Object} canvasEl Canvas element to apply filter to\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const distance = this.distance * 255,\n source = new Color(this.color).getSource(),\n lowC = [source[0] - distance, source[1] - distance, source[2] - distance],\n highC = [\n source[0] + distance,\n source[1] + distance,\n source[2] + distance,\n ];\n\n for (let i = 0; i < data.length; i += 4) {\n const r = data[i];\n const g = data[i + 1];\n const b = data[i + 2];\n\n if (\n r > lowC[0] &&\n g > lowC[1] &&\n b > lowC[2] &&\n r < highC[0] &&\n g < highC[1] &&\n b < highC[2]\n ) {\n data[i + 3] = 0;\n }\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n const source = new Color(this.color).getSource(),\n distance = this.distance,\n lowC = [\n 0 + source[0] / 255 - distance,\n 0 + source[1] / 255 - distance,\n 0 + source[2] / 255 - distance,\n 1,\n ],\n highC = [\n source[0] / 255 + distance,\n source[1] / 255 + distance,\n source[2] / 255 + distance,\n 1,\n ];\n gl.uniform4fv(uniformLocations.uLow, lowC);\n gl.uniform4fv(uniformLocations.uHigh, highC);\n }\n}\n\nclassRegistry.setClass(RemoveColor);\n","import { BaseFilter } from './BaseFilter';\nimport type {\n T2DPipelineState,\n TWebGLPipelineState,\n TWebGLUniformLocationMap,\n} from './typedefs';\nimport { isWebGLPipelineState } from './utils';\nimport { classRegistry } from '../ClassRegistry';\nimport { createCanvasElement } from '../util/misc/dom';\nimport type { XY } from '../Point';\n\nexport type TResizeType = 'bilinear' | 'hermite' | 'sliceHack' | 'lanczos';\n\nexport type ResizeOwnProps = {\n resizeType: TResizeType;\n scaleX: number;\n scaleY: number;\n lanczosLobes: number;\n};\n\nexport const resizeDefaultValues: ResizeOwnProps = {\n resizeType: 'hermite',\n scaleX: 1,\n scaleY: 1,\n lanczosLobes: 3,\n};\n\ntype ResizeDuring2DResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n};\n\ntype ResizeDuringWEBGLResize = Resize & {\n rcpScaleX: number;\n rcpScaleY: number;\n horizontal: boolean;\n width: number;\n height: number;\n taps: number[];\n tempScale: number;\n dH: number;\n dW: number;\n};\n\n/**\n * Resize image filter class\n * @example\n * const filter = new Resize();\n * object.filters.push(filter);\n * object.applyFilters(canvas.renderAll.bind(canvas));\n */\nexport class Resize extends BaseFilter<'Resize', ResizeOwnProps> {\n /**\n * Resize type\n * for webgl resizeType is just lanczos, for canvas2d can be:\n * bilinear, hermite, sliceHack, lanczos.\n * @default\n */\n declare resizeType: ResizeOwnProps['resizeType'];\n\n /**\n * Scale factor for resizing, x axis\n * @param {Number} scaleX\n * @default\n */\n declare scaleX: ResizeOwnProps['scaleX'];\n\n /**\n * Scale factor for resizing, y axis\n * @param {Number} scaleY\n * @default\n */\n declare scaleY: ResizeOwnProps['scaleY'];\n\n /**\n * LanczosLobes parameter for lanczos filter, valid for resizeType lanczos\n * @param {Number} lanczosLobes\n * @default\n */\n declare lanczosLobes: ResizeOwnProps['lanczosLobes'];\n\n static type = 'Resize';\n\n static defaults = resizeDefaultValues;\n\n static uniformLocations = ['uDelta', 'uTaps'];\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n this: ResizeDuringWEBGLResize,\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform2fv(\n uniformLocations.uDelta,\n this.horizontal ? [1 / this.width, 0] : [0, 1 / this.height],\n );\n gl.uniform1fv(uniformLocations.uTaps, this.taps);\n }\n\n getFilterWindow(this: ResizeDuringWEBGLResize) {\n const scale = this.tempScale;\n return Math.ceil(this.lanczosLobes / scale);\n }\n\n getCacheKey(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return `${this.type}_${filterWindow}`;\n }\n\n getFragmentSource(this: ResizeDuringWEBGLResize): string {\n const filterWindow = this.getFilterWindow();\n return this.generateShader(filterWindow);\n }\n\n getTaps(this: ResizeDuringWEBGLResize) {\n const lobeFunction = this.lanczosCreate(this.lanczosLobes),\n scale = this.tempScale,\n filterWindow = this.getFilterWindow(),\n taps = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n taps[i - 1] = lobeFunction(i * scale);\n }\n return taps;\n }\n\n /**\n * Generate vertex and shader sources from the necessary steps numbers\n * @param {Number} filterWindow\n */\n generateShader(filterWindow: number) {\n const offsets = new Array(filterWindow);\n for (let i = 1; i <= filterWindow; i++) {\n offsets[i - 1] = `${i}.0 * uDelta`;\n }\n return `\n precision highp float;\n uniform sampler2D uTexture;\n uniform vec2 uDelta;\n varying vec2 vTexCoord;\n uniform float uTaps[${filterWindow}];\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float sum = 1.0;\n ${offsets\n .map(\n (offset, i) => `\n color += texture2D(uTexture, vTexCoord + ${offset}) * uTaps[${i}] + texture2D(uTexture, vTexCoord - ${offset}) * uTaps[${i}];\n sum += 2.0 * uTaps[${i}];\n `,\n )\n .join('\\n')}\n gl_FragColor = color / sum;\n }\n `;\n }\n\n applyToForWebgl(this: ResizeDuringWEBGLResize, options: TWebGLPipelineState) {\n options.passes++;\n this.width = options.sourceWidth;\n this.horizontal = true;\n this.dW = Math.round(this.width * this.scaleX);\n this.dH = options.sourceHeight;\n this.tempScale = this.dW / this.width;\n this.taps = this.getTaps();\n options.destinationWidth = this.dW;\n super.applyTo(options);\n options.sourceWidth = options.destinationWidth;\n\n this.height = options.sourceHeight;\n this.horizontal = false;\n this.dH = Math.round(this.height * this.scaleY);\n this.tempScale = this.dH / this.height;\n this.taps = this.getTaps();\n options.destinationHeight = this.dH;\n super.applyTo(options);\n options.sourceHeight = options.destinationHeight;\n }\n\n /**\n * Apply the resize filter to the image\n * Determines whether to use WebGL or Canvas2D based on the options.webgl flag.\n *\n * @param {Object} options\n * @param {Number} options.passes The number of filters remaining to be executed\n * @param {Boolean} options.webgl Whether to use webgl to render the filter.\n * @param {WebGLTexture} options.sourceTexture The texture setup as the source to be filtered.\n * @param {WebGLTexture} options.targetTexture The texture where filtered output should be drawn.\n * @param {WebGLRenderingContext} options.context The GL context used for rendering.\n * @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.\n */\n applyTo(options: TWebGLPipelineState | T2DPipelineState) {\n if (isWebGLPipelineState(options)) {\n (this as unknown as ResizeDuringWEBGLResize).applyToForWebgl(options);\n } else {\n (this as unknown as ResizeDuring2DResize).applyTo2d(options);\n }\n }\n\n isNeutralState() {\n return this.scaleX === 1 && this.scaleY === 1;\n }\n\n lanczosCreate(lobes: number) {\n return (x: number) => {\n if (x >= lobes || x <= -lobes) {\n return 0.0;\n }\n if (x < 1.1920929e-7 && x > -1.1920929e-7) {\n return 1.0;\n }\n x *= Math.PI;\n const xx = x / lobes;\n return ((Math.sin(x) / x) * Math.sin(xx)) / xx;\n };\n }\n\n applyTo2d(this: ResizeDuring2DResize, options: T2DPipelineState) {\n const imageData = options.imageData,\n scaleX = this.scaleX,\n scaleY = this.scaleY;\n\n this.rcpScaleX = 1 / scaleX;\n this.rcpScaleY = 1 / scaleY;\n\n const oW = imageData.width;\n const oH = imageData.height;\n const dW = Math.round(oW * scaleX);\n const dH = Math.round(oH * scaleY);\n let newData: ImageData;\n\n if (this.resizeType === 'sliceHack') {\n newData = this.sliceByTwo(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'hermite') {\n newData = this.hermiteFastResize(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'bilinear') {\n newData = this.bilinearFiltering(options, oW, oH, dW, dH);\n } else if (this.resizeType === 'lanczos') {\n newData = this.lanczosResize(options, oW, oH, dW, dH);\n } else {\n // this should never trigger, is here just for safety net.\n newData = new ImageData(dW, dH);\n }\n options.imageData = newData;\n }\n\n /**\n * Filter sliceByTwo\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n sliceByTwo(\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const imageData = options.imageData;\n const mult = 0.5;\n let doneW = false;\n let doneH = false;\n let stepW = oW * mult;\n let stepH = oH * mult;\n const resources = options.filterBackend.resources;\n let sX = 0;\n let sY = 0;\n const dX = oW;\n let dY = 0;\n if (!resources.sliceByTwo) {\n resources.sliceByTwo = createCanvasElement();\n }\n const tmpCanvas = resources.sliceByTwo;\n if (tmpCanvas.width < oW * 1.5 || tmpCanvas.height < oH) {\n tmpCanvas.width = oW * 1.5;\n tmpCanvas.height = oH;\n }\n const ctx = tmpCanvas.getContext('2d')!;\n ctx.clearRect(0, 0, oW * 1.5, oH);\n ctx.putImageData(imageData, 0, 0);\n\n dW = Math.floor(dW);\n dH = Math.floor(dH);\n\n while (!doneW || !doneH) {\n oW = stepW;\n oH = stepH;\n if (dW < Math.floor(stepW * mult)) {\n stepW = Math.floor(stepW * mult);\n } else {\n stepW = dW;\n doneW = true;\n }\n if (dH < Math.floor(stepH * mult)) {\n stepH = Math.floor(stepH * mult);\n } else {\n stepH = dH;\n doneH = true;\n }\n ctx.drawImage(tmpCanvas, sX, sY, oW, oH, dX, dY, stepW, stepH);\n sX = dX;\n sY = dY;\n dY += stepH;\n }\n return ctx.getImageData(sX, sY, dW, dH);\n }\n\n /**\n * Filter lanczosResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n lanczosResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ): ImageData {\n function process(u: number): ImageData {\n let v, i, weight, idx, a, red, green, blue, alpha, fX, fY;\n center.x = (u + 0.5) * ratioX;\n icenter.x = Math.floor(center.x);\n for (v = 0; v < dH; v++) {\n center.y = (v + 0.5) * ratioY;\n icenter.y = Math.floor(center.y);\n a = 0;\n red = 0;\n green = 0;\n blue = 0;\n alpha = 0;\n for (i = icenter.x - range2X; i <= icenter.x + range2X; i++) {\n if (i < 0 || i >= oW) {\n continue;\n }\n fX = Math.floor(1000 * Math.abs(i - center.x));\n if (!cacheLanc[fX]) {\n cacheLanc[fX] = {};\n }\n for (let j = icenter.y - range2Y; j <= icenter.y + range2Y; j++) {\n if (j < 0 || j >= oH) {\n continue;\n }\n fY = Math.floor(1000 * Math.abs(j - center.y));\n if (!cacheLanc[fX][fY]) {\n cacheLanc[fX][fY] = lanczos(\n Math.sqrt(\n Math.pow(fX * rcpRatioX, 2) + Math.pow(fY * rcpRatioY, 2),\n ) / 1000,\n );\n }\n weight = cacheLanc[fX][fY];\n if (weight > 0) {\n idx = (j * oW + i) * 4;\n a += weight;\n red += weight * srcData[idx];\n green += weight * srcData[idx + 1];\n blue += weight * srcData[idx + 2];\n alpha += weight * srcData[idx + 3];\n }\n }\n }\n idx = (v * dW + u) * 4;\n destData[idx] = red / a;\n destData[idx + 1] = green / a;\n destData[idx + 2] = blue / a;\n destData[idx + 3] = alpha / a;\n }\n\n if (++u < dW) {\n return process(u);\n } else {\n return destImg;\n }\n }\n\n const srcData = options.imageData.data,\n destImg = options.ctx.createImageData(dW, dH),\n destData = destImg.data,\n lanczos = this.lanczosCreate(this.lanczosLobes),\n ratioX = this.rcpScaleX,\n ratioY = this.rcpScaleY,\n rcpRatioX = 2 / this.rcpScaleX,\n rcpRatioY = 2 / this.rcpScaleY,\n range2X = Math.ceil((ratioX * this.lanczosLobes) / 2),\n range2Y = Math.ceil((ratioY * this.lanczosLobes) / 2),\n cacheLanc: Record> = {},\n center: XY = { x: 0, y: 0 },\n icenter: XY = { x: 0, y: 0 };\n\n return process(0);\n }\n\n /**\n * bilinearFiltering\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n bilinearFiltering(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n let a;\n let b;\n let c;\n let d;\n let x;\n let y;\n let i;\n let j;\n let xDiff;\n let yDiff;\n let chnl;\n let color;\n let offset = 0;\n let origPix;\n const ratioX = this.rcpScaleX;\n const ratioY = this.rcpScaleY;\n const w4 = 4 * (oW - 1);\n const img = options.imageData;\n const pixels = img.data;\n const destImage = options.ctx.createImageData(dW, dH);\n const destPixels = destImage.data;\n for (i = 0; i < dH; i++) {\n for (j = 0; j < dW; j++) {\n x = Math.floor(ratioX * j);\n y = Math.floor(ratioY * i);\n xDiff = ratioX * j - x;\n yDiff = ratioY * i - y;\n origPix = 4 * (y * oW + x);\n\n for (chnl = 0; chnl < 4; chnl++) {\n a = pixels[origPix + chnl];\n b = pixels[origPix + 4 + chnl];\n c = pixels[origPix + w4 + chnl];\n d = pixels[origPix + w4 + 4 + chnl];\n color =\n a * (1 - xDiff) * (1 - yDiff) +\n b * xDiff * (1 - yDiff) +\n c * yDiff * (1 - xDiff) +\n d * xDiff * yDiff;\n destPixels[offset++] = color;\n }\n }\n }\n return destImage;\n }\n\n /**\n * hermiteFastResize\n * @param {Object} canvasEl Canvas element to apply filter to\n * @param {Number} oW Original Width\n * @param {Number} oH Original Height\n * @param {Number} dW Destination Width\n * @param {Number} dH Destination Height\n * @returns {ImageData}\n */\n hermiteFastResize(\n this: ResizeDuring2DResize,\n options: T2DPipelineState,\n oW: number,\n oH: number,\n dW: number,\n dH: number,\n ) {\n const ratioW = this.rcpScaleX,\n ratioH = this.rcpScaleY,\n ratioWHalf = Math.ceil(ratioW / 2),\n ratioHHalf = Math.ceil(ratioH / 2),\n img = options.imageData,\n data = img.data,\n img2 = options.ctx.createImageData(dW, dH),\n data2 = img2.data;\n for (let j = 0; j < dH; j++) {\n for (let i = 0; i < dW; i++) {\n const x2 = (i + j * dW) * 4;\n let weight = 0;\n let weights = 0;\n let weightsAlpha = 0;\n let gxR = 0;\n let gxG = 0;\n let gxB = 0;\n let gxA = 0;\n const centerY = (j + 0.5) * ratioH;\n for (let yy = Math.floor(j * ratioH); yy < (j + 1) * ratioH; yy++) {\n const dy = Math.abs(centerY - (yy + 0.5)) / ratioHHalf,\n centerX = (i + 0.5) * ratioW,\n w0 = dy * dy;\n for (let xx = Math.floor(i * ratioW); xx < (i + 1) * ratioW; xx++) {\n let dx = Math.abs(centerX - (xx + 0.5)) / ratioWHalf;\n const w = Math.sqrt(w0 + dx * dx);\n /* eslint-disable max-depth */\n if (w > 1 && w < -1) {\n continue;\n }\n //hermite filter\n weight = 2 * w * w * w - 3 * w * w + 1;\n if (weight > 0) {\n dx = 4 * (xx + yy * oW);\n //alpha\n gxA += weight * data[dx + 3];\n weightsAlpha += weight;\n //colors\n if (data[dx + 3] < 255) {\n weight = (weight * data[dx + 3]) / 250;\n }\n gxR += weight * data[dx];\n gxG += weight * data[dx + 1];\n gxB += weight * data[dx + 2];\n weights += weight;\n }\n /* eslint-enable max-depth */\n }\n }\n data2[x2] = gxR / weights;\n data2[x2 + 1] = gxG / weights;\n data2[x2 + 2] = gxB / weights;\n data2[x2 + 3] = gxA / weightsAlpha;\n }\n }\n return img2;\n }\n}\n\nclassRegistry.setClass(Resize);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uSaturation;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float rgMax = max(color.r, color.g);\n float rgbMax = max(rgMax, color.b);\n color.r += rgbMax != color.r ? (rgbMax - color.r) * uSaturation : 0.00;\n color.g += rgbMax != color.g ? (rgbMax - color.g) * uSaturation : 0.00;\n color.b += rgbMax != color.b ? (rgbMax - color.b) * uSaturation : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/saturation';\n\nexport type SaturationOwnProps = {\n saturation: number;\n};\n\nexport const saturationDefaultValues: SaturationOwnProps = {\n saturation: 0,\n};\n\n/**\n * Saturate filter class\n * @example\n * const filter = new Saturation({\n * saturation: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Saturation extends BaseFilter<'Saturation', SaturationOwnProps> {\n /**\n * Saturation value, from -1 to 1.\n * Increases/decreases the color saturation.\n * A value of 0 has no effect.\n *\n * @param {Number} saturation\n * @default\n */\n declare saturation: SaturationOwnProps['saturation'];\n\n static type = 'Saturation';\n\n static defaults = saturationDefaultValues;\n\n static uniformLocations = ['uSaturation'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Saturation operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.saturation;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n data[i] += max !== data[i] ? (max - data[i]) * adjust : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * adjust : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * adjust : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uSaturation, -this.saturation);\n }\n\n isNeutralState() {\n return this.saturation === 0;\n }\n}\n\nclassRegistry.setClass(Saturation);\n","export const fragmentSource = `\n precision highp float;\n uniform sampler2D uTexture;\n uniform float uVibrance;\n varying vec2 vTexCoord;\n void main() {\n vec4 color = texture2D(uTexture, vTexCoord);\n float max = max(color.r, max(color.g, color.b));\n float avg = (color.r + color.g + color.b) / 3.0;\n float amt = (abs(max - avg) * 2.0) * uVibrance;\n color.r += max != color.r ? (max - color.r) * amt : 0.00;\n color.g += max != color.g ? (max - color.g) * amt : 0.00;\n color.b += max != color.b ? (max - color.b) * amt : 0.00;\n gl_FragColor = color;\n }\n`;\n","import { BaseFilter } from './BaseFilter';\nimport type { T2DPipelineState, TWebGLUniformLocationMap } from './typedefs';\nimport { classRegistry } from '../ClassRegistry';\nimport { fragmentSource } from './shaders/vibrance';\n\nexport type VibranceOwnProps = {\n vibrance: number;\n};\n\nexport const vibranceDefaultValues: VibranceOwnProps = {\n vibrance: 0,\n};\n\n/**\n * Vibrance filter class\n * @example\n * const filter = new Vibrance({\n * vibrance: 1\n * });\n * object.filters.push(filter);\n * object.applyFilters();\n */\nexport class Vibrance extends BaseFilter<'Vibrance', VibranceOwnProps> {\n /**\n * Vibrance value, from -1 to 1.\n * Increases/decreases the saturation of more muted colors with less effect on saturated colors.\n * A value of 0 has no effect.\n *\n * @param {Number} vibrance\n * @default\n */\n declare vibrance: VibranceOwnProps['vibrance'];\n\n static type = 'Vibrance';\n\n static defaults = vibranceDefaultValues;\n\n static uniformLocations = ['uVibrance'];\n\n getFragmentSource() {\n return fragmentSource;\n }\n\n /**\n * Apply the Vibrance operation to a Uint8ClampedArray representing the pixels of an image.\n *\n * @param {Object} options\n * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.\n */\n applyTo2d({ imageData: { data } }: T2DPipelineState) {\n const adjust = -this.vibrance;\n for (let i = 0; i < data.length; i += 4) {\n const max = Math.max(data[i], data[i + 1], data[i + 2]);\n const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;\n const amt = ((Math.abs(max - avg) * 2) / 255) * adjust;\n data[i] += max !== data[i] ? (max - data[i]) * amt : 0;\n data[i + 1] += max !== data[i + 1] ? (max - data[i + 1]) * amt : 0;\n data[i + 2] += max !== data[i + 2] ? (max - data[i + 2]) * amt : 0;\n }\n }\n\n /**\n * Send data from this filter to its shader program's uniforms.\n *\n * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.\n * @param {TWebGLUniformLocationMap} uniformLocations A map of string uniform names to WebGLUniformLocation objects\n */\n sendUniformData(\n gl: WebGLRenderingContext,\n uniformLocations: TWebGLUniformLocationMap,\n ) {\n gl.uniform1f(uniformLocations.uVibrance, -this.vibrance);\n }\n\n isNeutralState() {\n return this.vibrance === 0;\n }\n}\n\nclassRegistry.setClass(Vibrance);\n","// First we set the env variable\n\nimport { setEnv } from './src/env';\nimport { getEnv, getNodeCanvas } from './src/env/node';\n\nsetEnv(getEnv());\n\n// After the env is set we can export everything and expose specific node functionality\n\nimport type { JpegConfig, PngConfig } from 'canvas';\nimport {\n Canvas as CanvasBase,\n StaticCanvas as StaticCanvasBase,\n} from './fabric';\nimport { FabricObject } from './src/shapes/Object/Object';\n\nFabricObject.ownDefaults.objectCaching = false;\n\nexport * from './fabric';\n\nexport class StaticCanvas extends StaticCanvasBase {\n getNodeCanvas() {\n return getNodeCanvas(this.getElement());\n }\n createPNGStream(opts?: PngConfig) {\n return this.getNodeCanvas().createPNGStream(opts);\n }\n createJPEGStream(opts?: JpegConfig) {\n return this.getNodeCanvas().createJPEGStream(opts);\n }\n}\n\n/**\n * **NOTICE**:\n * {@link Canvas} is designed for interactivity.\n * Therefore, using it in node has no benefit.\n * Use {@link StaticCanvas} instead.\n */\nexport class Canvas extends CanvasBase {\n getNodeCanvas() {\n return getNodeCanvas(this.getElement());\n }\n createPNGStream(opts?: PngConfig) {\n return this.getNodeCanvas().createPNGStream(opts);\n }\n createJPEGStream(opts?: JpegConfig) {\n return this.getNodeCanvas().createJPEGStream(opts);\n }\n}\n"],"names":["BaseConfiguration","constructor","_defineProperty","window","devicePixelRatio","Configuration","config","configure","arguments","length","undefined","Object","assign","addFonts","paths","fontPaths","_objectSpread","removeFonts","fontFamilys","forEach","fontFamily","clearFonts","restoreDefaults","keys","defaults","reduce","acc","key","log","severity","_len","optionalParams","Array","_key","console","FabricError","Error","message","options","concat","SignalAbortedError","context","GLProbe","WebGLProbe","testPrecision","gl","precision","fragmentSource","fragmentShader","createShader","FRAGMENT_SHADER","shaderSource","compileShader","getShaderParameter","COMPILE_STATUS","queryWebGL","canvas","getContext","maxTextureSize","getParameter","MAX_TEXTURE_SIZE","GLPrecision","find","getExtension","loseContext","isSupported","textureSize","copyPasteData","getEnv","document","isTouchSupported","navigator","maxTouchPoints","dispose","env","setEnv","value","getBrowserEnv","getFabricDocument","getFabricWindow","getDevicePixelRatio","_config$devicePixelRa","Math","max","NodeGLProbe","implForWrapper","jsdomImplForWrapper","utils","JSDOMWindow","JSDOM","decodeURIComponent","resources","pretendToBeVisual","getNodeCanvas","canvasEl","impl","_canvas","_image","element","_currentSrc","_attributes","_classList","Cache","getFontCache","_ref","fontStyle","fontWeight","toLowerCase","charWidthsCache","fontCache","cacheKey","clearFontCache","limitDimsByArea","ar","perfLimitSizeTotal","roughWidth","sqrt","floor","cache","VERSION","version","noop","halfPI","PI","twoMathPi","PiBy180","iMatrix","freeze","DEFAULT_SVG_FONT_SIZE","ALIASING_LIMIT","kRect","CENTER","LEFT","TOP","BOTTOM","RIGHT","NONE","reNewline","MOVING","SCALING","ROTATING","ROTATE","SKEWING","RESIZING","MODIFY_POLY","MODIFY_PATH","CHANGED","SCALE","SCALE_X","SCALE_Y","SKEW_X","SKEW_Y","FILL","STROKE","MODIFIED","JSON","SVG","ClassRegistry","Map","has","classType","getClass","get","setClass","classConstructor","set","type","getSVGClass","SVGTagName","setSVGClass","classRegistry","AnimationRegistry","remove","index","indexOf","splice","cancelAll","animations","animation","abort","cancelByCanvas","filter","_animation$target","target","cancelByTarget","runningAnimations","Observable","on","arg0","handler","__eventListeners","entries","eventName","off","push","once","disposers","_ref2","d","disposer","onceHandler","args","call","_removeEventListener","eventListener","_ref3","fire","_this$__eventListener","listenersForEvent","i","removeFromArray","array","idx","cos","angle","angleSlice","abs","sin","sign","Point","y","x","add","that","addEquals","scalarAdd","scalar","scalarAddEquals","subtract","subtractEquals","scalarSubtract","scalarSubtractEquals","multiply","scalarMultiply","scalarMultiplyEquals","divide","scalarDivide","scalarDivideEquals","eq","lt","lte","gt","gte","lerp","t","min","distanceFrom","dx","dy","midPointFrom","toString","setXY","setX","setY","setFromPoint","swap","clone","rotate","radians","origin","ZERO","sinus","cosinus","p","rotated","transform","ignoreOffset","isCollection","fabricObject","isArray","_objects","createCollectionMixin","Base","Collection","_onObjectAdded","object","_onObjectRemoved","_onStackOrderChanged","objects","size","insertAt","_len2","_key2","removed","_len3","_key3","forEachObject","callback","getObjects","_len4","types","_key4","o","isType","item","isEmpty","contains","deep","includes","some","obj","complexity","memo","current","sendObjectToBack","unshift","bringObjectToFront","sendObjectBackwards","intersecting","newIdx","findNewLowerIndex","bringObjectForward","findNewUpperIndex","moveObjectTo","isOverlapping","collectObjects","left","top","width","height","includeIntersecting","tl","br","selectable","visible","intersectsWithRect","isContainedWithinRect","containsPoint","CommonMethods","_setOptions","prop","_setObject","_set","toggle","property","requestAnimFrame","requestAnimationFrame","cancelAnimFrame","handle","cancelAnimationFrame","id","uid","createCanvasElement","createElement","createImage","copyCanvasElement","_newCanvas$getContext","newCanvas","drawImage","toDataURL","format","quality","isHTMLCanvas","degreesToRadians","degrees","radiansToDegrees","isIdentityMatrix","mat","every","transformPoint","invertTransform","a","r","multiplyTransformMatrices","b","is2x2","multiplyTransformMatrixArray","matrices","reduceRight","product","curr","calcPlaneRotation","atan2","qrDecompose","denom","pow","scaleX","scaleY","skewX","skewY","translateX","translateY","createTranslateMatrix","createRotateMatrix","angleRadiant","cosValue","sinValue","createScaleMatrix","angleToSkew","tan","createSkewXMatrix","skewValue","createSkewYMatrix","calcDimensionsMatrix","flipX","flipY","matrix","composeMatrix","scaleMatrix","loadImage","url","signal","crossOrigin","Promise","resolve","reject","aborted","img","err","src","addEventListener","done","onload","onerror","removeEventListener","enlivenObjects","reviver","instances","all","map","fromObject","then","fabricInstance","catch","error","instance","finally","enlivenObjectEnlivables","serializedObject","promises","values","enlived","pick","source","pickBy","predicate","ColorNameMap","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","reRGBa","reHSLa","reHex","hue2rgb","q","rgb2Hsl","g","maxValue","minValue","h","s","l","round","fromAlphaToFloat","parseFloat","endsWith","hexify","toUpperCase","padStart","greyAverage","avg","Color","color","setSource","_source","_tryParsingColor","sourceFromHex","sourceFromRgb","sourceFromHsl","isUnrecognised","getSource","toRgb","toRgba","join","toHsl","toHsla","toHex","fullHex","toHexa","slice","getAlpha","setAlpha","alpha","toGrayscale","toBlackWhite","threshold","average","bOrW","overlayWith","otherColor","otherAlpha","otherSource","R","G","B","fromRgb","fromRgba","match","parsedValue","fromHsl","fromHsla","match1degrees","parseAngletoDegrees","fromHex","isShortNotation","expandedValue","split","hex","hexCouple","parseInt","lowercase","numeric","toFixed","number","fractionDigits","Number","getSvgAttributes","commonAttributes","parseUnit","fontSize","unit","exec","dpi","DPI","parseAlign","align","parsePreserveAspectRatioAttribute","attribute","firstPart","secondPart","trim","alignX","alignY","meetOrSlice","matrixToSVG","NUM_FRACTION_DIGITS","colorPropToSVG","inlineStyle","colorValue","opacityValue","toLive","opacity","createSVGRect","svgColor","w","isFiller","filler","isSerializableFiller","toObject","isPattern","offsetX","isTextObject","_renderText","isPath","_renderPathCommands","isActiveSelection","getScrollLeftTop","doc","getDocumentFromElement","elementLoop","docElement","documentElement","body","scrollLeft","scrollTop","parentNode","host","nodeType","style","position","el","ownerDocument","getWindowFromElement","_el$ownerDocument","defaultView","setCanvasDimensions","ctx","retinaScaling","setAttribute","scale","setCSSDimensions","getElementOffset","_getWindowFromElement","offset","elemStyle","getComputedStyle","borderLeftWidth","borderTopWidth","paddingLeft","paddingTop","box","docElem","getBoundingClientRect","scrollLeftTop","clientLeft","clientTop","makeElementUnselectable","onselectstart","userSelect","StaticCanvasDOMManager","createLowerCanvas","lower","getElementById","hasAttribute","_originalCanvasStyle","cssText","classList","cleanupDOM","removeAttribute","setDimensions","calcOffset","staticCanvasDefaults","backgroundVpt","backgroundColor","overlayVpt","overlayColor","includeDefaultValues","svgViewportTransformation","renderOnAddRemove","skipOffscreen","enableRetinaScaling","imageSmoothingEnabled","controlsAboveOverlay","allowTouchScrolling","viewportTransform","StaticCanvas","lowerCanvasEl","_this$elements$lower","elements","contextContainer","_this$elements$lower2","getDefaults","ownDefaults","initElements","_setDimensionsImpl","skipControlsDrawing","calcViewportBoundaries","requestRenderAll","setCoords","getRetinaScaling","_offset","getWidth","getHeight","setWidth","setHeight","dimensions","cssOnly","backstoreOnly","hasLostContext","getZoom","setViewportTransform","vpt","zoomToPoint","point","before","newPoint","after","setZoom","absolutePan","relativePan","getElement","clearContext","clearRect","clear","backgroundImage","overlayImage","renderAll","cancelRequestedRender","destroyed","renderCanvas","renderAndReset","nextRenderHandle","disposed","iVpt","vptCoords","tr","bl","drawControls","_ctx","v","path","clipPath","patternQuality","_renderBackground","save","_renderObjects","restore","shouldCache","_transformDone","renderCache","forClipping","drawClipPathOnCanvas","_renderOverlay","__cleanupTask","globalCompositeOperation","zoomX","zoomY","_cacheCanvas","cacheTranslationX","cacheTranslationY","len","render","_renderBackgroundOrOverlay","fill","needsVpt","isAFiller","beginPath","moveTo","lineTo","closePath","fillStyle","offsetY","m","gradientTransform","patternTransform","getCenter","getCenterPoint","centerObjectH","_centerObject","centerObjectV","centerObject","viewportCenterObject","getVpCenter","viewportCenterObjectH","viewportCenterObjectV","center","toDatalessJSON","propertiesToInclude","toDatalessObject","_toObjectMethod","toJSON","methodName","clipPathData","excludeFromExport","_toObject","__serializeBgOverlay","originalValue","data","bgImage","bgColor","background","overlay","toSVG","markup","_setSVGPreamble","_setSVGHeader","clipPathId","_setSVGBgOverlayColor","_setSVGBgOverlayImage","_setSVGObjects","suppressPreamble","encoding","optViewBox","viewBox","createSVGFontFacesMarkup","createSVGRefElementsMarkup","createSVGClipPathMarkup","toClipPathSVG","shouldTransform","additionalTransform","fontList","styles","styleRow","fontListMarkup","_setSVGObject","bgOrOverlay","repeat","finalWidth","finalHeight","shouldInvert","loadFromJSON","json","serialized","parse","enlivedMap","properties","cloneWithoutData","multiplier","finalMultiplier","toCanvasElement","scaledWidth","scaledHeight","zoom","originalWidth","originalHeight","originalSkipControlsDrawing","newZoom","vp","newVp","originalRetina","objectsToRender","task","destroy","kill","touchEvents","getTouchInfo","event","touchProp","changedTouches","getPointer","scroll","_evt","clientX","clientY","isTouchEvent","pointerType","stopEvent","e","preventDefault","stopPropagation","makeBoundingBoxFromPoints","points","removeTransformFromObject","inverted","finalTransform","calcOwnMatrix","applyTransformToObject","addTransformToObject","_qrDecompose","otherOptions","_objectWithoutProperties","_excluded","setPositionByOrigin","resetObjectTransform","saveObjectTransform","sizeAfterTransform","dimX","dimY","bbox","calcPlaneChangeMatrix","from","to","sendPointToPlane","sendVectorToPlane","sendObjectToPlane","fireEvent","_target$canvas","originOffset","bottom","right","resolveOrigin","originValue","NOT_ALLOWED_CURSOR","getActionFromCorner","alreadySelected","corner","control","controls","getActionName","isTransformCentered","originX","originY","invertOrigin","isLocked","lockingKey","commonEventInfo","eventData","pointer","findCornerQuadrant","getTotalAngle","cornerAngle","normalizePoint","getRelativeCenterPoint","translateToGivenOrigin","p2","getLocalPoint","padding","localPoint","dragHandler","newLeft","newTop","moveX","moveY","FabricObjectSVGExportMixin","getSvgStyles","skipShadow","fillRule","strokeWidth","strokeDashArray","strokeDashOffset","strokeLineCap","strokeLineJoin","strokeMiterLimit","visibility","getSvgFilter","stroke","shadow","getSvgCommons","getSvgTransform","full","calcTransformMatrix","svgTransform","_toSVG","_reviver","_createBaseSVGMarkup","_createBaseClipPathSVGMarkup","objectMarkup","commonPieces","noStyle","withShadow","styleInfo","shadowInfo","vectorEffect","strokeUniform","absoluteClipPath","absolutePositioned","clipPathMarkup","addPaintOrder","paintFirst","getSvgRegex","arr","RegExp","reNum","String","raw","_templateObject","_taggedTemplateLiteral","svgNS","reFontDeclaration","svgValidTagNames","svgViewBoxElements","svgInvalidAncestors","svgValidParents","attributesMap","cx","cy","display","fSize","cPath","svgValidTagNamesRegEx","svgViewBoxElementsRegEx","svgValidParentsRegEx","reViewBoxAttrValue","unitVectorX","zero","rotateVector","vector","createVector","magnitude","calcAngleBetweenVectors","crossProduct","dotProduct","calcVectorRotation","getUnitVector","getOrthonormalVector","counterClockwise","isBetweenVectors","AxB","AxT","BxT","shadowOffsetRegex","reOffsetsAndBlur","shadowDefaultValues","blur","affectStroke","nonScaling","Shadow","parseShadow","shadowStr","replace","BLUR_BOX","fBoxX","fBoxY","capValue","stateProperties","cacheProperties","fabricObjectDefaultValues","minScaleLimit","objectCaching","centeredRotation","centeredScaling","dirty","interactiveObjectDefaultValues","noScaleCache","lockMovementX","lockMovementY","lockRotation","lockScalingX","lockScalingY","lockSkewingX","lockSkewingY","lockScalingFlip","cornerSize","touchCornerSize","transparentCorners","cornerColor","cornerStrokeColor","cornerStyle","cornerDashArray","hasControls","borderColor","borderDashArray","borderOpacityWhenMoving","borderScaleFactor","hasBorders","selectionBackgroundColor","evented","perPixelTargetFind","activeOn","hoverCursor","moveCursor","normalize","c","asin","elastic","defaultEasing","easeInCubic","easeOutCubic","easeInOutCubic","easeInQuart","easeOutQuart","easeInOutQuart","easeInQuint","easeOutQuint","easeInOutQuint","easeInSine","easeOutSine","easeInOutSine","easeInExpo","easeOutExpo","easeInOutExpo","easeInCirc","easeOutCirc","easeInOutCirc","easeInElastic","normA","normS","normP","easeOutElastic","normC","easeInOutElastic","easeInBack","easeOutBack","easeInOutBack","easeOutBounce","easeInBounce","easeInOutBounce","easeInQuad","easeOutQuad","easeInOutQuad","defaultAbort","AnimationBase","startValue","byValue","duration","delay","easing","onStart","onChange","onComplete","tick","bind","_onStart","_onChange","_onComplete","_abort","endValue","calculate","state","_state","isDone","start","firstTick","timestamp","startTime","Date","register","setTimeout","durationMs","boundDurationMs","durationProgress","valueProgress","unregister","ValueAnimation","timeElapsed","ArrayAnimation","defaultColorEasing","wrapColorCallback","rgba","ColorAnimation","startColor","endColor","isArrayAnimation","animate","animateColor","Intersection","status","append","isPointContained","T","A","infinite","AB","AT","isPointInPolygon","other","hits","inter","intersectSegmentSegment","intersectLineLine","a1","a2","b1","b2","aInfinite","bInfinite","a2xa1x","a2ya1y","b2xb1x","b2yb1y","a1xb1x","a1yb1y","uaT","ubT","uB","ua","ub","segmentsCoincide","intersectSegmentLine","s1","s2","l1","l2","intersectLinePolygon","result","intersectSegmentPolygon","intersectPolygonPolygon","points1","points2","coincidences","intersectPolygonRectangle","r1","r2","topRight","bottomLeft","ObjectGeometry","getX","getXY","getY","getRelativeX","setRelativeX","getRelativeY","setRelativeY","relativePosition","getRelativeXY","group","setRelativeXY","isStrokeAccountedForInDimensions","getCoords","aCoords","calcACoords","coords","intersection","intersectsWithObject","isContainedWithinObject","getBoundingRect","isOnScreen","isPartiallyOnScreen","allPointsAreOutside","getScaledWidth","_getTransformedDimensions","getScaledHeight","scaleToWidth","boundingRectFactor","scaleToHeight","getCanvasRetinaScaling","_this$canvas","getViewportTransform","_this$canvas2","rotateMatrix","tMatrix","finalMatrix","dim","transformMatrixKey","skipGroup","prefix","matrixCache","ownMatrixCache","_getNonTransformedDimensions","_calculateCurrentDimensions","dimOptions","preScalingStrokeValue","postScalingStrokeValue","noSkew","finalDimensions","fromOriginX","fromOriginY","toOriginX","toOriginY","translateToCenterPoint","translateToOriginPoint","relCenter","getPointByOrigin","pos","_getLeftTopCoords","FabricObject","name","setOptions","_createCacheCanvas","_cacheContext","_updateCacheCanvas","_limitCacheSize","dims","maxCacheSideLimit","minCacheSideLimit","limX","limY","capped","_getCacheCanvasDimensions","objectScale","getTotalObjectScaling","neededX","neededY","minCacheSize","dimensionsChanged","zoomChanged","drawingWidth","drawingHeight","shouldRedraw","additionalWidth","additionalHeight","shouldResizeCanvas","canvasWidth","canvasHeight","sizeGrowing","sizeShrinking","getHeightOfLine","ceil","setTransform","translate","needFullTransform","contextTop","getObjectScaling","retina","getObjectOpacity","_constrainScale","isChanged","parent","isNotVisible","_setupCompositeOperation","drawSelectionBackground","_setOpacity","_setShadow","drawCacheOnCanvas","_removeCacheCanvas","drawObject","isCacheDirty","hasStroke","hasFill","needsItsOwnCache","ownCaching","isOnACache","willDrawShadow","drawClipPathOnCache","originalFill","originalStroke","_setClippingProperties","_render","_drawClipPath","skipCanvas","fillRect","_removeShadow","globalAlpha","_setStrokeStyles","decl","lineWidth","lineCap","lineDashOffset","lineJoin","miterLimit","gradientUnits","_applyPatternForTransformedGradient","strokeStyle","_applyPatternGradientTransform","_setFillStyles","_setLineDash","dashArray","setLineDash","sx","sy","multX","multY","scaling","shadowColor","shadowBlur","browserShadowBlurConstant","shadowOffsetX","shadowOffsetY","_renderPaintInOrder","_renderStroke","_renderFill","_pCtx$createPattern","pCanvas","pCtx","createPattern","_findCenterFromElement","objectForm","cloneAsImage","ImageClass","origParams","originalGroup","originalShadow","canvasProvider","withoutTransform","withoutShadow","boundingRect","shadowOffset","originalCanvas","setOnGroup","animatable","_animate","propIsColor","colorProperties","animationOptions","isDescendantOf","getAncestors","ancestors","findCommonAncestors","fork","otherFork","common","otherAncestors","ancestor","j","hasCommonAncestors","commonAncestors","isInFrontOf","ancestorData","firstCommonAncestor","headOfFork","pop","headOfOtherFork","thisIndex","otherIndex","propertiesToSerialize","customProperties","toFixedBound","val","_removeDefaultValues","hasStaticDefaultValues","baseValues","getPrototypeOf","baseValue","_fromObject","serializedObjectOptions","_ref4","extraParam","_excluded2","enlivedObjectOptions","wrapWithFireEvent","actionHandler","extraEventInfo","actionPerformed","wrapWithFixedAnchor","centerPoint","constraint","changeObjectWidth","strokePadding","oldWidth","newWidth","changeWidth","renderCircleControl","styleOverride","xSize","sizeX","ySize","sizeY","myLeft","myTop","arc","renderSquareControl","xSizeBy2","ySizeBy2","strokeRect","Control","shouldActivate","controlKey","_fabricObject$canvas","getActiveObject","isControlVisible","getActionHandler","getMouseDownHandler","mouseDownHandler","getMouseUpHandler","mouseUpHandler","cursorStyleHandler","cursorStyle","actionName","getVisibility","_fabricObject$_contro","_fabricObject$_contro2","_controlsVisibility","setVisibility","positionHandler","currentControl","calcCornerCoords","objectCornerSize","centerX","centerY","isTouch","touchSizeX","touchSizeY","rotationStyleHandler","rotateObjectWithSnapping","ex","ey","theta","pivotPoint","lastAngle","curAngle","snapAngle","snapThreshold","rightAngleLocked","leftAngleLocked","hasRotated","rotationWithSnapping","scaleIsProportional","uniformIsToggled","uniScaleKey","uniformScaling","scalingIsForbidden","by","scaleProportionally","lockX","lockY","scaleMap","scaleCursorStyleHandler","n","scaleObject","forbidScaling","signX","signY","gestureScale","distance","original","originalDistance","oldScaleX","oldScaleY","scaleObjectFromCorner","scaleObjectX","scaleObjectY","scalingEqually","scalingX","scalingY","AXIS_KEYS","counterAxis","skew","lockSkewing","flip","skewMap","skewCursorStyleHandler","skewObject","axis","skewingSide","skewKey","skewingBefore","skewingStart","shearingStart","shearing","skewing","atan","changed","dimBefore","dimAfter","compensationFactor","skewHandler","originKey","lockSkewingKey","flipKey","counterOriginKey","counterFlipKey","counterOriginFactor","skewingDirection","finalHandler","skewHandlerX","skewHandlerY","isAltAction","altActionKey","scaleOrSkewActionName","isAlternative","scaleSkewCursorStyleHandler","scalingXOrSkewingY","scalingYOrSkewingX","createObjectDefaultControls","ml","mr","mb","mt","mtr","withConnection","createResizeControls","createTextboxDefaultControls","InteractiveFabricObject","createControls","targetCanvas","_currentTransform","action","startsWith","getActiveControl","__corner","coord","oCoords","findControl","forTouch","cornerEntries","touchCorner","calcOCoords","rMatrix","positionMatrix","startMatrix","transformOptions","forEachControl","_calcCornerCoords","fn","_activeObject","wh","strokeBorders","_drawBorders","drawControlsConnectingLines","_renderControls","styleOptions","shouldDrawBorders","shouldDrawControls","isMoving","drawBorders","forActiveSelection","shouldStroke","setControlVisible","setControlsVisibility","clearContextTop","restoreManually","onDeselect","_options","onSelect","shouldStartDragging","_e","onDragStart","canDrop","renderDragSourceEffect","renderDropTargetEffect","applyMixins","derivedCtor","constructors","baseCtor","getOwnPropertyNames","prototype","defineProperty","getOwnPropertyDescriptor","create","isTransparent","tolerance","getImageData","alphaChannel","rotatePoint","findIndexRight","StrokeProjectionsBase","strokeProjectionMagnitude","strokeUniformScalar","createSideVector","projectOrthogonally","applySkew","calcOrthogonalProjection","isSkewed","scaleUnitVector","unitVector","zeroVector","StrokeLineJoinProjections","getOrthogonalRotationFactor","vector1","vector2","C","AC","bisector","orthogonalProjection","correctSide","projectBevel","projections","projectMiter","hypotUnitScalar","miterVector","projectRoundNoSkew","startCircle","endCircle","radiusOnAxisX","radiusOnAxisY","projectRoundWithSkew","circleRadius","newY","furthestY","newX","furthestX","projectRound","isStraightLine","newOrigin","proj0","proj1","comparisonVector","isProj0Start","projectPoints","project","originPoint","projectedPoint","StrokeLineCapProjections","projectButt","projection","projectSquare","strokePointingOut","projectedA","projectStrokeOnPoints","openPath","reduced","cloneStyles","newObj","keyInner","capitalize","string","firstLetterOnly","charAt","escapeXml","graphemeSplit","textstring","graphemes","chr","getWholeChar","str","code","charCodeAt","isNaN","next","prev","hasStyleChanged","prevStyle","thisStyle","forTextSpans","textBackgroundColor","deltaY","overline","underline","linethrough","stylesToArray","text","textLines","stylesArray","charIndex","chars","end","stylesFromArray","stylesObject","styleIndex","SHARED_ATTRIBUTES","selectorMatches","selector","nodeName","classNames","getAttribute","azAz","matcher","splitClassNames","doesSomeParentMatch","selectors","parentMatching","parentElement","elementMatchesRule","firstMatching","getGlobalStylesForElement","cssRules","rule","normalizeAttr","attr","_attributesMap","regex","cleanupSvgAttribute","attributeValue","_templateObject2","_templateObject3","_templateObject4","_templateObject5","_templateObject6","transforms","transformList","_templateObject7","reTransformList","reTransform","reTransformAll","parseTransformAttribute","test","matchAll","transformMatch","matchedParams","operation","rawArgs","arg1","arg2","arg3","arg4","arg5","arg","normalizeValue","parentAttributes","parsed","ouputValue","transformMatrix","fillIndex","strokeIndex","parseFontDeclaration","oStyle","lineHeight","parseStyleObject","parseStyleString","chunk","parseStyleAttribute","colorAttributesMap","setStrokeFillOpacity","attributes","colorAttr","parseAttributes","parentFontSize","ownAttributes","normalizedStyle","normalizedAttr","normalizedValue","font","mergedAttrs","rectDefaultValues","rx","ry","RECT_PROPS","Rect","_initRxRy","isRounded","bezierCurveTo","fromElement","_parseAttributes","ATTRIBUTE_NAMES","restOfparsedAttributes","Boolean","LAYOUT_TYPE_INITIALIZATION","LAYOUT_TYPE_ADDED","LAYOUT_TYPE_REMOVED","LAYOUT_TYPE_IMPERATIVE","LAYOUT_TYPE_OBJECT_MODIFIED","LAYOUT_TYPE_OBJECT_MODIFYING","getObjectBounds","destinationGroup","currentGroup","objectCenter","accountForStroke","strokeUniformVector","scalingStrokeWidth","sizeVector","LayoutStrategy","calcLayoutResult","shouldPerformLayout","calcBoundingBox","prevStrategy","strategy","shouldLayoutClipPath","getInitialSize","overrides","bboxSize","bboxLeftTop","bboxCenter","actualSize","relativeCorrection","FitContentLayout","LAYOUT_MANAGER","LayoutManager","_subscriptions","performLayout","strictContext","bubbles","_prevLayoutStrategy","onBeforeLayout","layoutResult","getLayoutResult","commitLayout","onAfterLayout","attachHandlers","trigger","subscribe","unsubscribe","_context","delete","unsubscribeTargets","targets","subscribeTargets","tricklingContext","layoutManager","prevCenter","nextCenter","correction","layoutObjects","_context$x","_context$y","layoutObject","_","bubblingContext","NoopLayoutManager","groupDefaultValues","subTargetCheck","interactive","Group","groupInit","_options$layoutManage","__objectSelectionTracker","__objectSelectionMonitor","__objectSelectionDisposer","enterGroup","canEnterGroup","_filterObjectsBeforeEnteringGroup","allowedObjects","_onAfterObjectsChange","removeParentTransform","exitGroup","_shouldSetNestedCoords","removeAll","_activeObjects","selected","activeObjects","_watchObject","watch","_enterGroup","activeObject","_exitGroup","ownCache","preserveObjectStacking","triggerLayout","__serializeObjects","method","_includeDefaultValues","originalDefaults","_createSVGBgRect","fillStroke","commons","svgString","bg","abortable","hydratedOptions","layoutClass","strategyClass","groupSVGElements","findScaleToFit","destination","findScaleToCover","commaWsp","reArcCommandPoints","rePathCommand","repeatedCommands","M","segmentToBezier","theta1","theta2","cosTh","sinTh","cx1","cy1","mT","fromX","fromY","costh1","sinth1","costh2","sinth2","toX","toY","cp1X","cp1Y","cp2X","cp2Y","arcToSegments","large","sweep","rotateX","root","sinTheta","px","py","rx2","ry2","py2","px2","pl","_rx","_ry","mTheta","calcVectorAngle","dtheta","segments","mDelta","th3","ux","uy","vx","vy","ta","tb","CB1","CB2","CB3","CB4","getBoundsOfCurve","begx","begy","cp1x","cp1y","cp2x","cp2y","endx","endy","argsString","cachesBoundsOfCurve","boundsOfCurveCache","tvalues","bounds","b2ac","sqrtb2ac","t1","t2","jlen","iterator","getPointOnCubicBezierIterator","fromArcToBeziers","fx","fy","rot","tx","ty","segsNorm","makePathSimpler","x1","y1","destinationPath","previous","controlX","controlY","parsedCommand","converted","calcLineLength","x2","y2","pct","c1","c2","c3","c4","QB1","QB2","QB3","getTangentCubicIterator","p1x","p1y","p2x","p2y","p3x","p3y","p4x","p4y","qb1","qb2","qb3","tangentX","tangentY","getPointOnQuadraticBezierIterator","getTangentQuadraticIterator","invT","pathIterator","tempP","tmpLen","perc","findPercentageForDistance","segInfo","nextLen","nextStep","lastPerc","angleFinder","getPathSegmentsInfo","totalLength","tempInfo","info","basicInfo","command","destX","destY","getPointOnPath","infos","segPercent","segment","rePathCmdAll","regExpArcCommandPoints","reMyNum","commandLengths","parsePath","pathString","_pathString$match","chain","matchStr","commandLetter","commandLength","paramArr","lastIndex","out","newCommand","transformedCommand","getSmoothPathFromPoints","p1","multSignX","multSignY","manyPoints","midPoint","transformPath","pathOffset","pathSegment","newSegment","getRegularPolygonPath","numVertexes","radius","interiorAngle","rotationAdjustment","rad","joinPath","pathData","setStyle","elementStyle","setProperty","mergeClipPaths","_b$group","getRandomInt","random","request","xhr","XMLHttpRequest","removeListener","ontimeout","onreadystatechange","readyState","open","send","_assignTransformMatrixProps","removeTransformMatrixForSvgParsing","preserveAspectRatioOptions","cropX","cropY","offsetLeft","offsetTop","CanvasDOMManager","containerClass","upperCanvasEl","createUpperCanvas","upper","applyCanvasStyle","container","createContainerElement","replaceChild","className","removeChild","canvasDefaults","centeredKey","selection","selectionKey","selectionColor","selectionDashArray","selectionBorderColor","selectionLineWidth","selectionFullyContained","defaultCursor","freeDrawingCursor","notAllowedCursor","targetFindTolerance","skipTargetFind","stopContextMenu","fireRightClick","fireMiddleClick","enablePointerEvents","SelectableCanvas","_this$elements$upper","_this$elements$upper2","wrapperEl","_objectsToRender","deselected","_discardActiveObject","_hoveredTarget","_hoveredTargets","_chooseObjectsToRender","contextTopDirty","_groupSelector","isDrawingMode","renderTopLayer","_isCurrentlyDrawing","freeDrawingBrush","_drawSelection","renderTop","setTargetFindTolerance","pixelFindCanvasEl","pixelFindContext","isTargetTransparent","selectionBgc","enhancedTolerance","_isSelectionKeyPressed","sKey","_shouldClearSelection","getActiveObjects","_shouldCenterTransform","modifierKeyPressed","centerTransform","_getOriginFromCorner","controlName","_setupCurrentTransform","_control$getActionHan","getScenePoint","altKey","lastX","lastY","shiftKey","setCursor","cursor","deltaX","extent","strokeOffset","minX","minY","maxX","maxY","findTarget","getViewportPoint","aObjects","searchPossibleTargets","subTargets","altSelectionKey","_pointIsInObjectSelectionArea","viewportZoom","angleRadians","cosP","sinP","cosPSinP","cosPMinusSinP","_checkTarget","isEditing","_searchPossibleTargets","subTarget","_pointer","_absolutePointer","fromViewport","boundsWidth","boundsHeight","cssScale","_resetTransformEventData","_setBrushStyles","willReadFrequently","getTopContext","getSelectionContext","getSelectionElement","active","_fireSelectionEvents","oldObjects","somethingChanged","invalidate","added","setActiveObject","currentActives","_setActiveObject","prevActiveObject","endCurrentTransform","discardActiveObject","discarded","_finalizeCurrentTransform","_scaling","originalProperties","_realizeGroupTransformOnObject","layoutProps","originalValues","TextEditingManager","cb","hiddenTextarea","focus","__disposer","exitTextEditing","exitEditing","onMouseMove","_this$target","updateSelectionOnMouseMove","addEventOptions","passive","getEventPoints","viewportPoint","scenePoint","absolutePointer","addListener","syntheticEventConfig","mouse","in","targetIn","targetOut","canvasIn","canvasOut","drag","Canvas","eventHandler","addOrRemove","_getEventPrefix","functor","_eventjsFunctor","canvasElement","eventTypePrefix","_onResize","_onMouseDown","_onMouseMove","_onMouseOut","_onMouseEnter","_onMouseWheel","_onContextMenu","_onDoubleClick","_onDragStart","_onDragEnd","_onDragOver","_onDragEnter","_onDragLeave","_onDrop","_onTouchStart","removeListeners","_onMouseUp","_onTouchEnd","__onMouseWheel","shared","nestedTarget","_isClick","_dragSource","_onDragProgress","_renderDragEffects","dropTarget","_dropTarget","didDrop","dataTransfer","dropEffect","dragSource","_draggedoverTarget","findDragTargets","eventType","_fireEnterLeaveEvents","_basicEventHandler","_cacheTransformEventData","_handleEvent","getPointerId","evt","identifier","pointerId","_isMainEvent","isPrimary","touches","mainTouchId","__onMouseDown","__onMouseUp","_willAddMouseDown","clearTimeout","__onMouseMove","_shouldRender","_this$_activeObject","isClick","_target","button","_onMouseUpInDrawingMode","shouldRender","targetWasActive","handleSelection","found","originalControl","originalMouseUpHandler","_setCursorFromEvent","currentTarget","currentSubTargets","_onMouseDownInDrawingMode","onMouseDown","_onMouseMoveInDrawingMode","onMouseUp","grouped","handleMultiSelection","groupSelector","_fireOverOutEvents","_transformObject","textEditingManager","fireSyntheticInOutEvents","oldTarget","fireCanvas","draggedoverTarget","targetChanged","outOpt","nextTarget","inOpt","previousTarget","localPointer","_performTransformAction","activeSelection","reverse","isAS","prevActiveObjects","multiSelectAdd","klass","newActiveSelection","point1","point2","collectedObjects","linearDefaultCoords","radialDefaultCoords","ifNaN","valueIfNaN","RE_PERCENT","isPercent","parsePercent","NaN","RE_KEY_VALUE_PAIRS","RE_KEY_VALUE","parseColorStop","keyValuePairs","parseColorStops","opacityAttr","colorStops","colorStopEls","getElementsByTagName","parseType","parseGradientUnits","convertPercentUnitsToValues","valuesToConvert","finalValue","propValue","getValue","parseLinearCoords","parseRadialCoords","parseCoords","Gradient","addColorStop","colorStop","preTransform","sort","needsSwap","minRadius","maxRadius","percentageShift","gradient","createLinearGradient","createRadialGradient","svgOptions","viewBoxWidth","viewBoxHeight","Pattern","isImageSource","isCanvasSource","sourceToString","complete","naturalWidth","naturalHeight","patternSource","patternOffsetX","patternOffsetY","patternWidth","patternHeight","BaseBrush","_saveAndTransform","needsFullRender","_resetShadow","_isOutSideCanvas","Path","_setPath","adjustPosition","setBoundingBox","_calcBoundsFromPath","quadraticCurveTo","pathCmd","sourcePath","_getOffsetTransform","digits","_calcDimensions","subpathStartX","subpathStartY","parsedAttributes","isEmptySVGPath","PencilBrush","_points","_hasStraightLine","drawSegment","drawStraightLine","straightLineKey","_prepareForDrawing","_addPoint","limitedToCanvasSize","oldEnd","_finalizeAndAddPath","_reset","convertPointsToSVGPath","createPath","decimatePoints","lastPoint","cDistance","adjustedDistance","newPoints","decimate","CIRCLE_PROPS","circleDefaultValues","startAngle","endAngle","Circle","setRadius","getRadiusX","getRadiusY","startX","startY","endX","endY","largeFlag","sweepFlag","otherParsedAttributes","CircleBrush","drawDot","addPoint","dot","originalRenderOnAddRemove","circles","circle","pointerPoint","getUniqueRects","rects","uniqueRects","uniqueRectsArray","SprayBrush","sprayChunks","sprayChunk","addSprayChunk","renderChunck","chunck","rect","optimizeOverlapping","sprayChunck","density","dotWidthVariance","dotWidth","randomOpacity","PatternBrush","getPatternSrc","dotDistance","patternCanvas","patternCtx","getPattern","pattern","topLeft","coordProps","Line","_setWidthHeight","calcLinePoints","origStrokeStyle","_this$stroke","_x1","_x2","_y1","_y2","xMult","yMult","triangleDefaultValues","Triangle","widthBy2","heightBy2","ellipseDefaultValues","ELLIPSE_PROPS","Ellipse","getRx","getRy","parsePointsAttribute","pointsSplit","parsedPoints","polylineDefaultValues","exactBoundingBox","Polyline","initialized","isOpen","_projectStrokeOnPoints","strokeDiff","bboxNoStroke","layoutProperties","_options$width","_options$height","_options$width2","_options$height2","output","diffX","diffY","Polygon","fontProperties","textDecorationProperties","textLayoutProperties","additionalProps","styleProperties","textDefaultValues","_reNewline","_reSpacesAndTabs","_reSpaceAndTab","_reWords","textAlign","superscript","baseline","subscript","pathStartOffset","pathSide","pathAlign","_fontSizeFraction","offsets","_fontSizeMult","charSpacing","direction","CACHE_FONT_SIZE","MIN_TEXT_WIDTH","JUSTIFY","JUSTIFY_LEFT","JUSTIFY_RIGHT","JUSTIFY_CENTER","StyledText","isEmptyStyles","lineIndex","line","p3","styleHas","cleanStyle","stylesCount","letterCount","stylePropertyValue","allStyleObjectPropertiesMatch","graphemeCount","styleObject","stylePropertyHasBeenSet","_textLines","removeStyle","lineNum","charNum","_extendStyles","get2DCursorLocation","_getLineStyle","_setLineStyle","newStyle","_getStyleDeclaration","_setStyleDeclaration","getSelectionStyles","startIndex","endIndex","getStyleAtPosition","getCompleteStyleDeclaration","setSelectionStyles","_forceClearCache","_lineStyle$charIndex","lineStyle","_styleProperties","_deleteStyleDeclaration","_deleteLineStyle","multipleSpacesRegex","dblQuoteRegex","createSVGInlineRect","TextSVGExportMixin","_getSVGLeftTopOffsets","textAndBg","_getSVGTextAndBg","textTop","textLeft","_wrapSVGTextAndBg","lineTop","textBgRects","textSpans","noShadow","textDecoration","getSvgTextDecoration","textTopOffset","textLeftOffset","lineOffset","_getLineLeftOffset","_setSVGTextLineBg","_setSVGTextLineText","_createTextCharSpan","char","styleDecl","styleProps","getSvgSpanStyles","fillStyles","dySpan","isJustify","actualStyle","nextStyle","charsToRender","charBox","boxWidth","timeToRender","__charBounds","kernedWidth","leftOffset","heightOfLine","boxStart","currentColor","lastColor","getValueOfPropertyAt","_getSVGLineTopOffset","lineTopOffset","lastHeight","useWhiteSpace","decoration","measuringContext","getMeasuringContext","FabricText","setPathInfo","initDimensions","segmentsInfo","_splitText","newLines","_splitTextIntoLines","lines","graphemeLines","_unwrappedTextLines","_unwrappedLines","_text","graphemeText","_clearCache","calcTextWidth","cursorWidth","calcTextHeight","enlargeSpaces","diffSpace","currentLineWidth","numberOfSpaces","accumulatedSpace","charBound","spaces","isEndOfWrapping","getLineWidth","missingNewlineOffset","_lineIndex","selectionStart","skipWrapping","_setTextStyles","_renderTextLinesBackground","_renderTextDecoration","_renderTextStroke","_renderTextFill","charStyle","forMeasuring","textBaseline","_getFontDeclaration","maxWidth","_renderTextLine","_renderChars","_getLeftOffset","_getTopOffset","lineLeftOffset","drawStart","renderLeft","_measureChar","_char","previousChar","prevCharStyle","fontDeclaration","couple","stylesAreEqual","fontMultiplier","coupleWidth","previousWidth","measureText","getHeightOfChar","measureLine","lineInfo","_measureLine","_getWidthOfCharSpacing","prevGrapheme","graphemeInfo","llength","lineBounds","grapheme","_getGraphemeBox","positionInPath","totalPathLength","_setGraphemeOnPath","numOfSpaces","centerPosition","skipLeft","previousBox","__lineHeights","maxHeight","_renderTextCommon","lineHeights","shortCut","isLtr","currentDirection","drawingLeft","_renderChar","_applyPatternGradientTransformText","handleFiller","fullDecl","shouldFill","fillOffsets","fillText","strokeOffsets","strokeText","setSuperscript","_setScript","setSubscript","schema","loc","lineDiff","__lineWidths","_charStyle$property","topOffset","lastDecoration","lastFill","currentDecoration","currentFill","currentSize","currentDy","parsedFontFamily","genericFonts","newLine","newText","needsDims","isAddingPath","_options$parsedAttrib","textAnchor","restOfOptions","textContent","textHeightScaleFactor","lineHeightDiff","scaledDiff","textHeight","offX","DraggableTextDelegate","dragEnterHandler","dragOverHandler","dragLeaveHandler","dragEndHandler","dropHandler","_dispose","isPointerOverSelection","newSelection","getSelectionStartFromPointer","selectionEnd","__mouseDownInPlace","isActive","__dragStartFired","setCursorByClick","initDelayedCursor","__isDraggingOver","getDragStartSelection","__dragStartSelection","setDragImage","_e$dataTransfer","flipFactor","boundaries","_getCursorBoundaries","selectionPosition","diff","bgc","dragImage","border","__dragImageDisposer","appendChild","setData","stringify","effectAllowed","abortCursorAnimation","editable","defaultPrevented","dragStartSelection","targetCanDrop","ev","_e$dataTransfer2","insert","getData","trailing","selectionStartOffset","removeChars","trimEnd","insertChars","enterEditing","_updateTextarea","_e$dataTransfer3","reNonWord","ITextBehavior","initBehavior","_tick","_onTickComplete","_animateCursor","toValue","_currentCursorOpacity","renderCursorOrSelection","_currentTickState","cursorDuration","_this$_currentTickCom","_currentTickCompleteState","restart","cursorDelay","shouldClear","cursorAnimation","restartCursorIfNeeded","selectAll","_fireSelectionChanged","getSelectedText","findWordBoundaryLeft","startFrom","_reSpace","findWordBoundaryRight","findLineBoundaryLeft","findLineBoundaryRight","searchWordBoundary","selectWord","newSelectionStart","newSelectionEnd","selectLine","initHiddenTextarea","_saveEditingProps","_setEditingProps","_textBeforeEdit","activeElement","currentStart","currentEnd","__selectionStartOnMouseDown","editingBorderColor","fromStringToGraphemeSelection","smallerTextStart","graphemeStart","smallerTextEnd","graphemeEnd","fromGraphemeToStringSelection","cursorOffsetCache","inCompositionMode","updateTextareaPosition","updateFromTextArea","textarea","_calcTextareaPosition","desiredPosition","compositionStart","cursorLocation","charHeight","upperCanvas","upperCanvasWidth","upperCanvasHeight","clientWidth","clientHeight","_savedProps","_restoreEditingProps","_exitEditing","isTextChanged","_removeExtraneousStyles","removeStyleFromTo","lineStart","charStart","lineEnd","charEnd","styleObj","shiftLineStyles","numericChar","clonedStyles","numericLine","insertNewlineStyleObject","qty","copiedStyle","newLineStyles","originalLineLength","isEndOfLine","someStyleIsCarryingOver","currentCharStyle","numIndex","styleCarriedOver","insertCharStyleObject","quantity","currentLineStyles","currentLineStylesCloned","numericIndex","insertNewStyleBlock","insertedText","cursorLoc","addedLines","linesLength","setSelectionStartEndWithShift","_selectionDirection","ITextKeyBehavior","autocapitalize","autocorrect","autocomplete","spellcheck","wrap","hiddenTextareaContainer","keydown","keyup","input","copy","cut","paste","compositionstart","compositionupdate","compositionend","onKeyDown","keyMap","keysMapRtl","keysMap","keyCode","ctrlKeysMapDown","ctrlKey","metaKey","stopImmediatePropagation","onKeyUp","_copyDone","ctrlKeysMapUp","onInput","fromPaste","updateAndFire","nextText","charCount","nextCharCount","removedText","charDiff","removeFrom","removeTo","textareaSelection","backDelete","copiedText","disableStyleCopyPaste","copiedTextStyle","onCompositionStart","onCompositionEnd","onCompositionUpdate","compositionEnd","_getWidthBeforeCursor","widthBeforeCursor","bound","getDownCursorOffset","isRight","selectionProp","_getSelectionForOffset","indexOnOtherLine","_getIndexOnLine","textAfterCursor","getUpCursorOffset","textBeforeCursor","widthOfCharsOnLine","indexOnLine","charWidth","foundMatch","leftEdge","rightEdge","offsetFromLeftEdge","offsetFromRightEdge","moveCursorDown","_moveCursorUpOrDown","moveCursorUp","moveCursorWithShift","moveCursorWithoutShift","moveCursorLeft","_moveCursorLeftOrRight","_move","newValue","_moveLeft","_moveRight","moveCursorLeftWithoutShift","change","moveCursorLeftWithShift","moveCursorRight","moveCursorRightWithShift","moveCursorRightWithoutShift","notALeftClick","ITextClickBehavior","_mouseDownHandler","_mouseDownHandlerBefore","doubleClickHandler","tripleClickHandler","__lastClickTime","__lastLastClickTime","__lastPointer","draggableTextDelegate","__newClickTime","newPointer","isTripleClick","__lastSelected","didDrag","mouseOffset","charLength","widthAfter","MOVE_CURSOR_UP","MOVE_CURSOR_DOWN","MOVE_CURSOR_LEFT","MOVE_CURSOR_RIGHT","EXIT_EDITING","protectedDefaultValues","iTextDefaultValues","cursorColor","caching","IText","setSelectionStart","_updateAndFire","setSelectionEnd","renderCursor","renderSelection","skipCaching","_getCursorBoundariesOffsets","__getCursorBoundariesOffsets","renderCursorAt","_renderCursor","_renderSelection","dragSelection","startLine","endLine","startChar","endChar","realLineHeight","boxEnd","drawHeight","extraTop","drawWidth","compositionColor","getCurrentCharFontSize","cp","_getCurrentCharIndex","getCurrentCharColor","cursorPosition","textboxDefaultValues","minWidth","dynamicMinWidth","_wordJoiners","splitByGrapheme","Textbox","_styleMap","_generateStyleMap","textInfo","realLineCount","realLineCharCount","isWrapping","nextLineIndex","nextOffset","shouldLimit","mapNextLine","p2Number","_wrapText","desiredWidth","getGraphemeDataForRender","wrapped","wordsData","_wrapLine","infix","largestWordWidth","wordsOrGraphemes","wordSplit","word","graphemeArray","_measureWord","charOffset","reservedSpace","additionalSpace","infixWidth","lineJustStarted","wordWidth","getMinWidth","linesToKeep","propNumber","ClipPathLayout","clipPathCenter","FixedLayout","ActiveSelectionLayoutManager","parents","Set","selectedObjects","activeSelectionDefaultValues","multiSelectionStacking","ActiveSelection","findIndex","groups","childrenOverride","Canvas2dFilterBackend","applyFilters","filters","sourceElement","sourceWidth","sourceHeight","imageData","originalImageData","pipelineState","originalEl","filterBackend","applyTo","imageDataPostFilter","putImageData","WebGLFilterBackend","tileSize","Float32Array","setupGLContext","captureGPUInfo","createWebGLCanvas","glOptions","premultipliedAlpha","depth","stencil","antialias","clearColor","cachedTexture","getCachedTexture","destinationWidth","destinationHeight","sourceTexture","createTexture","targetTexture","originalTexture","passes","webgl","aPosition","programCache","pass","tempFbo","createFramebuffer","bindFramebuffer","FRAMEBUFFER","resizeCanvasIfNeeded","copyGLTo2D","bindTexture","TEXTURE_2D","deleteTexture","deleteFramebuffer","clearWebGLCaches","textureCache","textureImageSource","NEAREST","RGBA","UNSIGNED_BYTE","CLAMP_TO_EDGE","TEXTURE_MAG_FILTER","TEXTURE_MIN_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","texture","texParameteri","texImage2D","uniqueId","evictCachesForKey","glCanvas","sourceY","copyGLTo2DPutImageData","dWidth","dHeight","numBytes","u8","Uint8Array","imageBuffer","u8Clamped","Uint8ClampedArray","readPixels","imgData","ImageData","gpuInfo","renderer","vendor","ext","UNMASKED_RENDERER_WEBGL","UNMASKED_VENDOR_WEBGL","initFilterBackend","enableGLFiltering","getFilterBackend","strict","setFilterBackend","backend","imageDefaultValues","srcFromAttribute","minimumScaleTrigger","imageSmoothing","IMAGE_PROPS","FabricImage","setElement","_element","removeTexture","_originalElement","CSS_CANVAS","resizeFilter","applyResizeFilters","elementKey","getCrossOrigin","getOriginalSize","_stroke","filterObj","getSrc","hasCrop","imageMarkup","strokeSvg","imageRendering","getSvgSrc","origFill","filtered","setSrc","minimumScale","elementToFilter","_filteredEl","_filterScalingX","_filterScalingY","_lastScaleX","_lastScaleY","isNeutralState","imgElement","_needsResize","elementToDraw","elWidth","elHeight","sX","sY","sW","sH","maxDestW","maxDestH","_resetWidthHeight","pAR","preserveAspectRatio","pWidth","pHeight","rWidth","rHeight","f","rf","hydratedProps","fromURL","imageOptions","applyViewboxTransform","viewBoxAttr","widthAttr","heightAttr","goodViewbox","missingViewBox","missingDimAttr","translateMatrix","widthDiff","heightDiff","parsedDim","pasedViewBox","createElementNS","firstChild","getTagName","node","tagName","svgInvalidAncestorsRegEx","hasInvalidAncestor","getMultipleNodes","nodeNames","nodeArray","nodeList","getElementsByTagNameNS","parseUseDirectives","nodelist","skipAttributes","useElement","useAttributes","useAttrMap","xlink","href","referencedElement","clonedOriginal","cloneNode","originalAttributes","originalAttrMap","currentTrans","el3","setAttributeNS","childNodes","styleRecord","mergedStyles","entry","gradientsAttrs","xlinkAttr","recursivelyParseGradientsXlink","_gradient$getAttribut","xLink","referencedGradient","children","referenceClone","tagArray","getGradientDefs","elList","gradientDefs","getCSSRules","allRules","styleContents","ruleObj","declaration","propertyValuePairs","pair","_rule","findTag","ElementsParser","clipPaths","regexUrl","createObject","resolveGradient","resolveClipPath","extractPropertyDefinition","storage","gradientDef","usingElement","clipPathElements","objTransformInv","clipPathTag","clipPathOwner","clipPathElement","enlivedClippath","clipRule","gTransform","isValidSvgTag","createEmptyResponse","allElements","parseSVGDocument","descendants","localClipPaths","elementParser","loadSVGFromString","parser","DOMParser","parseFromString","loadSVGFromURL","xml","responseXML","parsedDoc","ACTION_NAME","createPolyPositionHandler","pointIndex","polyObject","polyActionHandler","poly","mouseLocalPosition","factoryPolyActionHandler","anchorPoint","anchorPointInParentPlane","newAnchorPointInParentPlane","createPolyActionHandler","createPolyControls","calcPathPointPosition","pathObject","commandIndex","movePathPoint","anchorCommand","pathPositionHandler","pathActionHandler","indexFromPrevCommand","previousCommandType","PathPointControl","controlFill","controlStroke","PathControlPointControl","connectToCommandIndex","connectToPointIndex","connectionDashArray","commandType","createControl","commandIndexPos","pointIndexPos","isControlPoint","controlPointStyle","pointStyle","createPathControls","isWebGLPipelineState","isPutImageFaster","sourceCanvas","ArrayBuffer","testContext","testPipelineState","performance","now","drawImageTime","putImageDataTime","highPsourceCode","identityFragmentShader","vertexSource","BaseFilter","getFragmentSource","getVertexSource","createProgram","vertexShader","VERTEX_SHADER","program","getShaderInfoLog","attachShader","linkProgram","getProgramParameter","LINK_STATUS","getProgramInfoLog","uniformLocations","getUniformLocations","uStepW","getUniformLocation","uStepH","attributeLocations","getAttributeLocations","getAttribLocation","locations","sendAttributeData","aPositionData","attributeLocation","buffer","createBuffer","bindBuffer","ARRAY_BUFFER","enableVertexAttribArray","vertexAttribPointer","FLOAT","bufferData","STATIC_DRAW","_setupFrameBuffer","framebufferTexture2D","COLOR_ATTACHMENT0","finish","_swapTextures","temp","applyToWebGL","applyTo2d","getCacheKey","retrieveShader","shader","useProgram","uniform1f","sendUniformData","viewport","drawArrays","TRIANGLE_STRIP","bindAdditionalTexture","textureUnit","activeTexture","TEXTURE0","unbindAdditionalTexture","_gl","_uniformLocations","createHelpLayer","helpLayer","defaultKeys","filterOptions","blendColorFragmentSource","screen","difference","lighten","darken","exclusion","tint","blendColorDefaultValues","mode","BlendColor","tg","alpha1","uniform4fv","uColor","mask","blendImageDefaultValues","BlendImage","image","TEXTURE1","calculateMatrix","blendImage","canvas1","blendData","uniform1i","uImage","uniformMatrix3fv","uTransformMatrix","enlivedImage","blurDefaultValues","Blur","aspectRatio","horizontal","simpleBlur","blurLayer1","blurLayer2","canvas2","ctx1","ctx2","nSamples","percent","newImageData","delta","chooseRightDelta","uniform2fv","uDelta","blurScale","brightnessDefaultValues","brightness","Brightness","uBrightness","colorMatrixDefaultValues","colorsOnly","ColorMatrix","constants","uniformMatrix4fv","uColorMatrix","uConstants","createColorMatrixFilter","_Class","newClass","Brownie","Vintage","Kodachrome","Technicolor","Polaroid","Sepia","BlackWhite","Composed","subFilters","enlivedFilters","contrastDefaultValues","contrast","Contrast","contrastF","uContrast","Convolute_3_1","Convolute_3_0","Convolute_5_1","Convolute_5_0","Convolute_7_1","Convolute_7_0","Convolute_9_1","Convolute_9_0","convoluteDefaultValues","opaque","Convolute","weights","side","halfSide","sw","sh","createImageData","dst","alphaFac","dstOff","scx","scy","srcOff","wt","uniform1fv","uMatrix","GAMMA","gammaDefaultValues","gamma","Gamma","rInv","gInv","bInv","rgbValues","rgb","uniform3fv","uGamma","lightness","luminosity","grayscaleDefaultValues","Grayscale","uMode","hueRotationDefaultValues","rotation","HueRotation","cosine","sine","aThird","aThirdSqtSin","OneMinusCos","invertDefaultValues","invert","Invert","uInvert","uAlpha","noiseDefaultValues","noise","Noise","rand","uNoise","uSeed","pixelateDefaultValues","blocksize","Pixelate","_i","_j","uBlocksize","removeColorDefaultValues","useAlpha","RemoveColor","lowC","highC","uLow","uHigh","resizeDefaultValues","resizeType","lanczosLobes","Resize","uTaps","taps","getFilterWindow","tempScale","filterWindow","generateShader","getTaps","lobeFunction","lanczosCreate","applyToForWebgl","dW","dH","lobes","xx","rcpScaleX","rcpScaleY","oW","oH","newData","sliceByTwo","hermiteFastResize","bilinearFiltering","lanczosResize","mult","doneW","doneH","stepW","stepH","dX","dY","tmpCanvas","process","u","weight","fX","fY","ratioX","icenter","ratioY","range2X","cacheLanc","range2Y","lanczos","rcpRatioX","rcpRatioY","srcData","destData","destImg","xDiff","yDiff","chnl","origPix","w4","pixels","destImage","destPixels","ratioW","ratioH","ratioWHalf","ratioHHalf","img2","data2","weightsAlpha","gxR","gxG","gxB","gxA","yy","w0","saturationDefaultValues","saturation","Saturation","adjust","uSaturation","vibranceDefaultValues","vibrance","Vibrance","amt","uVibrance","StaticCanvasBase","createPNGStream","opts","createJPEGStream","CanvasBase"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,MAAMA,iBAAiB,CAAC;EAAAC,WAAA,GAAA;AACtB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAbEC,IAAAA,eAAA,oCAc4B,CAAC,CAAA,CAAA;AAE7B;AACF;AACA;AAFEA,IAAAA,eAAA,cAGM,EAAE,CAAA,CAAA;AAER;AACF;AACA;AACA;IAHEA,eAAA,CAAA,IAAA,EAAA,kBAAA,EAKE,OAAOC,MAAM,KAAK,WAAW,GAAGA,MAAM,CAACC,gBAAgB,GAAG,CAAC,CAAA,CAAA;AAAE;AAE/D;AACF;AACA;AACA;AACA;AACA;AALEF,IAAAA,eAAA,6BAMqB,OAAO,CAAA,CAAA;AAE5B;AACF;AACA;AACA;AACA;AACA;AALEA,IAAAA,eAAA,4BAMoB,IAAI,CAAA,CAAA;AAExB;AACF;AACA;AACA;AACA;AACA;AALEA,IAAAA,eAAA,4BAMoB,GAAG,CAAA,CAAA;AAEvB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AAPEA,IAAAA,eAAA,gCAQwB,KAAK,CAAA,CAAA;AAE7B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AAPEA,IAAAA,eAAA,4BAQoB,IAAI,CAAA,CAAA;AAExB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AATEA,IAAAA,eAAA,sBAUc,IAAI,CAAA,CAAA;AAElB;AACF;AACA;AACA;AACA;AACA;AACA;AANEA,IAAAA,eAAA,8BAOsB,KAAK,CAAA,CAAA;AAE3B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AAPEA,IAAAA,eAAA,8BAQsB,KAAK,CAAA,CAAA;AAE3B;AACF;AACA;AACA;IAHEA,eAAA,CAAA,IAAA,EAAA,WAAA,EAIwE,EAAE,CAAA,CAAA;AAE1E;AACF;AACA;AACA;AACA;AAJEA,IAAAA,eAAA,8BAKsB,CAAC,CAAA,CAAA;AAAA,GAAA;AACzB,CAAA;AAEO,MAAMG,aAAa,SAASL,iBAAiB,CAAC;EACnDC,WAAWA,CAACK,MAAuB,EAAE;AACnC,IAAA,KAAK,EAAE,CAAA;AACP,IAAA,IAAI,CAACC,SAAS,CAACD,MAAM,CAAC,CAAA;AACxB,GAAA;AAEAC,EAAAA,SAASA,GAA8B;AAAA,IAAA,IAA7BD,MAAsB,GAAAE,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;AACnCG,IAAAA,MAAM,CAACC,MAAM,CAAC,IAAI,EAAEN,MAAM,CAAC,CAAA;AAC7B,GAAA;;AAEA;AACF;AACA;AACEO,EAAAA,QAAQA,GAEN;AAAA,IAAA,IADAC,KAAiE,GAAAN,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;AAEtE,IAAA,IAAI,CAACO,SAAS,GAAAC,cAAA,CAAAA,cAAA,CACT,EAAA,EAAA,IAAI,CAACD,SAAS,CACdD,EAAAA,KAAK,CACT,CAAA;AACH,GAAA;AAEAG,EAAAA,WAAWA,GAA6B;AAAA,IAAA,IAA5BC,WAAqB,GAAAV,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;AACpCU,IAAAA,WAAW,CAACC,OAAO,CAAEC,UAAU,IAAK;AAClC,MAAA,OAAO,IAAI,CAACL,SAAS,CAACK,UAAU,CAAC,CAAA;AACnC,KAAC,CAAC,CAAA;AACJ,GAAA;AAEAC,EAAAA,UAAUA,GAAG;AACX,IAAA,IAAI,CAACN,SAAS,GAAG,EAAE,CAAA;AACrB,GAAA;EAEAO,eAAeA,CAA8BC,IAAkB,EAAE;AAC/D,IAAA,MAAMC,QAAQ,GAAG,IAAIxB,iBAAiB,EAAO,CAAA;AAC7C,IAAA,MAAMM,MAAM,GACV,CAAAiB,IAAI,aAAJA,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJA,IAAI,CAAEE,MAAM,CAAC,CAACC,GAAG,EAAEC,GAAG,KAAK;AACzBD,MAAAA,GAAG,CAACC,GAAG,CAAC,GAAGH,QAAQ,CAACG,GAAG,CAAC,CAAA;AACxB,MAAA,OAAOD,GAAG,CAAA;AACZ,KAAC,EAAE,EAAO,CAAC,KAAIF,QAAQ,CAAA;AACzB,IAAA,IAAI,CAACjB,SAAS,CAACD,MAAM,CAAC,CAAA;AACxB,GAAA;AACF,CAAA;MAEaA,MAAM,GAAG,IAAID,aAAa;;ACnKhC,MAAMuB,GAAG,GAAG,UACjBC,QAAkC,EAAA;EAAA,KAAAC,IAAAA,IAAA,GAAAtB,SAAA,CAAAC,MAAA,EAC/BsB,cAAc,OAAAC,KAAA,CAAAF,IAAA,GAAAA,CAAAA,GAAAA,IAAA,WAAAG,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAH,IAAA,EAAAG,IAAA,EAAA,EAAA;AAAdF,IAAAA,cAAc,CAAAE,IAAA,GAAAzB,CAAAA,CAAAA,GAAAA,SAAA,CAAAyB,IAAA,CAAA,CAAA;AAAA,GAAA;AAAA,EAAA;AAEjB;AACAC,IAAAA,OAAO,CAACL,QAAQ,CAAC,CAAC,QAAQ,EAAE,GAAGE,cAAc,CAAA;AAAC,IAAA;AAAA,CAAA,CAAA;AAEzC,MAAMI,WAAW,SAASC,KAAK,CAAC;AACrCnC,EAAAA,WAAWA,CAACoC,OAAgB,EAAEC,OAAsB,EAAE;AACpD,IAAA,KAAK,YAAAC,MAAA,CAAYF,OAAO,CAAA,EAAIC,OAAO,CAAC,CAAA;AACtC,GAAA;AACF,CAAA;AAEO,MAAME,kBAAkB,SAASL,WAAW,CAAC;EAClDlC,WAAWA,CAACwC,OAAe,EAAE;AAC3B,IAAA,KAAK,CAAAF,EAAAA,CAAAA,MAAA,CAAIE,OAAO,4CAAyC,CAAC,CAAA;AAC5D,GAAA;AACF;;ACfO,MAAeC,OAAO,CAAC;;ACE9B;AACA;AACA;AACO,MAAMC,UAAU,SAASD,OAAO,CAAC;AAGtC;AACF;AACA;AACA;AACA;AACA;AACUE,EAAAA,aAAaA,CACnBC,EAAyB,EACzBC,SAAsB,EACb;AACT,IAAA,MAAMC,cAAc,GAAA,YAAA,CAAAR,MAAA,CAAgBO,SAAS,EAAwB,wBAAA,CAAA,CAAA;IACrE,MAAME,cAAc,GAAGH,EAAE,CAACI,YAAY,CAACJ,EAAE,CAACK,eAAe,CAAC,CAAA;IAC1D,IAAI,CAACF,cAAc,EAAE;AACnB,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;AACAH,IAAAA,EAAE,CAACM,YAAY,CAACH,cAAc,EAAED,cAAc,CAAC,CAAA;AAC/CF,IAAAA,EAAE,CAACO,aAAa,CAACJ,cAAc,CAAC,CAAA;IAChC,OAAO,CAAC,CAACH,EAAE,CAACQ,kBAAkB,CAACL,cAAc,EAAEH,EAAE,CAACS,cAAc,CAAC,CAAA;AACnE,GAAA;;AAEA;AACF;AACA;EACEC,UAAUA,CAACC,MAAyB,EAAE;AACpC,IAAA,MAAMX,EAAE,GAAGW,MAAM,CAACC,UAAU,CAAC,OAAO,CAAC,CAAA;AACrC,IAAA,IAAIZ,EAAE,EAAE;MACN,IAAI,CAACa,cAAc,GAAGb,EAAE,CAACc,YAAY,CAACd,EAAE,CAACe,gBAAgB,CAAC,CAAA;MAC1D,IAAI,CAACC,WAAW,GAAI,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAWC,IAAI,CAC5DhB,SAAS,IAAK,IAAI,CAACF,aAAa,CAACC,EAAE,EAAEC,SAAS,CACjD,CAAC,CAAA;MACDD,EAAE,CAACkB,YAAY,CAAC,oBAAoB,CAAC,CAAEC,WAAW,EAAE,CAAA;MACpDpC,GAAG,CAAC,KAAK,EAAAW,0BAAAA,CAAAA,MAAA,CAA6B,IAAI,CAACmB,cAAc,CAAE,CAAC,CAAA;AAC9D,KAAA;AACF,GAAA;EAEAO,WAAWA,CAACC,WAAmB,EAAE;IAC/B,OAAO,CAAC,CAAC,IAAI,CAACR,cAAc,IAAI,IAAI,CAACA,cAAc,IAAIQ,WAAW,CAAA;AACpE,GAAA;AACF;;AChDA;AAIA,MAAMC,eAA6B,GAAG,EAAE,CAAA;AAEjC,MAAMC,QAAM,GAAGA,MAAkB;EACtC,OAAO;IACLC,QAAQ;IACRlE,MAAM;IACNmE,gBAAgB,EACd,cAAc,IAAInE,MAAM,IACxB,cAAc,IAAIkE,QAAQ,IACzBlE,MAAM,IAAIA,MAAM,CAACoE,SAAS,IAAIpE,MAAM,CAACoE,SAAS,CAACC,cAAc,GAAG,CAAE;AACrE7B,IAAAA,UAAU,EAAE,IAAIA,UAAU,EAAE;AAC5B8B,IAAAA,OAAOA,GAAG;AACR;KACD;AACDN,mBAAAA,eAAAA;GACD,CAAA;AACH,CAAC;;ACpBD;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA,IAAIO,GAAe,CAAA;;AAEnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACaC,MAAAA,MAAM,GAAIC,KAAiB,IAAK;AAC3CF,EAAAA,GAAG,GAAGE,KAAK,CAAA;AACb,EAAC;;AAED;AACA;AACA;AACaR,MAAAA,QAAM,GAAGA,MAAMM,GAAG,KAAKA,GAAG,GAAGG,QAAa,EAAE,EAAC;AAEnD,MAAMC,iBAAiB,GAAGA,MAAgBV,QAAM,EAAE,CAACC,SAAQ;AAE3D,MAAMU,eAAe,GAAGA,MAC7BX,QAAM,EAAE,CAACjE,OAAM;;AAEjB;AACA;AACA;AACO,MAAM6E,mBAAmB,GAAGA,MAAA;AAAA,EAAA,IAAAC,qBAAA,CAAA;EAAA,OACjCC,IAAI,CAACC,GAAG,CAAA,CAAAF,qBAAA,GAAC3E,MAAM,CAACF,gBAAgB,MAAA,IAAA,IAAA6E,qBAAA,KAAAA,KAAAA,CAAAA,GAAAA,qBAAA,GAAIF,eAAe,EAAE,CAAC3E,gBAAgB,EAAE,CAAC,CAAC,CAAA;AAAA,CAAA;;AC5C5E;AACA;AACA;AACA;AACA;AACO,MAAMgF,WAAW,SAAS1C,OAAO,CAAC;AACvCa,EAAAA,UAAUA,GAAG;AACX;AAAA,GAAA;AAEFU,EAAAA,WAAWA,GAAG;AACZ,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;AACF;;ACdA;;AAQA,MAAM;AAAEoB,EAAAA,cAAc,EAAEC,mBAAAA;AAAoB,CAAC,GAAGC,KAAK,CAAA;AAErD,MAAMpB,aAA6B,GAAG,EAAE,CAAA;AAExC,MAAM;AAAEhE,EAAAA,MAAM,EAAEqF,WAAAA;AAAY,CAAC,GAAG,IAAIC,KAAK,CACvCC,kBAAkB,CAChB,4FACF,CAAC,EACD;AACEC,EAAAA,SAAS,EAAE,QAAQ;AACnB;AACAC,EAAAA,iBAAiB,EAAE,IAAA;AACrB,CACF,CAAC,CAAA;AAEM,MAAMC,aAAa,GAAIC,QAA2B,IAAK;AAC5D,EAAA,MAAMC,IAAI,GAAGT,mBAAmB,CAACQ,QAAQ,CAAC,CAAA;AAC1C,EAAA,OAAQC,IAAI,CAACC,OAAO,IAAID,IAAI,CAACE,MAAM,CAAA;AACrC,CAAC,CAAA;AAEM,MAAMxB,OAAO,GAAIyB,OAAgB,IAAK;AAC3C,EAAA,MAAMH,IAAI,GAAGT,mBAAmB,CAACY,OAAO,CAAC,CAAA;AACzC,EAAA,IAAIH,IAAI,EAAE;IACRA,IAAI,CAACE,MAAM,GAAG,IAAI,CAAA;IAClBF,IAAI,CAACC,OAAO,GAAG,IAAI,CAAA;AACnB;IACAD,IAAI,CAACI,WAAW,GAAG,IAAI,CAAA;IACvBJ,IAAI,CAACK,WAAW,GAAG,IAAI,CAAA;IACvBL,IAAI,CAACM,UAAU,GAAG,IAAI,CAAA;AACxB,GAAA;AACF,CAAC,CAAA;AAEM,MAAMjC,MAAM,GAAGA,MAAkB;EACtC,OAAO;IACLC,QAAQ,EAAEmB,WAAW,CAACnB,QAAQ;AAC9BlE,IAAAA,MAAM,EAAEqF,WAAW;AACnBlB,IAAAA,gBAAgB,EAAE,KAAK;AACvB3B,IAAAA,UAAU,EAAE,IAAIyC,WAAW,EAAE;IAC7BX,OAAO;AACPN,IAAAA,aAAAA;GACD,CAAA;AACH,CAAC;;AC9CM,MAAMmC,KAAK,CAAC;EAAArG,WAAA,GAAA;AACjB;AACF;AACA;IAFEC,eAAA,CAAA,IAAA,EAAA,iBAAA,EASI,EAAE,CAAA,CAAA;AAiEN;AACF;AACA;AACA;AACA;AACA;AACA;AACA;IAPEA,eAAA,CAAA,IAAA,EAAA,oBAAA,EAQkD,EAAE,CAAA,CAAA;AAAA,GAAA;AAvEpD;AACF;AACA;EACEqG,YAAYA,CAAAC,IAAA,EAQT;IAAA,IARU;MACXpF,UAAU;MACVqF,SAAS;AACTC,MAAAA,UAAAA;AAKF,KAAC,GAAAF,IAAA,CAAA;AACCpF,IAAAA,UAAU,GAAGA,UAAU,CAACuF,WAAW,EAAE,CAAA;AACrC,IAAA,IAAI,CAAC,IAAI,CAACC,eAAe,CAACxF,UAAU,CAAC,EAAE;AACrC,MAAA,IAAI,CAACwF,eAAe,CAACxF,UAAU,CAAC,GAAG,EAAE,CAAA;AACvC,KAAA;AACA,IAAA,MAAMyF,SAAS,GAAG,IAAI,CAACD,eAAe,CAACxF,UAAU,CAAC,CAAA;IAClD,MAAM0F,QAAQ,MAAAvE,MAAA,CAAMkE,SAAS,CAACE,WAAW,EAAE,EAAA,GAAA,CAAA,CAAApE,MAAA,CAAI,CAC7CmE,UAAU,GAAG,EAAE,EACfC,WAAW,EAAE,CAAE,CAAA;AACjB,IAAA,IAAI,CAACE,SAAS,CAACC,QAAQ,CAAC,EAAE;AACxBD,MAAAA,SAAS,CAACC,QAAQ,CAAC,GAAG,EAAE,CAAA;AAC1B,KAAA;IACA,OAAOD,SAAS,CAACC,QAAQ,CAAC,CAAA;AAC5B,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEC,cAAcA,CAAC3F,UAAmB,EAAE;IAClCA,UAAU,GAAG,CAACA,UAAU,IAAI,EAAE,EAAEuF,WAAW,EAAE,CAAA;IAC7C,IAAI,CAACvF,UAAU,EAAE;AACf,MAAA,IAAI,CAACwF,eAAe,GAAG,EAAE,CAAA;KAC1B,MAAM,IAAI,IAAI,CAACA,eAAe,CAACxF,UAAU,CAAC,EAAE;AAC3C,MAAA,OAAO,IAAI,CAACwF,eAAe,CAACxF,UAAU,CAAC,CAAA;AACzC,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;EACE4F,eAAeA,CAACC,EAAU,EAAE;IAC1B,MAAM;AAAEC,MAAAA,kBAAAA;AAAmB,KAAC,GAAG5G,MAAM,CAAA;IACrC,MAAM6G,UAAU,GAAGjC,IAAI,CAACkC,IAAI,CAACF,kBAAkB,GAAGD,EAAE,CAAC,CAAA;AACrD;AACA;AACA,IAAA,OAAO,CACL/B,IAAI,CAACmC,KAAK,CAACF,UAAU,CAAC,EACtBjC,IAAI,CAACmC,KAAK,CAACH,kBAAkB,GAAGC,UAAU,CAAC,CAC5C,CAAA;AACH,GAAA;AAWF,CAAA;MAEaG,KAAK,GAAG,IAAIhB,KAAK;;;;ACxF9B;AAGO,MAAMiB,OAAO,GAAGC,QAAO;AAC9B;AACO,SAASC,IAAIA,GAAG,EAAC;AAEjB,MAAMC,MAAM,GAAGxC,IAAI,CAACyC,EAAE,GAAG,CAAC,CAAA;AAC1B,MAAMC,SAAS,GAAG1C,IAAI,CAACyC,EAAE,GAAG,CAAC,CAAA;AAC7B,MAAME,OAAO,GAAG3C,IAAI,CAACyC,EAAE,GAAG,GAAG,CAAA;AAE7B,MAAMG,OAAO,GAAGnH,MAAM,CAACoH,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAW;AAC3D,MAAMC,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAMC,cAAc,GAAG,CAAC,CAAA;;AAE/B;AACO,MAAMC,KAAK,GAAG,CAAC,GAAG,YAAY,CAAA;AAE9B,MAAMC,MAAM,GAAG,QAAQ,CAAA;AACvB,MAAMC,IAAI,GAAG,MAAM,CAAA;AACnB,MAAMC,GAAG,GAAG,KAAK,CAAA;AACjB,MAAMC,MAAM,GAAG,QAAQ,CAAA;AACvB,MAAMC,KAAK,GAAG,OAAO,CAAA;AACrB,MAAMC,IAAI,GAAG,MAAM,CAAA;AAEnB,MAAMC,SAAS,GAAG,OAAO,CAAA;AAEzB,MAAMC,MAAM,GAAG,QAAQ,CAAA;AACvB,MAAMC,OAAO,GAAG,SAAS,CAAA;AACzB,MAAMC,QAAQ,GAAG,UAAU,CAAA;AAC3B,MAAMC,MAAM,GAAG,QAAQ,CAAA;AACvB,MAAMC,OAAO,GAAG,SAAS,CAAA;AACzB,MAAMC,QAAQ,GAAG,UAAU,CAAA;AAC3B,MAAMC,WAAW,GAAG,YAAY,CAAA;AAChC,MAAMC,WAAW,GAAG,YAAY,CAAA;AAChC,MAAMC,OAAO,GAAG,SAAS,CAAA;AACzB,MAAMC,KAAK,GAAG,OAAO,CAAA;AACrB,MAAMC,OAAO,GAAG,QAAQ,CAAA;AACxB,MAAMC,OAAO,GAAG,QAAQ,CAAA;AACxB,MAAMC,MAAM,GAAG,OAAO,CAAA;AACtB,MAAMC,MAAM,GAAG,OAAO,CAAA;AACtB,MAAMC,IAAI,GAAG,MAAM,CAAA;AACnB,MAAMC,MAAM,GAAG,QAAQ,CAAA;AACvB,MAAMC,QAAQ,GAAG,UAAU;;AC1ClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEO,MAAMC,MAAI,GAAG,MAAM,CAAA;AACnB,MAAMC,GAAG,GAAG,KAAK,CAAA;AAEjB,MAAMC,aAAa,CAAC;AAIzB5J,EAAAA,WAAWA,GAAG;AACZ,IAAA,IAAI,CAAC0J,MAAI,CAAC,GAAG,IAAIG,GAAG,EAAE,CAAA;AACtB,IAAA,IAAI,CAACF,GAAG,CAAC,GAAG,IAAIE,GAAG,EAAE,CAAA;AACvB,GAAA;EAEAC,GAAGA,CAACC,SAAiB,EAAW;IAC9B,OAAO,IAAI,CAACL,MAAI,CAAC,CAACI,GAAG,CAACC,SAAS,CAAC,CAAA;AAClC,GAAA;EAEAC,QAAQA,CAAID,SAAiB,EAAK;IAChC,MAAM/J,WAAW,GAAG,IAAI,CAAC0J,MAAI,CAAC,CAACO,GAAG,CAACF,SAAS,CAAC,CAAA;IAC7C,IAAI,CAAC/J,WAAW,EAAE;AAChB,MAAA,MAAM,IAAIkC,WAAW,CAAA,0BAAA,CAAAI,MAAA,CAA4ByH,SAAS,CAAE,CAAC,CAAA;AAC/D,KAAA;AACA,IAAA,OAAO/J,WAAW,CAAA;AACpB,GAAA;AAEAkK,EAAAA,QAAQA,CAACC,gBAAqB,EAAEJ,SAAkB,EAAE;AAClD,IAAA,IAAIA,SAAS,EAAE;MACb,IAAI,CAACL,MAAI,CAAC,CAACU,GAAG,CAACL,SAAS,EAAEI,gBAAgB,CAAC,CAAA;AAC7C,KAAC,MAAM;MACL,IAAI,CAACT,MAAI,CAAC,CAACU,GAAG,CAACD,gBAAgB,CAACE,IAAI,EAAEF,gBAAgB,CAAC,CAAA;AACvD;AACA;AACA,MAAA,IAAI,CAACT,MAAI,CAAC,CAACU,GAAG,CAACD,gBAAgB,CAACE,IAAI,CAAC3D,WAAW,EAAE,EAAEyD,gBAAgB,CAAC,CAAA;AACvE,KAAA;AACF,GAAA;EAEAG,WAAWA,CAACC,UAAkB,EAAO;IACnC,OAAO,IAAI,CAACZ,GAAG,CAAC,CAACM,GAAG,CAACM,UAAU,CAAC,CAAA;AAClC,GAAA;AAEAC,EAAAA,WAAWA,CAACL,gBAAqB,EAAEI,UAAmB,EAAE;IACtD,IAAI,CAACZ,GAAG,CAAC,CAACS,GAAG,CACXG,UAAU,aAAVA,UAAU,KAAA,KAAA,CAAA,GAAVA,UAAU,GAAIJ,gBAAgB,CAACE,IAAI,CAAC3D,WAAW,EAAE,EACjDyD,gBACF,CAAC,CAAA;AACH,GAAA;AACF,CAAA;MAEaM,aAAa,GAAG,IAAIb,aAAa;;ACzD9C;AACA;AACA;AACA,MAAMc,iBAAiB,SAAS3I,KAAK,CAAgB;AACnD;AACF;AACA;AACA;EACE4I,MAAMA,CAACnI,OAAsB,EAAE;AAC7B,IAAA,MAAMoI,KAAK,GAAG,IAAI,CAACC,OAAO,CAACrI,OAAO,CAAC,CAAA;IACnCoI,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI,CAACE,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC,CAAA;AACrC,GAAA;;AAEA;AACF;AACA;AACEG,EAAAA,SAASA,GAAG;AACV,IAAA,MAAMC,UAAU,GAAG,IAAI,CAACF,MAAM,CAAC,CAAC,CAAC,CAAA;IACjCE,UAAU,CAAC9J,OAAO,CAAE+J,SAAS,IAAKA,SAAS,CAACC,KAAK,EAAE,CAAC,CAAA;AACpD,IAAA,OAAOF,UAAU,CAAA;AACnB,GAAA;;AAEA;AACF;AACA;AACA;EACEG,cAAcA,CAAC5H,MAAoB,EAAE;IACnC,IAAI,CAACA,MAAM,EAAE;AACX,MAAA,OAAO,EAAE,CAAA;AACX,KAAA;AACA,IAAA,MAAMyH,UAAU,GAAG,IAAI,CAACI,MAAM,CAC3BH,SAAS,IAAA;AAAA,MAAA,IAAAI,iBAAA,CAAA;MAAA,OACRJ,SAAS,CAACK,MAAM,KAAK/H,MAAM,IAC1B,OAAO0H,SAAS,CAACK,MAAM,KAAK,QAAQ,IACnC,EAAAD,iBAAA,GAACJ,SAAS,CAACK,MAAM,MAAA,IAAA,IAAAD,iBAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAjBA,iBAAA,CAAoC9H,MAAM,MAAKA,MAAO,CAAA;AAAA,KAC5D,CAAC,CAAA;IACDyH,UAAU,CAAC9J,OAAO,CAAE+J,SAAS,IAAKA,SAAS,CAACC,KAAK,EAAE,CAAC,CAAA;AACpD,IAAA,OAAOF,UAAU,CAAA;AACnB,GAAA;;AAEA;AACF;AACA;AACA;EACEO,cAAcA,CAACD,MAA+B,EAAE;IAC9C,IAAI,CAACA,MAAM,EAAE;AACX,MAAA,OAAO,EAAE,CAAA;AACX,KAAA;AACA,IAAA,MAAMN,UAAU,GAAG,IAAI,CAACI,MAAM,CAAEH,SAAS,IAAKA,SAAS,CAACK,MAAM,KAAKA,MAAM,CAAC,CAAA;IAC1EN,UAAU,CAAC9J,OAAO,CAAE+J,SAAS,IAAKA,SAAS,CAACC,KAAK,EAAE,CAAC,CAAA;AACpD,IAAA,OAAOF,UAAU,CAAA;AACnB,GAAA;AACF,CAAA;MAEaQ,iBAAiB,GAAG,IAAId,iBAAiB;;ACpDtD;AACA;AACA;AACA;AACO,MAAMe,UAAU,CAAY;EAAAzL,WAAA,GAAA;IAAAC,eAAA,CAAA,IAAA,EAAA,kBAAA,EAE/B,EAAE,CAAA,CAAA;AAAA,GAAA;AAEJ;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AAMEyL,EAAAA,EAAEA,CACAC,IAAwC,EACxCC,OAA2B,EACb;AACd,IAAA,IAAI,CAAC,IAAI,CAACC,gBAAgB,EAAE;AAC1B,MAAA,IAAI,CAACA,gBAAgB,GAAG,EAA+C,CAAA;AACzE,KAAA;AACA,IAAA,IAAI,OAAOF,IAAI,KAAK,QAAQ,EAAE;AAC5B;MACAjL,MAAM,CAACoL,OAAO,CAACH,IAAI,CAAC,CAACzK,OAAO,CAACqF,IAAA,IAA0B;AAAA,QAAA,IAAzB,CAACwF,SAAS,EAAEH,OAAO,CAAC,GAAArF,IAAA,CAAA;AAChD,QAAA,IAAI,CAACmF,EAAE,CAACK,SAAS,EAAOH,OAAyB,CAAC,CAAA;AACpD,OAAC,CAAC,CAAA;AACF,MAAA,OAAO,MAAM,IAAI,CAACI,GAAG,CAACL,IAAI,CAAC,CAAA;KAC5B,MAAM,IAAIC,OAAO,EAAE;MAClB,MAAMG,SAAS,GAAGJ,IAAI,CAAA;AACtB,MAAA,IAAI,CAAC,IAAI,CAACE,gBAAgB,CAACE,SAAS,CAAC,EAAE;AACrC,QAAA,IAAI,CAACF,gBAAgB,CAACE,SAAS,CAAC,GAAG,EAAE,CAAA;AACvC,OAAA;MACA,IAAI,CAACF,gBAAgB,CAACE,SAAS,CAAC,CAACE,IAAI,CAACL,OAAO,CAAC,CAAA;MAC9C,OAAO,MAAM,IAAI,CAACI,GAAG,CAACD,SAAS,EAAEH,OAAO,CAAC,CAAA;AAC3C,KAAC,MAAM;AACL;AACA,MAAA,OAAO,MAAM,KAAK,CAAA;AACpB,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;AAMEM,EAAAA,IAAIA,CACFP,IAAwC,EACxCC,OAA2B,EACb;AACd,IAAA,IAAI,OAAOD,IAAI,KAAK,QAAQ,EAAE;AAC5B;MACA,MAAMQ,SAAyB,GAAG,EAAE,CAAA;MACpCzL,MAAM,CAACoL,OAAO,CAACH,IAAI,CAAC,CAACzK,OAAO,CAACkL,KAAA,IAA0B;AAAA,QAAA,IAAzB,CAACL,SAAS,EAAEH,OAAO,CAAC,GAAAQ,KAAA,CAAA;QAChDD,SAAS,CAACF,IAAI,CAAC,IAAI,CAACC,IAAI,CAACH,SAAS,EAAOH,OAAyB,CAAC,CAAC,CAAA;AACtE,OAAC,CAAC,CAAA;MACF,OAAO,MAAMO,SAAS,CAACjL,OAAO,CAAEmL,CAAC,IAAKA,CAAC,EAAE,CAAC,CAAA;KAC3C,MAAM,IAAIT,OAAO,EAAE;MAClB,MAAMU,QAAQ,GAAG,IAAI,CAACZ,EAAE,CACtBC,IAAI,EACJ,SAASY,WAAWA,GAAuC;AAAA,QAAA,KAAA,IAAA1K,IAAA,GAAAtB,SAAA,CAAAC,MAAA,EAANgM,IAAI,GAAAzK,IAAAA,KAAA,CAAAF,IAAA,GAAAG,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAH,IAAA,EAAAG,IAAA,EAAA,EAAA;AAAJwK,UAAAA,IAAI,CAAAxK,IAAA,CAAAzB,GAAAA,SAAA,CAAAyB,IAAA,CAAA,CAAA;AAAA,SAAA;AACvD4J,QAAAA,OAAO,CAACa,IAAI,CAAC,IAAI,EAAE,GAAGD,IAAI,CAAC,CAAA;AAC3BF,QAAAA,QAAQ,EAAE,CAAA;AACZ,OACF,CAAC,CAAA;AACD,MAAA,OAAOA,QAAQ,CAAA;AACjB,KAAC,MAAM;AACL;AACA,MAAA,OAAO,MAAM,KAAK,CAAA;AACpB,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACUI,EAAAA,oBAAoBA,CAC1BX,SAAY,EACZH,OAAwB,EACxB;AACA,IAAA,IAAI,CAAC,IAAI,CAACC,gBAAgB,CAACE,SAAS,CAAC,EAAE;AACrC,MAAA,OAAA;AACF,KAAA;AAEA,IAAA,IAAIH,OAAO,EAAE;AACX,MAAA,MAAMe,aAAa,GAAG,IAAI,CAACd,gBAAgB,CAACE,SAAS,CAAC,CAAA;AACtD,MAAA,MAAMnB,KAAK,GAAG+B,aAAa,CAAC9B,OAAO,CAACe,OAAO,CAAC,CAAA;MAC5ChB,KAAK,GAAG,CAAC,CAAC,IAAI+B,aAAa,CAAC7B,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC,CAAA;AAC9C,KAAC,MAAM;AACL,MAAA,IAAI,CAACiB,gBAAgB,CAACE,SAAS,CAAC,GAAG,EAAE,CAAA;AACvC,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;;AAEE;AACF;AACA;AACA;AACA;;AAEE;AACF;AACA;AACA;;AAEE;AACF;AACA;;AAEEC,EAAAA,GAAGA,CACDL,IAAyC,EACzCC,OAAwB,EACxB;AACA,IAAA,IAAI,CAAC,IAAI,CAACC,gBAAgB,EAAE;AAC1B,MAAA,OAAA;AACF,KAAA;;AAEA;AACA,IAAA,IAAI,OAAOF,IAAI,KAAK,WAAW,EAAE;AAC/B,MAAA,KAAK,MAAMI,SAAS,IAAI,IAAI,CAACF,gBAAgB,EAAE;AAC7C,QAAA,IAAI,CAACa,oBAAoB,CAACX,SAAS,CAAC,CAAA;AACtC,OAAA;AACF,KAAA;AACA;AAAA,SACK,IAAI,OAAOJ,IAAI,KAAK,QAAQ,EAAE;MACjCjL,MAAM,CAACoL,OAAO,CAACH,IAAI,CAAC,CAACzK,OAAO,CAAC0L,KAAA,IAA0B;AAAA,QAAA,IAAzB,CAACb,SAAS,EAAEH,OAAO,CAAC,GAAAgB,KAAA,CAAA;AAChD,QAAA,IAAI,CAACF,oBAAoB,CAACX,SAAS,EAAOH,OAAyB,CAAC,CAAA;AACtE,OAAC,CAAC,CAAA;AACJ,KAAC,MAAM;AACL,MAAA,IAAI,CAACc,oBAAoB,CAACf,IAAI,EAAEC,OAAO,CAAC,CAAA;AAC1C,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACEiB,EAAAA,IAAIA,CAA4Bd,SAAY,EAAE1J,OAAsB,EAAE;AAAA,IAAA,IAAAyK,qBAAA,CAAA;AACpE,IAAA,IAAI,CAAC,IAAI,CAACjB,gBAAgB,EAAE;AAC1B,MAAA,OAAA;AACF,KAAA;AAEA,IAAA,MAAMkB,iBAAiB,GAAAD,CAAAA,qBAAA,GAAG,IAAI,CAACjB,gBAAgB,CAACE,SAAS,CAAC,cAAAe,qBAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAhCA,qBAAA,CAAkCxK,MAAM,EAAE,CAAA;AACpE,IAAA,IAAIyK,iBAAiB,EAAE;AACrB,MAAA,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGD,iBAAiB,CAACvM,MAAM,EAAEwM,CAAC,EAAE,EAAE;AACjDD,QAAAA,iBAAiB,CAACC,CAAC,CAAC,CAACP,IAAI,CAAC,IAAI,EAAEpK,OAAO,IAAI,EAAE,CAAC,CAAA;AAChD,OAAA;AACF,KAAA;AACF,GAAA;AACF;;AClLA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM4K,eAAe,GAAGA,CAAIC,KAAU,EAAEvI,KAAQ,KAAU;AAC/D,EAAA,MAAMwI,GAAG,GAAGD,KAAK,CAACrC,OAAO,CAAClG,KAAK,CAAC,CAAA;AAChC,EAAA,IAAIwI,GAAG,KAAK,CAAC,CAAC,EAAE;AACdD,IAAAA,KAAK,CAACpC,MAAM,CAACqC,GAAG,EAAE,CAAC,CAAC,CAAA;AACtB,GAAA;AACA,EAAA,OAAOD,KAAK,CAAA;AACd,CAAC;;ACVD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,GAAG,GAAIC,KAAc,IAAa;EAC7C,IAAIA,KAAK,KAAK,CAAC,EAAE;AACf,IAAA,OAAO,CAAC,CAAA;AACV,GAAA;EACA,MAAMC,UAAU,GAAGrI,IAAI,CAACsI,GAAG,CAACF,KAAK,CAAC,GAAG5F,MAAM,CAAA;AAC3C,EAAA,QAAQ6F,UAAU;AAChB,IAAA,KAAK,CAAC,CAAA;AACN,IAAA,KAAK,CAAC;AACJ,MAAA,OAAO,CAAC,CAAA;AACV,IAAA,KAAK,CAAC;AACJ,MAAA,OAAO,CAAC,CAAC,CAAA;AACb,GAAA;AACA,EAAA,OAAOrI,IAAI,CAACmI,GAAG,CAACC,KAAK,CAAC,CAAA;AACxB,CAAC;;ACpBD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,GAAG,GAAIH,KAAc,IAAa;EAC7C,IAAIA,KAAK,KAAK,CAAC,EAAE;AACf,IAAA,OAAO,CAAC,CAAA;AACV,GAAA;AACA,EAAA,MAAMC,UAAU,GAAGD,KAAK,GAAG5F,MAAM,CAAA;AACjC,EAAA,MAAM9C,KAAK,GAAGM,IAAI,CAACwI,IAAI,CAACJ,KAAK,CAAC,CAAA;AAC9B,EAAA,QAAQC,UAAU;AAChB,IAAA,KAAK,CAAC;AACJ,MAAA,OAAO3I,KAAK,CAAA;AACd,IAAA,KAAK,CAAC;AACJ,MAAA,OAAO,CAAC,CAAA;AACV,IAAA,KAAK,CAAC;AACJ,MAAA,OAAO,CAACA,KAAK,CAAA;AACjB,GAAA;AACA,EAAA,OAAOM,IAAI,CAACuI,GAAG,CAACH,KAAK,CAAC,CAAA;AACxB,CAAC;;AChBD;AACA;AACA;AACO,MAAMK,KAAK,CAAe;AAQ/B1N,EAAAA,WAAWA,GAA+B;AAAA,IAAA,IAA9B2L,IAAiB,GAAApL,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,CAAC,CAAA;AAAA,IAAA,IAAEoN,CAAC,GAAApN,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,CAAC,CAAA;AACtC,IAAA,IAAI,OAAOoL,IAAI,KAAK,QAAQ,EAAE;AAC5B,MAAA,IAAI,CAACiC,CAAC,GAAGjC,IAAI,CAACiC,CAAC,CAAA;AACf,MAAA,IAAI,CAACD,CAAC,GAAGhC,IAAI,CAACgC,CAAC,CAAA;AACjB,KAAC,MAAM;MACL,IAAI,CAACC,CAAC,GAAGjC,IAAI,CAAA;MACb,IAAI,CAACgC,CAAC,GAAGA,CAAC,CAAA;AACZ,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEE,GAAGA,CAACC,IAAQ,EAAS;AACnB,IAAA,OAAO,IAAIJ,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGE,IAAI,CAACF,CAAC,EAAE,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEI,SAASA,CAACD,IAAQ,EAAS;AACzB,IAAA,IAAI,CAACF,CAAC,IAAIE,IAAI,CAACF,CAAC,CAAA;AAChB,IAAA,IAAI,CAACD,CAAC,IAAIG,IAAI,CAACH,CAAC,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEK,SAASA,CAACC,MAAc,EAAS;AAC/B,IAAA,OAAO,IAAIP,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGK,MAAM,EAAE,IAAI,CAACN,CAAC,GAAGM,MAAM,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEC,eAAeA,CAACD,MAAc,EAAS;IACrC,IAAI,CAACL,CAAC,IAAIK,MAAM,CAAA;IAChB,IAAI,CAACN,CAAC,IAAIM,MAAM,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEE,QAAQA,CAACL,IAAQ,EAAS;AACxB,IAAA,OAAO,IAAIJ,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGE,IAAI,CAACF,CAAC,EAAE,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACES,cAAcA,CAACN,IAAQ,EAAS;AAC9B,IAAA,IAAI,CAACF,CAAC,IAAIE,IAAI,CAACF,CAAC,CAAA;AAChB,IAAA,IAAI,CAACD,CAAC,IAAIG,IAAI,CAACH,CAAC,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEU,cAAcA,CAACJ,MAAc,EAAS;AACpC,IAAA,OAAO,IAAIP,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGK,MAAM,EAAE,IAAI,CAACN,CAAC,GAAGM,MAAM,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEK,oBAAoBA,CAACL,MAAc,EAAS;IAC1C,IAAI,CAACL,CAAC,IAAIK,MAAM,CAAA;IAChB,IAAI,CAACN,CAAC,IAAIM,MAAM,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEM,QAAQA,CAACT,IAAQ,EAAS;AACxB,IAAA,OAAO,IAAIJ,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGE,IAAI,CAACF,CAAC,EAAE,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEa,cAAcA,CAACP,MAAc,EAAS;AACpC,IAAA,OAAO,IAAIP,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGK,MAAM,EAAE,IAAI,CAACN,CAAC,GAAGM,MAAM,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEQ,oBAAoBA,CAACR,MAAc,EAAS;IAC1C,IAAI,CAACL,CAAC,IAAIK,MAAM,CAAA;IAChB,IAAI,CAACN,CAAC,IAAIM,MAAM,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACES,MAAMA,CAACZ,IAAQ,EAAS;AACtB,IAAA,OAAO,IAAIJ,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGE,IAAI,CAACF,CAAC,EAAE,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEgB,YAAYA,CAACV,MAAc,EAAS;AAClC,IAAA,OAAO,IAAIP,KAAK,CAAC,IAAI,CAACE,CAAC,GAAGK,MAAM,EAAE,IAAI,CAACN,CAAC,GAAGM,MAAM,CAAC,CAAA;AACpD,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACEW,kBAAkBA,CAACX,MAAc,EAAS;IACxC,IAAI,CAACL,CAAC,IAAIK,MAAM,CAAA;IAChB,IAAI,CAACN,CAAC,IAAIM,MAAM,CAAA;AAChB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEY,EAAEA,CAACf,IAAQ,EAAW;AACpB,IAAA,OAAO,IAAI,CAACF,CAAC,KAAKE,IAAI,CAACF,CAAC,IAAI,IAAI,CAACD,CAAC,KAAKG,IAAI,CAACH,CAAC,CAAA;AAC/C,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEmB,EAAEA,CAAChB,IAAQ,EAAW;AACpB,IAAA,OAAO,IAAI,CAACF,CAAC,GAAGE,IAAI,CAACF,CAAC,IAAI,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAA;AAC3C,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEoB,GAAGA,CAACjB,IAAQ,EAAW;AACrB,IAAA,OAAO,IAAI,CAACF,CAAC,IAAIE,IAAI,CAACF,CAAC,IAAI,IAAI,CAACD,CAAC,IAAIG,IAAI,CAACH,CAAC,CAAA;AAC7C,GAAA;;AAEA;AACF;AACA;AACA;AACA;EAEEqB,EAAEA,CAAClB,IAAQ,EAAW;AACpB,IAAA,OAAO,IAAI,CAACF,CAAC,GAAGE,IAAI,CAACF,CAAC,IAAI,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAA;AAC3C,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEsB,GAAGA,CAACnB,IAAQ,EAAW;AACrB,IAAA,OAAO,IAAI,CAACF,CAAC,IAAIE,IAAI,CAACF,CAAC,IAAI,IAAI,CAACD,CAAC,IAAIG,IAAI,CAACH,CAAC,CAAA;AAC7C,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;EACEuB,IAAIA,CAACpB,IAAQ,EAAkB;AAAA,IAAA,IAAhBqB,CAAC,GAAA5O,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,GAAG,CAAA;AACpB4O,IAAAA,CAAC,GAAGlK,IAAI,CAACC,GAAG,CAACD,IAAI,CAACmK,GAAG,CAAC,CAAC,EAAED,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAC/B,IAAA,OAAO,IAAIzB,KAAK,CACd,IAAI,CAACE,CAAC,GAAG,CAACE,IAAI,CAACF,CAAC,GAAG,IAAI,CAACA,CAAC,IAAIuB,CAAC,EAC9B,IAAI,CAACxB,CAAC,GAAG,CAACG,IAAI,CAACH,CAAC,GAAG,IAAI,CAACA,CAAC,IAAIwB,CAC/B,CAAC,CAAA;AACH,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEE,YAAYA,CAACvB,IAAQ,EAAU;IAC7B,MAAMwB,EAAE,GAAG,IAAI,CAAC1B,CAAC,GAAGE,IAAI,CAACF,CAAC;AACxB2B,MAAAA,EAAE,GAAG,IAAI,CAAC5B,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAA;IACtB,OAAO1I,IAAI,CAACkC,IAAI,CAACmI,EAAE,GAAGA,EAAE,GAAGC,EAAE,GAAGA,EAAE,CAAC,CAAA;AACrC,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEC,YAAYA,CAAC1B,IAAQ,EAAS;AAC5B,IAAA,OAAO,IAAI,CAACoB,IAAI,CAACpB,IAAI,CAAC,CAAA;AACxB,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEsB,GAAGA,CAACtB,IAAQ,EAAS;AACnB,IAAA,OAAO,IAAIJ,KAAK,CAACzI,IAAI,CAACmK,GAAG,CAAC,IAAI,CAACxB,CAAC,EAAEE,IAAI,CAACF,CAAC,CAAC,EAAE3I,IAAI,CAACmK,GAAG,CAAC,IAAI,CAACzB,CAAC,EAAEG,IAAI,CAACH,CAAC,CAAC,CAAC,CAAA;AACtE,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEzI,GAAGA,CAAC4I,IAAQ,EAAS;AACnB,IAAA,OAAO,IAAIJ,KAAK,CAACzI,IAAI,CAACC,GAAG,CAAC,IAAI,CAAC0I,CAAC,EAAEE,IAAI,CAACF,CAAC,CAAC,EAAE3I,IAAI,CAACC,GAAG,CAAC,IAAI,CAACyI,CAAC,EAAEG,IAAI,CAACH,CAAC,CAAC,CAAC,CAAA;AACtE,GAAA;;AAEA;AACF;AACA;AACA;AACE8B,EAAAA,QAAQA,GAAW;IACjB,OAAAnN,EAAAA,CAAAA,MAAA,CAAU,IAAI,CAACsL,CAAC,OAAAtL,MAAA,CAAI,IAAI,CAACqL,CAAC,CAAA,CAAA;AAC5B,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACE+B,EAAAA,KAAKA,CAAC9B,CAAS,EAAED,CAAS,EAAE;IAC1B,IAAI,CAACC,CAAC,GAAGA,CAAC,CAAA;IACV,IAAI,CAACD,CAAC,GAAGA,CAAC,CAAA;AACV,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEgC,IAAIA,CAAC/B,CAAS,EAAE;IACd,IAAI,CAACA,CAAC,GAAGA,CAAC,CAAA;AACV,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEgC,IAAIA,CAACjC,CAAS,EAAE;IACd,IAAI,CAACA,CAAC,GAAGA,CAAC,CAAA;AACV,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEkC,YAAYA,CAAC/B,IAAQ,EAAE;AACrB,IAAA,IAAI,CAACF,CAAC,GAAGE,IAAI,CAACF,CAAC,CAAA;AACf,IAAA,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAA;AACf,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;EACEmC,IAAIA,CAAChC,IAAQ,EAAE;AACb,IAAA,MAAMF,CAAC,GAAG,IAAI,CAACA,CAAC;MACdD,CAAC,GAAG,IAAI,CAACA,CAAC,CAAA;AACZ,IAAA,IAAI,CAACC,CAAC,GAAGE,IAAI,CAACF,CAAC,CAAA;AACf,IAAA,IAAI,CAACD,CAAC,GAAGG,IAAI,CAACH,CAAC,CAAA;IACfG,IAAI,CAACF,CAAC,GAAGA,CAAC,CAAA;IACVE,IAAI,CAACH,CAAC,GAAGA,CAAC,CAAA;AACZ,GAAA;;AAEA;AACF;AACA;AACA;AACEoC,EAAAA,KAAKA,GAAU;IACb,OAAO,IAAIrC,KAAK,CAAC,IAAI,CAACE,CAAC,EAAE,IAAI,CAACD,CAAC,CAAC,CAAA;AAClC,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEqC,MAAMA,CAACC,OAAgB,EAA4B;AAAA,IAAA,IAA1BC,MAAU,GAAA3P,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG4P,IAAI,CAAA;AACxC;AACA;AACA,IAAA,MAAMC,KAAK,GAAG5C,GAAG,CAACyC,OAAO,CAAC;AACxBI,MAAAA,OAAO,GAAGjD,GAAG,CAAC6C,OAAO,CAAC,CAAA;AACxB,IAAA,MAAMK,CAAC,GAAG,IAAI,CAACnC,QAAQ,CAAC+B,MAAM,CAAC,CAAA;AAC/B,IAAA,MAAMK,OAAO,GAAG,IAAI7C,KAAK,CACvB4C,CAAC,CAAC1C,CAAC,GAAGyC,OAAO,GAAGC,CAAC,CAAC3C,CAAC,GAAGyC,KAAK,EAC3BE,CAAC,CAAC1C,CAAC,GAAGwC,KAAK,GAAGE,CAAC,CAAC3C,CAAC,GAAG0C,OACtB,CAAC,CAAA;AACD,IAAA,OAAOE,OAAO,CAAC1C,GAAG,CAACqC,MAAM,CAAC,CAAA;AAC5B,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;EACEM,SAASA,CAACrB,CAAS,EAA+B;AAAA,IAAA,IAA7BsB,YAAY,GAAAlQ,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,KAAK,CAAA;IACvC,OAAO,IAAImN,KAAK,CACdyB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAACvB,CAAC,GAAGuB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAACxB,CAAC,IAAI8C,YAAY,GAAG,CAAC,GAAGtB,CAAC,CAAC,CAAC,CAAC,CAAC,EACzDA,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAACvB,CAAC,GAAGuB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAACxB,CAAC,IAAI8C,YAAY,GAAG,CAAC,GAAGtB,CAAC,CAAC,CAAC,CAAC,CAC1D,CAAC,CAAA;AACH,GAAA;AACF,CAAA;AAEO,MAAMgB,IAAI,GAAG,IAAIzC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;;AC3X5B,MAAMgD,YAAY,GACvBC,YAA2B,IACiB;EAC5C,OAAO,CAAC,CAACA,YAAY,IAAI5O,KAAK,CAAC6O,OAAO,CAAED,YAAY,CAAWE,QAAQ,CAAC,CAAA;AAC1E,CAAC,CAAA;AAEM,SAASC,qBAAqBA,CAA4BC,IAAW,EAAE;EAC5E,MAAMC,UAAU,SAASD,IAAI,CAAC;IAAA/Q,WAAA,GAAA;AAAA,MAAA,KAAA,CAAA,GAAAO,SAAA,CAAA,CAAA;AAC5B;AACJ;AACA;AACA;AAHIN,MAAAA,eAAA,mBAI2B,EAAE,CAAA,CAAA;AAAA,KAAA;AAE7B;IACAgR,cAAcA,CAACC,MAAoB,EAAE;AACnC;AAAA,KAAA;;AAGF;IACAC,gBAAgBA,CAACD,MAAoB,EAAE;AACrC;AAAA,KAAA;;AAGF;IACAE,oBAAoBA,CAACF,MAAoB,EAAE;AACzC;AAAA,KAAA;;AAGF;AACJ;AACA;AACA;AACA;AACA;AACIrD,IAAAA,GAAGA,GAAqC;AAAA,MAAA,KAAA,IAAAhM,IAAA,GAAAtB,SAAA,CAAAC,MAAA,EAAjC6Q,OAAO,GAAAtP,IAAAA,KAAA,CAAAF,IAAA,GAAAG,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAH,IAAA,EAAAG,IAAA,EAAA,EAAA;AAAPqP,QAAAA,OAAO,CAAArP,IAAA,CAAAzB,GAAAA,SAAA,CAAAyB,IAAA,CAAA,CAAA;AAAA,OAAA;MACZ,MAAMsP,IAAI,GAAG,IAAI,CAACT,QAAQ,CAAC5E,IAAI,CAAC,GAAGoF,OAAO,CAAC,CAAA;MAC3CA,OAAO,CAACnQ,OAAO,CAAEgQ,MAAM,IAAK,IAAI,CAACD,cAAc,CAACC,MAAM,CAAC,CAAC,CAAA;AACxD,MAAA,OAAOI,IAAI,CAAA;AACb,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;IACIC,QAAQA,CAAC3G,KAAa,EAA8B;MAAA,KAAA4G,IAAAA,KAAA,GAAAjR,SAAA,CAAAC,MAAA,EAAzB6Q,OAAO,OAAAtP,KAAA,CAAAyP,KAAA,GAAAA,CAAAA,GAAAA,KAAA,WAAAC,KAAA,GAAA,CAAA,EAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA,EAAA,EAAA;AAAPJ,QAAAA,OAAO,CAAAI,KAAA,GAAAlR,CAAAA,CAAAA,GAAAA,SAAA,CAAAkR,KAAA,CAAA,CAAA;AAAA,OAAA;MAChC,IAAI,CAACZ,QAAQ,CAAC/F,MAAM,CAACF,KAAK,EAAE,CAAC,EAAE,GAAGyG,OAAO,CAAC,CAAA;MAC1CA,OAAO,CAACnQ,OAAO,CAAEgQ,MAAM,IAAK,IAAI,CAACD,cAAc,CAACC,MAAM,CAAC,CAAC,CAAA;AACxD,MAAA,OAAO,IAAI,CAACL,QAAQ,CAACrQ,MAAM,CAAA;AAC7B,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACImK,IAAAA,MAAMA,GAA6B;AACjC,MAAA,MAAMuC,KAAK,GAAG,IAAI,CAAC2D,QAAQ;AACzBa,QAAAA,OAAuB,GAAG,EAAE,CAAA;AAAC,MAAA,KAAA,IAAAC,KAAA,GAAApR,SAAA,CAAAC,MAAA,EAFvB6Q,OAAO,GAAAtP,IAAAA,KAAA,CAAA4P,KAAA,GAAAC,KAAA,GAAA,CAAA,EAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA,EAAA,EAAA;AAAPP,QAAAA,OAAO,CAAAO,KAAA,CAAArR,GAAAA,SAAA,CAAAqR,KAAA,CAAA,CAAA;AAAA,OAAA;AAGfP,MAAAA,OAAO,CAACnQ,OAAO,CAAEgQ,MAAM,IAAK;AAC1B,QAAA,MAAMtG,KAAK,GAAGsC,KAAK,CAACrC,OAAO,CAACqG,MAAM,CAAC,CAAA;AACnC;AACA,QAAA,IAAItG,KAAK,KAAK,CAAC,CAAC,EAAE;AAChBsC,UAAAA,KAAK,CAACpC,MAAM,CAACF,KAAK,EAAE,CAAC,CAAC,CAAA;AACtB8G,UAAAA,OAAO,CAACzF,IAAI,CAACiF,MAAM,CAAC,CAAA;AACpB,UAAA,IAAI,CAACC,gBAAgB,CAACD,MAAM,CAAC,CAAA;AAC/B,SAAA;AACF,OAAC,CAAC,CAAA;AACF,MAAA,OAAOQ,OAAO,CAAA;AAChB,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIG,aAAaA,CACXC,QAIQ,EACR;MACA,IAAI,CAACC,UAAU,EAAE,CAAC7Q,OAAO,CAAC,CAACgQ,MAAM,EAAEtG,KAAK,EAAEyG,OAAO,KAC/CS,QAAQ,CAACZ,MAAM,EAAEtG,KAAK,EAAEyG,OAAO,CACjC,CAAC,CAAA;AACH,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACIU,IAAAA,UAAUA,GAAqB;AAAA,MAAA,KAAA,IAAAC,KAAA,GAAAzR,SAAA,CAAAC,MAAA,EAAjByR,KAAK,GAAAlQ,IAAAA,KAAA,CAAAiQ,KAAA,GAAAE,KAAA,GAAA,CAAA,EAAAA,KAAA,GAAAF,KAAA,EAAAE,KAAA,EAAA,EAAA;AAALD,QAAAA,KAAK,CAAAC,KAAA,CAAA3R,GAAAA,SAAA,CAAA2R,KAAA,CAAA,CAAA;AAAA,OAAA;AACjB,MAAA,IAAID,KAAK,CAACzR,MAAM,KAAK,CAAC,EAAE;AACtB,QAAA,OAAO,CAAC,GAAG,IAAI,CAACqQ,QAAQ,CAAC,CAAA;AAC3B,OAAA;AACA,MAAA,OAAO,IAAI,CAACA,QAAQ,CAACzF,MAAM,CAAE+G,CAAC,IAAKA,CAAC,CAACC,MAAM,CAAC,GAAGH,KAAK,CAAC,CAAC,CAAA;AACxD,KAAA;;AAEA;AACJ;AACA;AACA;AACA;IACII,IAAIA,CAACzH,KAAa,EAAE;AAClB,MAAA,OAAO,IAAI,CAACiG,QAAQ,CAACjG,KAAK,CAAC,CAAA;AAC7B,KAAA;;AAEA;AACJ;AACA;AACA;AACI0H,IAAAA,OAAOA,GAAG;AACR,MAAA,OAAO,IAAI,CAACzB,QAAQ,CAACrQ,MAAM,KAAK,CAAC,CAAA;AACnC,KAAA;;AAEA;AACJ;AACA;AACA;AACI8Q,IAAAA,IAAIA,GAAG;AACL,MAAA,OAAO,IAAI,CAACT,QAAQ,CAACrQ,MAAM,CAAA;AAC7B,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACI+R,IAAAA,QAAQA,CAACrB,MAAoB,EAAEsB,IAAc,EAAW;MACtD,IAAI,IAAI,CAAC3B,QAAQ,CAAC4B,QAAQ,CAACvB,MAAM,CAAC,EAAE;AAClC,QAAA,OAAO,IAAI,CAAA;OACZ,MAAM,IAAIsB,IAAI,EAAE;QACf,OAAO,IAAI,CAAC3B,QAAQ,CAAC6B,IAAI,CACtBC,GAAG,IACFA,GAAG,YAAY3B,UAAU,IACxB2B,GAAG,CAA2BJ,QAAQ,CAACrB,MAAM,EAAE,IAAI,CACxD,CAAC,CAAA;AACH,OAAA;AACA,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;;AAEA;AACJ;AACA;AACA;AACI0B,IAAAA,UAAUA,GAAG;MACX,OAAO,IAAI,CAAC/B,QAAQ,CAACrP,MAAM,CAAC,CAACqR,IAAI,EAAEC,OAAO,KAAK;QAC7CD,IAAI,IAAIC,OAAO,CAACF,UAAU,GAAGE,OAAO,CAACF,UAAU,EAAE,GAAG,CAAC,CAAA;AACrD,QAAA,OAAOC,IAAI,CAAA;OACZ,EAAE,CAAC,CAAC,CAAA;AACP,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;IACIE,gBAAgBA,CAAC7B,MAAoB,EAAE;MACrC,IAAI,CAACA,MAAM,IAAIA,MAAM,KAAK,IAAI,CAACL,QAAQ,CAAC,CAAC,CAAC,EAAE;AAC1C,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;AACA5D,MAAAA,eAAe,CAAC,IAAI,CAAC4D,QAAQ,EAAEK,MAAM,CAAC,CAAA;AACtC,MAAA,IAAI,CAACL,QAAQ,CAACmC,OAAO,CAAC9B,MAAM,CAAC,CAAA;AAC7B,MAAA,IAAI,CAACE,oBAAoB,CAACF,MAAM,CAAC,CAAA;AACjC,MAAA,OAAO,IAAI,CAAA;AACb,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;IACI+B,kBAAkBA,CAAC/B,MAAoB,EAAE;AACvC,MAAA,IAAI,CAACA,MAAM,IAAIA,MAAM,KAAK,IAAI,CAACL,QAAQ,CAAC,IAAI,CAACA,QAAQ,CAACrQ,MAAM,GAAG,CAAC,CAAC,EAAE;AACjE,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;AACAyM,MAAAA,eAAe,CAAC,IAAI,CAAC4D,QAAQ,EAAEK,MAAM,CAAC,CAAA;AACtC,MAAA,IAAI,CAACL,QAAQ,CAAC5E,IAAI,CAACiF,MAAM,CAAC,CAAA;AAC1B,MAAA,IAAI,CAACE,oBAAoB,CAACF,MAAM,CAAC,CAAA;AACjC,MAAA,OAAO,IAAI,CAAA;AACb,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIgC,IAAAA,mBAAmBA,CAAChC,MAAoB,EAAEiC,YAAsB,EAAE;MAChE,IAAI,CAACjC,MAAM,EAAE;AACX,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;MACA,MAAM/D,GAAG,GAAG,IAAI,CAAC0D,QAAQ,CAAChG,OAAO,CAACqG,MAAM,CAAC,CAAA;MACzC,IAAI/D,GAAG,KAAK,CAAC,EAAE;AACb;QACA,MAAMiG,MAAM,GAAG,IAAI,CAACC,iBAAiB,CAACnC,MAAM,EAAE/D,GAAG,EAAEgG,YAAY,CAAC,CAAA;AAChElG,QAAAA,eAAe,CAAC,IAAI,CAAC4D,QAAQ,EAAEK,MAAM,CAAC,CAAA;QACtC,IAAI,CAACL,QAAQ,CAAC/F,MAAM,CAACsI,MAAM,EAAE,CAAC,EAAElC,MAAM,CAAC,CAAA;AACvC,QAAA,IAAI,CAACE,oBAAoB,CAACF,MAAM,CAAC,CAAA;AACjC,QAAA,OAAO,IAAI,CAAA;AACb,OAAA;AACA,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACIoC,IAAAA,kBAAkBA,CAACpC,MAAoB,EAAEiC,YAAsB,EAAE;MAC/D,IAAI,CAACjC,MAAM,EAAE;AACX,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;MACA,MAAM/D,GAAG,GAAG,IAAI,CAAC0D,QAAQ,CAAChG,OAAO,CAACqG,MAAM,CAAC,CAAA;MACzC,IAAI/D,GAAG,KAAK,IAAI,CAAC0D,QAAQ,CAACrQ,MAAM,GAAG,CAAC,EAAE;AACpC;QACA,MAAM4S,MAAM,GAAG,IAAI,CAACG,iBAAiB,CAACrC,MAAM,EAAE/D,GAAG,EAAEgG,YAAY,CAAC,CAAA;AAChElG,QAAAA,eAAe,CAAC,IAAI,CAAC4D,QAAQ,EAAEK,MAAM,CAAC,CAAA;QACtC,IAAI,CAACL,QAAQ,CAAC/F,MAAM,CAACsI,MAAM,EAAE,CAAC,EAAElC,MAAM,CAAC,CAAA;AACvC,QAAA,IAAI,CAACE,oBAAoB,CAACF,MAAM,CAAC,CAAA;AACjC,QAAA,OAAO,IAAI,CAAA;AACb,OAAA;AACA,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACIsC,IAAAA,YAAYA,CAACtC,MAAoB,EAAEtG,KAAa,EAAE;MAChD,IAAIsG,MAAM,KAAK,IAAI,CAACL,QAAQ,CAACjG,KAAK,CAAC,EAAE;AACnC,QAAA,OAAO,KAAK,CAAA;AACd,OAAA;AACAqC,MAAAA,eAAe,CAAC,IAAI,CAAC4D,QAAQ,EAAEK,MAAM,CAAC,CAAA;MACtC,IAAI,CAACL,QAAQ,CAAC/F,MAAM,CAACF,KAAK,EAAE,CAAC,EAAEsG,MAAM,CAAC,CAAA;AACtC,MAAA,IAAI,CAACE,oBAAoB,CAACF,MAAM,CAAC,CAAA;AACjC,MAAA,OAAO,IAAI,CAAA;AACb,KAAA;AAEAmC,IAAAA,iBAAiBA,CACfnC,MAAoB,EACpB/D,GAAW,EACXgG,YAAsB,EACtB;AACA,MAAA,IAAIC,MAAM,CAAA;AAEV,MAAA,IAAID,YAAY,EAAE;AAChBC,QAAAA,MAAM,GAAGjG,GAAG,CAAA;AACZ;AACA,QAAA,KAAK,IAAIH,CAAC,GAAGG,GAAG,GAAG,CAAC,EAAEH,CAAC,IAAI,CAAC,EAAE,EAAEA,CAAC,EAAE;UACjC,IAAIkE,MAAM,CAACuC,aAAa,CAAC,IAAI,CAAC5C,QAAQ,CAAC7D,CAAC,CAAC,CAAC,EAAE;AAC1CoG,YAAAA,MAAM,GAAGpG,CAAC,CAAA;AACV,YAAA,MAAA;AACF,WAAA;AACF,SAAA;AACF,OAAC,MAAM;QACLoG,MAAM,GAAGjG,GAAG,GAAG,CAAC,CAAA;AAClB,OAAA;AAEA,MAAA,OAAOiG,MAAM,CAAA;AACf,KAAA;AAEAG,IAAAA,iBAAiBA,CACfrC,MAAoB,EACpB/D,GAAW,EACXgG,YAAsB,EACtB;AACA,MAAA,IAAIC,MAAM,CAAA;AAEV,MAAA,IAAID,YAAY,EAAE;AAChBC,QAAAA,MAAM,GAAGjG,GAAG,CAAA;AACZ;AACA,QAAA,KAAK,IAAIH,CAAC,GAAGG,GAAG,GAAG,CAAC,EAAEH,CAAC,GAAG,IAAI,CAAC6D,QAAQ,CAACrQ,MAAM,EAAE,EAAEwM,CAAC,EAAE;UACnD,IAAIkE,MAAM,CAACuC,aAAa,CAAC,IAAI,CAAC5C,QAAQ,CAAC7D,CAAC,CAAC,CAAC,EAAE;AAC1CoG,YAAAA,MAAM,GAAGpG,CAAC,CAAA;AACV,YAAA,MAAA;AACF,WAAA;AACF,SAAA;AACF,OAAC,MAAM;QACLoG,MAAM,GAAGjG,GAAG,GAAG,CAAC,CAAA;AAClB,OAAA;AAEA,MAAA,OAAOiG,MAAM,CAAA;AACf,KAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;IACIM,cAAcA,CAAAnN,IAAA,EAGZ;MAAA,IAFA;QAAEoN,IAAI;QAAEC,GAAG;QAAEC,KAAK;AAAEC,QAAAA,MAAAA;AAAc,OAAC,GAAAvN,IAAA,CAAA;MAAA,IACnC;AAAEwN,QAAAA,mBAAmB,GAAG,IAAA;AAAwC,OAAC,GAAAxT,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;MAEtE,MAAM8Q,OAAkC,GAAG,EAAE;AAC3C2C,QAAAA,EAAE,GAAG,IAAItG,KAAK,CAACiG,IAAI,EAAEC,GAAG,CAAC;AACzBK,QAAAA,EAAE,GAAGD,EAAE,CAACnG,GAAG,CAAC,IAAIH,KAAK,CAACmG,KAAK,EAAEC,MAAM,CAAC,CAAC,CAAA;;AAEvC;AACA,MAAA,KAAK,IAAI9G,CAAC,GAAG,IAAI,CAAC6D,QAAQ,CAACrQ,MAAM,GAAG,CAAC,EAAEwM,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;AAClD,QAAA,MAAMkE,MAAM,GAAG,IAAI,CAACL,QAAQ,CAAC7D,CAAC,CAAuC,CAAA;QACrE,IACEkE,MAAM,CAACgD,UAAU,IACjBhD,MAAM,CAACiD,OAAO,KACZJ,mBAAmB,IAAI7C,MAAM,CAACkD,kBAAkB,CAACJ,EAAE,EAAEC,EAAE,CAAC,IACxD/C,MAAM,CAACmD,qBAAqB,CAACL,EAAE,EAAEC,EAAE,CAAC,IACnCF,mBAAmB,IAAI7C,MAAM,CAACoD,aAAa,CAACN,EAAE,CAAE,IAChDD,mBAAmB,IAAI7C,MAAM,CAACoD,aAAa,CAACL,EAAE,CAAE,CAAC,EACpD;AACA5C,UAAAA,OAAO,CAACpF,IAAI,CAACiF,MAAM,CAAC,CAAA;AACtB,SAAA;AACF,OAAA;AAEA,MAAA,OAAOG,OAAO,CAAA;AAChB,KAAA;AACF,GAAA;;AAEA;AACA,EAAA,OAAOL,UAAU,CAAA;AACnB;;AChWO,MAAMuD,aAAa,SAAoB9I,UAAU,CAAY;AAClE;AACF;AACA;AACA;AACA;AACY+I,EAAAA,WAAWA,GAAoB;AAAA,IAAA,IAAnBnS,OAAY,GAAA9B,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;AACrC,IAAA,KAAK,MAAMkU,IAAI,IAAIpS,OAAO,EAAE;MAC1B,IAAI,CAAC+H,GAAG,CAACqK,IAAI,EAAEpS,OAAO,CAACoS,IAAI,CAAC,CAAC,CAAA;AAC/B,KAAA;AACF,GAAA;;AAEA;AACF;AACA;EACEC,UAAUA,CAAC/B,GAAwB,EAAE;AACnC,IAAA,KAAK,MAAM8B,IAAI,IAAI9B,GAAG,EAAE;MACtB,IAAI,CAACgC,IAAI,CAACF,IAAI,EAAE9B,GAAG,CAAC8B,IAAI,CAAC,CAAC,CAAA;AAC5B,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACErK,EAAAA,GAAGA,CAAC1I,GAAiC,EAAEiD,KAAW,EAAE;AAClD,IAAA,IAAI,OAAOjD,GAAG,KAAK,QAAQ,EAAE;AAC3B,MAAA,IAAI,CAACgT,UAAU,CAAChT,GAAG,CAAC,CAAA;AACtB,KAAC,MAAM;AACL,MAAA,IAAI,CAACiT,IAAI,CAACjT,GAAG,EAAEiD,KAAK,CAAC,CAAA;AACvB,KAAA;AACA,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AAEAgQ,EAAAA,IAAIA,CAACjT,GAAW,EAAEiD,KAAU,EAAE;AAC5B,IAAA,IAAI,CAACjD,GAAG,CAAe,GAAGiD,KAAK,CAAA;AACjC,GAAA;;AAEA;AACF;AACA;AACA;EACEiQ,MAAMA,CAACC,QAAgB,EAAE;AACvB,IAAA,MAAMlQ,KAAK,GAAG,IAAI,CAACsF,GAAG,CAAC4K,QAAQ,CAAC,CAAA;AAChC,IAAA,IAAI,OAAOlQ,KAAK,KAAK,SAAS,EAAE;AAC9B,MAAA,IAAI,CAACyF,GAAG,CAACyK,QAAQ,EAAE,CAAClQ,KAAK,CAAC,CAAA;AAC5B,KAAA;AACA,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACEsF,GAAGA,CAAC4K,QAAgB,EAAO;IACzB,OAAO,IAAI,CAACA,QAAQ,CAAe,CAAA;AACrC,GAAA;AACF;;AC3DO,SAASC,gBAAgBA,CAAChD,QAA8B,EAAU;AACvE,EAAA,OAAOhN,eAAe,EAAE,CAACiQ,qBAAqB,CAACjD,QAAQ,CAAC,CAAA;AAC1D,CAAA;AAEO,SAASkD,eAAeA,CAACC,MAAc,EAAQ;AACpD,EAAA,OAAOnQ,eAAe,EAAE,CAACoQ,oBAAoB,CAACD,MAAM,CAAC,CAAA;AACvD;;ACRA,IAAIE,EAAE,GAAG,CAAC,CAAA;AAEH,MAAMC,GAAG,GAAGA,MAAMD,EAAE,EAAE;;ACC7B;AACA;AACA;AACA;AACO,MAAME,mBAAmB,GAAGA,MAAyB;EAC1D,MAAMpP,OAAO,GAAGpB,iBAAiB,EAAE,CAACyQ,aAAa,CAAC,QAAQ,CAAC,CAAA;EAC3D,IAAI,CAACrP,OAAO,IAAI,OAAOA,OAAO,CAACzC,UAAU,KAAK,WAAW,EAAE;AACzD,IAAA,MAAM,IAAItB,WAAW,CAAC,mCAAmC,CAAC,CAAA;AAC5D,GAAA;AACA,EAAA,OAAO+D,OAAO,CAAA;AAChB,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACO,MAAMsP,WAAW,GAAGA,MACzB1Q,iBAAiB,EAAE,CAACyQ,aAAa,CAAC,KAAK,CAAC,CAAA;;AAE1C;AACA;AACA;AACA;AACA;AACO,MAAME,iBAAiB,GAC5BjS,MAAyB,IACH;AAAA,EAAA,IAAAkS,qBAAA,CAAA;AACtB,EAAA,MAAMC,SAAS,GAAGL,mBAAmB,EAAE,CAAA;AACvCK,EAAAA,SAAS,CAAC7B,KAAK,GAAGtQ,MAAM,CAACsQ,KAAK,CAAA;AAC9B6B,EAAAA,SAAS,CAAC5B,MAAM,GAAGvQ,MAAM,CAACuQ,MAAM,CAAA;EAChC,CAAA2B,qBAAA,GAAAC,SAAS,CAAClS,UAAU,CAAC,IAAI,CAAC,MAAAiS,IAAAA,IAAAA,qBAAA,eAA1BA,qBAAA,CAA4BE,SAAS,CAACpS,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;AACnD,EAAA,OAAOmS,SAAS,CAAA;AAClB,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,SAAS,GAAGA,CACvB/P,QAA2B,EAC3BgQ,MAAmB,EACnBC,OAAe,KACZjQ,QAAQ,CAAC+P,SAAS,CAAAtT,QAAAA,CAAAA,MAAA,CAAUuT,MAAM,CAAA,EAAIC,OAAO,CAAC,CAAA;AAE5C,MAAMC,YAAY,GACvBxS,MAAmC,IACH;EAChC,OAAO,CAAC,CAACA,MAAM,IAAKA,MAAM,CAAuBC,UAAU,KAAK/C,SAAS,CAAA;AAC3E,CAAC;;ACpDD;AACA;AACA;AACA;AACA;AACO,MAAMuV,gBAAgB,GAAIC,OAAgB,IAC9CA,OAAO,GAAGrO,OAAmB,CAAA;;AAEhC;AACA;AACA;AACA;AACA;AACO,MAAMsO,gBAAgB,GAAIjG,OAAgB,IAC9CA,OAAO,GAAGrI,OAAmB;;ACiBzB,MAAMuO,gBAAgB,GAAIC,GAAW,IAC1CA,GAAG,CAACC,KAAK,CAAC,CAAC1R,KAAK,EAAEiG,KAAK,KAAKjG,KAAK,KAAKkD,OAAO,CAAC+C,KAAK,CAAC,CAAC,CAAA;;AAEvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM0L,cAAc,GAAGA,CAC5BhG,CAAK,EACLnB,CAAS,EACTsB,YAAsB,KACZ,IAAI/C,KAAK,CAAC4C,CAAC,CAAC,CAACE,SAAS,CAACrB,CAAC,EAAEsB,YAAY,CAAC,CAAA;;AAEnD;AACA;AACA;AACA;AACA;AACO,MAAM8F,eAAe,GAAIpH,CAAS,IAAa;EACpD,MAAMqH,CAAC,GAAG,CAAC,IAAIrH,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,CAAC;AACvCsH,IAAAA,CAAC,GAAG,CAACD,CAAC,GAAGrH,CAAC,CAAC,CAAC,CAAC,EAAE,CAACqH,CAAC,GAAGrH,CAAC,CAAC,CAAC,CAAC,EAAE,CAACqH,CAAC,GAAGrH,CAAC,CAAC,CAAC,CAAC,EAAEqH,CAAC,GAAGrH,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAW;AAC9D,IAAA;MAAEvB,CAAC;AAAED,MAAAA,CAAAA;KAAG,GAAG,IAAID,KAAK,CAACyB,CAAC,CAAC,CAAC,CAAC,EAAEA,CAAC,CAAC,CAAC,CAAC,CAAC,CAACqB,SAAS,CAACiG,CAAC,EAAE,IAAI,CAAC,CAAA;AACrDA,EAAAA,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC7I,CAAC,CAAA;AACT6I,EAAAA,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC9I,CAAC,CAAA;AACT,EAAA,OAAO8I,CAAC,CAAA;AACV,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,yBAAyB,GAAGA,CACvCF,CAAS,EACTG,CAAS,EACTC,KAAe,KAEf,CACEJ,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,EACzBH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,EACzBH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,EACzBH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,EACzBC,KAAK,GAAG,CAAC,GAAGJ,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,EAC5CI,KAAK,GAAG,CAAC,GAAGJ,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,GAAGH,CAAC,CAAC,CAAC,CAAC,CACnC,CAAA;;AAEb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMK,4BAA4B,GAAGA,CAC1CC,QAA+C,EAC/CF,KAAe,KAEfE,QAAQ,CAACC,WAAW,CAClB,CAACC,OAAe,EAAEC,IAAI,KACpBA,IAAI,IAAID,OAAO,GACXN,yBAAyB,CAACO,IAAI,EAAED,OAAO,EAAEJ,KAAK,CAAC,GAC/CK,IAAI,IAAID,OAAO,EACrBvW,SACF,CAAC,IAAIoH,OAAO,CAACvF,MAAM,EAAE,CAAA;AAEhB,MAAM4U,iBAAiB,GAAG3Q,IAAA,IAAA;AAAA,EAAA,IAAC,CAACiQ,CAAC,EAAEG,CAAC,CAAS,GAAApQ,IAAA,CAAA;AAAA,EAAA,OAC9CtB,IAAI,CAACkS,KAAK,CAACR,CAAC,EAAEH,CAAC,CAAC,CAAA;AAAA,CAAW,CAAA;;AAE7B;AACA;AACA;AACA;AACA;AACO,MAAMY,WAAW,GAAIZ,CAAS,IAAsB;AACzD,EAAA,MAAMnJ,KAAK,GAAG6J,iBAAiB,CAACV,CAAC,CAAC;IAChCa,KAAK,GAAGpS,IAAI,CAACqS,GAAG,CAACd,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAGvR,IAAI,CAACqS,GAAG,CAACd,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC7Ce,IAAAA,MAAM,GAAGtS,IAAI,CAACkC,IAAI,CAACkQ,KAAK,CAAC;IACzBG,MAAM,GAAG,CAAChB,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,IAAIe,MAAM;IAC7CE,KAAK,GAAGxS,IAAI,CAACkS,KAAK,CAACX,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,GAAGA,CAAC,CAAC,CAAC,CAAC,EAAEa,KAAK,CAAC,CAAA;EACtD,OAAO;AACLhK,IAAAA,KAAK,EAAE6I,gBAAgB,CAAC7I,KAAK,CAAC;IAC9BkK,MAAM;IACNC,MAAM;AACNC,IAAAA,KAAK,EAAEvB,gBAAgB,CAACuB,KAAK,CAAC;AAC9BC,IAAAA,KAAK,EAAE,CAAY;AACnBC,IAAAA,UAAU,EAAEnB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrBoB,IAAAA,UAAU,EAAEpB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;GACrB,CAAA;AACH,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMqB,qBAAqB,GAAG,UAACjK,CAAS,EAAA;AAAA,EAAA,IAAED,CAAC,GAAApN,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,CAAC,CAAA;AAAA,EAAA,OAAa,CACjE,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,EACDqN,CAAC,EACDD,CAAC,CACF,CAAA;AAAA,CAAA,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASmK,kBAAkBA,GAGxB;EAAA,IAFR;AAAEzK,IAAAA,KAAK,GAAG,CAAA;AAAqB,GAAC,GAAA9M,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;EAAA,IACrC;AAAEqN,IAAAA,CAAC,GAAG,CAAC;AAAED,IAAAA,CAAC,GAAG,CAAA;AAAe,GAAC,GAAApN,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;AAElC,EAAA,MAAMwX,YAAY,GAAG/B,gBAAgB,CAAC3I,KAAK,CAAC;AAC1C2K,IAAAA,QAAQ,GAAG5K,GAAG,CAAC2K,YAAY,CAAC;AAC5BE,IAAAA,QAAQ,GAAGzK,GAAG,CAACuK,YAAY,CAAC,CAAA;AAC9B,EAAA,OAAO,CACLC,QAAQ,EACRC,QAAQ,EACR,CAACA,QAAQ,EACTD,QAAQ,EACRpK,CAAC,GAAGA,CAAC,IAAIoK,QAAQ,GAAGpK,CAAC,GAAGqK,QAAQ,GAAGtK,CAAC,CAAC,GAAG,CAAC,EACzCA,CAAC,GAAGA,CAAC,IAAIsK,QAAQ,GAAGrK,CAAC,GAAGoK,QAAQ,GAAGrK,CAAC,CAAC,GAAG,CAAC,CAC1C,CAAA;AACH,CAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMuK,iBAAiB,GAAG,UAACtK,CAAS,EAAA;AAAA,EAAA,IAAED,CAAS,GAAApN,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAGqN,CAAC,CAAA;AAAA,EAAA,OAAa,CACrEA,CAAC,EACD,CAAC,EACD,CAAC,EACDD,CAAC,EACD,CAAC,EACD,CAAC,CACF,CAAA;AAAA,CAAA,CAAA;AAEM,MAAMwK,WAAW,GAAI9K,KAAc,IACxCpI,IAAI,CAACmT,GAAG,CAACpC,gBAAgB,CAAC3I,KAAK,CAAC,CAAC,CAAA;;AAKnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMgL,iBAAiB,GAAIC,SAAkB,IAAa,CAC/D,CAAC,EACD,CAAC,EACDH,WAAW,CAACG,SAAS,CAAC,EACtB,CAAC,EACD,CAAC,EACD,CAAC,CACF,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,iBAAiB,GAAID,SAAkB,IAAa,CAC/D,CAAC,EACDH,WAAW,CAACG,SAAS,CAAC,EACtB,CAAC,EACD,CAAC,EACD,CAAC,EACD,CAAC,CACF,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAME,oBAAoB,GAAGpM,KAAA,IAOZ;EAAA,IAPa;AACnCmL,IAAAA,MAAM,GAAG,CAAC;AACVC,IAAAA,MAAM,GAAG,CAAC;AACViB,IAAAA,KAAK,GAAG,KAAK;AACbC,IAAAA,KAAK,GAAG,KAAK;AACbjB,IAAAA,KAAK,GAAG,CAAY;AACpBC,IAAAA,KAAK,GAAG,CAAA;AACQ,GAAC,GAAAtL,KAAA,CAAA;AACjB,EAAA,IAAIuM,MAAM,GAAGT,iBAAiB,CAC5BO,KAAK,GAAG,CAAClB,MAAM,GAAGA,MAAM,EACxBmB,KAAK,GAAG,CAAClB,MAAM,GAAGA,MACpB,CAAC,CAAA;AACD,EAAA,IAAIC,KAAK,EAAE;IACTkB,MAAM,GAAGjC,yBAAyB,CAACiC,MAAM,EAAEN,iBAAiB,CAACZ,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;AAC5E,GAAA;AACA,EAAA,IAAIC,KAAK,EAAE;IACTiB,MAAM,GAAGjC,yBAAyB,CAACiC,MAAM,EAAEJ,iBAAiB,CAACb,KAAK,CAAC,EAAE,IAAI,CAAC,CAAA;AAC5E,GAAA;AACA,EAAA,OAAOiB,MAAM,CAAA;AACf,CAAC,CAAA;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,aAAa,GAAIvW,OAA2B,IAAa;EACpE,MAAM;AAAEsV,IAAAA,UAAU,GAAG,CAAC;AAAEC,IAAAA,UAAU,GAAG,CAAC;AAAEvK,IAAAA,KAAK,GAAG,CAAA;AAAa,GAAC,GAAGhL,OAAO,CAAA;AACxE,EAAA,IAAIsW,MAAM,GAAGd,qBAAqB,CAACF,UAAU,EAAEC,UAAU,CAAC,CAAA;AAC1D,EAAA,IAAIvK,KAAK,EAAE;AACTsL,IAAAA,MAAM,GAAGjC,yBAAyB,CAACiC,MAAM,EAAEb,kBAAkB,CAAC;AAAEzK,MAAAA,KAAAA;AAAM,KAAC,CAAC,CAAC,CAAA;AAC3E,GAAA;AACA,EAAA,MAAMwL,WAAW,GAAGL,oBAAoB,CAACnW,OAAO,CAAC,CAAA;AACjD,EAAA,IAAI,CAAC8T,gBAAgB,CAAC0C,WAAW,CAAC,EAAE;AAClCF,IAAAA,MAAM,GAAGjC,yBAAyB,CAACiC,MAAM,EAAEE,WAAW,CAAC,CAAA;AACzD,GAAA;AACA,EAAA,OAAOF,MAAM,CAAA;AACf,CAAC;;AC5SD;AACA;AACA;AACA;AACA;AACA;AACO,MAAMG,SAAS,GAAG,UACvBC,GAAW,EAAA;EAAA,IACX;IAAEC,MAAM;AAAEC,IAAAA,WAAW,GAAG,IAAA;AAAuB,GAAC,GAAA1Y,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;AAAA,EAAA,OAErD,IAAI2Y,OAAO,CAAmB,UAAUC,OAAO,EAAEC,MAAM,EAAE;AACvD,IAAA,IAAIJ,MAAM,IAAIA,MAAM,CAACK,OAAO,EAAE;AAC5B,MAAA,OAAOD,MAAM,CAAC,IAAI7W,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAA;AACpD,KAAA;AACA,IAAA,MAAM+W,GAAG,GAAG/D,WAAW,EAAE,CAAA;AACzB,IAAA,IAAIrK,KAAyC,CAAA;AAC7C,IAAA,IAAI8N,MAAM,EAAE;AACV9N,MAAAA,KAAK,GAAG,UAAUqO,GAAU,EAAE;QAC5BD,GAAG,CAACE,GAAG,GAAG,EAAE,CAAA;QACZJ,MAAM,CAACG,GAAG,CAAC,CAAA;OACZ,CAAA;AACDP,MAAAA,MAAM,CAACS,gBAAgB,CAAC,OAAO,EAAEvO,KAAK,EAAE;AAAEgB,QAAAA,IAAI,EAAE,IAAA;AAAK,OAAC,CAAC,CAAA;AACzD,KAAA;AACA,IAAA,MAAMwN,IAAI,GAAG,YAAY;AACvBJ,MAAAA,GAAG,CAACK,MAAM,GAAGL,GAAG,CAACM,OAAO,GAAG,IAAI,CAAA;AAC/B1O,MAAAA,KAAK,KAAI8N,MAAM,KAANA,IAAAA,IAAAA,MAAM,KAANA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAM,CAAEa,mBAAmB,CAAC,OAAO,EAAE3O,KAAK,CAAC,CAAA,CAAA;MACpDiO,OAAO,CAACG,GAAG,CAAC,CAAA;KACb,CAAA;IACD,IAAI,CAACP,GAAG,EAAE;AACRW,MAAAA,IAAI,EAAE,CAAA;AACN,MAAA,OAAA;AACF,KAAA;IACAJ,GAAG,CAACK,MAAM,GAAGD,IAAI,CAAA;IACjBJ,GAAG,CAACM,OAAO,GAAG,YAAY;AACxB1O,MAAAA,KAAK,KAAI8N,MAAM,KAANA,IAAAA,IAAAA,MAAM,KAANA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAM,CAAEa,mBAAmB,CAAC,OAAO,EAAE3O,KAAK,CAAC,CAAA,CAAA;MACpDkO,MAAM,CAAC,IAAIlX,WAAW,CAAAI,gBAAAA,CAAAA,MAAA,CAAkBgX,GAAG,CAACE,GAAG,CAAE,CAAC,CAAC,CAAA;KACpD,CAAA;AACDP,IAAAA,WAAW,KAAKK,GAAG,CAACL,WAAW,GAAGA,WAAW,CAAC,CAAA;IAC9CK,GAAG,CAACE,GAAG,GAAGT,GAAG,CAAA;AACf,GAAC,CAAC,CAAA;AAAA,CAAA,CAAA;AAoBJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMe,cAAc,GAAG,UAQ5BzI,OAAc,EAAA;EAAA,IACd;IAAE2H,MAAM;AAAEe,IAAAA,OAAO,GAAGvS,IAAAA;AAA2B,GAAC,GAAAjH,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;AAAA,EAAA,OAErD,IAAI2Y,OAAO,CAAM,CAACC,OAAO,EAAEC,MAAM,KAAK;IACpC,MAAMY,SAAc,GAAG,EAAE,CAAA;IACzBhB,MAAM,IAAIA,MAAM,CAACS,gBAAgB,CAAC,OAAO,EAAEL,MAAM,EAAE;AAAElN,MAAAA,IAAI,EAAE,IAAA;AAAK,KAAC,CAAC,CAAA;IAClEgN,OAAO,CAACe,GAAG,CACT5I,OAAO,CAAC6I,GAAG,CAAEvH,GAAG,IACdlI,aAAa,CACVT,QAAQ,CAIP2I,GAAG,CAACtI,IAAI,CAAC,CACV8P,UAAU,CAACxH,GAAG,EAAE;AAAEqG,MAAAA,MAAAA;AAAO,KAAC,CAAC,CAC3BoB,IAAI,CAAEC,cAAc,IAAK;AACxBN,MAAAA,OAAO,CAACpH,GAAG,EAAE0H,cAAc,CAAC,CAAA;AAC5BL,MAAAA,SAAS,CAAC/N,IAAI,CAACoO,cAAc,CAAC,CAAA;AAC9B,MAAA,OAAOA,cAAc,CAAA;AACvB,KAAC,CACL,CACF,CAAC,CACED,IAAI,CAACjB,OAAO,CAAC,CACbmB,KAAK,CAAEC,KAAK,IAAK;AAChB;AACAP,MAAAA,SAAS,CAAC9Y,OAAO,CAAEsZ,QAAQ,IAAK;AAC7BA,QAAAA,QAAQ,CAAkBhW,OAAO,IAC/BgW,QAAQ,CAAkBhW,OAAO,EAAE,CAAA;AACxC,OAAC,CAAC,CAAA;MACF4U,MAAM,CAACmB,KAAK,CAAC,CAAA;AACf,KAAC,CAAC,CACDE,OAAO,CAAC,MAAM;MACbzB,MAAM,IAAIA,MAAM,CAACa,mBAAmB,CAAC,OAAO,EAAET,MAAM,CAAC,CAAA;AACvD,KAAC,CAAC,CAAA;AACN,GAAC,CAAC,CAAA;AAAA,CAAA,CAAA;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMsB,uBAAuB,GAAG,UAGrCC,gBAAqB,EAAA;EAAA,IACrB;AAAE3B,IAAAA,MAAAA;AAAkB,GAAC,GAAAzY,SAAA,CAAAC,MAAA,GAAAD,CAAAA,IAAAA,SAAA,CAAAE,CAAAA,CAAAA,KAAAA,SAAA,GAAAF,SAAA,CAAG,CAAA,CAAA,GAAA,EAAE,CAAA;AAAA,EAAA,OAE1B,IAAI2Y,OAAO,CAAI,CAACC,OAAO,EAAEC,MAAM,KAAK;IAClC,MAAMY,SAA8C,GAAG,EAAE,CAAA;IACzDhB,MAAM,IAAIA,MAAM,CAACS,gBAAgB,CAAC,OAAO,EAAEL,MAAM,EAAE;AAAElN,MAAAA,IAAI,EAAE,IAAA;AAAK,KAAC,CAAC,CAAA;AAClE;AACA,IAAA,MAAM0O,QAAQ,GAAGla,MAAM,CAACma,MAAM,CAACF,gBAAgB,CAAC,CAACT,GAAG,CAAEvV,KAAU,IAAK;MACnE,IAAI,CAACA,KAAK,EAAE;AACV,QAAA,OAAOA,KAAK,CAAA;AACd,OAAA;AACA;AACN;AACA;AACA;AACA;AACA;AACM,MAAA,IAAIA,KAAK,CAAC0F,IAAI,IAAII,aAAa,CAACX,GAAG,CAACnF,KAAK,CAAC0F,IAAI,CAAC,EAAE;AAC/C,QAAA,OAAOyP,cAAc,CAAkC,CAACnV,KAAK,CAAC,EAAE;AAC9DqU,UAAAA,MAAAA;AACF,SAAC,CAAC,CAACoB,IAAI,CAAC7T,IAAA,IAAe;AAAA,UAAA,IAAd,CAACuU,OAAO,CAAC,GAAAvU,IAAA,CAAA;AAChByT,UAAAA,SAAS,CAAC/N,IAAI,CAAC6O,OAAO,CAAC,CAAA;AACvB,UAAA,OAAOA,OAAO,CAAA;AAChB,SAAC,CAAC,CAAA;AACJ,OAAA;AACA,MAAA,OAAOnW,KAAK,CAAA;AACd,KAAC,CAAC,CAAA;AACF,IAAA,MAAMrD,IAAI,GAAGZ,MAAM,CAACY,IAAI,CAACqZ,gBAAgB,CAAC,CAAA;IAC1CzB,OAAO,CAACe,GAAG,CAACW,QAAQ,CAAC,CAClBR,IAAI,CAAEU,OAAO,IAAK;MACjB,OAAOA,OAAO,CAACtZ,MAAM,CAAC,CAACC,GAAG,EAAE+Y,QAAQ,EAAE5P,KAAK,KAAK;AAC9CnJ,QAAAA,GAAG,CAACH,IAAI,CAACsJ,KAAK,CAAC,CAAC,GAAG4P,QAAQ,CAAA;AAC3B,QAAA,OAAO/Y,GAAG,CAAA;OACX,EAAE,EAAE,CAAC,CAAA;KACP,CAAC,CACD2Y,IAAI,CAACjB,OAAO,CAAC,CACbmB,KAAK,CAAEC,KAAK,IAAK;AAChB;AACAP,MAAAA,SAAS,CAAC9Y,OAAO,CAAEsZ,QAAa,IAAK;AACnCA,QAAAA,QAAQ,CAAChW,OAAO,IAAIgW,QAAQ,CAAChW,OAAO,EAAE,CAAA;AACxC,OAAC,CAAC,CAAA;MACF4U,MAAM,CAACmB,KAAK,CAAC,CAAA;AACf,KAAC,CAAC,CACDE,OAAO,CAAC,MAAM;MACbzB,MAAM,IAAIA,MAAM,CAACa,mBAAmB,CAAC,OAAO,EAAET,MAAM,CAAC,CAAA;AACvD,KAAC,CAAC,CAAA;AACN,GAAC,CAAC,CAAA;AAAA,CAAA;;AC/LJ;AACA;AACA;AACA;AACA;AACA;AACO,MAAM2B,IAAI,GAAG,UAClBC,MAAS,EAEN;AAAA,EAAA,IADH1Z,IAAiB,GAAAf,SAAA,CAAAC,MAAA,GAAA,CAAA,IAAAD,SAAA,CAAA,CAAA,CAAA,KAAAE,SAAA,GAAAF,SAAA,CAAA,CAAA,CAAA,GAAG,EAAE,CAAA;EAEtB,OAAOe,IAAI,CAACE,MAAM,CAAC,CAAC2Q,CAAC,EAAEzQ,GAAG,KAAK;IAC7B,IAAIA,GAAG,IAAIsZ,MAAM,EAAE;AACjB7I,MAAAA,CAAC,CAACzQ,GAAG,CAAC,GAAGsZ,MAAM,CAACtZ,GAAG,CAAC,CAAA;AACtB,KAAA;AACA,IAAA,OAAOyQ,CAAC,CAAA;GACT,EAAE,EAAgB,CAAC,CAAA;AACtB,CAAC,CAAA;AAEM,MAAM8I,MAAM,GAAGA,CACpBD,MAAS,EACTE,SAA6E,KAC1E;AACH,EAAA,OAAQxa,MAAM,CAACY,IAAI,CAAC0Z,MAAM,CAAC,CAAiBxZ,MAAM,CAAC,CAAC2Q,CAAC,EAAEzQ,GAAG,KAAK;IAC7D,IAAIwZ,SAAS,CAACF,MAAM,CAACtZ,GAAG,CAAC,EAAEA,GAAG,EAAEsZ,MAAM,CAAC,EAAE;AACvC7I,MAAAA,CAAC,CAACzQ,GAAG,CAAC,GAAGsZ,MAAM,CAACtZ,GAAG,CAAC,CAAA;AACtB,KAAA;AACA,IAAA,OAAOyQ,CAAC,CAAA;GACT,EAAE,EAAgB,CAAC,CAAA;AACtB,CAAC;;AC5BD;AACA;AACA;AACA;AACO,MAAMgJ,YAAY,GAAG;AAC1BC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,IAAI,EAAE,MAAM;AACZC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,KAAK,EAAE,MAAM;AACbC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,IAAI,EAAE,MAAM;AACZC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,IAAI,EAAE,MAAM;AACZC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,OAAO,EAAE,MAAM;AACfC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,oBAAoB,EAAE,SAAS;AAC/BC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,cAAc,EAAE,MAAM;AACtBC,EAAAA,cAAc,EAAE,MAAM;AACtBC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,IAAI,EAAE,MAAM;AACZC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,OAAO,EAAE,MAAM;AACfC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,gBAAgB,EAAE,SAAS;AAC3BC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,cAAc,EAAE,SAAS;AACzBC,EAAAA,eAAe,EAAE,SAAS;AAC1BC,EAAAA,iBAAiB,EAAE,SAAS;AAC5BC,EAAAA,eAAe,EAAE,SAAS;AAC1BC,EAAAA,eAAe,EAAE,SAAS;AAC1BC,EAAAA,YAAY,EAAE,SAAS;AACvBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,aAAa,EAAE,SAAS;AACxBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,aAAa,EAAE,MAAM;AACrBC,EAAAA,GAAG,EAAE,MAAM;AACXC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,QAAQ,EAAE,SAAS;AACnBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,WAAW,EAAE,SAAS;AACtBC,EAAAA,SAAS,EAAE,SAAS;AACpBxL,EAAAA,GAAG,EAAE,SAAS;AACdyL,EAAAA,IAAI,EAAE,SAAS;AACfC,EAAAA,OAAO,EAAE,SAAS;AAClBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,SAAS,EAAE,SAAS;AACpBC,EAAAA,MAAM,EAAE,SAAS;AACjBC,EAAAA,KAAK,EAAE,SAAS;AAChBC,EAAAA,KAAK,EAAE,MAAM;AACbC,EAAAA,UAAU,EAAE,SAAS;AACrBC,EAAAA,MAAM,EAAE,MAAM;AACdC,EAAAA,WAAW,EAAE,SAAA;AACf,CAAC;;ACzJD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,MAAM,GAAGA,MACpB,kJAAkJ,CAAA;;AAEpJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,MAAM,GAAGA,MACpB,kKAAkK,CAAA;;AAEpK;AACA;AACA;AACO,MAAMC,KAAK,GAAGA,MAAM,2CAA2C;;AC/GtE;AACA;AACA;AACA;AACA;AACA;AAC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"} \ No newline at end of file diff --git a/rollup.config.mjs b/rollup.config.mjs index 899d20187a8..3759f6e5535 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -107,6 +107,7 @@ export default [ } : null, // umd module in bundle, the cdn one for fiddles + // deprecated, this will be available only minified for cdn. { file: path.resolve(dirname, `${basename}.js`), name: 'fabric', @@ -135,7 +136,7 @@ export default [ format: 'es', sourcemap: true, }, - // todo remove + // deprecated remove { file: path.resolve(dirname, `${basename}.node.cjs`), name: 'fabric',