From: Saivan Date: Tue, 27 Feb 2018 00:41:21 +0000 (+1100) Subject: Merged the 3.0.0 branch to add the linter X-Git-Tag: 3.0.0~60^2~96 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4b078f8732a494b7f184556f276b011317a766b5;p=svg.js.git Merged the 3.0.0 branch to add the linter I added the linter here to make programming and running the tests easier throughout the programming process. --- 4b078f8732a494b7f184556f276b011317a766b5 diff --cc src/fx.js index ed81cc7,242c997..9fcdd4c --- a/src/fx.js +++ b/src/fx.js @@@ -597,17 -592,18 +592,18 @@@ SVG.FX = SVG.invent( // save last eased position for once callback triggering this.lastPos = eased return this - - } + }, // calculates the step for every property and calls block with it - , eachAt: function(){ - var i, len, at, self = this, target = this.target(), s = this.situation + eachAt: function () { - var i, len, at ++ var i, at + var self = this + var target = this.target() + var s = this.situation // apply animations which can be called trough a method - for(i in s.animations){ - - at = [].concat(s.animations[i]).map(function(el){ + for (i in s.animations) { + at = [].concat(s.animations[i]).map(function (el) { return typeof el !== 'string' && el.at ? el.at(s.ease(self.pos), self.pos) : el }) @@@ -637,40 -629,34 +629,39 @@@ } // animate initialTransformation which has to be chained - if(s.transforms.length){ + if (s.transforms.length) { - // get initial initialTransformation - at = s.initialTransformation - for (i = 0, len = s.transforms.length; i < len; i++) { - // get next transformation in chain - var a = s.transforms[i] - - // multiply matrix directly - if (a instanceof SVG.Matrix) { - if (a.relative) { - at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos))) - } else { - at = at.morph(a).at(s.ease(this.pos)) - } - continue - } - - // when transformation is absolute we have to reset the needed transformation first - if (!a.relative) { - a.undo(at.extract()) - } - // and reapply it after - at = at.multiply(a.at(s.ease(this.pos))) - } - - // set new matrix on element - target.matrix(at) + // TODO: ANIMATE THE TRANSFORMS + + // // get initial initialTransformation + // at = s.initialTransformation + // for(i = 0, len = s.transforms.length; i < len; i++){ + // + // // get next transformation in chain + // var a = s.transforms[i] + // + // // multiply matrix directly + // if(a instanceof SVG.Matrix){ + // + // if(a.relative){ + // at = at.multiply(new SVG.Matrix().morph(a).at(s.ease(this.pos))) + // }else{ + // at = at.morph(a).at(s.ease(this.pos)) + // } + // continue + // } + // + // // when transformation is absolute we have to reset the needed transformation first + // if(!a.relative) + // a.undo(at.decompose()) + // + // // and reapply it after + // at = at.multiply(a.at(s.ease(this.pos))) + // + // } + // + // // set new matrix on element + // target.matrix(at) } return this diff --cc src/helpers.js index b6c2fe6,9a7f47e..56565a0 --- a/src/helpers.js +++ b/src/helpers.js @@@ -105,8 -109,16 +109,8 @@@ function proportionalSize (element, wid } } -// Delta transform point -function deltaTransformPoint (matrix, x, y) { - return { - x: x * matrix.a + y * matrix.c + 0, - y: x * matrix.b + y * matrix.d + 0 - } -} - // Map matrix array to object - function arrayToMatrix(a) { + function arrayToMatrix (a) { return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] } } @@@ -201,18 -216,3 +208,18 @@@ function idFromReference (url) // Create matrix array for looping var abcdef = 'abcdef'.split('') + +// Gets the distance of a point (a, b) from the origin +function mag (a, b) { + return Math.sqrt(a * a + b * b) +} + +// Given a coordinate (a, b), this will calculate the sin, cosine and angle +// of this point projected onto the unit circle directly +function unitCircle (a, b) { + var len = Math.sqrt(a * a + b * b) - , cos = a / len - , sin = b / len - , theta = Math.atan2(b, a) * 180 / Math.PI ++ var cos = a / len ++ var sin = b / len ++ var theta = Math.atan2(b, a) * 180 / Math.PI + return {theta: theta, cos: cos, sin: sin} +} diff --cc src/matrix.js index cde44ca,6e918d8..48ed7a1 --- a/src/matrix.js +++ b/src/matrix.js @@@ -1,161 -1,65 +1,185 @@@ + /* global abcdef, arrayToMatrix, deltaTransformPoint, parseMatrix */ + SVG.Matrix = SVG.invent({ // Initialize - create: function(source) { - var i, base = arrayToMatrix([1, 0, 0, 1, 0, 0]) + create: function (source) { + var base = arrayToMatrix([1, 0, 0, 1, 0, 0]) + var i // ensure source as object - source = source instanceof SVG.Element ? - source.matrixify() : - typeof source === 'string' ? - arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) : - arguments.length == 6 ? - arrayToMatrix([].slice.call(arguments)) : - Array.isArray(source) ? - arrayToMatrix(source) : - typeof source === 'object' ? - source : base + source = source instanceof SVG.Element ? source.matrixify() + : typeof source === 'string' ? arrayToMatrix(source.split(SVG.regex.delimiter).map(parseFloat)) + : arguments.length === 6 ? arrayToMatrix([].slice.call(arguments)) + : Array.isArray(source) ? arrayToMatrix(source) + : typeof source === 'object' ? source + : base // merge source - for (i = abcdef.length - 1; i >= 0; --i) - this[abcdef[i]] = source[abcdef[i]] != null ? - source[abcdef[i]] : base[abcdef[i]] - } + for (i = abcdef.length - 1; i >= 0; --i) { + this[abcdef[i]] = source[abcdef[i]] != null + ? source[abcdef[i]] + : base[abcdef[i]] + } + }, // Add methods - extend: { - // Extract individual transformations - extract: function () { - // find delta transform points - var px = deltaTransformPoint(this, 0, 1) - var py = deltaTransformPoint(this, 1, 0) - var skewX = 180 / Math.PI * Math.atan2(px.y, px.x) - 90 +, extend: { + // Convert an object of affine parameters into a matrix + compose: function (o, cx, cy) { + + // Set the defaults + var tx = o.translateX || 0 + , ty = o.translateY || 0 + , theta = o.theta || 0 + , sx = o.scaleX || 1 + , sy = o.scaleY || 1 + , lam = o.shear || 0 + , cx = cx || 0 + , cy = cy || 0 + + // Calculate the trigonometric values + var ct = Math.cos(theta * Math.PI / 180) + , st Math.sin(theta * Math.PI / 180) + + // Calculate the matrix components directly + var a = sx * ct + , b = sx * st + , c = lam * sx * ct - sy * st + , d = lam * sx * st + sy * ct + , e = - sx * ct * (cx + cy * lam) + sy * st * cy + tx + cx + , f = - sx * st * (cx + cy * lam) - sy * ct * cy + ty + cy + + // Construct a new matrix and return it + var matrix = new SVG.Matrix([a, b, c, d, e, f]) + return matrix + } + // Decompose a matrix into the affine parameters needed to form it + , decompose: function (matrix, cx, cy) { + + // Get the paramaters of the current matrix + var a = matrix.a + , b = matrix.b + , c = matrix.c + , d = matrix.d + , e = matrix.e + , f = matrix.f + + // Project the first basis vector onto the unit circle + var circle = unitCircle (a, b) + , theta = circle.theta + , ct = circle.cos + , st = circle.sin + + // Work out the transformation parameters + var signX = Math.sign(a * ct + b * st) + , sx = signX * mag (a, b) + , lam = (st * d + ct * c) / (ct * a + st * b) + , signY = Math.sign(- c * st + d * ct) + , sy = mag (lam * a - c, d - lam * b) + , tx = e - cx + cx * ct * sx + cy * (lam * ct * sx - st * sy) + , ty = f - cy + cx * st * sx + cy * (lam * st * sx + ct * sy) + + // Package and return the parameters return { + + // Bundle the affine parameters + translateX: tx + , translateY: ty + , theta: theta + , scaleX: sx + , scaleY: sy + , shear: lam + + // Bundle the matrix parameters + , a: this.a + , b: this.b + , c: this.c + , d: this.d + , e: this.e + , f: this.f + + // Return the new origin point + , x: this.e + , y: this.f + + // Store the matrix + , matrix: new SVG.Matrix(this) + // translation + x: this.e, + y: this.f, + transformedX: (this.e * Math.cos(skewX * Math.PI / 180) + this.f * Math.sin(skewX * Math.PI / 180)) / Math.sqrt(this.a * this.a + this.b * this.b), + transformedY: (this.f * Math.cos(skewX * Math.PI / 180) + this.e * Math.sin(-skewX * Math.PI / 180)) / Math.sqrt(this.c * this.c + this.d * this.d), + // skew + skewX: -skewX, + skewY: 180 / Math.PI * Math.atan2(py.y, py.x), + // scale + scaleX: Math.sqrt(this.a * this.a + this.b * this.b), + scaleY: Math.sqrt(this.c * this.c + this.d * this.d), + // rotation + rotation: skewX, + a: this.a, + b: this.b, + c: this.c, + d: this.d, + e: this.e, + f: this.f, + matrix: new SVG.Matrix(this) ++>>>>>>> 3.0.0 } - } + }, // Clone matrix + , form: function (o) { + + // Get all of the parameters required to form the matrix + var flipX = o.flip && (o.flip == "x" || o.flip == "both") ? -1 : 1 + , flipY = o.flip && (o.flip == "y" || o.flip == "both") ? -1 : 1 + , kX = o.skew.length ? o.skew[0] + : isFinite(o.skew) ? o.skew + : isFinite(o.skewX) ? o.skewX + : 0 + , kY = o.skew.length ? o.skew[1] + : isFinite(o.skew) ? o.skew + : isFinite(o.skewY) ? o.skewY + : 0 + , skewX = o.scale.length ? o.scale[0] * flipX + : isFinite(o.scale) ? o.scale * flipX + : isFinite(o.scaleX) ? o.scaleX * flipX + : flipX + , skewY = o.scale.length ? o.scale[1] * flipY + : isFinite(o.scale) ? o.scale * flipY + : isFinite(o.scaleY) ? o.scaleY * flipY + : flipY + , kx = Math.tan(SVG.utils.radians(skewX)) + , ky = Math.tan(SVG.utils.radians(skewY)) + , lam = o.shear || 0 + , theta = SVG.utils.radians(o.rotate || 0) + , st = Math.sin(theta) + , ct = Math.cos(theta) + , ox = o.origin.length ? o.origin[0] : o.ox || 0 + , oy = o.origin.length ? o.origin[1] : o.oy || 0 + , px = o.position.length ? o.position[0] : o.px || ox + , py = o.position.length ? o.position[1] : o.py || oy + , tx = o.translate.length ? o.translate[0] : o.tx || 0 + , ty = o.translate.length ? o.translate[1] : o.ty || 0 + + // Form the matrix parameters... aka. welcome to wonderland! (used wolfram) + var a = ct*sx + ky*st*sy + , b = ct*ky*sy - st*sx + , c = ct*kx*sx + st*sy + lam*(ct*sx+ky*st*sy) + , d = -kx*st*sx + ct*sy + lam*(-st*sx + ct*ky*sy) + , e = px + tx + cx*(ct*sx+ky*st*sy) + cy*(ct*kx*sx+st*sy+lam*(ct*sx+ky*st*sy)) + , f = py + ty + cx*(-st*sx + ct*ky*sy) + cy*(-kx*st*sx + ct*sy + lam*(-st*sx + ct*ky*sy)) + , result = new Matrix(a, b, c, d, e, f) + return result + } + , clone: function() { + clone: function () { ++>>>>>>> 3.0.0 return new SVG.Matrix(this) - } + }, // Morph one matrix into another - , morph: function(matrix) { + morph: function (matrix) { // store new destination this.destination = new SVG.Matrix(matrix) @@@ -177,70 -81,51 +201,68 @@@ }) return matrix - } + }, // Multiplies by given matrix - , multiply: function(matrix) { + multiply: function (matrix) { return new SVG.Matrix(this.native().multiply(parseMatrix(matrix).native())) - } + }, // Inverses matrix - , inverse: function() { + inverse: function () { return new SVG.Matrix(this.native().inverse()) - } + }, // Translate matrix - translate: function (x, y) { - return new SVG.Matrix(this.native().translate(x || 0, y || 0)) - }, + , translate: function(x, y) { + var translation = new SVG.Matrix(this.native().translate(x || 0, y || 0)) + , matrix = this.multiply(translation) + return matrix + } // Scale matrix - scale: function (x, y, cx, cy) { - // support uniformal scale - if (arguments.length === 1) { + , scale: function(x, y, cx, cy) { + // Support uniform scaling + if (arguments.length == 1) { y = x - } else if (arguments.length == 3) { + } else if (arguments.length === 3) { cy = cx cx = y y = x } - return this.around(cx, cy, new SVG.Matrix(x, 0, 0, y, 0, 0)) - }, + // Rotate the current matrix + var scale = new SVG.Matrix(x, 0, 0, y, 0, 0) + , centered = this.around(cx, cy, rotation) + , matrix = this.multiply(centered) + return scale + } // Rotate matrix - rotate: function (r, cx, cy) { - // convert degrees to radians + , rotate: function(r, cx, cy) { + + // Convert degrees to radians r = SVG.utils.radians(r) - return this.around(cx, cy, new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0)) - }, + // Construct the rotation matrix + var rotation = new SVG.Matrix(Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0) + , centered = this.around(cx, cy, rotation) + , matrix = this.multiply(centered) + return matrix + } // Flip matrix on x or y, at a given offset - , flip: function(a, o) { - return a == 'x' ? - this.scale(-1, 1, o, 0) : - a == 'y' ? - this.scale(1, -1, 0, o) : - this.scale(-1, -1, a, o != null ? o : a) - } + flip: function (a, o) { + return a === 'x' ? this.scale(-1, 1, o, 0) + : a === 'y' ? this.scale(1, -1, 0, o) + : this.scale(-1, -1, a, o != null ? o : a) + }, // Skew - skew: function (x, y, cx, cy) { + , shear: function(a, cx, cy) { + var shear = new SVG.Matrix(1, a, 0, 1, 0, 0) + , centered = this.around(cx, cy, shear) + , matrix = this.multiply(centered) + return matrix + } + , skew: function(x, y, cx, cy) { // support uniformal skew - if (arguments.length == 1) { + if (arguments.length === 1) { y = x - } else if (arguments.length == 3) { + } else if (arguments.length === 3) { cy = cx cx = y y = x @@@ -250,22 -135,18 +272,22 @@@ x = SVG.utils.radians(x) y = SVG.utils.radians(y) - return this.around(cx, cy, new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0)) - }, + // Construct the matrix + var skew = new SVG.Matrix(1, Math.tan(y), Math.tan(x), 1, 0, 0) + , centered = this.around(cx, cy, skew) + , matrix = this.multiply(centered) + return matrix + } // SkewX - , skewX: function(x, cx, cy) { + skewX: function (x, cx, cy) { return this.skew(x, 0, cx, cy) - } + }, // SkewY - , skewY: function(y, cx, cy) { + skewY: function (y, cx, cy) { return this.skew(0, y, cx, cy) - } + }, // Transform around a center point - , around: function(cx, cy, matrix) { + around: function (cx, cy, matrix) { return this .multiply(new SVG.Matrix(1, 0, 0, 1, cx || 0, cy || 0)) .multiply(matrix) diff --cc src/sugar.js index 838592c,c3a3332..7c555da --- a/src/sugar.js +++ b/src/sugar.js @@@ -32,46 -35,48 +35,46 @@@ var sugar = SVG.extend([SVG.Element, SVG.FX], { // Map rotation to transform - rotate: function (d, cx, cy) { +, rotate: function(angle, cx, cy) { + var matrix = new SVG.Matrix().rotate(angle, cx, cy) - ++ return this.transform({ rotation: d, cx: cx, cy: cy }) - } + }, // Map skew to transform - skew: function (x, y, cx, cy) { - return arguments.length === 1 || arguments.length === 3 - ? this.transform({ skew: x, cx: y, cy: cx }) - : this.transform({ skewX: x, skewY: y, cx: cx, cy: cy }) - }, +, skew: function(x, y, cx, cy) { + return arguments.length == 1 || arguments.length == 3 ? + this.transform({ skew: x, cx: y, cy: cx }) : + this.transform({ skewX: x, skewY: y, cx: cx, cy: cy }) + } // Map scale to transform - , scale: function(x, y, cx, cy) { - return arguments.length == 1 || arguments.length == 3 ? - this.transform({ scale: x, cx: y, cy: cx }) : - this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy }) - } + scale: function (x, y, cx, cy) { + return arguments.length === 1 || arguments.length === 3 + ? this.transform({ scale: x, cx: y, cy: cx }) + : this.transform({ scaleX: x, scaleY: y, cx: cx, cy: cy }) + }, // Map translate to transform - , translate: function(x, y) { + translate: function (x, y) { return this.transform({ x: x, y: y }) - } + }, // Map flip to transform - , flip: function(a, o) { - o = typeof a == 'number' ? a : o + flip: function (a, o) { + o = typeof a === 'number' ? a : o return this.transform({ flip: a || 'both', offset: o }) - }, - // Map matrix to transform - matrix: function (m) { - return this.attr('transform', new SVG.Matrix(arguments.length === 6 ? [].slice.call(arguments) : m)) - }, + } // Opacity - , opacity: function(value) { + opacity: function (value) { return this.attr('opacity', value) - } + }, // Relative move over x axis - , dx: function(x) { + dx: function (x) { return this.x(new SVG.Number(x).plus(this instanceof SVG.FX ? 0 : this.x()), true) - } + }, // Relative move over y axis - , dy: function(y) { + dy: function (y) { return this.y(new SVG.Number(y).plus(this instanceof SVG.FX ? 0 : this.y()), true) - } + }, // Relative move over x and y axes - , dmove: function(x, y) { + dmove: function (x, y) { return this.dx(x).dy(y) } }) diff --cc src/transform.js index 1175b13,54e9900..4076301 --- a/src/transform.js +++ b/src/transform.js @@@ -1,152 -1,188 +1,255 @@@ + /* global ensureCentre, capitalize, arrayToMatrix */ SVG.extend(SVG.Element, { + // Add transformations - transform: function (o, relative) { - // get target in case of the fx module, otherwise reference this - var target = this - var matrix, bbox + transform: function (o) { - // act as a getter - if (typeof o !== 'object') { - // get current matrix - matrix = new SVG.Matrix(target).extract() + /** + * EXTRACTING PARAMETERS + */ + // Act as a getter if no object was passed + if (typeof o !== 'object') { + matrix = new SVG.Matrix(this).extract() return typeof o === 'string' ? matrix[o] : matrix } + // Allow the user to define the origin with a string + if (typeof o.origin === "string") { + + // Get the bounding box and string to use in our calculations + var string = o.origin.toLowerCase().trim() + , bbox = this.bbox() + , x = bbox.x + , y = bbox.y + , width = bbox.width + , height = bbox.height + + // Set the bounds eg : "bottom-left", "Top right", "middle" etc... + o.ox = string.includes("left") ? x + : string.includes("right") ? x + width + : x + width / 2 + o.oy = string.includes("top") ? y + : string.includes("bottom") ? y + height + : y + height / 2 + + // Make sure we only pass ox and oy + o.origin = null + } + + // Get the resulting matrix and apply it to the element + var result = new SVG.Matrix().form(o) + , matrixString = result.toString() + // get current matrix + matrix = new SVG.Matrix(target) + + // ensure relative flag + relative = !!relative || !!o.relative + + // act on matrix + if (o.a != null) { + matrix = relative + ? matrix.multiply(new SVG.Matrix(o)) + : new SVG.Matrix(o) + + // act on rotation + } else if (o.rotation != null) { + // ensure centre point + ensureCentre(o, target) + + // apply transformation + matrix = relative + ? matrix.rotate(o.rotation, o.cx, o.cy) + : matrix.rotate(o.rotation - matrix.extract().rotation, o.cx, o.cy) + + // act on scale + } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { + // ensure centre point + ensureCentre(o, target) + + // ensure scale values on both axes + o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 + o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 + + if (!relative) { + // absolute; multiply inversed values + var e = matrix.extract() + o.scaleX = o.scaleX * 1 / e.scaleX + o.scaleY = o.scaleY * 1 / e.scaleY + } + + matrix = matrix.scale(o.scaleX, o.scaleY, o.cx, o.cy) + + // act on skew + } else if (o.skew != null || o.skewX != null || o.skewY != null) { + // ensure centre point + ensureCentre(o, target) + + // ensure skew values on both axes + o.skewX = o.skew != null ? o.skew : o.skewX != null ? o.skewX : 0 + o.skewY = o.skew != null ? o.skew : o.skewY != null ? o.skewY : 0 + + if (!relative) { + // absolute; reset skew values + var el = matrix.extract() + matrix = matrix.multiply(new SVG.Matrix().skew(el.skewX, el.skewY, el.cx, el.cy).inverse()) + } ++>>>>>>> 3.0.0 - matrix = matrix.skew(o.skewX, o.skewY, o.cx, o.cy) + // Apply the result + return this.attr('transform', matrix) + } + } - // act on flip - } else if (o.flip) { - if (o.flip === 'x' || o.flip === 'y') { - o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset - } else { - if (o.offset == null) { - bbox = target.bbox() - o.flip = bbox.cx - o.offset = bbox.cy - } else { - o.flip = o.offset - } - } + // Map matrix to transform +, matrix: function(m, relative) { - matrix = new SVG.Matrix().flip(o.flip, o.offset) + // Construct a matrix from the first parameter + var matrix = new SVG.Matrix(m) - // act on translate - } else if (o.x != null || o.y != null) { - if (relative) { - // relative - matrix = matrix.translate(o.x, o.y) - } else { - // absolute - if (o.x != null) matrix.e = o.x - if (o.y != null) matrix.f = o.y - } + // If we have a relative matrix, we just apply the old matrix + if (relative) { + var oldMatrix = new SVG.Matrix(this) + matrix = oldMatrix.multiply(matrix) } + // Apply the matrix directly return this.attr('transform', matrix) } }) SVG.extend(SVG.FX, { - transform: function (o, relative) { - // get target in case of the fx module, otherwise reference this - var target = this.target() - var matrix, bbox - - // act as a getter - if (typeof o !== 'object') { - // get current matrix - matrix = new SVG.Matrix(target).extract() - return typeof o === 'string' ? matrix[o] : matrix - } - - // ensure relative flag - relative = !!relative || !!o.relative - - // act on matrix - if (o.a != null) { - matrix = new SVG.Matrix(o) - - // act on rotation - } else if (o.rotation != null) { - // ensure centre point - ensureCentre(o, target) - - // apply transformation - matrix = new SVG.Rotate(o.rotation, o.cx, o.cy) - - // act on scale - } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { - // ensure centre point - ensureCentre(o, target) - + transform: function(o, relative) { + + + + + // // get target in case of the fx module, otherwise reference this + // var target = this.target() + // , matrix, bbox + // + // // act as a getter + // if (typeof o !== 'object') { + // // get current matrix + // matrix = new SVG.Matrix(target).extract() + // + // return typeof o === 'string' ? matrix[o] : matrix + // } + // + // // ensure relative flag + // relative = !!relative || !!o.relative + // + // // act on matrix + // if (o.a != null) { + // matrix = new SVG.Matrix(o) + // + // // act on rotation + // } else if (o.rotation != null) { + // // ensure centre point + // ensureCentre(o, target) + // + // // apply transformation + // matrix = new SVG.Rotate(o.rotation, o.cx, o.cy) + // + // // act on scale + // } else if (o.scale != null || o.scaleX != null || o.scaleY != null) { + // // ensure centre point + // ensureCentre(o, target) + // + // // ensure scale values on both axes + // o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 + // o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 + // + // matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy) + // + // // act on skew + // } else if (o.skewX != null || o.skewY != null) { + // // ensure centre point + // ensureCentre(o, target) + // + // // ensure skew values on both axes + // o.skewX = o.skewX != null ? o.skewX : 0 + // o.skewY = o.skewY != null ? o.skewY : 0 + // + // matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy) + // + // // act on flip + // } else if (o.flip) { + // if(o.flip == 'x' || o.flip == 'y') { + // o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset + // } else { + // if(o.offset == null) { + // bbox = target.bbox() + // o.flip = bbox.cx + // o.offset = bbox.cy + // } else { + // o.flip = o.offset + // } + // } + // + // matrix = new SVG.Matrix().flip(o.flip, o.offset) + // + // // act on translate + // } else if (o.x != null || o.y != null) { + // matrix = new SVG.Translate(o.x, o.y) + // } + // + // if(!matrix) return this + // + // matrix.relative = relative + // + // this.last().transforms.push(matrix) + // + // return this._callStart() + // } + // ensure scale values on both axes + o.scaleX = o.scale != null ? o.scale : o.scaleX != null ? o.scaleX : 1 + o.scaleY = o.scale != null ? o.scale : o.scaleY != null ? o.scaleY : 1 + + matrix = new SVG.Scale(o.scaleX, o.scaleY, o.cx, o.cy) + + // act on skew + } else if (o.skewX != null || o.skewY != null) { + // ensure centre point + ensureCentre(o, target) + + // ensure skew values on both axes + o.skewX = o.skewX != null ? o.skewX : 0 + o.skewY = o.skewY != null ? o.skewY : 0 + + matrix = new SVG.Skew(o.skewX, o.skewY, o.cx, o.cy) + + // act on flip + } else if (o.flip) { + if (o.flip === 'x' || o.flip === 'y') { + o.offset = o.offset == null ? target.bbox()['c' + o.flip] : o.offset + } else { + if (o.offset == null) { + bbox = target.bbox() + o.flip = bbox.cx + o.offset = bbox.cy + } else { + o.flip = o.offset + } + } + + matrix = new SVG.Matrix().flip(o.flip, o.offset) + + // act on translate + } else if (o.x != null || o.y != null) { + matrix = new SVG.Translate(o.x, o.y) + } + + if (!matrix) return this + + matrix.relative = relative + + this.last().transforms.push(matrix) + + return this._callStart() + } ++>>>>>>> 3.0.0 }) SVG.extend(SVG.Element, { @@@ -185,150 -218,142 +285,284 @@@ return this }, // same as above with parent equals root-svg - toDoc: function() { + toDoc: function () { return this.toParent(this.doc()) } - }) +// TODO: DESTROY +// ======= +// +// +// SVG.Transformation = SVG.invent({ +// +// create: function(source, inversed){ +// +// if(arguments.length > 1 && typeof inversed != 'boolean'){ +// return this.constructor.call(this, [].slice.call(arguments)) +// } +// +// if(Array.isArray(source)){ +// for(var i = 0, len = this.arguments.length; i < len; ++i){ +// this[this.arguments[i]] = source[i] +// } +// } else if(typeof source == 'object'){ +// for(var i = 0, len = this.arguments.length; i < len; ++i){ +// this[this.arguments[i]] = source[this.arguments[i]] +// } +// } +// +// this.inversed = false +// +// if(inversed === true){ +// this.inversed = true +// } +// +// } +// +// , extend: { +// +// arguments: [] +// , method: '' +// +// , at: function(pos){ +// +// var params = [] +// +// for(var i = 0, len = this.arguments.length; i < len; ++i){ +// params.push(this[this.arguments[i]]) +// } +// +// var m = this._undo || new SVG.Matrix() +// +// m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos) +// +// return this.inversed ? m.inverse() : m +// +// } +// +// , undo: function(o){ +// for(var i = 0, len = this.arguments.length; i < len; ++i){ +// o[this.arguments[i]] = typeof this[this.arguments[i]] == 'undefined' ? 0 : o[this.arguments[i]] +// } +// +// // The method SVG.Matrix.extract which was used before calling this +// // method to obtain a value for the parameter o doesn't return a cx and +// // a cy so we use the ones that were provided to this object at its creation +// o.cx = this.cx +// o.cy = this.cy +// +// this._undo = new SVG[capitalize(this.method)](o, true).at(1) +// +// return this +// } +// +// } +// +// }) +// +// SVG.Translate = SVG.invent({ +// +// parent: SVG.Matrix +// , inherit: SVG.Transformation +// +// , create: function(source, inversed){ +// this.constructor.apply(this, [].slice.call(arguments)) +// } +// +// , extend: { +// arguments: ['transformedX', 'transformedY'] +// , method: 'translate' +// } +// +// }) +// +// SVG.Rotate = SVG.invent({ +// +// parent: SVG.Matrix +// , inherit: SVG.Transformation +// +// , create: function(source, inversed){ +// this.constructor.apply(this, [].slice.call(arguments)) +// } +// +// , extend: { +// arguments: ['rotation', 'cx', 'cy'] +// , method: 'rotate' +// , at: function(pos){ +// var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy) +// return this.inversed ? m.inverse() : m +// } +// , undo: function(o){ +// this._undo = o +// return this +// } +// } +// +// }) +// +// SVG.Scale = SVG.invent({ +// +// parent: SVG.Matrix +// , inherit: SVG.Transformation +// +// , create: function(source, inversed){ +// this.constructor.apply(this, [].slice.call(arguments)) +// } +// +// , extend: { +// arguments: ['scaleX', 'scaleY', 'cx', 'cy'] +// , method: 'scale' +// } +// +// }) +// +// SVG.Skew = SVG.invent({ +// +// parent: SVG.Matrix +// , inherit: SVG.Transformation +// +// , create: function(source, inversed){ +// this.constructor.apply(this, [].slice.call(arguments)) +// } +// +// , extend: { +// arguments: ['skewX', 'skewY', 'cx', 'cy'] +// , method: 'skew' +// } +// +// }) + SVG.Transformation = SVG.invent({ + + create: function (source, inversed) { + if (arguments.length > 1 && typeof inversed !== 'boolean') { + return this.constructor.bind(this)([].slice.call(arguments)) + } + + var i, len + if (Array.isArray(source)) { + for (i = 0, len = this.arguments.length; i < len; ++i) { + this[this.arguments[i]] = source[i] + } + } else if (typeof source === 'object') { + for (i = 0, len = this.arguments.length; i < len; ++i) { + this[this.arguments[i]] = source[this.arguments[i]] + } + } + + this.inversed = false + + if (inversed === true) { + this.inversed = true + } + }, + + extend: { + + arguments: [], + method: '', + + at: function (pos) { + var params = [] + + for (var i = 0, len = this.arguments.length; i < len; ++i) { + params.push(this[this.arguments[i]]) + } + + var m = this._undo || new SVG.Matrix() + + m = new SVG.Matrix().morph(SVG.Matrix.prototype[this.method].apply(m, params)).at(pos) + + return this.inversed ? m.inverse() : m + }, + + undo: function (o) { + for (var i = 0, len = this.arguments.length; i < len; ++i) { + o[this.arguments[i]] = typeof this[this.arguments[i]] === 'undefined' ? 0 : o[this.arguments[i]] + } + + // The method SVG.Matrix.extract which was used before calling this + // method to obtain a value for the parameter o doesn't return a cx and + // a cy so we use the ones that were provided to this object at its creation + o.cx = this.cx + o.cy = this.cy + + this._undo = new SVG[capitalize(this.method)](o, true).at(1) + return this + } + + } + + }) + + SVG.Translate = SVG.invent({ + + parent: SVG.Matrix, + inherit: SVG.Transformation, + + create: function (source, inversed) { + this.constructor.apply(this, [].slice.call(arguments)) + }, + + extend: { + arguments: ['transformedX', 'transformedY'], + method: 'translate' + } + + }) + + SVG.Rotate = SVG.invent({ + + parent: SVG.Matrix, + inherit: SVG.Transformation, + + create: function (source, inversed) { + this.constructor.apply(this, [].slice.call(arguments)) + }, + + extend: { + arguments: ['rotation', 'cx', 'cy'], + method: 'rotate', + at: function (pos) { + var m = new SVG.Matrix().rotate(new SVG.Number().morph(this.rotation - (this._undo ? this._undo.rotation : 0)).at(pos), this.cx, this.cy) + return this.inversed ? m.inverse() : m + }, + undo: function (o) { + this._undo = o + return this + } + } + + }) + + SVG.Scale = SVG.invent({ + + parent: SVG.Matrix, + inherit: SVG.Transformation, + + create: function (source, inversed) { + this.constructor.apply(this, [].slice.call(arguments)) + }, + + extend: { + arguments: ['scaleX', 'scaleY', 'cx', 'cy'], + method: 'scale' + } + + }) + + SVG.Skew = SVG.invent({ + + parent: SVG.Matrix, + inherit: SVG.Transformation, + + create: function (source, inversed) { + this.constructor.apply(this, [].slice.call(arguments)) + }, + + extend: { + arguments: ['skewX', 'skewY', 'cx', 'cy'], + method: 'skew' + } + }) ++>>>>>>> 3.0.0