UNPKG

hx-white-board

Version:

```bash npm install hx-white-board ```

1,421 lines 750 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; function getAugmentedNamespace(n) { if (n.__esModule) return n; var a = Object.defineProperty({}, "__esModule", { value: true }); Object.keys(n).forEach(function(k) { var d2 = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d2.get ? d2 : { enumerable: true, get: function() { return n[k]; } }); }); return a; } var fabric = {}; var __viteBrowserExternal = {}; var __viteBrowserExternal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, "default": __viteBrowserExternal }, Symbol.toStringTag, { value: "Module" })); var require$$2 = /* @__PURE__ */ getAugmentedNamespace(__viteBrowserExternal$1); (function(exports) { /*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */ var fabric2 = fabric2 || { version: "5.3.0" }; { exports.fabric = fabric2; } if (typeof document !== "undefined" && typeof window !== "undefined") { if (document instanceof (typeof HTMLDocument !== "undefined" ? HTMLDocument : Document)) { fabric2.document = document; } else { fabric2.document = document.implementation.createHTMLDocument(""); } fabric2.window = window; } else { var jsdom = require$$2; var virtualWindow = new jsdom.JSDOM( decodeURIComponent("%3C!DOCTYPE%20html%3E%3Chtml%3E%3Chead%3E%3C%2Fhead%3E%3Cbody%3E%3C%2Fbody%3E%3C%2Fhtml%3E"), { features: { FetchExternalResources: ["img"] }, resources: "usable" } ).window; fabric2.document = virtualWindow.document; fabric2.jsdomImplForWrapper = require$$2.implForWrapper; fabric2.nodeCanvas = require$$2.Canvas; fabric2.window = virtualWindow; DOMParser = fabric2.window.DOMParser; } fabric2.isTouchSupported = "ontouchstart" in fabric2.window || "ontouchstart" in fabric2.document || fabric2.window && fabric2.window.navigator && fabric2.window.navigator.maxTouchPoints > 0; fabric2.isLikelyNode = typeof Buffer !== "undefined" && typeof window === "undefined"; fabric2.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" ]; fabric2.DPI = 96; fabric2.reNum = "(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)"; fabric2.commaWsp = "(?:\\s+,?\\s*|,\\s*)"; fabric2.rePathCommand = /([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:[eE][-+]?\d+)?)/ig; fabric2.reNonWord = /[ \n\.,;!\?\-]/; fabric2.fontPaths = {}; fabric2.iMatrix = [1, 0, 0, 1, 0, 0]; fabric2.svgNS = "http://www.w3.org/2000/svg"; fabric2.perfLimitSizeTotal = 2097152; fabric2.maxCacheSideLimit = 4096; fabric2.minCacheSideLimit = 256; fabric2.charWidthsCache = {}; fabric2.textureSize = 2048; fabric2.disableStyleCopyPaste = false; fabric2.enableGLFiltering = true; fabric2.devicePixelRatio = fabric2.window.devicePixelRatio || fabric2.window.webkitDevicePixelRatio || fabric2.window.mozDevicePixelRatio || 1; fabric2.browserShadowBlurConstant = 1; fabric2.arcToSegmentsCache = {}; fabric2.boundsOfCurveCache = {}; fabric2.cachesBoundsOfCurve = true; fabric2.forceGLPutImageData = false; fabric2.initFilterBackend = function() { if (fabric2.enableGLFiltering && fabric2.isWebglSupported && fabric2.isWebglSupported(fabric2.textureSize)) { console.log("max texture size: " + fabric2.maxTextureSize); return new fabric2.WebglFilterBackend({ tileSize: fabric2.textureSize }); } else if (fabric2.Canvas2dFilterBackend) { return new fabric2.Canvas2dFilterBackend(); } }; if (typeof document !== "undefined" && typeof window !== "undefined") { window.fabric = fabric2; } (function() { function _removeEventListener(eventName, handler) { if (!this.__eventListeners[eventName]) { return; } var eventListener = this.__eventListeners[eventName]; if (handler) { eventListener[eventListener.indexOf(handler)] = false; } else { fabric2.util.array.fill(eventListener, false); } } function on(eventName, handler) { if (!this.__eventListeners) { this.__eventListeners = {}; } if (arguments.length === 1) { for (var prop in eventName) { this.on(prop, eventName[prop]); } } else { if (!this.__eventListeners[eventName]) { this.__eventListeners[eventName] = []; } this.__eventListeners[eventName].push(handler); } return this; } function _once(eventName, handler) { var _handler = function() { handler.apply(this, arguments); this.off(eventName, _handler); }.bind(this); this.on(eventName, _handler); } function once(eventName, handler) { if (arguments.length === 1) { for (var prop in eventName) { _once.call(this, prop, eventName[prop]); } } else { _once.call(this, eventName, handler); } return this; } function off(eventName, handler) { if (!this.__eventListeners) { return this; } if (arguments.length === 0) { for (eventName in this.__eventListeners) { _removeEventListener.call(this, eventName); } } else if (arguments.length === 1 && typeof arguments[0] === "object") { for (var prop in eventName) { _removeEventListener.call(this, prop, eventName[prop]); } } else { _removeEventListener.call(this, eventName, handler); } return this; } function fire(eventName, options) { if (!this.__eventListeners) { return this; } var listenersForEvent = this.__eventListeners[eventName]; if (!listenersForEvent) { return this; } for (var i = 0, len = listenersForEvent.length; i < len; i++) { listenersForEvent[i] && listenersForEvent[i].call(this, options || {}); } this.__eventListeners[eventName] = listenersForEvent.filter(function(value) { return value !== false; }); return this; } fabric2.Observable = { fire, on, once, off }; })(); fabric2.Collection = { _objects: [], add: function() { this._objects.push.apply(this._objects, arguments); if (this._onObjectAdded) { for (var i = 0, length = arguments.length; i < length; i++) { this._onObjectAdded(arguments[i]); } } this.renderOnAddRemove && this.requestRenderAll(); return this; }, insertAt: function(object, index, nonSplicing) { var objects = this._objects; if (nonSplicing) { objects[index] = object; } else { objects.splice(index, 0, object); } this._onObjectAdded && this._onObjectAdded(object); this.renderOnAddRemove && this.requestRenderAll(); return this; }, remove: function() { var objects = this._objects, index, somethingRemoved = false; for (var i = 0, length = arguments.length; i < length; i++) { index = objects.indexOf(arguments[i]); if (index !== -1) { somethingRemoved = true; objects.splice(index, 1); this._onObjectRemoved && this._onObjectRemoved(arguments[i]); } } this.renderOnAddRemove && somethingRemoved && this.requestRenderAll(); return this; }, forEachObject: function(callback, context) { var objects = this.getObjects(); for (var i = 0, len = objects.length; i < len; i++) { callback.call(context, objects[i], i, objects); } return this; }, getObjects: function(type) { if (typeof type === "undefined") { return this._objects.concat(); } return this._objects.filter(function(o) { return o.type === type; }); }, item: function(index) { return this._objects[index]; }, isEmpty: function() { return this._objects.length === 0; }, size: function() { return this._objects.length; }, contains: function(object, deep) { if (this._objects.indexOf(object) > -1) { return true; } else if (deep) { return this._objects.some(function(obj) { return typeof obj.contains === "function" && obj.contains(object, true); }); } return false; }, complexity: function() { return this._objects.reduce(function(memo, current) { memo += current.complexity ? current.complexity() : 0; return memo; }, 0); } }; fabric2.CommonMethods = { _setOptions: function(options) { for (var prop in options) { this.set(prop, options[prop]); } }, _initGradient: function(filler, property) { if (filler && filler.colorStops && !(filler instanceof fabric2.Gradient)) { this.set(property, new fabric2.Gradient(filler)); } }, _initPattern: function(filler, property, callback) { if (filler && filler.source && !(filler instanceof fabric2.Pattern)) { this.set(property, new fabric2.Pattern(filler, callback)); } else { callback && callback(); } }, _setObject: function(obj) { for (var prop in obj) { this._set(prop, obj[prop]); } }, set: function(key, value) { if (typeof key === "object") { this._setObject(key); } else { this._set(key, value); } return this; }, _set: function(key, value) { this[key] = value; }, toggle: function(property) { var value = this.get(property); if (typeof value === "boolean") { this.set(property, !value); } return this; }, get: function(property) { return this[property]; } }; (function(global2) { var sqrt = Math.sqrt, atan2 = Math.atan2, pow = Math.pow, PiBy180 = Math.PI / 180, PiBy2 = Math.PI / 2; fabric2.util = { cos: function(angle) { if (angle === 0) { return 1; } if (angle < 0) { angle = -angle; } var angleSlice = angle / PiBy2; switch (angleSlice) { case 1: case 3: return 0; case 2: return -1; } return Math.cos(angle); }, sin: function(angle) { if (angle === 0) { return 0; } var angleSlice = angle / PiBy2, sign = 1; if (angle < 0) { sign = -1; } switch (angleSlice) { case 1: return sign; case 2: return 0; case 3: return -sign; } return Math.sin(angle); }, removeFromArray: function(array, value) { var idx = array.indexOf(value); if (idx !== -1) { array.splice(idx, 1); } return array; }, getRandomInt: function(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, degreesToRadians: function(degrees) { return degrees * PiBy180; }, radiansToDegrees: function(radians) { return radians / PiBy180; }, rotatePoint: function(point, origin, radians) { var newPoint = new fabric2.Point(point.x - origin.x, point.y - origin.y), v = fabric2.util.rotateVector(newPoint, radians); return new fabric2.Point(v.x, v.y).addEquals(origin); }, rotateVector: function(vector, radians) { var sin = fabric2.util.sin(radians), cos = fabric2.util.cos(radians), rx = vector.x * cos - vector.y * sin, ry = vector.x * sin + vector.y * cos; return { x: rx, y: ry }; }, createVector: function(from, to) { return new fabric2.Point(to.x - from.x, to.y - from.y); }, calcAngleBetweenVectors: function(a, b) { return Math.acos((a.x * b.x + a.y * b.y) / (Math.hypot(a.x, a.y) * Math.hypot(b.x, b.y))); }, getHatVector: function(v) { return new fabric2.Point(v.x, v.y).multiply(1 / Math.hypot(v.x, v.y)); }, getBisector: function(A, B, C) { var AB = fabric2.util.createVector(A, B), AC = fabric2.util.createVector(A, C); var alpha = fabric2.util.calcAngleBetweenVectors(AB, AC); var ro = fabric2.util.calcAngleBetweenVectors(fabric2.util.rotateVector(AB, alpha), AC); var phi = alpha * (ro === 0 ? 1 : -1) / 2; return { vector: fabric2.util.getHatVector(fabric2.util.rotateVector(AB, phi)), angle: alpha }; }, projectStrokeOnPoints: function(points, options, openPath) { var coords = [], s2 = options.strokeWidth / 2, strokeUniformScalar = options.strokeUniform ? new fabric2.Point(1 / options.scaleX, 1 / options.scaleY) : new fabric2.Point(1, 1), getStrokeHatVector = function(v) { var scalar = s2 / Math.hypot(v.x, v.y); return new fabric2.Point(v.x * scalar * strokeUniformScalar.x, v.y * scalar * strokeUniformScalar.y); }; if (points.length <= 1) { return coords; } points.forEach(function(p, index) { var A = new fabric2.Point(p.x, p.y), B, C; if (index === 0) { C = points[index + 1]; B = openPath ? getStrokeHatVector(fabric2.util.createVector(C, A)).addEquals(A) : points[points.length - 1]; } else if (index === points.length - 1) { B = points[index - 1]; C = openPath ? getStrokeHatVector(fabric2.util.createVector(B, A)).addEquals(A) : points[0]; } else { B = points[index - 1]; C = points[index + 1]; } var bisector = fabric2.util.getBisector(A, B, C), bisectorVector = bisector.vector, alpha = bisector.angle, scalar, miterVector; if (options.strokeLineJoin === "miter") { scalar = -s2 / Math.sin(alpha / 2); miterVector = new fabric2.Point( bisectorVector.x * scalar * strokeUniformScalar.x, bisectorVector.y * scalar * strokeUniformScalar.y ); if (Math.hypot(miterVector.x, miterVector.y) / s2 <= options.strokeMiterLimit) { coords.push(A.add(miterVector)); coords.push(A.subtract(miterVector)); return; } } scalar = -s2 * Math.SQRT2; miterVector = new fabric2.Point( bisectorVector.x * scalar * strokeUniformScalar.x, bisectorVector.y * scalar * strokeUniformScalar.y ); coords.push(A.add(miterVector)); coords.push(A.subtract(miterVector)); }); return coords; }, transformPoint: function(p, t, ignoreOffset) { if (ignoreOffset) { return new fabric2.Point( t[0] * p.x + t[2] * p.y, t[1] * p.x + t[3] * p.y ); } return new fabric2.Point( t[0] * p.x + t[2] * p.y + t[4], t[1] * p.x + t[3] * p.y + t[5] ); }, makeBoundingBoxFromPoints: function(points, transform) { if (transform) { for (var i = 0; i < points.length; i++) { points[i] = fabric2.util.transformPoint(points[i], transform); } } var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x], minX = fabric2.util.array.min(xPoints), maxX = fabric2.util.array.max(xPoints), width = maxX - minX, yPoints = [points[0].y, points[1].y, points[2].y, points[3].y], minY = fabric2.util.array.min(yPoints), maxY = fabric2.util.array.max(yPoints), height = maxY - minY; return { left: minX, top: minY, width, height }; }, invertTransform: function(t) { var a = 1 / (t[0] * t[3] - t[1] * t[2]), r = [a * t[3], -a * t[1], -a * t[2], a * t[0]], o = fabric2.util.transformPoint({ x: t[4], y: t[5] }, r, true); r[4] = -o.x; r[5] = -o.y; return r; }, toFixed: function(number, fractionDigits) { return parseFloat(Number(number).toFixed(fractionDigits)); }, parseUnit: function(value, fontSize) { var unit = /\D{0,2}$/.exec(value), number = parseFloat(value); if (!fontSize) { fontSize = fabric2.Text.DEFAULT_SVG_FONT_SIZE; } switch (unit[0]) { case "mm": return number * fabric2.DPI / 25.4; case "cm": return number * fabric2.DPI / 2.54; case "in": return number * fabric2.DPI; case "pt": return number * fabric2.DPI / 72; case "pc": return number * fabric2.DPI / 72 * 12; case "em": return number * fontSize; default: return number; } }, falseFunction: function() { return false; }, getKlass: function(type, namespace) { type = fabric2.util.string.camelize(type.charAt(0).toUpperCase() + type.slice(1)); return fabric2.util.resolveNamespace(namespace)[type]; }, getSvgAttributes: function(type) { var attributes = [ "instantiated_by_use", "style", "id", "class" ]; switch (type) { case "linearGradient": attributes = attributes.concat(["x1", "y1", "x2", "y2", "gradientUnits", "gradientTransform"]); break; case "radialGradient": attributes = attributes.concat(["gradientUnits", "gradientTransform", "cx", "cy", "r", "fx", "fy", "fr"]); break; case "stop": attributes = attributes.concat(["offset", "stop-color", "stop-opacity"]); break; } return attributes; }, resolveNamespace: function(namespace) { if (!namespace) { return fabric2; } var parts = namespace.split("."), len = parts.length, i, obj = global2 || fabric2.window; for (i = 0; i < len; ++i) { obj = obj[parts[i]]; } return obj; }, loadImage: function(url, callback, context, crossOrigin) { if (!url) { callback && callback.call(context, url); return; } var img = fabric2.util.createImage(); var onLoadCallback = function() { callback && callback.call(context, img, false); img = img.onload = img.onerror = null; }; img.onload = onLoadCallback; img.onerror = function() { fabric2.log("Error loading " + img.src); callback && callback.call(context, null, true); img = img.onload = img.onerror = null; }; if (url.indexOf("data") !== 0 && crossOrigin !== void 0 && crossOrigin !== null) { img.crossOrigin = crossOrigin; } if (url.substring(0, 14) === "data:image/svg") { img.onload = null; fabric2.util.loadImageInDom(img, onLoadCallback); } img.src = url; }, loadImageInDom: function(img, onLoadCallback) { var div = fabric2.document.createElement("div"); div.style.width = div.style.height = "1px"; div.style.left = div.style.top = "-100%"; div.style.position = "absolute"; div.appendChild(img); fabric2.document.querySelector("body").appendChild(div); img.onload = function() { onLoadCallback(); div.parentNode.removeChild(div); div = null; }; }, enlivenObjects: function(objects, callback, namespace, reviver) { objects = objects || []; var enlivenedObjects = [], numLoadedObjects = 0, numTotalObjects = objects.length; function onLoaded() { if (++numLoadedObjects === numTotalObjects) { callback && callback(enlivenedObjects.filter(function(obj) { return obj; })); } } if (!numTotalObjects) { callback && callback(enlivenedObjects); return; } objects.forEach(function(o, index) { if (!o || !o.type) { onLoaded(); return; } var klass = fabric2.util.getKlass(o.type, namespace); klass.fromObject(o, function(obj, error) { error || (enlivenedObjects[index] = obj); reviver && reviver(o, obj, error); onLoaded(); }); }); }, enlivenObjectEnlivables: function(object, context, callback) { var enlivenProps = fabric2.Object.ENLIVEN_PROPS.filter(function(key) { return !!object[key]; }); fabric2.util.enlivenObjects(enlivenProps.map(function(key) { return object[key]; }), function(enlivedProps) { var objects = {}; enlivenProps.forEach(function(key, index) { objects[key] = enlivedProps[index]; context && (context[key] = enlivedProps[index]); }); callback && callback(objects); }); }, enlivenPatterns: function(patterns, callback) { patterns = patterns || []; function onLoaded() { if (++numLoadedPatterns === numPatterns) { callback && callback(enlivenedPatterns); } } var enlivenedPatterns = [], numLoadedPatterns = 0, numPatterns = patterns.length; if (!numPatterns) { callback && callback(enlivenedPatterns); return; } patterns.forEach(function(p, index) { if (p && p.source) { new fabric2.Pattern(p, function(pattern) { enlivenedPatterns[index] = pattern; onLoaded(); }); } else { enlivenedPatterns[index] = p; onLoaded(); } }); }, groupSVGElements: function(elements, options, path) { var object; if (elements && elements.length === 1) { if (typeof path !== "undefined") { elements[0].sourcePath = path; } return elements[0]; } if (options) { if (options.width && options.height) { options.centerPoint = { x: options.width / 2, y: options.height / 2 }; } else { delete options.width; delete options.height; } } object = new fabric2.Group(elements, options); if (typeof path !== "undefined") { object.sourcePath = path; } return object; }, populateWithProperties: function(source, destination, properties) { if (properties && Array.isArray(properties)) { for (var i = 0, len = properties.length; i < len; i++) { if (properties[i] in source) { destination[properties[i]] = source[properties[i]]; } } } }, createCanvasElement: function() { return fabric2.document.createElement("canvas"); }, copyCanvasElement: function(canvas) { var newCanvas = fabric2.util.createCanvasElement(); newCanvas.width = canvas.width; newCanvas.height = canvas.height; newCanvas.getContext("2d").drawImage(canvas, 0, 0); return newCanvas; }, toDataURL: function(canvasEl, format, quality) { return canvasEl.toDataURL("image/" + format, quality); }, createImage: function() { return fabric2.document.createElement("img"); }, multiplyTransformMatrices: function(a, b, is2x2) { return [ 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] ]; }, qrDecompose: function(a) { var angle = atan2(a[1], a[0]), denom = pow(a[0], 2) + pow(a[1], 2), scaleX = sqrt(denom), scaleY = (a[0] * a[3] - a[2] * a[1]) / scaleX, skewX = atan2(a[0] * a[2] + a[1] * a[3], denom); return { angle: angle / PiBy180, scaleX, scaleY, skewX: skewX / PiBy180, skewY: 0, translateX: a[4], translateY: a[5] }; }, calcRotateMatrix: function(options) { if (!options.angle) { return fabric2.iMatrix.concat(); } var theta = fabric2.util.degreesToRadians(options.angle), cos = fabric2.util.cos(theta), sin = fabric2.util.sin(theta); return [cos, sin, -sin, cos, 0, 0]; }, calcDimensionsMatrix: function(options) { var scaleX = typeof options.scaleX === "undefined" ? 1 : options.scaleX, scaleY = typeof options.scaleY === "undefined" ? 1 : options.scaleY, scaleMatrix = [ options.flipX ? -scaleX : scaleX, 0, 0, options.flipY ? -scaleY : scaleY, 0, 0 ], multiply = fabric2.util.multiplyTransformMatrices, degreesToRadians = fabric2.util.degreesToRadians; if (options.skewX) { scaleMatrix = multiply( scaleMatrix, [1, 0, Math.tan(degreesToRadians(options.skewX)), 1], true ); } if (options.skewY) { scaleMatrix = multiply( scaleMatrix, [1, Math.tan(degreesToRadians(options.skewY)), 0, 1], true ); } return scaleMatrix; }, composeMatrix: function(options) { var matrix = [1, 0, 0, 1, options.translateX || 0, options.translateY || 0], multiply = fabric2.util.multiplyTransformMatrices; if (options.angle) { matrix = multiply(matrix, fabric2.util.calcRotateMatrix(options)); } if (options.scaleX !== 1 || options.scaleY !== 1 || options.skewX || options.skewY || options.flipX || options.flipY) { matrix = multiply(matrix, fabric2.util.calcDimensionsMatrix(options)); } return matrix; }, resetObjectTransform: function(target) { target.scaleX = 1; target.scaleY = 1; target.skewX = 0; target.skewY = 0; target.flipX = false; target.flipY = false; target.rotate(0); }, saveObjectTransform: function(target) { return { 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 }; }, isTransparent: function(ctx, x, y2, tolerance) { if (tolerance > 0) { if (x > tolerance) { x -= tolerance; } else { x = 0; } if (y2 > tolerance) { y2 -= tolerance; } else { y2 = 0; } } var _isTransparent = true, i, temp, imageData = ctx.getImageData(x, y2, tolerance * 2 || 1, tolerance * 2 || 1), l = imageData.data.length; for (i = 3; i < l; i += 4) { temp = imageData.data[i]; _isTransparent = temp <= 0; if (_isTransparent === false) { break; } } imageData = null; return _isTransparent; }, parsePreserveAspectRatioAttribute: function(attribute) { var meetOrSlice = "meet", alignX = "Mid", alignY = "Mid", aspectRatioAttrs = attribute.split(" "), align; if (aspectRatioAttrs && aspectRatioAttrs.length) { meetOrSlice = aspectRatioAttrs.pop(); if (meetOrSlice !== "meet" && meetOrSlice !== "slice") { align = meetOrSlice; meetOrSlice = "meet"; } else if (aspectRatioAttrs.length) { align = aspectRatioAttrs.pop(); } } alignX = align !== "none" ? align.slice(1, 4) : "none"; alignY = align !== "none" ? align.slice(5, 8) : "none"; return { meetOrSlice, alignX, alignY }; }, clearFabricFontCache: function(fontFamily) { fontFamily = (fontFamily || "").toLowerCase(); if (!fontFamily) { fabric2.charWidthsCache = {}; } else if (fabric2.charWidthsCache[fontFamily]) { delete fabric2.charWidthsCache[fontFamily]; } }, limitDimsByArea: function(ar, maximumArea) { var roughWidth = Math.sqrt(maximumArea * ar), perfLimitSizeY = Math.floor(maximumArea / roughWidth); return { x: Math.floor(roughWidth), y: perfLimitSizeY }; }, capValue: function(min, value, max) { return Math.max(min, Math.min(value, max)); }, findScaleToFit: function(source, destination) { return Math.min(destination.width / source.width, destination.height / source.height); }, findScaleToCover: function(source, destination) { return Math.max(destination.width / source.width, destination.height / source.height); }, matrixToSVG: function(transform) { return "matrix(" + transform.map(function(value) { return fabric2.util.toFixed(value, fabric2.Object.NUM_FRACTION_DIGITS); }).join(" ") + ")"; }, removeTransformFromObject: function(object, transform) { var inverted = fabric2.util.invertTransform(transform), finalTransform = fabric2.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix()); fabric2.util.applyTransformToObject(object, finalTransform); }, addTransformToObject: function(object, transform) { fabric2.util.applyTransformToObject( object, fabric2.util.multiplyTransformMatrices(transform, object.calcOwnMatrix()) ); }, applyTransformToObject: function(object, transform) { var options = fabric2.util.qrDecompose(transform), center = new fabric2.Point(options.translateX, options.translateY); object.flipX = false; object.flipY = false; object.set("scaleX", options.scaleX); object.set("scaleY", options.scaleY); object.skewX = options.skewX; object.skewY = options.skewY; object.angle = options.angle; object.setPositionByOrigin(center, "center", "center"); }, sizeAfterTransform: function(width, height, options) { var dimX = width / 2, dimY = height / 2, points = [ { x: -dimX, y: -dimY }, { x: dimX, y: -dimY }, { x: -dimX, y: dimY }, { x: dimX, y: dimY } ], transformMatrix = fabric2.util.calcDimensionsMatrix(options), bbox = fabric2.util.makeBoundingBoxFromPoints(points, transformMatrix); return { x: bbox.width, y: bbox.height }; }, mergeClipPaths: function(c1, c2) { var a = c1, b = c2; if (a.inverted && !b.inverted) { a = c2; b = c1; } fabric2.util.applyTransformToObject( b, fabric2.util.multiplyTransformMatrices( fabric2.util.invertTransform(a.calcTransformMatrix()), b.calcTransformMatrix() ) ); var inverted = a.inverted && b.inverted; if (inverted) { a.inverted = b.inverted = false; } return new fabric2.Group([a], { clipPath: b, inverted }); }, hasStyleChanged: function(prevStyle, thisStyle, forTextSpans) { forTextSpans = forTextSpans || 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); }, stylesToArray: function(styles, text) { var styles = fabric2.util.object.clone(styles, true), textLines = text.split("\n"), charIndex = -1, prevStyle = {}, stylesArray = []; for (var i = 0; i < textLines.length; i++) { if (!styles[i]) { charIndex += textLines[i].length; continue; } for (var c = 0; c < textLines[i].length; c++) { charIndex++; var thisStyle = styles[i][c]; if (thisStyle && Object.keys(thisStyle).length > 0) { var styleChanged = fabric2.util.hasStyleChanged(prevStyle, thisStyle, true); if (styleChanged) { stylesArray.push({ start: charIndex, end: charIndex + 1, style: thisStyle }); } else { stylesArray[stylesArray.length - 1].end++; } } prevStyle = thisStyle || {}; } } return stylesArray; }, stylesFromArray: function(styles, text) { if (!Array.isArray(styles)) { return styles; } var textLines = text.split("\n"), charIndex = -1, styleIndex = 0, stylesObject = {}; for (var i = 0; i < textLines.length; i++) { for (var c = 0; c < textLines[i].length; c++) { charIndex++; if (styles[styleIndex] && styles[styleIndex].start <= charIndex && charIndex < styles[styleIndex].end) { stylesObject[i] = stylesObject[i] || {}; stylesObject[i][c] = Object.assign({}, styles[styleIndex].style); if (charIndex === styles[styleIndex].end - 1) { styleIndex++; } } } } return stylesObject; } }; })(exports); (function() { var _join = Array.prototype.join, commandLengths = { m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7 }, repeatedCommands = { m: "l", M: "L" }; function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) { var costh2 = fabric2.util.cos(th2), sinth2 = fabric2.util.sin(th2), costh3 = fabric2.util.cos(th3), sinth3 = fabric2.util.sin(th3), toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1, toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1, cp1X = fromX + mT * (-cosTh * rx * sinth2 - sinTh * ry * costh2), cp1Y = fromY + mT * (-sinTh * rx * sinth2 + cosTh * ry * costh2), cp2X = toX + mT * (cosTh * rx * sinth3 + sinTh * ry * costh3), cp2Y = toY + mT * (sinTh * rx * sinth3 - cosTh * ry * costh3); return [ "C", cp1X, cp1Y, cp2X, cp2Y, toX, toY ]; } function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) { var PI = Math.PI, th = rotateX * PI / 180, sinTh = fabric2.util.sin(th), cosTh = fabric2.util.cos(th), fromX = 0, fromY = 0; rx = Math.abs(rx); ry = Math.abs(ry); var px = -cosTh * toX * 0.5 - sinTh * toY * 0.5, py = -cosTh * toY * 0.5 + sinTh * toX * 0.5, rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px, pl = rx2 * ry2 - rx2 * py2 - ry2 * px2, root2 = 0; if (pl < 0) { var s2 = Math.sqrt(1 - pl / (rx2 * ry2)); rx *= s2; ry *= s2; } else { root2 = (large === sweep ? -1 : 1) * Math.sqrt(pl / (rx2 * py2 + ry2 * px2)); } var cx = root2 * rx * py / ry, cy = -root2 * ry * px / rx, cx1 = cosTh * cx - sinTh * cy + toX * 0.5, cy1 = sinTh * cx + cosTh * cy + toY * 0.5, mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry), 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; } var 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), th3 = mTheta + mDelta; for (var i = 0; i < segments; i++) { result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY); fromX = result[i][5]; fromY = result[i][6]; mTheta = th3; th3 += mDelta; } return result; } function calcVectorAngle(ux, uy, vx, vy) { var ta = Math.atan2(uy, ux), tb = Math.atan2(vy, vx); if (tb >= ta) { return tb - ta; } else { return 2 * Math.PI - (ta - tb); } } function getBoundsOfCurve(x0, y0, x1, y1, x2, y2, x3, y3) { var argsString; if (fabric2.cachesBoundsOfCurve) { argsString = _join.call(arguments); if (fabric2.boundsOfCurveCache[argsString]) { return fabric2.boundsOfCurveCache[argsString]; } } var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs, tvalues = [], bounds = [[], []], a, b, c, t, t1, t2, b2ac, sqrtb2ac; b = 6 * x0 - 12 * x1 + 6 * x2; a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; c = 3 * x1 - 3 * x0; for (var i = 0; i < 2; ++i) { if (i > 0) { b = 6 * y0 - 12 * y1 + 6 * y2; a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; c = 3 * y1 - 3 * y0; } if (abs(a) < 1e-12) { if (abs(b) < 1e-12) { continue; } t = -c / b; if (0 < t && t < 1) { tvalues.push(t); } continue; } b2ac = b * b - 4 * c * a; if (b2ac < 0) { continue; } sqrtb2ac = sqrt(b2ac); t1 = (-b + sqrtb2ac) / (2 * a); if (0 < t1 && t1 < 1) { tvalues.push(t1); } t2 = (-b - sqrtb2ac) / (2 * a); if (0 < t2 && t2 < 1) { tvalues.push(t2); } } var x, y4, j = tvalues.length, jlen = j, mt; while (j--) { t = tvalues[j]; mt = 1 - t; x = mt * mt * mt * x0 + 3 * mt * mt * t * x1 + 3 * mt * t * t * x2 + t * t * t * x3; bounds[0][j] = x; y4 = mt * mt * mt * y0 + 3 * mt * mt * t * y1 + 3 * mt * t * t * y2 + t * t * t * y3; bounds[1][j] = y4; } bounds[0][jlen] = x0; bounds[1][jlen] = y0; bounds[0][jlen + 1] = x3; bounds[1][jlen + 1] = y3; var result = [ { x: min.apply(null, bounds[0]), y: min.apply(null, bounds[1]) }, { x: max.apply(null, bounds[0]), y: max.apply(null, bounds[1]) } ]; if (fabric2.cachesBoundsOfCurve) { fabric2.boundsOfCurveCache[argsString] = result; } return result; } function fromArcToBeziers(fx, fy, coords) { var rx = coords[1], ry = coords[2], rot = coords[3], large = coords[4], sweep = coords[5], tx = coords[6], ty = coords[7], segsNorm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot); for (var 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; } function makePathSimpler(path) { var x = 0, y2 = 0, len = path.length, x1 = 0, y1 = 0, current, i, converted, destinationPath = [], previous, controlX, controlY; for (i = 0; i < len; ++i) { converted = false; current = path[i].slice(0); switch (current[0]) { case "l": current[0] = "L"; current[1] += x; current[2] += y2; case "L": x = current[1]; y2 = current[2]; break; case "h": current[1] += x; case "H": current[0] = "L"; current[2] = y2; x = current[1]; break; case "v": current[1] += y2; case "V": current[0] = "L"; y2 = current[1]; current[1] = x; current[2] = y2; break; case "m": current[0] = "M"; current[1] += x; current[2] += y2; case "M": x = current[1]; y2 = current[2]; x1 = current[1]; y1 = current[2]; break; case "c": current[0] = "C"; current[1] += x; current[2] += y2; current[3] += x; current[4] += y2; current[5] += x; current[6] += y2; case "C": controlX = current[3]; controlY = current[4]; x = current[5]; y2 = current[6]; break; case "s": current[0] = "S"; current[1] += x; current[2] += y2; current[3] += x; current[4] += y2; case "S": if (previous === "C") { controlX = 2 * x - controlX; controlY = 2 * y2 - controlY; } else { controlX = x; controlY = y2; } x = current[3]; y2 = current[4]; current[0] = "C"; current[5] = current[3]; current[6] = current[4]; current[3] = current[1]; current[4] = current[2]; current[1] = controlX; current[2] = controlY; controlX = current[3]; controlY = current[4]; break; case "q": current[0] = "Q"; current[1] += x; current[2] += y2; current[3] += x; current[4] += y2; case "Q": controlX = current[1]; controlY = current[2]; x = current[3]; y2 = current[4]; break; case "t": current[0] = "T"; current[1] += x; current[2] += y2; case "T": if (previous === "Q") { controlX = 2 * x - controlX; controlY = 2 * y2 - controlY; } else { controlX = x; controlY = y2; } current[0] = "Q"; x = current[1]; y2 = current[2]; current[1] = controlX; current[2] = controlY; current[3] = x; current[4] = y2; break; case "a": current[0] = "A"; current[6] += x; current[7] += y2; case "A": converted = true; destinationPath = destinationPath.concat(fromArcToBeziers(x, y2, current)); x = current[6]; y2 = current[7]; break; case "z": case "Z": x = x1; y2 = y1; break; } if (!converted) { destinationPath.push(current); } previous = current[0]; } return destinationPath; } function calcLineLength(x1, y1, x2, y2) { return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } function CB1(t) { return t * t * t; } function CB2(t) { return 3 * t * t * (1 - t); } function CB3(t) { return 3 * t * (1 - t) * (1 - t); } function CB4(t) { return (1 - t) * (1 - t) * (1 - t); } function getPointOnCubicBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { return function(pct) { var c1 = CB1(pct), c2 = CB2(pct), c3 = CB3(pct), c4 = CB4(pct); return { x: p4x * c1 + p3x * c2 + p2x * c3 + p1x * c4, y: p4y * c1 + p3y * c2 + p2y * c3 + p1y * c4 }; }; } function getTangentCubicIterator(p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y) { return function(pct) { var invT = 1 - pct, tangentX = 3 * invT * invT * (p2x - p1x) + 6 * invT * pct * (p3x - p2x) + 3 * pct * pct * (p4x - p3x), tangentY = 3 * invT * invT * (p2y - p1y) + 6 * invT * pct * (p3y - p2y) + 3 * pct * pct * (p4y - p3y); return Math.atan2(tangentY, tangentX); }; } function QB1(t) { return t * t; } function QB2(t) { return 2 * t * (1 - t); } function QB3(t) { return (1 - t) * (1 - t); } function getPointOnQuadraticBezierIterator(p1x, p1y, p2x, p2y, p3x, p3y) { return function(pct) { var c1 = QB1(pct), c2 = QB2(pct), c3 = QB3(pct); return { x: p3x * c1 + p2x * c2 + p1x * c3, y: p3y * c1 + p2y * c2 + p1y * c3 }; }; } function getTangentQuadraticIterator(p1x, p1y, p2x, p2y, p3x, p3y) { return function(pct) { var invT = 1 - pct, tangentX = 2 * invT * (p2x - p1x) + 2 * pct * (p3x - p2x), tangentY = 2 * invT * (p2y - p1y) + 2 * pct * (p3y - p2y); return Math.atan2(tangentY, tangentX); }; } function pathIterator(iterator, x1, y1) { var tempP = { x: x1, y: y1 }, p, tmpLen = 0, perc; for (perc = 1; perc <= 100; perc += 1) { p = iterator(perc / 100); tmpLen += calcLineLength(tempP.x, tempP.y, p.x, p.y); tempP = p; } return tmpLen; } function findPercentageForDistance(segInfo, distance) { var perc = 0, tmpLen = 0, iterator = segInfo.iterator, tempP = { x: segInfo.x, y: segInfo.y }, p, nextLen, nextStep = 0.01, angleFinder = segInfo.angleFinder, lastPerc; while (tmpLen < distance && nextStep > 1e-4) { p = iterator(perc); lastPerc = perc; nextLen = calcLineLength(tempP.x, tempP.y, p.x, p.y); if (nextLen + tmpLen > distance) { perc -= nextStep; nextStep /= 2; } else { tempP = p; perc += nextStep; tmpLen += nextLen; } } p.angle = angleFinder(lastPerc); return p; } function getPathSegmentsInfo(path) { var totalLength = 0, len = path.length, current, x1 = 0, y1 = 0, x2 = 0, y2 = 0, info = [], iterator, tempInfo, angleFinder; for (var i = 0; i < len; i++) { current = path[i]; tempInfo = { x: x1, y: y1, command: current[0] }; switch (current[0]) { case "M": tempInfo.length = 0; x2 = x1 = current[1]; y2 = y1 = current[2]; break; case "L": 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] ); angleFinder = getTangentCubicIterator( x1, y1, current[1], current[2], current[3], current[4], current[5], current[6] ); tempInfo.iterator = iterator; tempInfo.angleFinder = angleFinder; 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] ); angleFinder = getTangentQuadraticIterator( x1, y1, current[1], current[2], current[3], current[4] ); tempInfo.iterator = iterator; tempInfo.angleFinder = angleFinder; tempInfo.length = pathIterator(iterator, x1, y1); x1 = current[3]; y1 = current[4]; break; case "Z": case "z": 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; } function getPointOnPath(path, distance, infos) { if (!infos) { infos = getPathSegmentsInfo(path); } var i = 0; while (distance - infos[i].length > 0 && i < infos.length - 2) { distance -= infos[i].length; i++; }