CUSTOM PAGE TRANSITIONS 2
You will remember from last time, that to use a CSS transition with jQM, we create a class name for the transition and point that class at a named CSS animation. We can use different animations for the page entering, leaving, and the 2 reverse directions. An animation in CSS is created by defining a set of transforms at various points during the transition duration called keyFrames. Each KeyFrame’s time is defined as a percentage of the animation duration, so the simplest animations can be defined with only 2 KeyFrames: 0% – start transform, and 100% – end transform. The browser is responsible for figuring out how to animate the transform values between the KeyFrames.
1 – A Simple Slide In/Out Animation
Lets start simple and define an animation that slides the page in from 50% of its width on the left, and slides out 50% of its width on the right. To achieve this, for the IN animation we need to setup a start KeyFrame with an X translation of –50% and an end X translation of 0; and for the OUT animation we need to setup a start KeyFrame with an X translation of 0 and an end X translation of 50%
@-webkit-keyframes simpleSlide {
0% {
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
100% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
}
@keyframes simpleSlide {
0% {
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
transform: translateX(-50%);
}
100% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
}
OUT animation
@-webkit-keyframes simpleSlideOut {
0% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
100% {
-webkit-transform: translateX(50%);
-moz-transform: translateX(50%);
-ms-transform: translateX(50%);
transform: translateX(50%);
}
}
@keyframes simpleSlideOut {
0% {
-webkit-transform: translateX(0);
-moz-transform: translateX(0);
-ms-transform: translateX(0);
transform: translateX(0);
}
100% {
-webkit-transform: translateX(50%);
-moz-transform: translateX(50%);
-ms-transform: translateX(50%);
transform: translateX(50%);
}
}
In this example we have named the animations simpleSlide and simpleSlideOut, so to use them, we create a class called simpleSlideTrans and assign the in and out animations.
.simpleSlideTrans.in {
-webkit-animation-name: simpleSlide;
-moz-animation-name: simpleSlide;
animation-name: simpleSlide;
-webkit-animation-timing-function: ease-out;
-moz-animation-timing-function: ease-out;
animation-timing-function: ease-out;
-webkit-animation-duration: 900ms;
-moz-animation-duration: 900ms;
animation-duration: 900ms;
}
.simpleSlideTrans.out {
-webkit-animation-name: simpleSlideOut;
-moz-animation-name: simpleSlideOut;
animation-name: simpleSlideOut;
-webkit-animation-timing-function: ease-out;
-moz-animation-timing-function: ease-out;
animation-timing-function: ease-out;
-webkit-animation-duration: 900ms;
-moz-animation-duration: 900ms;
animation-duration: 900ms;
}
2 – A Complex 3d Animation
For this more complex animation I will remove all the vendor prefixed CSS attributes in the following code blocks so that it is easier to read. The linked demo will include the full CSS. Here is the IN animation:
@keyframes sideTwist {
0% {
transform-style: preserve-3d;
transform: perspective(800px) translate3d(-50%, 0px, -300px) rotateX(0deg) rotateY(30deg) rotateZ(50deg);
transform-origin: 0 100%;
opacity: 0.4;
}
40% {
transform: perspective(800px) translate3d(-30%, 0px, 30px) rotateX(40deg) rotateY(10deg) rotateZ(-10deg);
opacity: 0.7;
}
60% {
transform: perspective(800px) translate3d(-20%, 0px, 0px) rotateX(50deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 50% 0;
opacity: 0.8;
}
100% {
transform: perspective(800px) translate3d(0,0,0) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
opacity: 1;
}
}
For our animation we have defined 4 KeyFrames:
- We start partially faded out (opacity of 0.4), translated 50% to the left and 300px away from us, rotated 30 degrees on the Y-axis and 50 degrees on the Z-axis. Our transform-origin is at the bottom left.
- At 40% we have animated to an opacity of 0.7, 30% to the left, 30px away from us, rotated 40 degrees on the X-axis, 10 degrees on the Y-axis and –10 degrees on the Z-axis.
- At 60% we have animated to an opacity of 0.8, 20% to the left and rotated 50 degrees on the X-axis; no more rotation in Y or Z axes. The transform-origin is now at the center top.
- Finally we end up with no more translation or rotation and fully faded in.
The OUT animation mostly just reverses the frames and transforms:
@keyframes sideTwistBack {
100% {
transform: perspective(800px) translate3d(50%, 0px, -300px) rotateX(0deg) rotateY(-30deg) rotateZ(-50deg);
opacity: 0.4;
}
60% {
transform: perspective(800px) translate3d(30%, 0px, 30px) rotateX(-40deg) rotateY(-10deg) rotateZ(10deg);
opacity: 0.8;
}
40% {
transform: perspective(800px) translate3d(20%, 0px, 0px) rotateX(-50deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 50% 0;
opacity: 0.8;
}
0% {
transform-style: preserve-3d;
transform: perspective(800px) translate3d(0,0,0) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 0 100%;
opacity: 1;
}
}
Again our animation has defined 4 KeyFrames:
- We start with no fade, translation, or rotation.
- At 40% we have animated to an opacity of 0.8, 20% to the right and rotated -50 degrees on the X-axis. The transform-origin is now at the center top.
- At 60% we have animated to an opacity of 0.8, 30% to the right, 30px away from us, rotated -40 degrees on the X-axis, -10 degrees on the Y-axis and 10 degrees on the Z-axis.
- Finally we end up with an opacity of 0.4, 50% to the right, 300px away from us, rotated –30 degrees on the Y-axis and –50 degrees on the Z-Axis.
The reverse animations change the in and out directions for back button operations:
@keyframes sideTwistReverse {
0% {
transform-style: preserve-3d;
transform: perspective(800px) translate3d(50%, 0px, -300px) rotateX(0deg) rotateY(-30deg) rotateZ(50deg);
transform-origin: 0 100%;
opacity: 0.4;
}
40% {
transform: perspective(800px) translate3d(30%, 0px, 30px) rotateX(-40deg) rotateY(-10deg) rotateZ(-10deg);
opacity: 0.7;
}
60% {
transform: perspective(800px) translate3d(20%, 0px, 0px) rotateX(-50deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 50% 0;
opacity: 0.8;
}
100% {
transform: perspective(800px) translate3d(0,0,0) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
opacity: 1;
}
}
@keyframes sideTwistBackReverse {
100% {
transform: perspective(800px) translate3d(-50%, 0px, -300px) rotateX(0deg) rotateY(30deg) rotateZ(50deg);
opacity: 0.4;
}
60% {
transform: perspective(800px) translate3d(-30%, 0px, 30px) rotateX(40deg) rotateY(10deg) rotateZ(-10deg);
opacity: 0.8;
}
40% {
transform: perspective(800px) translate3d(-20%, 0px, 0px) rotateX(50deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 50% 0;
opacity: 0.8;
}
0% {
transform-style: preserve-3d;
transform: perspective(800px) translate3d(0,0,0) rotateX(0deg) rotateY(0deg) rotateZ(0deg);
transform-origin: 0 100%;
opacity: 1;
}
}
Finally to use our animations, we create a class called sideTwistTrans and assign the in, out, reverse in, and reverse out animations:
.sideTwistTrans.in {
-webkit-animation-name: sideTwist;
-moz-animation-name: sideTwist;
animation-name: sideTwist;
-webkit-animation-timing-function: ease-out;
-moz-animation-timing-function: ease-out;
animation-timing-function: ease-out;
-webkit-animation-duration: 900ms;
-moz-animation-duration: 900ms;
animation-duration: 900ms;
}
.sideTwistTrans.out {
-webkit-animation-name: sideTwistBack;
-moz-animation-name: sideTwistBack;
animation-name: sideTwistBack;
-webkit-animation-timing-function: ease-in;
-moz-animation-timing-function: ease-in;
animation-timing-function: ease-in;
-webkit-animation-duration: 800ms;
-moz-animation-duration: 800ms;
animation-duration: 800ms;
}
.sideTwistTrans.in.reverse {
-webkit-animation-name: sideTwistReverse;
-moz-animation-name: sideTwistReverse;
animation-name: sideTwistReverse;
}
.sideTwistTrans.out.reverse {
-webkit-animation-name: sideTwistBackReverse;
-moz-animation-name: sideTwistBackReverse;
animation-name: sideTwistBackReverse;
}
