Jump to content


Transition of 3d cube

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Can anybody tell what the best solution or strategy is for the following problem please:

I have a 3d cube with different elements on each face. The is a seperate button for each face that should rotate the cube to the equivalent face.

The problem I have is that setting the rotate aspect is relative to the face you are at. In other words if I click on the button linked to the back face the cube rotates 180deg. If you are looking at the front face at the time it works great. But if you are looking at any other face the cube simply rotates 180deg from its current position.

So the real question is, how do I target the faces of a 3d cube? I cant get round the logic.

Link to comment
Share on other sites



Well as far as I know every cube face is at a specific angle, for example before any rotation the front face is at 0, the right face is at 90. back face 180 and left face at 270 for a rotation in the Y axis. For any rotation in that axis the remaining ones (X and Z) should be at 0 degrees. Now for the top and bottom faces; the top face is at 90 degrees while the bottom is at 270 in the X axis, for those rotations the Y axis angle should be 0.

//This contains the faces
var cube = document.getElementById("cubeWrap");

TweenMax.set(cube, {rotationX:0, rotationY:0, transformStyle:'preserve-3d'});

//show front face
TweenMax.to(cube, 1, {rotationY:0});
//show right face
TweenMax.to(cube, 1, {rotationY:90});
//show back face
TweenMax.to(cube, 1, {rotationY:180});
//show left face
TweenMax.to(cube, 1, {rotationY:270});

//show top face
TweenMax.to(cube, 1, {rotationX:-90});
//show bottom  face
TweenMax.to(cube, 1, {rotationX:-270});

You should keep in mind some things. First this is a very rough and rigid approach just six buttons and this stuff will always rotate in the same way, kind of dull.


Second I'm using a container to rotate all the faces, therefore this won't work in IE10 (it doesn't recognize the preserve-3d property).


To see a working sample of how the cube rotates using the container take a look at this:

See the Pen bc58f04e3f93abc1d063613aeadd2386 by rhernando (@rhernando) on CodePen


Hope this helps,


Link to comment
Share on other sites

Thanks for the reply Rodrigo. The set up you show is what I have so far and I thought it would work like the css transition. The problem is this:

TweenMax.to(cube, 1, {rotationX:-90}) rotates the cube by -90 degrees on the x axis. So only works if you click on the top face button when you are looking at the front face. Since my cube has a link to each face it wont work if you are looking at any other face.


Link to comment
Share on other sites



The rotations are absolute not relative, there lies the trick.


If you're looking at the back face the cube is at 180 degrees in the Y axis and if you tween it to 0 degrees you go back to the front face.


Take a look at this file:



Also if'll be very helpful if you could set up a codepen or fiddle to take a better look.


Hope this helps,


  • Like 1
Link to comment
Share on other sites



Also I forgot to mention that since you're working with buttons, you should check the element's current angle in the X and Y axis, so if you want to rotate the cube in the X axis first the cube should be at 0 degrees in the Y axis. You can do that by checking the _gsTransform object, that stores all transform properties:

	if(cubeParent[0]._gsTransform.rotationX != 0)
		TweenMax.to(cubeParent, 1, {rotationX:0});
		TweenMax.to(cubeParent, 1, {rotationY:180});
		TweenMax.to(cubeParent, 1, {rotationY:180});

With that code, that corresponds to the button to see the back face, you're saying: "if the cube is rotated at any degree in the  X axis turn it to 0 AND show the backface, but if the rotation in the X axis is 0 just show the back face".


You should add that conditional logic in all your buttons and it should be fine.


Sorry for not considering that from the beginning, it slipped :P


Hope this helps,


  • Like 1
Link to comment
Share on other sites

Thats cool Rodrigo.. i did not know you could access the _gsTransform object... Nice! :)

Link to comment
Share on other sites

Yep is that simple and it's very helpful as you can see.


Any way I tinkered a little bit with the file so you'll have to download it again (link is updated) or you can see it here:

See the Pen aokHc by rhernando (@rhernando) on CodePen



  • Like 3
Link to comment
Share on other sites

Nice work, guys - I just wanted to point out that if your goal is to tween things in a relative fashion, you can always use the "+=" and "-=" prefixes. Like to tween the rotationX 90 degrees more than whatever it currently is, you can do:

TweenLite.to(element, 1, {rotationX:"+=90"});

Not that you need to do this - just wanted to point it out in case it helps.

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Simple question: the effects are great (thanks) for mimic the cube transitions watching from outside. What to change to achieve transition for surfaces which are painted inside the cube?

E.g. maybe simplest (display biased) way would be change viewing point or screen projection plane to be inside the cube but GreenSock is not OpenGL etc. Maybe just little z-trick (negated values) would do?

Link to comment
Share on other sites

Hi and welcome to the forums.


It's not an easy task but neither impossible. I remember creating some sort of 3D environment experiment but is just that, a very simple approach.


The keys are that the main container should use the entire width and height of the screen, or as much as possible, in order to create the illusion of things coming at you without generating any distort. You can download it from here:




Now if you want a jaw dropping sample check this one:

See the Pen Cpjln by mjarosinski (@mjarosinski) on CodePen


Is far better and more complex but the main idea is to notice the fact that the full screen creates a cool projection effect. If you start with that and play around with the z value of the cube container you could achieve what you're looking for.




  • Like 1
Link to comment
Share on other sites

Thank you, Rodrigo, powerful examples indeed. I'll try first with simple 2D synchronized operations - after all it's just simple travelling of two image corners over x and y while revealing the second image. If I fail with that, I'll try with z-axis math.

I promise I'll post at least an algorithm back.

Link to comment
Share on other sites

  • 6 years later...

How can this be implemented in Pixi? The cube rotation as given above.


I tried this


 const app = new PIXI.Application({

    width: 800,

    height: 600,

    backgroundColor: 0x1099bb,





      // Create a new texture

      const texture1 = PIXI.Texture.from('https://s.cdpn.io/33073/1-150x150.jpg');

      const texture2 = PIXI.Texture.from('https://s.cdpn.io/33073/2-150x150.jpg');

      const texture3 = PIXI.Texture.from('https://s.cdpn.io/33073/3-150x150.jpg');

      const texture4 = PIXI.Texture.from('https://s.cdpn.io/33073/4-150x150.jpg');

      const texture5 = PIXI.Texture.from('https://s.cdpn.io/33073/5-150x150.jpg');

      const texture6 = PIXI.Texture.from('https://s.cdpn.io/33073/6-150x150.jpg');



      // time animation in seconds

      const time = 2.0;

      const cont = new PIXI.Container();

      const parentCont = new PIXI.Container();

      const bunny1 = new PIXI.Sprite(texture1);

      const bunny2 = new PIXI.Sprite(texture2);

      const bunny3 = new PIXI.Sprite(texture3);

      const bunny4 = new PIXI.Sprite(texture4);

      const bunny5 = new PIXI.Sprite(texture5);

      const bunny6 = new PIXI.Sprite(texture6);     










      parentCont.x = 500;

      parentCont.y = 300;


      var tl3 = new gsap.timeline({paused:true}),

    tl4 = new gsap.timeline({paused:true}),

    face1 = bunny1,

    face2 =bunny2,

    face3 =bunny3,

    face4 =bunny4,

    face5 =bunny5,

    face6 =bunny6,

    cubeParent  = cont;




gsap.set(parentCont, {pixi:{perspective:500}});


gsap.set(cubeParent , {transformStyle:"preserve-3d"});



    .to(cubeParent , 5, {pixi: {rotationY:720}})

    .to(cubeParent , 2, {pixi: {rotationX:360}}, "-=2.5")

    .to(cubeParent , 1, {pixi: {rotationY:-360, rotationX:0}});


but this doesn't seem to work

Link to comment
Share on other sites

2 hours ago, bj22 said:

this doesn't seem to work

Hey BJ and welcome to the GreenSock forums! Could you please create a minimal demo showing the issue? This thread gives more info on how to do so:


  • Like 1
Link to comment
Share on other sites

Like @ZachSaucier said, a demo will be super helpful in getting you an answer but I'll just mention some things I noticed right away: 

  1. Don't use the "new" keyword when creating timelines. 
    // BAD!
    tl3 = new gsap.timeline({paused:true})
    // GOOD
    tl3 = gsap.timeline({paused:true})


  2. You initially created your timelines as paused (paused: true)...but you never unpaused them. You probably don't need to pause them initially (I'm not sure why you're doing that). 
  3. You seem to be mixing plain DOM CSS concepts with PIXI inappropriately. For example, there's no such thing as "rotationX" or "rotationY" or "perspective" or "transformStyle" in PIXI, so you can't animate those properties with GSAP (they don't exist). 

And without a demo, we can't tell if you're even loading GSAP (and which version) or properly registering the PixiPlugin. Once we see your demo, I'm sure we'll be able to better identify the issues, but I'm concerned that perhaps this is not so much a GSAP question but more of a fundamental misunderstanding about PIXI (which is not a GreenSock product). 


Lastly, please create a new forums thread with your question rather than hijacking a really old thread. It just helps to keep things cleaner. 


Happy tweening!


  • Like 3
Link to comment
Share on other sites

@bj22 Keep in mind that PIXI is mostly a 2D renderer. While they have a 3D with the pixi projection plugin, I'm quite sure that the approach you have in your code is not going to work with it. Honestly I haven't even used it so I can't give you an example, but it seems a bit complicated for just a cube:




In this post in the PIXI forums there is a short discussion about it:



Also it seems that using ThreeJS could be a simpler approach IMHO:



I've seen a few things using GSAP with ThreeJS and the results are quite good actually.


Finally perhaps @OSUblake (the forums' PIXI wizard) could have more info regarding this.


Happy Tweening!!!

  • Like 4
Link to comment
Share on other sites

29 minutes ago, Rodrigo said:

Finally perhaps @OSUblake (the forums' PIXI wizard) could have more info regarding this.


I'd echo everything Ivan said in that pixi forum post. You can do 3d in pixi, but it's not going to be easy. If you just need a cube, then make it with divs. There is no point in loading a huge WebGL library to make a cube.



  • Like 3
Link to comment
Share on other sites

Thanks all, I already have a threejs rotating cube working in Pixi stage. I wanted to check if i can do this with gsap but i understand it now where i have gone wrong. Jack's 3rd point gives me more idea. I was trying to create a cube with gsap as given in the thread. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.