3

Having an element with the following transformation:

style="transform: rotate3d(1, 0, 0, -50deg);"

I want to be able to get the value -50 with Javascript/jQuery. I want to get the absolute value, so if it is 370deg, i do not want to get 10, but 370.

Using $('#element').css('transform') returns a matrix like this:

matrix3d(1, 0, 0, 0, 0, 0.642788, -0.766044, 0, 0, 0.766044, 0.642788, 0, 0, 0, 0, 1)

Which can be better represented as:

matrix3d(
    1, 0, 0, 0, 
    0, 0.642788, -0.766044, 0, 
    0, 0.766044, 0.642788, 0,
    0, 0, 0, 1
)

Is solving the equations the only way to get this value?

enter image description here

Knowing that Z =0 and X =1 as rotate3d(1, 0, 0, -50deg);

enter image description here

Isn't there any faster alternative to this?

3
  • How is the value being set in the first place? Could you simply keep track of it? Commented Oct 4, 2016 at 12:22
  • I'm using css3 transitions. So nop, it can not get tracked during the animation. Thus the question :) Commented Oct 4, 2016 at 12:24
  • paper.js has some good functions to handle this, but I would love to hear about some native solutions as well ... paperjs.org/reference/matrix Commented Oct 4, 2016 at 12:37

3 Answers 3

2

While it still requires calculations ran on the matrix values, the simplest example I could find is as follows:

var el = document.getElementById('test');
var st = window.getComputedStyle(el, null);
var m = st.getPropertyValue('transform');

var values = m.slice(7,-1).split(',');
// angle is in range -180 > 180
var angle = Math.round(Math.atan2(values[1], values[0]) * (180/Math.PI));

Fiddle here. More info here.


Note: The example given was tested on a matrix rather than matrix3d. However from MDN:

matrix(a, b, c, d, tx, ty) is a shorthand for matrix3d(a, b, 0, 0, c, d, 0, 0, 0, 0, 1, 0, tx, ty, 0, 1)

So you can apply the exact same method to solve in either case, you will just need to update the method for pulling out the values.

Sign up to request clarification or add additional context in comments.

4 Comments

Did you notice that the matrix returned by st.getPropertyValue('transform') isn't exactly the same as in the question?
Yeah, I figured that would provide the gist needed to construct a working version. I have updated the answer to explain how there isn't much difference.
Nice... I felt like I had to give you a point since I copied your Math.atan2 angle calculation!
Looks good! But it doesn't work with rotateX values? Your example is using rotateZ, I guess I should choose other indexes in the last line? jsfiddle.net/apg5e2kv/2
2

The most simple solution I could come up with ...

var el = $('.el');
var matrix = el.css('transform');
var values = matrix.split('(')[1].match(/-?[\d\.]+/g);
var rad = Math.atan2(values[6], values[5]);
if ( rad < 0 ) rad += (2 * Math.PI);
var angle = rad * (180/Math.PI);
el.text(Math.round(angle));
.el {
  width: 50px; height: 50px;
  background: tomato;
  transform: rotate3d(1, 0, 0, 60deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="el"></div>

If you want to use libraries, you can use one of this:

http://github.com/Luxiyalu/jquery-transformer

http://paperjs.org/reference/matrix/

11 Comments

Looking good, but fails with -180 deg and returns -129 instead ? jsfiddle.net/apg5e2kv/4
Also, any value over 180 won't get retrieved as such, for example -350 will return 10. And I'm interested in the absolute value not in the relative one.
I'm gonna write a full support code for this and update the question. Just gimme a couple hours plz ;D
Just saying, the idea was good, pity it doesn't work to solve the issue proposed in the question.
do not think more. There's no mathematical solution to it. I'll provide my own answer explaining it.
|
2

I should have payed a bit more attention to it. After a while I realized this can not be solved mathematically. Not if I want to get the exact absolute degrees and not the relative ones.

The matrix we get with a transformation of 370 degrees is exactly the same one we get with a transformation of 10 degrees. Therefore it is impossible to get two different resulting values for alpha with the exact same input.

with transform: rotate3d(1, 0, 0, 10deg); we get:

matrix3d(1, 0, 0, 0, 0, 0.984808, 0.173648, 0, 0, -0.173648, 0.984808, 0, 0, 0, 0, 1)

And with transform: rotate3d(1, 0, 0, 370deg); the exact same one:

matrix3d(1, 0, 0, 0, 0, 0.984808, 0.173648, 0, 0, -0.173648, 0.984808, 0, 0, 0, 0, 1)

Reproduction online

1 Comment

That's really interesting, but can we have a good relative solution? I'm still trying ... (by good I mean without the 180º to 129º error and with a reasonable performance)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.