// Add methods
, extend: {
- // Convert an array of affine parameters into a matrix
+
+ // Convert an object of affine parameters into a matrix
compose: function (o, cx, cy) {
// Set the defaults
return matrix
}
// Decompose a matrix into the affine parameters needed to form it
- , decompose: function (matrix, cx, cy) {
+ , decompose: function (matrix, cx, cy) {
// Get the paramaters of the current matrix
var a = matrix.a
}
}
// 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 = -st*sx+ct*ky*sy
+ , 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() {
return new SVG.Matrix(this)
}
this.scale(-1, -1, a, o != null ? o : a)
}
// Skew
+ , shear: function(a, cx, cy) {
+ return this.around(cx, cy, new SVG.Matrix(1, a, 0, 1, 0, 0))
+ }
, skew: function(x, y, cx, cy) {
// support uniformal skew
if (arguments.length == 1) {
SVG.extend(SVG.Element, {
// Add transformations
- transform: function(o, relative) {
+ transform: function (o) {
+
+ /**
+ * EXTRACTING PARAMETERS
+ */
// Get target in case of the fx module, otherwise reference this
var target = this
- , matrix, bbox
// Act as a getter if no object was passed
if (typeof o !== 'object') {
-
matrix = new SVG.Matrix(target).extract()
return typeof o === 'string' ? matrix[o] : matrix
+ }
+
+ // Get the origin location
+ var ox = o.ox
+ , oy = o.oy
- // If an object was passed, then we should apply the transformations
- } else {
+ // Allow the user to define the origin with a string
+ if (typeof o.origin == "string") {
// Get the bounding box to use in our calculations
var bbox = target.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
- // Extract the parameters for the affine transform
- var cx = (o.origin && o.origin.length) ?
+ }
+ // Get the resulting matrix and apply it to the element
+ var result = new SVG.Matrix().form(o)
+ , matrixString = result.toString()