This function defines rotation* , transform* and scale for a given cross-browser DOM element.
If you need something else or find errors in math, this is a discussion of math.stackexchange.com
Tested in browsers listed at http://caniuse.com/transforms3d :
var reverseEngineerTransform3d = function (domElement, parameterName) { parameterName = parameterName.toLowerCase(); var computedStyle = window.getComputedStyle(domElement), matrixStyle = computedStyle.transform || computedStyle.WebkitTransform || computedStyle.MozTransform || computedStyle.msTransform || computedStyle.OTransform; if (matrixStyle) { matrixStyle = matrixStyle.trim(); } if (matrixStyle === 'none') { if (parameterName.indexOf('rotate') === 0) { return '0deg'; } else if (parameterName.indexOf('translate') === 0) { return '0px'; } else if (parameterName === 'scale') { return 1; } else { throw "Unsupported 3D parameter " + parameterName; } } else if (!matrixStyle || matrixStyle.substr(0, 9) !== 'matrix3d(') { //return something or die ????? throw "Something is wrong with 3D transform style. Probably no style applied at all OR unknown CSS3 vendor OR unknown/unsupported 3D matrix representation string OR CSS3 3D transform is not fully supported in this browser"; } var matrix = window.WebKitCSSMatrix && (new WebKitCSSMatrix(matrixStyle)) || window.MozCSSMatrix && (new MozCSSMatrix(matrixStyle)) || window.MsCSSMatrix && (new MsCSSMatrix(matrixStyle)) || window.OCSSMatrix && (new OCSSMatrix(matrixStyle)) || window.CSSMatrix && (new CSSMatrix(matrixStyle)); // sorry 4 copy-paste my friends if (!matrix || isNaN(matrix.a) || isNaN(matrix.b) || isNaN(matrix.c) || isNaN(matrix.m41) || isNaN(matrix.m42) || isNaN(matrix.m43) || isNaN(matrix.m11)) { throw "Could not catch CSSMatrix constructor for current browser, OR the constructor has returned a non-standard matrix object (need .a, .b, .c and mXX numerical properties to work)"; } // todo: giving a parameters array (and returning an array) is a good idea, or we could return everything if no parameters given switch (parameterName) { case 'rotatey': // in degrees return Math.acos(matrix.m11)*180/Math.PI * (matrix.m13 > 0 ? -1 : 1) + 'deg'; case 'rotatex': // in degrees return Math.asin(matrix.m22)*180/Math.PI + 'deg'; case 'rotatez': // in degrees throw "TODO: Sorry, math people. I really need help here! Please implement this case for me. This will help you: http://9elements.com/html5demos/matrix3d/"; case 'translatex': // in pixels return matrix.m41 + 'px'; case 'translatey': // in pixels return matrix.m42 + 'px'; case 'translatez': // in pixels return matrix.m43 + 'px'; case 'scale': // no units if (matrix.m11 === matrix.m22 && matrix.m22 === matrix.m33) { return matrix.m11; } else { throw "I'm not so smart to calculate scale from this matrix"; } // todo: anything else? skew ???? default: throw "This function accepts 3d-parameter name (case-insensitive string) as the second argument. Currently supported: 'rotate[xyz]', 'translate[xyz]', 'scale'. This parameter is unsupported: " + parameterName; } };
Dan
source share