Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
UP_AND_ATOM

Card flipping with TweenMax and CSS

Recommended Posts

I've been working on reproducing one of my favorite card games in JavaScript and I'm having some problems getting the 3d rotations to work the way I'd like.

 

I'm using TweenLite to flip the cards' divs with rotationX and rotationY, but I can't figure out how to tell when I need to swap out the front and back of the card. Is there a way to detect which side of the card is visible?

 

I've seen it done with CSS like this: http://davidwalsh.name/css-flip, but 'backface-visibility: hidden' doesn't seem to affect objects that are rotated with TweenLite.

Link to post
Share on other sites

Hi and welcome to the forums.

 

Maybe you could try adding a relative rotation, for example enhance the element's rotation by 180 degrees each time, like this:

TweenMax.to(element, time, {rotationY:'+=180'});

Another possibility would be to create a timeline for each card and you can play it forward on mouse over and backwards on mouse out, like this:

$("div.element").each(function(i, element)
{
    var tl = new TimelineLite({paused:true});
    tl.to(element, 1, {rotationY:180});
    element.animation = tl;
})

$("div.element").hover(elOver, elOut);

function elOver()
{
    this.animation.play();
}

function elOut()
{
    this.animation.reverse();
}

I've created a codepen so you can see it working:

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

 

Also take a look at this codepen by Chris Gannon is completely awesome, maybe you can get a couple of ideas out of it:

See the Pen JtljL by chrisgannon (@chrisgannon) on CodePen

 

Hope this helps,

Cheers,

Rodrigo.

 

On a side note great picture, I remembered the phrase:"arghh... the goggles do nothing!!"

  • Like 1
Link to post
Share on other sites

Hi

As you can see there's a serious flaw in the code I've posted. Please give me a couple of hours to correct it.

Sorry for the inconvenience.

 

Is corrected now, just an issue with selectors. The only problem I can't put my finger on is why it looks so hideous in IE10, I'll try to correct it.

Rodrigo.

Link to post
Share on other sites

This is great, but the issue I'm having is with swapping out the card's front for the back when it rotates, and vice-versa. I need to know which of the two faces is visible so that I can remove the front-facing div and add the back-facing div.

Link to post
Share on other sites

Hi,

 

Is really necessary to remove the elements?; If you check the samples you'll see that the css has the following:

backface-visibility: hidden;

That means that when the element has rotated 180 degrees you can't see it, allowing you to see the other face of the card. If you check both codepens you'll see that the animation shows  one side and then the other and each side is a DIV element, so there's no need to remove one and then add it again to the DOM, they both are there all the time. If you check David Walsh's sample with developer tools or firebug you'll see that both elements are there all the time, like I said the key is in the backface-visibility property.

 

Please double check my codepen so you can see how the code works and consider the following: the bread image represent's the back-face of the card and the painting the front-face. Also there's a new line with playing cards design(the best I could find in a short search) that'll give you a better idea.

 

Now if you really need to remove and add the DIV elements, you have to track the front-face's angle through an onUpdate callback, so when the element's angle is over 90 you  can remove it and add the back-face element. Keep in mind that the back-face element must have a 90 degrees rotation in order to simulate the effect and once you've add it you have to tween it to zero degrees.

 

It would be great if you could provide a simple codepen or fiddle, or fork my codepen, to get a better idea of what the problem is.

 

Hope this helps,

Cheers,

Rodrigo.

Link to post
Share on other sites

Hmm take a look at this codepen:

See the Pen vGEDm by jamiejefferson (@jamiejefferson) on CodePen

 

It uses the same premise as Rodrigos codepens, but it also shows how to access the current rotation - maybe you could use something like that to determine a point to swap divs?

Link to post
Share on other sites

Thanks, being able to get the current rotationX and rotationY is exactly what I was looking for! I'll swap out the card faces when the card is at 90 degrees. 

 

The one issue I'm still having is that when I adjust the x and y values for the card, its perspective gets offset so that the card isn't perpendicular to the camera when it's turned 90 degrees. Should I just wrap the card in another div and apply position transforms to that parent div and keep 3D rotations on the child div?

Link to post
Share on other sites

Hi,

 

All you have to do is give a perspective value to the elements you are rotating, not their parents. So if you have a class for the front-face of the card and another for the back-face, just set a perspective for those elements and the transformation should be more "flat" and the element will vanish at 90 degrees, like this:

TweenMax.set([$("div.cardBack"),$("div.cardFront")], {perspective:500});

Or you can do it through the CSS markup, like this:

.cardFront, .cardBack
{
  position:absolute;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -ms-backface-visibility: hidden;
  perspective:500;
}

Hope this helps,

Cheers,

Rodrigo.

Link to post
Share on other sites
On 7/21/2013 at 7:22 PM, Rodrigo said:

Hi and welcome to the forums.

 

Maybe you could try adding a relative rotation, for example enhance the element's rotation by 180 degrees each time, like this:


TweenMax.to(element, time, {rotationY:'+=180'});

Another possibility would be to create a timeline for each card and you can play it forward on mouse over and backwards on mouse out, like this:


$("div.element").each(function(i, element)
{
    var tl = new TimelineLite({paused:true});
    tl.to(element, 1, {rotationY:180});
    element.animation = tl;
})

$("div.element").hover(elOver, elOut);

function elOver()
{
    this.animation.play();
}

function elOut()
{
    this.animation.reverse();
}

I've created a codepen so you can see it working:

 

 

 

Also take a look at this codepen by Chris Gannon is completely awesome, maybe you can get a couple of ideas out of it:

 

 

 

Hope this helps,

Cheers,

Rodrigo.

 

On a side note great picture, I remembered the phrase:"arghh... the goggles do nothing!!"

This is really beautiful. How can I replace the image in the back with an html div?

Link to post
Share on other sites
5 hours ago, Rhaffaele said:

I mean the second, the one with the click

Hi, you mean the sample by @chrisgannon?

 

Chris is just adding the card's content (image actually) and the cards container through JS code, but that could be a regular DOM element with an ID, actually all could be DOM elements. Then all you have to do is point to the specific element: TweenMax.to("#cardContainer", 2, { rotationY: "+=180" });It shouldn't be more complicated than that.

 

Happy Tweening!!!

 

 

  • Like 3
Link to post
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.

×