0

Check out https://jsfiddle.net/u5L1dmvx/

transform: rotate3d(0, 0, 1, 45deg);
transform: rotate3d(1, 0, 0, 90deg);

Suppose I would like to perform two rotations. First rotate around z axis by 45 degrees and then rotate around x axis by 90 degrees.

How can I combine these two? I mean, this can be two questions.

In math, I would like to know, if I use transform: rotate3d(x, y, z, wdeg);, how to calculate x, y, z and w for the combined effect?

In programming, is it possible to change style of div by js to combine these two? I mean, write code to apply a new rotation on an already rotated div to achieve the combined effect.

UPDATE:

Currently I have a temporary brute answer:

transform: rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg);

But if the rotation operation list is long, style of div could become longer every time an operation is executed:

transform: rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg) rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg);

Is there a more elegant way?

MoYummy
  • 809
  • 1
  • 8
  • 14
  • 1
    Possible duplicate of [How to apply multiple transforms in CSS?](https://stackoverflow.com/questions/10765755/how-to-apply-multiple-transforms-in-css) – Sven van de Scheur Jun 28 '18 at 08:51
  • 1
    This is a duplicate of https://stackoverflow.com/questions/10765755/how-to-apply-multiple-transforms-in-css, the real question is how to combine transformations :). – Sven van de Scheur Jun 28 '18 at 08:51
  • Wouldn’t this be easier if you just added another wrapper element - and then simply applied one rotation to the outer and one to the inner element? – CBroe Jun 28 '18 at 08:54
  • @SvenvandeScheur This is quite different from the link you pasted. I tried to add the two rotations literally but the final result is not what I expect. – MoYummy Jun 28 '18 at 08:56
  • @CBroe That would not be what I expect. Maybe I will perform 10 rotations in a row in other cases. Actually, as you can see, I would like to find a way to apply rotations one after another maybe endlessly. – MoYummy Jun 28 '18 at 09:00

2 Answers2

1

You can combine multiple transformations, even of the same type, like this:

transform: rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg);

If you change the style of the DIV element using JavaScript you would just replace the transform property so you need to get the value first and then append the additional transform, just like in the CSS above.

See also https://developer.mozilla.org/en-US/docs/Web/CSS/transform

Not all combinations of rotate3d transforms can be replaced with a single rotate3d transform. You can however combine multiple transformations into one single matrix transform. I consider that out of scope for this answer but if you are interested then maybe you should have a look here: https://www.khanacademy.org/math/linear-algebra/matrix-transformations#composition-of-transformations

If you want to continue adding transformations later (perhaps interactively?) as you suggest, you can read the current transformation matrix back from the element and combine it with more transformations.

I played around with some JS in your fiddle: https://jsfiddle.net/u5L1dmvx/66/

Here is an example, not the most elegant but it works on my Firefox:

var element = document.getElementById("div1");
var style = window.getComputedStyle(element);

//this will (probably) give you a matrix(..) transform representing the current transform of the element
var currentTransform = document.getElementById("div3").style.transform;

console.log(currentTransform)

//prepend another rotate3d transform to the current transform
document.getElementById("div3").style.transform = "rotate3d(1,0,0,90deg) "+style.transform;

Update: Fixed the broken transform and added example of how to add more transformations.

Max
  • 821
  • 10
  • 11
0

This order worked for me:

transform: rotate3d(1, 0, 0, 90deg) rotate3d(0, 0, 1, 45deg);

Cyphall
  • 348
  • 1
  • 10
  • This can be an answer. But what if I have hundreds of rotations? Every time I perform one, `style` of `div` would become longer and longer. – MoYummy Jun 28 '18 at 09:23
  • What do you mean by "hundreds of rotations"? – Cyphall Jun 28 '18 at 09:28
  • e.g. performing these two rotations each 50 times. You can imagine you are playing Rubik's Cube. – MoYummy Jun 28 '18 at 09:31
  • Do you want to rotate 50 different squares or make a loop animation on a single one? – Cyphall Jun 28 '18 at 09:37
  • Not different squares. I mean, 50 rotations over same `div`, but maybe not looping. – MoYummy Jun 28 '18 at 09:39
  • Let me describe a concrete example. I write two js functions, `rotateTargetAroundZBy45Degree()` and `rotateTargetAroundXBy90Degree()` and have two buttons triggering them. I can click on these two buttons endlessly to make rotations over target `div`. As in you method, in either of the functions, I would append a rotation to `style` of `div`, and then the line would become longer and longer. – MoYummy Jun 28 '18 at 09:48
  • As you are using javascript, I think you can just store the current rotation angle in js vars, calculate the new angle on each button click and overwrite the rotation3d() property over and over with the new calculated angles – Cyphall Jun 28 '18 at 09:59
  • This is exactly what I originally expect. So my first question is there, asking how to calculate latest transform rotation3d, maybe reverse calculation also required for cancelling operations. – MoYummy Jun 28 '18 at 10:13
  • Isn't it just an incrementation/decrementation of 90 and 45 respectively ? (or am I missing something?) – Cyphall Jun 28 '18 at 10:53
  • No, the rotation axis is different and in other cases, the axis may be a random line, not parallel to x, y or z axis – MoYummy Jun 29 '18 at 01:39