hx-white-board
Version:
```bash npm install hx-white-board ```
1,421 lines • 750 kB
JavaScript
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++;
}