38

I'm manipulating a div with the new cool css3 way of doing a transform like this:

$("#thediv").css("-webkit-transform","translate(-770px, 0px)");

Later on in the script I thought to get the value of the transform like this:

$("#thediv").css("-webkit-transform");

It returns a matrix like this: matrix(1, 0, 0, 1, -770, 0)

What I can't figure out is how to get the 5th value (-770) of this matrix...

Any suggestions? Thanks!

Matthias Loibl
  • 863
  • 1
  • 8
  • 19

6 Answers6

58

Your matrix is a 4x4 transformation matrix:

matrix stuff

The -770 corresponds to the vx. To extract it, construct a WebkitCSSMatrix object:

var style = window.getComputedStyle($('#thediv').get(0));  // Need the DOM object
var matrix = new WebKitCSSMatrix(style.webkitTransform);

console.log(matrix.m41);  // -770
Blender
  • 289,723
  • 53
  • 439
  • 496
  • 6
    Thank you. To save time somebody looking for `translateY`, it's `matrix[5]`. – Dan Abramov Oct 29 '13 at 17:00
  • WebKitCSSMatrix is not supported by Firefox or Opera – koosa Dec 13 '13 at 19:34
  • 1
    @koosa: Well, yeah. Neither of them use the WebKit rendering engine. I don't think they have equivalents to WebKitCSSMatrix. – Blender Dec 14 '13 at 04:54
  • @Blender - yep so I think yckart's answer might be better to use for the moment – koosa Dec 14 '13 at 17:26
  • You shouldn't just give a Chrome/Safari answer without actually stating that. This answer is pretty useless in everyday web development. – 30secondstosam Apr 30 '15 at 15:55
  • 3
    @30secondstosam: The question was tagged `webkit` and my answer clearly uses `WebKitCSSMatrix`, so what's the issue? – Blender Apr 30 '15 at 18:28
  • There is an alternative: Just replace `WebKitCSSMatrix` with the alternate `DOMMatrix`. See here: https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix – benhatsor Jan 28 '21 at 06:38
30

You could split the string into an array and get the desired value as usual. Here's a little helper function that does the split part.

function matrixToArray(str) {
  return str.match(/\d+/g);
}

Update

To preserve decimals: rgba(0, 0, 0, 0.5)

and negatives: matrix(1, 0, 0, 1, -770, 0)

function matrixToArray(str) {
  return str.split('(')[1].split(')')[0].split(',');
}

Update2

RegExp based solution that preserves decimal and negative numbers:

function matrixToArray(str) {
  return str.match(/(-?[0-9\.]+)/g);
}

matrixToArray('rgba(0, 0, 0, 0.5)'); // => ['0', '0', '0', '0.5']
matrixToArray('matrix(1, 0, 0, 1, -770, 0)'); // => ['1', '0', '0', '1', '-770', '0']
yckart
  • 32,460
  • 9
  • 122
  • 129
  • 1
    This is a much more flexible solution, and the Update 2 example is very useful, because usually iterating over the various matches of a RegExp.exec is a lot more hazardous. +10 if I could. – kontur Jul 28 '14 at 11:14
  • I think this answer is much better than the one above for most purposes. – d4rklit3 Dec 10 '14 at 21:21
2

The reason you get the matrix string value, is that jQuery's css function is obtaining the computed style (the result of window.getComputedStyle($("#thediv")[0]).webkitTransform).

To get the actual string value which you set it to in the previous call ("translate(-770px, 0px)") you can use:

var t = $("#thediv")[0].style.webkitTransform;

From that you could just use string methods to get the x value, e.g:

t.substring(t.indexOf("(") + 1, t.indexOf(",") - 2)

which gives -770. However, note that this is only acceptable if you know that the value exists and is in the form you're using (with just a translate(xpx, ypx), since other values are valid!

If you'd prefer to use the computed style, then (to add to @Maz's suggestion), to get the 5th value (the x transform), you can do:

new WebKitCSSMatrix($("#thediv").css("-webkit-transform")).e;

To get the sixth one (the y transform) you use the f property of the matrix.

Mark Rhodes
  • 10,049
  • 4
  • 48
  • 51
  • Is this method of getting the original string value going to work across all major browsers? – ygesher Jan 30 '14 at 07:33
  • Unfortunately not.. generally anything with a "vendor prefix" (e.g. "ms", "webkit", "o", "moz") is platform specific. – Mark Rhodes Jan 30 '14 at 08:57
  • In any case, I found an alternate solution to my original problem, which was animating the transformation: [fiddle](http://jsfiddle.net/CqAU2/) (not my code) – ygesher Jan 30 '14 at 09:05
2

Since I constantly need to use jQuery together with TweenMax and since TweenMax already took care of all the parsing of various types of transformation strings as well as compatibility issues, I wrote a tiny jquery plugin here (more of a wrap up of gsap's) that could directly access these values like this:

$('#ele').transform('rotationX') // returns 0
$('#ele').transform('x')         // returns value of translate-x

The list of properties you could get/set, along with their initial properties:

perspective: 0
rotation: 0
rotationX: 0
rotationY: 0
scaleX: 1
scaleY: 1
scaleZ: 1
skewX: 0
skewY: 0
x: 0
y: 0
z: 0
zOrigin: 0

Paste from my other answer, hope this helps.

Lucia
  • 13,033
  • 6
  • 44
  • 50
2

I would recommend using the WebkitCSSMatrix object. http://developer.apple.com/library/safari/#documentation/AudioVideo/Reference/WebKitCSSMatrixClassReference/WebKitCSSMatrix/WebKitCSSMatrix.html#//apple_ref/doc/uid/TP40009363

This object has as its attributes the matrix elements. It also provides convenience functions for various transformations.

Maz
  • 3,375
  • 1
  • 22
  • 27
-1

I have coded the simplest solution that ALSO works in Safari, Chrome AND Firefox :)

The trick is NOT to reference the

.css("transform")

but the

.css("translate")

property instead :

var matrix = $("#thediv").css('translate');
console.log ( matrix[1] ); 
// matrix result is of form [x , y]
// so for example matrix[1] will give you the transformY value :)
$('html,body').animate({scrollTop: matrix[1]}, 750);

I'm delighted to have found such an economical solution since I have been dealing with 3D transforms in webkit and 2D transforms in Firefox simultaneously, and using this method the property values can be accessed directly :)

AABSTRKT
  • 49
  • 1
  • 2