// Form the matrix parameters... aka. welcome to wonderland! (used wolfram)
var a = ct*sx + ky*st*sy
- , b = -st*sx+ct*ky*sy
- , c = ct*kx*sx+st*sy + lam*(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))
}
// Translate matrix
, translate: function(x, y) {
- return new SVG.Matrix(this.native().translate(x || 0, y || 0))
+ 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
+ // Support uniform scaling
if (arguments.length == 1) {
y = x
} else if (arguments.length == 3) {
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
+
+ // 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) {
}
// Skew
, shear: function(a, cx, cy) {
- return this.around(cx, cy, new SVG.Matrix(1, a, 0, 1, 0, 0))
+ 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
y = x
}
- // convert degrees to radians
+ // Convert degrees to radians
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) {
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({ skew: x, cx: y, cy: cx }) :
this.transform({ skewX: x, skewY: y, cx: cx, cy: cy })
}
// Map scale to transform
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) {
return this.attr('opacity', value)
+
SVG.extend(SVG.Element, {
+
// Add transformations
transform: function (o) {
* EXTRACTING PARAMETERS
*/
- // Get target in case of the fx module, otherwise reference this
- var target = this
-
// Act as a getter if no object was passed
if (typeof o !== 'object') {
- matrix = new SVG.Matrix(target).extract()
+ matrix = new SVG.Matrix(this).extract()
return typeof o === 'string' ? matrix[o] : matrix
}
- // Get the origin location
- var ox = o.ox
- , oy = o.oy
-
// Allow the user to define the origin with a string
- if (typeof o.origin == "string") {
+ if (typeof o.origin === "string") {
- // Get the bounding box to use in our calculations
- var bbox = target.bbox()
+ // 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
- // Get the string to modify
- var string = o.origin.toLowerCase().trim()
-
// Set the bounds eg : "bottom-left", "Top right", "middle" etc...
- ox = string.includes("left") ? x
- : string.includes("right") ? x + width
- : x + width / 2
- oy = string.includes("top") ? y
- : string.includes("bottom") ? y + height
- : y + height / 2
-
+ 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()
-
-
+ // Apply the result
+ return this.attr('transform', matrix)
}
+ }
+ // Map matrix to transform
+, matrix: function(m, relative) {
+ // Construct a matrix from the first parameter
+ var matrix = new SVG.Matrix(m)
+ // If we have a relative matrix, we just apply the old matrix
+ if (relative) {
+ var oldMatrix = new SVG.Matrix(this)
+ matrix = oldMatrix.multiply(matrix)
+ }
-
-
-
-
-
-
-
-
-
- //
- // // get current matrix
- // matrix = new SVG.Matrix(target)
- //
- // // ensure relative flag
- // relative = !!relative || !!o.relative
- //
- // // act on matrix
- // if (o.a != null) {
- // matrix = relative ?
- // // relative
- // matrix.multiply(new SVG.Matrix(o)) :
- // // absolute
- // new SVG.Matrix(o)
- //
- // // act on rotation
- // } else if (o.rotation != null) {
- // // ensure centre point
- // ensureCentre(o, target)
- //
- // // apply transformation
- // matrix = relative ?
- // // relative
- // matrix.rotate(o.rotation, o.cx, o.cy) :
- // // absolute
- // 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 e = matrix.extract()
- // matrix = matrix.multiply(new SVG.Matrix().skew(e.skewX, e.skewY, o.cx, o.cy).inverse())
- // }
- //
- // matrix = matrix.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) {
- // 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
- // }
- // }
- //
- // return this.attr('transform', matrix)
+ // Apply the matrix directly
+ return this.attr('transform', matrix)
}
})
toDoc: function() {
return this.toParent(this.doc())
}
-
})
// TODO: DESTROY