diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | dist/svg.js | 1845 | ||||
-rw-r--r-- | spec/spec/element.js | 7 | ||||
-rw-r--r-- | spec/spec/matrix.js | 7 | ||||
-rw-r--r-- | spec/spec/point.js | 10 | ||||
-rw-r--r-- | src/elements/Dom.js | 5 | ||||
-rw-r--r-- | src/elements/Element.js | 15 | ||||
-rw-r--r-- | src/modules/core/parser.js | 4 | ||||
-rw-r--r-- | src/types/Box.js | 22 | ||||
-rw-r--r-- | src/types/Matrix.js | 58 | ||||
-rw-r--r-- | src/types/Point.js | 25 |
11 files changed, 950 insertions, 1049 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 94fff52..034cdae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ The document follows the conventions described in [“Keep a CHANGELOG”](http: - removed `show()` from `SVG.A` to avoid name clash (#802) - removed `size()` from `SVG.Text` to avoid name clash (#799) - removed `move(), dmove()` etc for groups to avoid inconsistencies, we will expect users to use transforms to move around groups as they should (especially since they are much simpler now). +- removed `native()` function ### Changed - gradients now have there corresponding node as type and not only radial/linear diff --git a/dist/svg.js b/dist/svg.js index 3a2d11a..ab443a7 100644 --- a/dist/svg.js +++ b/dist/svg.js @@ -6,7 +6,7 @@ * @copyright Wout Fierens <wout@mick-wout.com> * @license MIT * -* BUILT: Mon Nov 12 2018 13:58:37 GMT+0100 (GMT+01:00) +* BUILT: Mon Nov 12 2018 14:48:34 GMT+0100 (GMT+01:00) */; var SVG = (function () { 'use strict'; @@ -1089,6 +1089,749 @@ var SVG = (function () { return Color; }(); + var Point = + /*#__PURE__*/ + function () { + // Initialize + function Point() { + _classCallCheck(this, Point); + + this.init.apply(this, arguments); + } + + _createClass(Point, [{ + key: "init", + value: function init(x, y) { + var source; + var base = { + x: 0, + y: 0 // ensure source as object + + }; + source = Array.isArray(x) ? { + x: x[0], + y: x[1] + } : _typeof(x) === 'object' ? { + x: x.x, + y: x.y + } : { + x: x, + y: y // merge source + + }; + this.x = source.x == null ? base.x : source.x; + this.y = source.y == null ? base.y : source.y; + return this; + } // Clone point + + }, { + key: "clone", + value: function clone() { + return new Point(this); + } // transform point with matrix + + }, { + key: "transform", + value: function transform(m) { + // Perform the matrix multiplication + var x = m.a * this.x + m.c * this.y + m.e; + var y = m.b * this.x + m.d * this.y + m.f; // Return the required point + + return new Point(x, y); + } + }, { + key: "toArray", + value: function toArray() { + return [this.x, this.y]; + } + }]); + + return Point; + }(); + function point(x, y) { + return new Point(x, y).transform(this.screenCTM().inverse()); + } + + function parser() { + // Reuse cached element if possible + if (!parser.nodes) { + var svg = makeInstance().size(2, 0); + svg.node.cssText = ['opacity: 0', 'position: absolute', 'left: -100%', 'top: -100%', 'overflow: hidden'].join(';'); + var path = svg.path().node; + parser.nodes = { + svg: svg, + path: path + }; + } + + if (!parser.nodes.svg.node.parentNode) { + var b = globals.document.body || globals.document.documentElement; + parser.nodes.svg.addTo(b); + } + + return parser.nodes; + } + + function isNulledBox(box) { + return !box.w && !box.h && !box.x && !box.y; + } + + function domContains(node) { + return (globals.document.documentElement.contains || function (node) { + // This is IE - it does not support contains() for top-level SVGs + while (node.parentNode) { + node = node.parentNode; + } + + return node === document; + }).call(globals.document.documentElement, node); + } + + var Box = + /*#__PURE__*/ + function () { + function Box() { + _classCallCheck(this, Box); + + this.init.apply(this, arguments); + } + + _createClass(Box, [{ + key: "init", + value: function init(source) { + var base = [0, 0, 0, 0]; + source = typeof source === 'string' ? source.split(delimiter).map(parseFloat) : Array.isArray(source) ? source : _typeof(source) === 'object' ? [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] : arguments.length === 4 ? [].slice.call(arguments) : base; + this.x = source[0] || 0; + this.y = source[1] || 0; + this.width = this.w = source[2] || 0; + this.height = this.h = source[3] || 0; // Add more bounding box properties + + this.x2 = this.x + this.w; + this.y2 = this.y + this.h; + this.cx = this.x + this.w / 2; + this.cy = this.y + this.h / 2; + return this; + } // Merge rect box with another, return a new instance + + }, { + key: "merge", + value: function merge(box) { + var x = Math.min(this.x, box.x); + var y = Math.min(this.y, box.y); + var width = Math.max(this.x + this.width, box.x + box.width) - x; + var height = Math.max(this.y + this.height, box.y + box.height) - y; + return new Box(x, y, width, height); + } + }, { + key: "transform", + value: function transform(m) { + var xMin = Infinity; + var xMax = -Infinity; + var yMin = Infinity; + var yMax = -Infinity; + var pts = [new Point(this.x, this.y), new Point(this.x2, this.y), new Point(this.x, this.y2), new Point(this.x2, this.y2)]; + pts.forEach(function (p) { + p = p.transform(m); + xMin = Math.min(xMin, p.x); + xMax = Math.max(xMax, p.x); + yMin = Math.min(yMin, p.y); + yMax = Math.max(yMax, p.y); + }); + return new Box(xMin, yMin, xMax - xMin, yMax - yMin); + } + }, { + key: "addOffset", + value: function addOffset() { + // offset by window scroll position, because getBoundingClientRect changes when window is scrolled + this.x += globals.window.pageXOffset; + this.y += globals.window.pageYOffset; + return this; + } + }, { + key: "toString", + value: function toString() { + return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height; + } + }, { + key: "toArray", + value: function toArray() { + return [this.x, this.y, this.width, this.height]; + } + }, { + key: "isNulled", + value: function isNulled() { + return isNulledBox(this); + } + }]); + + return Box; + }(); + + function getBox(cb) { + var box; + + try { + box = cb(this.node); + + if (isNulledBox(box) && !domContains(this.node)) { + throw new Error('Element not in the dom'); + } + } catch (e) { + try { + var clone = this.clone().addTo(parser().svg).show(); + box = cb(clone.node); + clone.remove(); + } catch (e) { + throw new Error('Getting a bounding box of element "' + this.node.nodeName + '" is not possible'); + } + } + + return box; + } + + function bbox() { + return new Box(getBox.call(this, function (node) { + return node.getBBox(); + })); + } + function rbox(el) { + var box = new Box(getBox.call(this, function (node) { + return node.getBoundingClientRect(); + })); + if (el) return box.transform(el.screenCTM().inverse()); + return box.addOffset(); + } + registerMethods({ + viewbox: { + viewbox: function viewbox(x, y, width, height) { + // act as getter + if (x == null) return new Box(this.attr('viewBox')); // act as setter + + return this.attr('viewBox', new Box(x, y, width, height)); + } + } + }); + + function closeEnough(a, b, threshold) { + return Math.abs(b - a) < (threshold || 1e-6); + } + + var Matrix = + /*#__PURE__*/ + function () { + function Matrix() { + _classCallCheck(this, Matrix); + + this.init.apply(this, arguments); + } // Initialize + + + _createClass(Matrix, [{ + key: "init", + value: function init(source) { + var base = Matrix.fromArray([1, 0, 0, 1, 0, 0]); // ensure source as object + + source = source instanceof Element ? source.matrixify() : typeof source === 'string' ? Matrix.fromArray(source.split(delimiter).map(parseFloat)) : Array.isArray(source) ? Matrix.fromArray(source) : _typeof(source) === 'object' && Matrix.isMatrixLike(source) ? source : _typeof(source) === 'object' ? new Matrix().transform(source) : arguments.length === 6 ? Matrix.fromArray([].slice.call(arguments)) : base; // Merge the source matrix with the base matrix + + this.a = source.a != null ? source.a : base.a; + this.b = source.b != null ? source.b : base.b; + this.c = source.c != null ? source.c : base.c; + this.d = source.d != null ? source.d : base.d; + this.e = source.e != null ? source.e : base.e; + this.f = source.f != null ? source.f : base.f; + return this; + } // Clones this matrix + + }, { + key: "clone", + value: function clone() { + return new Matrix(this); + } // Transform a matrix into another matrix by manipulating the space + + }, { + key: "transform", + value: function transform(o) { + // Check if o is a matrix and then left multiply it directly + if (Matrix.isMatrixLike(o)) { + var matrix = new Matrix(o); + return matrix.multiplyO(this); + } // Get the proposed transformations and the current transformations + + + var t = Matrix.formatTransforms(o); + var current = this; + + var _transform = new Point(t.ox, t.oy).transform(current), + ox = _transform.x, + oy = _transform.y; // Construct the resulting matrix + + + var transformer = new Matrix().translateO(t.rx, t.ry).lmultiplyO(current).translateO(-ox, -oy).scaleO(t.scaleX, t.scaleY).skewO(t.skewX, t.skewY).shearO(t.shear).rotateO(t.theta).translateO(ox, oy); // If we want the origin at a particular place, we force it there + + if (isFinite(t.px) || isFinite(t.py)) { + var origin = new Point(ox, oy).transform(transformer); // TODO: Replace t.px with isFinite(t.px) + + var dx = t.px ? t.px - origin.x : 0; + var dy = t.py ? t.py - origin.y : 0; + transformer.translateO(dx, dy); + } // Translate now after positioning + + + transformer.translateO(t.tx, t.ty); + return transformer; + } // Applies a matrix defined by its affine parameters + + }, { + key: "compose", + value: function compose(o) { + if (o.origin) { + o.originX = o.origin[0]; + o.originY = o.origin[1]; + } // Get the parameters + + + var ox = o.originX || 0; + var oy = o.originY || 0; + var sx = o.scaleX || 1; + var sy = o.scaleY || 1; + var lam = o.shear || 0; + var theta = o.rotate || 0; + var tx = o.translateX || 0; + var ty = o.translateY || 0; // Apply the standard matrix + + var result = new Matrix().translateO(-ox, -oy).scaleO(sx, sy).shearO(lam).rotateO(theta).translateO(tx, ty).lmultiplyO(this).translateO(ox, oy); + return result; + } // Decomposes this matrix into its affine parameters + + }, { + key: "decompose", + value: function decompose() { + var cx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var cy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + // Get the parameters from the matrix + var a = this.a; + var b = this.b; + var c = this.c; + var d = this.d; + var e = this.e; + var f = this.f; // Figure out if the winding direction is clockwise or counterclockwise + + var determinant = a * d - b * c; + var ccw = determinant > 0 ? 1 : -1; // Since we only shear in x, we can use the x basis to get the x scale + // and the rotation of the resulting matrix + + var sx = ccw * Math.sqrt(a * a + b * b); + var thetaRad = Math.atan2(ccw * b, ccw * a); + var theta = 180 / Math.PI * thetaRad; + var ct = Math.cos(thetaRad); + var st = Math.sin(thetaRad); // We can then solve the y basis vector simultaneously to get the other + // two affine parameters directly from these parameters + + var lam = (a * c + b * d) / determinant; + var sy = c * sx / (lam * a - b) || d * sx / (lam * b + a); // Use the translations + + var tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy); + var ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy); // Construct the decomposition and return it + + return { + // Return the affine parameters + scaleX: sx, + scaleY: sy, + shear: lam, + rotate: theta, + translateX: tx, + translateY: ty, + originX: cx, + originY: cy, + // Return the matrix parameters + a: this.a, + b: this.b, + c: this.c, + d: this.d, + e: this.e, + f: this.f + }; + } // Left multiplies by the given matrix + + }, { + key: "multiply", + value: function multiply(matrix) { + return this.clone().multiplyO(matrix); + } + }, { + key: "multiplyO", + value: function multiplyO(matrix) { + // Get the matrices + var l = this; + var r = matrix instanceof Matrix ? matrix : new Matrix(matrix); + return Matrix.matrixMultiply(l, r, this); + } + }, { + key: "lmultiply", + value: function lmultiply(matrix) { + return this.clone().lmultiplyO(matrix); + } + }, { + key: "lmultiplyO", + value: function lmultiplyO(matrix) { + var r = this; + var l = matrix instanceof Matrix ? matrix : new Matrix(matrix); + return Matrix.matrixMultiply(l, r, this); + } // Inverses matrix + + }, { + key: "inverseO", + value: function inverseO() { + // Get the current parameters out of the matrix + var a = this.a; + var b = this.b; + var c = this.c; + var d = this.d; + var e = this.e; + var f = this.f; // Invert the 2x2 matrix in the top left + + var det = a * d - b * c; + if (!det) throw new Error('Cannot invert ' + this); // Calculate the top 2x2 matrix + + var na = d / det; + var nb = -b / det; + var nc = -c / det; + var nd = a / det; // Apply the inverted matrix to the top right + + var ne = -(na * e + nc * f); + var nf = -(nb * e + nd * f); // Construct the inverted matrix + + this.a = na; + this.b = nb; + this.c = nc; + this.d = nd; + this.e = ne; + this.f = nf; + return this; + } + }, { + key: "inverse", + value: function inverse() { + return this.clone().inverseO(); + } // Translate matrix + + }, { + key: "translate", + value: function translate(x, y) { + return this.clone().translateO(x, y); + } + }, { + key: "translateO", + value: function translateO(x, y) { + this.e += x || 0; + this.f += y || 0; + return this; + } // Scale matrix + + }, { + key: "scale", + value: function scale(x, y, cx, cy) { + var _this$clone; + + return (_this$clone = this.clone()).scaleO.apply(_this$clone, arguments); + } + }, { + key: "scaleO", + value: function scaleO(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var cx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var cy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + + // Support uniform scaling + if (arguments.length === 3) { + cy = cx; + cx = y; + y = x; + } + + var a = this.a, + b = this.b, + c = this.c, + d = this.d, + e = this.e, + f = this.f; + this.a = a * x; + this.b = b * y; + this.c = c * x; + this.d = d * y; + this.e = e * x - cx * x + cx; + this.f = f * y - cy * y + cy; + return this; + } // Rotate matrix + + }, { + key: "rotate", + value: function rotate(r, cx, cy) { + return this.clone().rotateO(r, cx, cy); + } + }, { + key: "rotateO", + value: function rotateO(r) { + var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + // Convert degrees to radians + r = radians(r); + var cos = Math.cos(r); + var sin = Math.sin(r); + var a = this.a, + b = this.b, + c = this.c, + d = this.d, + e = this.e, + f = this.f; + this.a = a * cos - b * sin; + this.b = b * cos + a * sin; + this.c = c * cos - d * sin; + this.d = d * cos + c * sin; + this.e = e * cos - f * sin + cy * sin - cx * cos + cx; + this.f = f * cos + e * sin - cx * sin - cy * cos + cy; + return this; + } // Flip matrix on x or y, at a given offset + + }, { + key: "flip", + value: function flip(axis, around) { + return this.clone().flipO(axis, around); + } + }, { + key: "flipO", + value: function flipO(axis, around) { + return axis === 'x' ? this.scaleO(-1, 1, around, 0) : axis === 'y' ? this.scaleO(1, -1, 0, around) : this.scaleO(-1, -1, axis, around || axis); // Define an x, y flip point + } // Shear matrix + + }, { + key: "shear", + value: function shear(a, cx, cy) { + return this.clone().shearO(a, cx, cy); + } + }, { + key: "shearO", + value: function shearO(lx) { + var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var a = this.a, + b = this.b, + c = this.c, + d = this.d, + e = this.e, + f = this.f; + this.a = a + b * lx; + this.c = c + d * lx; + this.e = e + f * lx - cy * lx; + return this; + } // Skew Matrix + + }, { + key: "skew", + value: function skew(x, y, cx, cy) { + var _this$clone2; + + return (_this$clone2 = this.clone()).skewO.apply(_this$clone2, arguments); + } + }, { + key: "skewO", + value: function skewO(x) { + var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; + var cx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + var cy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; + + // support uniformal skew + if (arguments.length === 3) { + cy = cx; + cx = y; + y = x; + } // Convert degrees to radians + + + x = radians(x); + y = radians(y); + var lx = Math.tan(x); + var ly = Math.tan(y); + var a = this.a, + b = this.b, + c = this.c, + d = this.d, + e = this.e, + f = this.f; + this.a = a + b * lx; + this.b = b + a * ly; + this.c = c + d * lx; + this.d = d + c * ly; + this.e = e + f * lx - cy * lx; + this.f = f + e * ly - cx * ly; + return this; + } // SkewX + + }, { + key: "skewX", + value: function skewX(x, cx, cy) { + return this.skew(x, 0, cx, cy); + } + }, { + key: "skewXO", + value: function skewXO(x, cx, cy) { + return this.skewO(x, 0, cx, cy); + } // SkewY + + }, { + key: "skewY", + value: function skewY(y, cx, cy) { + return this.skew(0, y, cx, cy); + } + }, { + key: "skewYO", + value: function skewYO(y, cx, cy) { + return this.skewO(0, y, cx, cy); + } // Transform around a center point + + }, { + key: "aroundO", + value: function aroundO(cx, cy, matrix) { + var dx = cx || 0; + var dy = cy || 0; + return this.translateO(-dx, -dy).lmultiplyO(matrix).translateO(dx, dy); + } + }, { + key: "around", + value: function around(cx, cy, matrix) { + return this.clone().aroundO(cx, cy, matrix); + } // Check if two matrices are equal + + }, { + key: "equals", + value: function equals(other) { + var comp = new Matrix(other); + return closeEnough(this.a, comp.a) && closeEnough(this.b, comp.b) && closeEnough(this.c, comp.c) && closeEnough(this.d, comp.d) && closeEnough(this.e, comp.e) && closeEnough(this.f, comp.f); + } // Convert matrix to string + + }, { + key: "toString", + value: function toString() { + return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')'; + } + }, { + key: "toArray", + value: function toArray() { + return [this.a, this.b, this.c, this.d, this.e, this.f]; + } + }, { + key: "valueOf", + value: function valueOf() { + return { + a: this.a, + b: this.b, + c: this.c, + d: this.d, + e: this.e, + f: this.f + }; + } + }], [{ + key: "fromArray", + value: function fromArray(a) { + return { + a: a[0], + b: a[1], + c: a[2], + d: a[3], + e: a[4], + f: a[5] + }; + } + }, { + key: "isMatrixLike", + value: function isMatrixLike(o) { + return o.a != null || o.b != null || o.c != null || o.d != null || o.e != null || o.f != null; + } + }, { + key: "formatTransforms", + value: function formatTransforms(o) { + // Get all of the parameters required to form the matrix + var flipBoth = o.flip === 'both' || o.flip === true; + var flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1; + var flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1; + var skewX = o.skew && o.skew.length ? o.skew[0] : isFinite(o.skew) ? o.skew : isFinite(o.skewX) ? o.skewX : 0; + var skewY = o.skew && o.skew.length ? o.skew[1] : isFinite(o.skew) ? o.skew : isFinite(o.skewY) ? o.skewY : 0; + var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX : isFinite(o.scale) ? o.scale * flipX : isFinite(o.scaleX) ? o.scaleX * flipX : flipX; + var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY : isFinite(o.scale) ? o.scale * flipY : isFinite(o.scaleY) ? o.scaleY * flipY : flipY; + var shear = o.shear || 0; + var theta = o.rotate || o.theta || 0; + var origin = new Point(o.origin || o.around || o.ox || o.originX, o.oy || o.originY); + var ox = origin.x; + var oy = origin.y; + var position = new Point(o.position || o.px || o.positionX, o.py || o.positionY); + var px = position.x; + var py = position.y; + var translate = new Point(o.translate || o.tx || o.translateX, o.ty || o.translateY); + var tx = translate.x; + var ty = translate.y; + var relative = new Point(o.relative || o.rx || o.relativeX, o.ry || o.relativeY); + var rx = relative.x; + var ry = relative.y; // Populate all of the values + + return { + scaleX: scaleX, + scaleY: scaleY, + skewX: skewX, + skewY: skewY, + shear: shear, + theta: theta, + rx: rx, + ry: ry, + tx: tx, + ty: ty, + ox: ox, + oy: oy, + px: px, + py: py + }; + } // left matrix, right matrix, target matrix which is overwritten + + }, { + key: "matrixMultiply", + value: function matrixMultiply(l, r, o) { + // Work out the product directly + var a = l.a * r.a + l.c * r.b; + var b = l.b * r.a + l.d * r.b; + var c = l.a * r.c + l.c * r.d; + var d = l.b * r.c + l.d * r.d; + var e = l.e + l.a * r.e + l.c * r.f; + var f = l.f + l.b * r.e + l.d * r.f; // make sure to use local variables because l/r and o could be the same + + o.a = a; + o.b = b; + o.c = c; + o.d = d; + o.e = e; + o.f = f; + return o; + } + }]); + + return Matrix; + }(); + function ctm() { + return new Matrix(this.node.getCTM()); + } + function screenCTM() { + /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 + This is needed because FF does not return the transformation matrix + for the inner coordinate system when getScreenCTM() is called on nested svgs. + However all other Browsers do that */ + if (typeof this.isRoot === 'function' && !this.isRoot()) { + var rect = this.rect(1, 1); + var m = rect.node.getScreenCTM(); + rect.remove(); + return new Matrix(m); + } + + return new Matrix(this.node.getScreenCTM()); + } + var EventTarget = /*#__PURE__*/ function (_Base) { @@ -1670,12 +2413,6 @@ var SVG = (function () { value: function matches(selector) { var el = this.node; return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); - } // Returns the svg node to call native svg methods on it - - }, { - key: "native", - value: function native() { - return this.node; } // Returns the parent element instance }, { @@ -1995,793 +2732,14 @@ var SVG = (function () { return Element; }(Dom); - register(Element); - - var Container = - /*#__PURE__*/ - function (_Element) { - _inherits(Container, _Element); - - function Container() { - _classCallCheck(this, Container); - - return _possibleConstructorReturn(this, _getPrototypeOf(Container).apply(this, arguments)); - } - - _createClass(Container, [{ - key: "flatten", - value: function flatten(parent) { - this.each(function () { - if (this instanceof Container) return this.flatten(parent).ungroup(parent); - return this.toParent(parent); - }); // we need this so that Doc does not get removed - - this.node.firstElementChild || this.remove(); - return this; - } - }, { - key: "ungroup", - value: function ungroup(parent) { - parent = parent || this.parent(); - this.each(function () { - return this.toParent(parent); - }); - this.remove(); - return this; - } - }]); - - return Container; - }(Element); - register(Container); - - var Defs = - /*#__PURE__*/ - function (_Container) { - _inherits(Defs, _Container); - - function Defs(node) { - _classCallCheck(this, Defs); - - return _possibleConstructorReturn(this, _getPrototypeOf(Defs).call(this, nodeOrNew('defs', node), node)); - } - - _createClass(Defs, [{ - key: "flatten", - value: function flatten() { - return this; - } - }, { - key: "ungroup", - value: function ungroup() { - return this; - } - }]); - - return Defs; - }(Container); - register(Defs); - - var Doc$1 = - /*#__PURE__*/ - function (_Container) { - _inherits(Doc, _Container); - - function Doc(node) { - var _this; - - _classCallCheck(this, Doc); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Doc).call(this, nodeOrNew('svg', node), node)); - - _this.namespace(); - - return _this; - } - - _createClass(Doc, [{ - key: "isRoot", - value: function isRoot() { - return !this.node.parentNode || !(this.node.parentNode instanceof globals.window.SVGElement) || this.node.parentNode.nodeName === '#document'; - } // Check if this is a root svg - // If not, call docs from this element - - }, { - key: "doc", - value: function doc() { - if (this.isRoot()) return this; - return _get(_getPrototypeOf(Doc.prototype), "doc", this).call(this); - } // Add namespaces - - }, { - key: "namespace", - value: function namespace() { - if (!this.isRoot()) return this.doc().namespace(); - return this.attr({ - xmlns: ns, - version: '1.1' - }).attr('xmlns:xlink', xlink, xmlns).attr('xmlns:svgjs', svgjs, xmlns); - } // Creates and returns defs element - - }, { - key: "defs", - value: function defs() { - if (!this.isRoot()) return this.doc().defs(); - return adopt(this.node.getElementsByTagName('defs')[0]) || this.put(new Defs()); - } // custom parent method - - }, { - key: "parent", - value: function parent(type) { - if (this.isRoot()) { - return this.node.parentNode.nodeName === '#document' ? null : adopt(this.node.parentNode); - } - - return _get(_getPrototypeOf(Doc.prototype), "parent", this).call(this, type); - } - }, { - key: "clear", - value: function clear() { - // remove children - while (this.node.hasChildNodes()) { - this.node.removeChild(this.node.lastChild); - } - - return this; - } - }]); - - return Doc; - }(Container); - registerMethods({ - Container: { - // Create nested svg document - nested: wrapWithAttrCheck(function () { - return this.put(new Doc$1()); - }) - } - }); - register(Doc$1, 'Doc', true); - - function parser() { - // Reuse cached element if possible - if (!parser.nodes) { - var svg = new Doc$1().size(2, 0); - svg.node.cssText = ['opacity: 0', 'position: absolute', 'left: -100%', 'top: -100%', 'overflow: hidden'].join(';'); - var path = svg.path().node; - parser.nodes = { - svg: svg, - path: path - }; - } - - if (!parser.nodes.svg.node.parentNode) { - var b = globals.document.body || globals.document.documentElement; - parser.nodes.svg.addTo(b); - } - - return parser.nodes; - } - - var Point = - /*#__PURE__*/ - function () { - // Initialize - function Point() { - _classCallCheck(this, Point); - - this.init.apply(this, arguments); - } - - _createClass(Point, [{ - key: "init", - value: function init(x, y) { - var source; - var base = { - x: 0, - y: 0 // ensure source as object - - }; - source = Array.isArray(x) ? { - x: x[0], - y: x[1] - } : _typeof(x) === 'object' ? { - x: x.x, - y: x.y - } : { - x: x, - y: y // merge source - - }; - this.x = source.x == null ? base.x : source.x; - this.y = source.y == null ? base.y : source.y; - return this; - } // Clone point - - }, { - key: "clone", - value: function clone() { - return new Point(this); - } // Convert to native SVGPoint - - }, { - key: "native", - value: function native() { - // create new point - var point = parser().svg.node.createSVGPoint(); // update with current values - - point.x = this.x; - point.y = this.y; - return point; - } // transform point with matrix - - }, { - key: "transform", - value: function transform(m) { - // Perform the matrix multiplication - var x = m.a * this.x + m.c * this.y + m.e; - var y = m.b * this.x + m.d * this.y + m.f; // Return the required point - - return new Point(x, y); - } - }, { - key: "toArray", - value: function toArray() { - return [this.x, this.y]; - } - }]); - - return Point; - }(); - registerMethods({ - Element: { - // Get point - point: function point(x, y) { - return new Point(x, y).transform(this.screenCTM().inverse()); - } - } - }); - - var abcdef = 'abcdef'.split(''); - - function closeEnough(a, b, threshold) { - return Math.abs(b - a) < (threshold || 1e-6); - } - - var Matrix = - /*#__PURE__*/ - function () { - function Matrix() { - _classCallCheck(this, Matrix); - - this.init.apply(this, arguments); - } // Initialize - - - _createClass(Matrix, [{ - key: "init", - value: function init(source) { - var base = Matrix.fromArray([1, 0, 0, 1, 0, 0]); // ensure source as object - - source = source instanceof Element ? source.matrixify() : typeof source === 'string' ? Matrix.fromArray(source.split(delimiter).map(parseFloat)) : Array.isArray(source) ? Matrix.fromArray(source) : _typeof(source) === 'object' && Matrix.isMatrixLike(source) ? source : _typeof(source) === 'object' ? new Matrix().transform(source) : arguments.length === 6 ? Matrix.fromArray([].slice.call(arguments)) : base; // Merge the source matrix with the base matrix - - this.a = source.a != null ? source.a : base.a; - this.b = source.b != null ? source.b : base.b; - this.c = source.c != null ? source.c : base.c; - this.d = source.d != null ? source.d : base.d; - this.e = source.e != null ? source.e : base.e; - this.f = source.f != null ? source.f : base.f; - return this; - } // Clones this matrix - - }, { - key: "clone", - value: function clone() { - return new Matrix(this); - } // Transform a matrix into another matrix by manipulating the space - - }, { - key: "transform", - value: function transform(o) { - // Check if o is a matrix and then left multiply it directly - if (Matrix.isMatrixLike(o)) { - var matrix = new Matrix(o); - return matrix.multiplyO(this); - } // Get the proposed transformations and the current transformations - - - var t = Matrix.formatTransforms(o); - var current = this; - - var _transform = new Point(t.ox, t.oy).transform(current), - ox = _transform.x, - oy = _transform.y; // Construct the resulting matrix - - - var transformer = new Matrix().translateO(t.rx, t.ry).lmultiplyO(current).translateO(-ox, -oy).scaleO(t.scaleX, t.scaleY).skewO(t.skewX, t.skewY).shearO(t.shear).rotateO(t.theta).translateO(ox, oy); // If we want the origin at a particular place, we force it there - - if (isFinite(t.px) || isFinite(t.py)) { - var origin = new Point(ox, oy).transform(transformer); // TODO: Replace t.px with isFinite(t.px) - - var dx = t.px ? t.px - origin.x : 0; - var dy = t.py ? t.py - origin.y : 0; - transformer.translateO(dx, dy); - } // Translate now after positioning - - - transformer.translateO(t.tx, t.ty); - return transformer; - } // Applies a matrix defined by its affine parameters - - }, { - key: "compose", - value: function compose(o) { - if (o.origin) { - o.originX = o.origin[0]; - o.originY = o.origin[1]; - } // Get the parameters - - - var ox = o.originX || 0; - var oy = o.originY || 0; - var sx = o.scaleX || 1; - var sy = o.scaleY || 1; - var lam = o.shear || 0; - var theta = o.rotate || 0; - var tx = o.translateX || 0; - var ty = o.translateY || 0; // Apply the standard matrix - - var result = new Matrix().translateO(-ox, -oy).scaleO(sx, sy).shearO(lam).rotateO(theta).translateO(tx, ty).lmultiplyO(this).translateO(ox, oy); - return result; - } // Decomposes this matrix into its affine parameters - - }, { - key: "decompose", - value: function decompose() { - var cx = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; - var cy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - // Get the parameters from the matrix - var a = this.a; - var b = this.b; - var c = this.c; - var d = this.d; - var e = this.e; - var f = this.f; // Figure out if the winding direction is clockwise or counterclockwise - - var determinant = a * d - b * c; - var ccw = determinant > 0 ? 1 : -1; // Since we only shear in x, we can use the x basis to get the x scale - // and the rotation of the resulting matrix - - var sx = ccw * Math.sqrt(a * a + b * b); - var thetaRad = Math.atan2(ccw * b, ccw * a); - var theta = 180 / Math.PI * thetaRad; - var ct = Math.cos(thetaRad); - var st = Math.sin(thetaRad); // We can then solve the y basis vector simultaneously to get the other - // two affine parameters directly from these parameters - - var lam = (a * c + b * d) / determinant; - var sy = c * sx / (lam * a - b) || d * sx / (lam * b + a); // Use the translations - - var tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy); - var ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy); // Construct the decomposition and return it - - return { - // Return the affine parameters - scaleX: sx, - scaleY: sy, - shear: lam, - rotate: theta, - translateX: tx, - translateY: ty, - originX: cx, - originY: cy, - // Return the matrix parameters - a: this.a, - b: this.b, - c: this.c, - d: this.d, - e: this.e, - f: this.f - }; - } // Left multiplies by the given matrix - - }, { - key: "multiply", - value: function multiply(matrix) { - return this.clone().multiplyO(matrix); - } - }, { - key: "multiplyO", - value: function multiplyO(matrix) { - // Get the matrices - var l = this; - var r = matrix instanceof Matrix ? matrix : new Matrix(matrix); - return Matrix.matrixMultiply(l, r, this); - } - }, { - key: "lmultiply", - value: function lmultiply(matrix) { - return this.clone().lmultiplyO(matrix); - } - }, { - key: "lmultiplyO", - value: function lmultiplyO(matrix) { - var r = this; - var l = matrix instanceof Matrix ? matrix : new Matrix(matrix); - return Matrix.matrixMultiply(l, r, this); - } // Inverses matrix - - }, { - key: "inverseO", - value: function inverseO() { - // Get the current parameters out of the matrix - var a = this.a; - var b = this.b; - var c = this.c; - var d = this.d; - var e = this.e; - var f = this.f; // Invert the 2x2 matrix in the top left - - var det = a * d - b * c; - if (!det) throw new Error('Cannot invert ' + this); // Calculate the top 2x2 matrix - - var na = d / det; - var nb = -b / det; - var nc = -c / det; - var nd = a / det; // Apply the inverted matrix to the top right - - var ne = -(na * e + nc * f); - var nf = -(nb * e + nd * f); // Construct the inverted matrix - - this.a = na; - this.b = nb; - this.c = nc; - this.d = nd; - this.e = ne; - this.f = nf; - return this; - } - }, { - key: "inverse", - value: function inverse() { - return this.clone().inverseO(); - } // Translate matrix - - }, { - key: "translate", - value: function translate(x, y) { - return this.clone().translateO(x, y); - } - }, { - key: "translateO", - value: function translateO(x, y) { - this.e += x || 0; - this.f += y || 0; - return this; - } // Scale matrix - - }, { - key: "scale", - value: function scale(x, y, cx, cy) { - var _this$clone; - - return (_this$clone = this.clone()).scaleO.apply(_this$clone, arguments); - } - }, { - key: "scaleO", - value: function scaleO(x) { - var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; - var cx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - var cy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; - - // Support uniform scaling - if (arguments.length === 3) { - cy = cx; - cx = y; - y = x; - } - - var a = this.a, - b = this.b, - c = this.c, - d = this.d, - e = this.e, - f = this.f; - this.a = a * x; - this.b = b * y; - this.c = c * x; - this.d = d * y; - this.e = e * x - cx * x + cx; - this.f = f * y - cy * y + cy; - return this; - } // Rotate matrix - - }, { - key: "rotate", - value: function rotate(r, cx, cy) { - return this.clone().rotateO(r, cx, cy); - } - }, { - key: "rotateO", - value: function rotateO(r) { - var cx = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - // Convert degrees to radians - r = radians(r); - var cos = Math.cos(r); - var sin = Math.sin(r); - var a = this.a, - b = this.b, - c = this.c, - d = this.d, - e = this.e, - f = this.f; - this.a = a * cos - b * sin; - this.b = b * cos + a * sin; - this.c = c * cos - d * sin; - this.d = d * cos + c * sin; - this.e = e * cos - f * sin + cy * sin - cx * cos + cx; - this.f = f * cos + e * sin - cx * sin - cy * cos + cy; - return this; - } // Flip matrix on x or y, at a given offset - - }, { - key: "flip", - value: function flip(axis, around) { - return this.clone().flipO(axis, around); - } - }, { - key: "flipO", - value: function flipO(axis, around) { - return axis === 'x' ? this.scaleO(-1, 1, around, 0) : axis === 'y' ? this.scaleO(1, -1, 0, around) : this.scaleO(-1, -1, axis, around || axis); // Define an x, y flip point - } // Shear matrix - - }, { - key: "shear", - value: function shear(a, cx, cy) { - return this.clone().shearO(a, cx, cy); - } - }, { - key: "shearO", - value: function shearO(lx) { - var cy = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - var a = this.a, - b = this.b, - c = this.c, - d = this.d, - e = this.e, - f = this.f; - this.a = a + b * lx; - this.c = c + d * lx; - this.e = e + f * lx - cy * lx; - return this; - } // Skew Matrix - - }, { - key: "skew", - value: function skew(x, y, cx, cy) { - var _this$clone2; - - return (_this$clone2 = this.clone()).skewO.apply(_this$clone2, arguments); - } - }, { - key: "skewO", - value: function skewO(x) { - var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x; - var cx = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; - var cy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0; - - // support uniformal skew - if (arguments.length === 3) { - cy = cx; - cx = y; - y = x; - } // Convert degrees to radians - - - x = radians(x); - y = radians(y); - var lx = Math.tan(x); - var ly = Math.tan(y); - var a = this.a, - b = this.b, - c = this.c, - d = this.d, - e = this.e, - f = this.f; - this.a = a + b * lx; - this.b = b + a * ly; - this.c = c + d * lx; - this.d = d + c * ly; - this.e = e + f * lx - cy * lx; - this.f = f + e * ly - cx * ly; - return this; - } // SkewX - - }, { - key: "skewX", - value: function skewX(x, cx, cy) { - return this.skew(x, 0, cx, cy); - } - }, { - key: "skewXO", - value: function skewXO(x, cx, cy) { - return this.skewO(x, 0, cx, cy); - } // SkewY - - }, { - key: "skewY", - value: function skewY(y, cx, cy) { - return this.skew(0, y, cx, cy); - } - }, { - key: "skewYO", - value: function skewYO(y, cx, cy) { - return this.skewO(0, y, cx, cy); - } // Transform around a center point - - }, { - key: "aroundO", - value: function aroundO(cx, cy, matrix) { - var dx = cx || 0; - var dy = cy || 0; - return this.translateO(-dx, -dy).lmultiplyO(matrix).translateO(dx, dy); - } - }, { - key: "around", - value: function around(cx, cy, matrix) { - return this.clone().aroundO(cx, cy, matrix); - } // Convert to native SVGMatrix - - }, { - key: "native", - value: function native() { - // create new matrix - var matrix = parser().svg.node.createSVGMatrix(); // update with current values - - for (var i = abcdef.length - 1; i >= 0; i--) { - matrix[abcdef[i]] = this[abcdef[i]]; - } - - return matrix; - } // Check if two matrices are equal - - }, { - key: "equals", - value: function equals(other) { - var comp = new Matrix(other); - return closeEnough(this.a, comp.a) && closeEnough(this.b, comp.b) && closeEnough(this.c, comp.c) && closeEnough(this.d, comp.d) && closeEnough(this.e, comp.e) && closeEnough(this.f, comp.f); - } // Convert matrix to string - - }, { - key: "toString", - value: function toString() { - return 'matrix(' + this.a + ',' + this.b + ',' + this.c + ',' + this.d + ',' + this.e + ',' + this.f + ')'; - } - }, { - key: "toArray", - value: function toArray() { - return [this.a, this.b, this.c, this.d, this.e, this.f]; - } - }, { - key: "valueOf", - value: function valueOf() { - return { - a: this.a, - b: this.b, - c: this.c, - d: this.d, - e: this.e, - f: this.f - }; - } - }], [{ - key: "fromArray", - value: function fromArray(a) { - return { - a: a[0], - b: a[1], - c: a[2], - d: a[3], - e: a[4], - f: a[5] - }; - } - }, { - key: "isMatrixLike", - value: function isMatrixLike(o) { - return o.a != null || o.b != null || o.c != null || o.d != null || o.e != null || o.f != null; - } - }, { - key: "formatTransforms", - value: function formatTransforms(o) { - // Get all of the parameters required to form the matrix - var flipBoth = o.flip === 'both' || o.flip === true; - var flipX = o.flip && (flipBoth || o.flip === 'x') ? -1 : 1; - var flipY = o.flip && (flipBoth || o.flip === 'y') ? -1 : 1; - var skewX = o.skew && o.skew.length ? o.skew[0] : isFinite(o.skew) ? o.skew : isFinite(o.skewX) ? o.skewX : 0; - var skewY = o.skew && o.skew.length ? o.skew[1] : isFinite(o.skew) ? o.skew : isFinite(o.skewY) ? o.skewY : 0; - var scaleX = o.scale && o.scale.length ? o.scale[0] * flipX : isFinite(o.scale) ? o.scale * flipX : isFinite(o.scaleX) ? o.scaleX * flipX : flipX; - var scaleY = o.scale && o.scale.length ? o.scale[1] * flipY : isFinite(o.scale) ? o.scale * flipY : isFinite(o.scaleY) ? o.scaleY * flipY : flipY; - var shear = o.shear || 0; - var theta = o.rotate || o.theta || 0; - var origin = new Point(o.origin || o.around || o.ox || o.originX, o.oy || o.originY); - var ox = origin.x; - var oy = origin.y; - var position = new Point(o.position || o.px || o.positionX, o.py || o.positionY); - var px = position.x; - var py = position.y; - var translate = new Point(o.translate || o.tx || o.translateX, o.ty || o.translateY); - var tx = translate.x; - var ty = translate.y; - var relative = new Point(o.relative || o.rx || o.relativeX, o.ry || o.relativeY); - var rx = relative.x; - var ry = relative.y; // Populate all of the values - - return { - scaleX: scaleX, - scaleY: scaleY, - skewX: skewX, - skewY: skewY, - shear: shear, - theta: theta, - rx: rx, - ry: ry, - tx: tx, - ty: ty, - ox: ox, - oy: oy, - px: px, - py: py - }; - } // left matrix, right matrix, target matrix which is overwritten - - }, { - key: "matrixMultiply", - value: function matrixMultiply(l, r, o) { - // Work out the product directly - var a = l.a * r.a + l.c * r.b; - var b = l.b * r.a + l.d * r.b; - var c = l.a * r.c + l.c * r.d; - var d = l.b * r.c + l.d * r.d; - var e = l.e + l.a * r.e + l.c * r.f; - var f = l.f + l.b * r.e + l.d * r.f; // make sure to use local variables because l/r and o could be the same - - o.a = a; - o.b = b; - o.c = c; - o.d = d; - o.e = e; - o.f = f; - return o; - } - }]); - - return Matrix; - }(); - registerMethods({ - Element: { - // Get current matrix - ctm: function ctm() { - return new Matrix(this.node.getCTM()); - }, - // Get current screen matrix - screenCTM: function screenCTM() { - /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 - This is needed because FF does not return the transformation matrix - for the inner coordinate system when getScreenCTM() is called on nested svgs. - However all other Browsers do that */ - if (typeof this.isRoot === 'function' && !this.isRoot()) { - var rect = this.rect(1, 1); - var m = rect.node.getScreenCTM(); - rect.remove(); - return new Matrix(m); - } - - return new Matrix(this.node.getScreenCTM()); - } - } + extend(Element, { + bbox: bbox, + rbox: rbox, + point: point, + ctm: ctm, + screenCTM: screenCTM }); + register(Element); var sugar = { stroke: ['color', 'width', 'opacity', 'linecap', 'linejoin', 'miterlimit', 'dasharray', 'dashoffset'], @@ -2989,9 +2947,9 @@ var SVG = (function () { function toParent(parent) { if (this === parent) return this; - var ctm = this.screenCTM(); + var ctm$$1 = this.screenCTM(); var pCtm = parent.screenCTM().inverse(); - this.addTo(parent).untransform().transform(pCtm.multiply(ctm)); + this.addTo(parent).untransform().transform(pCtm.multiply(ctm$$1)); return this; } // same as above with parent equals root-svg @@ -3026,149 +2984,6 @@ var SVG = (function () { transform: transform }); - function isNulledBox(box) { - return !box.w && !box.h && !box.x && !box.y; - } - - function domContains(node) { - return (globals.document.documentElement.contains || function (node) { - // This is IE - it does not support contains() for top-level SVGs - while (node.parentNode) { - node = node.parentNode; - } - - return node === document; - }).call(globals.document.documentElement, node); - } - - var Box = - /*#__PURE__*/ - function () { - function Box() { - _classCallCheck(this, Box); - - this.init.apply(this, arguments); - } - - _createClass(Box, [{ - key: "init", - value: function init(source) { - var base = [0, 0, 0, 0]; - source = typeof source === 'string' ? source.split(delimiter).map(parseFloat) : Array.isArray(source) ? source : _typeof(source) === 'object' ? [source.left != null ? source.left : source.x, source.top != null ? source.top : source.y, source.width, source.height] : arguments.length === 4 ? [].slice.call(arguments) : base; - this.x = source[0] || 0; - this.y = source[1] || 0; - this.width = this.w = source[2] || 0; - this.height = this.h = source[3] || 0; // Add more bounding box properties - - this.x2 = this.x + this.w; - this.y2 = this.y + this.h; - this.cx = this.x + this.w / 2; - this.cy = this.y + this.h / 2; - return this; - } // Merge rect box with another, return a new instance - - }, { - key: "merge", - value: function merge(box) { - var x = Math.min(this.x, box.x); - var y = Math.min(this.y, box.y); - var width = Math.max(this.x + this.width, box.x + box.width) - x; - var height = Math.max(this.y + this.height, box.y + box.height) - y; - return new Box(x, y, width, height); - } - }, { - key: "transform", - value: function transform(m) { - var xMin = Infinity; - var xMax = -Infinity; - var yMin = Infinity; - var yMax = -Infinity; - var pts = [new Point(this.x, this.y), new Point(this.x2, this.y), new Point(this.x, this.y2), new Point(this.x2, this.y2)]; - pts.forEach(function (p) { - p = p.transform(m); - xMin = Math.min(xMin, p.x); - xMax = Math.max(xMax, p.x); - yMin = Math.min(yMin, p.y); - yMax = Math.max(yMax, p.y); - }); - return new Box(xMin, yMin, xMax - xMin, yMax - yMin); - } - }, { - key: "addOffset", - value: function addOffset() { - // offset by window scroll position, because getBoundingClientRect changes when window is scrolled - this.x += globals.window.pageXOffset; - this.y += globals.window.pageYOffset; - return this; - } - }, { - key: "toString", - value: function toString() { - return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height; - } - }, { - key: "toArray", - value: function toArray() { - return [this.x, this.y, this.width, this.height]; - } - }, { - key: "isNulled", - value: function isNulled() { - return isNulledBox(this); - } - }]); - - return Box; - }(); - - function getBox(cb) { - var box; - - try { - box = cb(this.node); - - if (isNulledBox(box) && !domContains(this.node)) { - throw new Error('Element not in the dom'); - } - } catch (e) { - try { - var clone = this.clone().addTo(parser().svg).show(); - box = cb(clone.node); - clone.remove(); - } catch (e) { - throw new Error('Getting a bounding box of element "' + this.node.nodeName + '" is not possible'); - } - } - - return box; - } - - registerMethods({ - Element: { - // Get bounding box - bbox: function bbox() { - return new Box(getBox.call(this, function (node) { - return node.getBBox(); - })); - }, - rbox: function rbox(el) { - var box = new Box(getBox.call(this, function (node) { - return node.getBoundingClientRect(); - })); - if (el) return box.transform(el.screenCTM().inverse()); - return box.addOffset(); - } - }, - viewbox: { - viewbox: function viewbox(x, y, width, height) { - // act as getter - if (x == null) return new Box(this.attr('viewBox')); // act as setter - - return this.attr('viewBox', new Box(x, y, width, height)); - } - } - }); - function rx(rx) { return this.attr('rx', rx); } // Radius y value @@ -3282,6 +3097,152 @@ var SVG = (function () { }); register(Circle); + var Container = + /*#__PURE__*/ + function (_Element) { + _inherits(Container, _Element); + + function Container() { + _classCallCheck(this, Container); + + return _possibleConstructorReturn(this, _getPrototypeOf(Container).apply(this, arguments)); + } + + _createClass(Container, [{ + key: "flatten", + value: function flatten(parent) { + this.each(function () { + if (this instanceof Container) return this.flatten(parent).ungroup(parent); + return this.toParent(parent); + }); // we need this so that Doc does not get removed + + this.node.firstElementChild || this.remove(); + return this; + } + }, { + key: "ungroup", + value: function ungroup(parent) { + parent = parent || this.parent(); + this.each(function () { + return this.toParent(parent); + }); + this.remove(); + return this; + } + }]); + + return Container; + }(Element); + register(Container); + + var Defs = + /*#__PURE__*/ + function (_Container) { + _inherits(Defs, _Container); + + function Defs(node) { + _classCallCheck(this, Defs); + + return _possibleConstructorReturn(this, _getPrototypeOf(Defs).call(this, nodeOrNew('defs', node), node)); + } + + _createClass(Defs, [{ + key: "flatten", + value: function flatten() { + return this; + } + }, { + key: "ungroup", + value: function ungroup() { + return this; + } + }]); + + return Defs; + }(Container); + register(Defs); + + var Doc$1 = + /*#__PURE__*/ + function (_Container) { + _inherits(Doc, _Container); + + function Doc(node) { + var _this; + + _classCallCheck(this, Doc); + + _this = _possibleConstructorReturn(this, _getPrototypeOf(Doc).call(this, nodeOrNew('svg', node), node)); + + _this.namespace(); + + return _this; + } + + _createClass(Doc, [{ + key: "isRoot", + value: function isRoot() { + return !this.node.parentNode || !(this.node.parentNode instanceof globals.window.SVGElement) || this.node.parentNode.nodeName === '#document'; + } // Check if this is a root svg + // If not, call docs from this element + + }, { + key: "doc", + value: function doc() { + if (this.isRoot()) return this; + return _get(_getPrototypeOf(Doc.prototype), "doc", this).call(this); + } // Add namespaces + + }, { + key: "namespace", + value: function namespace() { + if (!this.isRoot()) return this.doc().namespace(); + return this.attr({ + xmlns: ns, + version: '1.1' + }).attr('xmlns:xlink', xlink, xmlns).attr('xmlns:svgjs', svgjs, xmlns); + } // Creates and returns defs element + + }, { + key: "defs", + value: function defs() { + if (!this.isRoot()) return this.doc().defs(); + return adopt(this.node.getElementsByTagName('defs')[0]) || this.put(new Defs()); + } // custom parent method + + }, { + key: "parent", + value: function parent(type) { + if (this.isRoot()) { + return this.node.parentNode.nodeName === '#document' ? null : adopt(this.node.parentNode); + } + + return _get(_getPrototypeOf(Doc.prototype), "parent", this).call(this, type); + } + }, { + key: "clear", + value: function clear() { + // remove children + while (this.node.hasChildNodes()) { + this.node.removeChild(this.node.lastChild); + } + + return this; + } + }]); + + return Doc; + }(Container); + registerMethods({ + Container: { + // Create nested svg document + nested: wrapWithAttrCheck(function () { + return this.put(new Doc$1()); + }) + } + }); + register(Doc$1, 'Doc', true); + var Ellipse = /*#__PURE__*/ function (_Shape) { @@ -3440,7 +3401,7 @@ var SVG = (function () { } }, { key: "bbox", - value: function bbox() { + value: function bbox$$1() { return new Box(); } }]); @@ -3515,7 +3476,7 @@ var SVG = (function () { } }, { key: "bbox", - value: function bbox() { + value: function bbox$$1() { return new Box(); } }]); @@ -6067,12 +6028,12 @@ var SVG = (function () { }); return this; }, - zoom: function zoom(level, point) { + zoom: function zoom(level, point$$1) { var morpher = new Morphable(this._stepper).to(new SVGNumber(level)); this.queue(function () { morpher = morpher.from(this.zoom()); }, function (pos) { - this.element().zoom(morpher.at(pos), point); + this.element().zoom(morpher.at(pos), point$$1); return morpher.done(); }); return this; diff --git a/spec/spec/element.js b/spec/spec/element.js index b36ea82..9afedc6 100644 --- a/spec/spec/element.js +++ b/spec/spec/element.js @@ -10,13 +10,6 @@ describe('Element', function() { expect(rect.node.instance).toBe(rect) }) - describe('native()', function() { - it('returns the node reference', function() { - var rect = draw.rect(100,100) - expect(rect.native()).toBe(rect.node) - }) - }) - describe('attr()', function() { var rect diff --git a/spec/spec/matrix.js b/spec/spec/matrix.js index 42ac1fe..b6c0348 100644 --- a/spec/spec/matrix.js +++ b/spec/spec/matrix.js @@ -372,11 +372,4 @@ describe('Matrix', function() { expect(matrix.f).toBeCloseTo(-81.2931393017) }) }) - - describe('native()', function() { - it('returns the node reference', function() { - expect(new SVG.Matrix().native() instanceof window.SVGMatrix).toBeTruthy() - }) - }) - }) diff --git a/spec/spec/point.js b/spec/spec/point.js index 768d7e9..8be944a 100644 --- a/spec/spec/point.js +++ b/spec/spec/point.js @@ -60,16 +60,6 @@ describe('Point', function() { expect(point.y).toBe(4) }) }) - - describe('with native SVGPoint given', function() { - it('creates a point from native SVGPoint', function() { - var point = new SVG.Point(new SVG.Point(2,4).native()) - - expect(point.x).toBe(2) - expect(point.y).toBe(4) - }) - }) - }) describe('clone()', function() { diff --git a/src/elements/Dom.js b/src/elements/Dom.js index 6d35f1e..55d5858 100644 --- a/src/elements/Dom.js +++ b/src/elements/Dom.js @@ -137,11 +137,6 @@ export default class Dom extends EventTarget { return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector) } - // Returns the svg node to call native svg methods on it - native () { - return this.node - } - // Returns the parent element instance parent (type) { var parent = this diff --git a/src/elements/Element.js b/src/elements/Element.js index 3b96bf4..456ddad 100644 --- a/src/elements/Element.js +++ b/src/elements/Element.js @@ -1,5 +1,14 @@ -import { getClass, makeInstance, register, root } from '../utils/adopter.js' +import { bbox, rbox } from '../types/Box.js' +import { ctm, screenCTM } from '../types/Matrix.js' +import { + extend, + getClass, + makeInstance, + register, + root +} from '../utils/adopter.js' import { globals } from '../utils/window.js' +import { point } from '../types/Point.js' import { proportionalSize } from '../utils/utils.js' import { reference } from '../modules/core/regex.js' import Dom from './Dom.js' @@ -145,4 +154,8 @@ export default class Element extends Dom { } } +extend(Element, { + bbox, rbox, point, ctm, screenCTM +}) + register(Element) diff --git a/src/modules/core/parser.js b/src/modules/core/parser.js index ccbbc54..1ff2380 100644 --- a/src/modules/core/parser.js +++ b/src/modules/core/parser.js @@ -1,10 +1,10 @@ -import Doc from '../../elements/Doc.js' import { globals } from '../../utils/window.js' +import { makeInstance } from '../../utils/adopter.js' export default function parser () { // Reuse cached element if possible if (!parser.nodes) { - let svg = new Doc().size(2, 0) + let svg = makeInstance().size(2, 0) svg.node.cssText = [ 'opacity: 0', 'position: absolute', diff --git a/src/types/Box.js b/src/types/Box.js index 8c1c4ca..e55f114 100644 --- a/src/types/Box.js +++ b/src/types/Box.js @@ -125,19 +125,17 @@ function getBox (cb) { return box } +export function bbox () { + return new Box(getBox.call(this, (node) => node.getBBox())) +} + +export function rbox (el) { + let box = new Box(getBox.call(this, (node) => node.getBoundingClientRect())) + if (el) return box.transform(el.screenCTM().inverse()) + return box.addOffset() +} + registerMethods({ - Element: { - // Get bounding box - bbox () { - return new Box(getBox.call(this, (node) => node.getBBox())) - }, - - rbox (el) { - let box = new Box(getBox.call(this, (node) => node.getBoundingClientRect())) - if (el) return box.transform(el.screenCTM().inverse()) - return box.addOffset() - } - }, viewbox: { viewbox (x, y, width, height) { // act as getter diff --git a/src/types/Matrix.js b/src/types/Matrix.js index ee12488..a1eb317 100644 --- a/src/types/Matrix.js +++ b/src/types/Matrix.js @@ -1,12 +1,7 @@ import { delimiter } from '../modules/core/regex.js' import { radians } from '../utils/utils.js' -import { registerMethods } from '../utils/methods.js' import Element from '../elements/Element.js' import Point from './Point.js' -import parser from '../modules/core/parser.js' - -// Create matrix array for looping -const abcdef = 'abcdef'.split('') function closeEnough (a, b, threshold) { return Math.abs(b - a) < (threshold || 1e-6) @@ -379,19 +374,6 @@ export default class Matrix { return this.clone().aroundO(cx, cy, matrix) } - // Convert to native SVGMatrix - native () { - // create new matrix - var matrix = parser().svg.node.createSVGMatrix() - - // update with current values - for (var i = abcdef.length - 1; i >= 0; i--) { - matrix[abcdef[i]] = this[abcdef[i]] - } - - return matrix - } - // Check if two matrices are equal equals (other) { var comp = new Matrix(other) @@ -499,26 +481,20 @@ export default class Matrix { } } -registerMethods({ - Element: { - // Get current matrix - ctm () { - return new Matrix(this.node.getCTM()) - }, - - // Get current screen matrix - screenCTM () { - /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 - This is needed because FF does not return the transformation matrix - for the inner coordinate system when getScreenCTM() is called on nested svgs. - However all other Browsers do that */ - if (typeof this.isRoot === 'function' && !this.isRoot()) { - var rect = this.rect(1, 1) - var m = rect.node.getScreenCTM() - rect.remove() - return new Matrix(m) - } - return new Matrix(this.node.getScreenCTM()) - } - } -}) +export function ctm () { + return new Matrix(this.node.getCTM()) +} + +export function screenCTM () { + /* https://bugzilla.mozilla.org/show_bug.cgi?id=1344537 + This is needed because FF does not return the transformation matrix + for the inner coordinate system when getScreenCTM() is called on nested svgs. + However all other Browsers do that */ + if (typeof this.isRoot === 'function' && !this.isRoot()) { + var rect = this.rect(1, 1) + var m = rect.node.getScreenCTM() + rect.remove() + return new Matrix(m) + } + return new Matrix(this.node.getScreenCTM()) +} diff --git a/src/types/Point.js b/src/types/Point.js index 6a2b968..27d81ea 100644 --- a/src/types/Point.js +++ b/src/types/Point.js @@ -1,6 +1,3 @@ -import { registerMethods } from '../utils/methods.js' -import parser from '../modules/core/parser.js' - export default class Point { // Initialize constructor (...args) { @@ -28,17 +25,6 @@ export default class Point { return new Point(this) } - // Convert to native SVGPoint - native () { - // create new point - var point = parser().svg.node.createSVGPoint() - - // update with current values - point.x = this.x - point.y = this.y - return point - } - // transform point with matrix transform (m) { // Perform the matrix multiplication @@ -54,11 +40,6 @@ export default class Point { } } -registerMethods({ - Element: { - // Get point - point: function (x, y) { - return new Point(x, y).transform(this.screenCTM().inverse()) - } - } -}) +export function point (x, y) { + return new Point(x, y).transform(this.screenCTM().inverse()) +} |