Carousel Animations

How we achieved animations on Carousel

Problem – Fast, browser compatible, easily maintainable
Solution – CSS3 Animation Wrapper with Fallback

The Carousel feature of Zoosk animates in a candidate that may be appealing to the user. The user can either click Yes, Maybe, or No to express interest, and on press of the button, the candidate animates out and a new one comes in, similar to a spinning carousel.

 

The CSS

The CSS that we used includes basic CSS3 animation, translate and scale. Ease-out is used to create smooth effect and forwards is used to keep the computed style once the animation is finished.

//Animating a user in
.carousel-animate-in {
.round-pic-frame { /* Bubble displaying the users photo */
-webkit-animation: carousel-user-photo-in .6s ease-out forwards;
-moz-animation: carousel-user-photo-in .6s ease-out forwards;
-o-animation: carousel-user-photo-in .6s ease-out forwards;
animation: carousel-user-photo-in .6s ease-out forwards;
}
//... more animations
}
@-webkit-keyframes carousel-user-photo-in {
0% {
-webkit-transform: translate(-150%, 25%) scale(.1);
}
100% {
-webkit-transform: translate(0, 0) scale(1);
}
}
//Animating a user out
.carousel-animate-out {
.round-pic-frame { /* Bubble displaying the users photo */
-webkit-animation: carousel-user-photo-out .2s ease-in .05s forwards;
-moz-animation: carousel-user-photo-out .2s ease-in .05s forwards;
-o-animation: carousel-user-photo-out .2s ease-in .05s forwards;
animation: carousel-user-photo-out .2s ease-in .05s forwards;
}
}
view raw gistfile1.css hosted with ❤ by GitHub

 

The Javascript

For browsers that support CSS3, we just add the .carousel-animate-in class property to the Carousel bubble element in Javascript when the Carousel page loads and this will cause the bubble to grow and move to the center of the page from the left.

bubbleEl.className = 'carousel-animate-in';
view raw gistfile1.js hosted with ❤ by GitHub

Once this class is added, the browser starts the animation and the animation ends when the user bubble is focused on the center of the page.

Animating out a user bubble is done in much the same way:

bubbleEl.className = 'carousel-animate-out'
view raw gistfile1.js hosted with ❤ by GitHub

When a user clicks on a button, we need to sequentially animate the current bubble out and a new bubble in. This is done by listening to the animation end event:

var animationEndEventString = userAgent == WEBKIT ? 'webkitAnimationEnd' :
(goog.userAgent.OPERA ? 'oAnimationEnd' : 'animationend');
bubbleEl.addEventListener(animationEndEventString, handleAnimationEnd);
function handleAnimationEnd() {
//Update model
//Animate in next bubble
nextBubbleEl.className = 'carousel-animate-in'
}
view raw gistfile1.js hosted with ❤ by GitHub

While this works, the code relies on knowing the animation name and also setting the class name to perform the animation. To simplify this, we can create a Javascript class called CssAnimationClass. The code has been simplified for demonstration purposes and you can use your preferred method of creating Javascript classes.

function CssAnimationClass(element, cssClassName, callback) {
this.animationEndEventString = userAgent == WEBKIT ? 'webkitAnimationEnd' :
(goog.userAgent.OPERA ? 'oAnimationEnd' : 'animationend');
this.element = element;
this.cssClassName = cssClassName;
this.callback = callback;
}
CssAnimationClass.prototype.play = function() {
this.element.addEventListener(this.animationEndEventString, this.handleAnimationEnd.bind(this)) //Function.prototype.bind() is supported from Javascript 1.8.5
this.element.className = this.cssClassName;
}
CssAnimationClass.prototype.handleAnimationEnd = function() {
this.callback();
}
view raw gistfile1.js hosted with ❤ by GitHub

Then animating an element out simplifies to:

var carouselOutAnimation = new CssAnimationClass(bubbleEl, 'carousel-animate-out', handleCarouselAnimateOutEndEvent);
carouselOutAnimation.play();
function handleCarouselAnimateOutEndEvent() {
//Handle carousel animate out end event
}
view raw gistfile1.js hosted with ❤ by GitHub

The function handleCarouselAnimateOutEndEvent will run when the animation ends and we handle animating a Carousel candidate in.

 

Fallback for Non-CSS3 Browsers

There’s still another problem, supporting non-CSS3 browsers. This is where we have a fallback to use Javascript animations and cannot add the CSS animation class property.

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
if (isAnimationSupported()) {
//Create CssAnimationClass and play
} else {
//Fallback to js animations
requestAnimationFrame(animateCarouselBubbleIn)
}
var start = null;
function animateCarouselBubbleIn(timestamp) {
var progress;
if (start === null) {
start = timestamp;
}
progress = Math.min((timestamp - start) / 600, 1); //Percent progress
bubbleEl.style.left = (1 - progress) * -150 + "%";
bubbleEl.style.top = (1 - progress) * 25 + "%";
bubbleEl.style.height = .9 * (progress * origHeight) + .1 * origHeight + "%" //Add .1 since the CSS3 animation starts from scale .1
bubbleEl.style.width = .9 * (progress * origWidth) + .1 * origHeight + "%"
if (progress < 1) {
requestAnimationFrame(animateCarouselBubbleIn);
}
}
view raw gistfile1.js hosted with ❤ by GitHub

The animateCarouselBubbleIn method is used as a callback to the browser window’s requestAnimationFrame method. This method updates the bubbleEl element style at regular intervals and finishes after .6 seconds, like the CSS3 animation.