Implementing Backwards-Compatible CSS3 Animated Transitions
Azoft Blog Implementing Backwards-Compatible CSS3 Animated Transitions

Implementing Backwards-Compatible CSS3 Animated Transitions

By Anton Kavytin on January 16, 2014

How to Implement Backwards-Compatible CSS3 Animated Transitions

As web technologies become increasingly powerful and complex, so do web-based special effects as well — and in particular animated transitions between HTML elements. Their level of sophistication evolves quickly from simple, unpretentious accordion-style transitions to highly complex iPhone-style animations. Recently I posted about how to switch between scenes smoothly using the Kinetic.JS HTML5 Canvas framework. However, those transitions can only be applied in instances where just part of a scene is changing, and not the entire view.

Today I will demonstrate how to implement smooth full-page transitions...

There are a number of solutions to this task that work properly only in modern browsers supporting CSS animation, which renders useless certain versions of IE. However, there are still users of outdated versions of IE and — for those who may benefit — today's post includes a script providing backwards-compatible browser animation. CSS3 will be used for Firefox, Chrome, and Safari; jQuery gets the call for use in IE7. See the script in action.

Implementation

HTML structure

<div id="container"></div>
As you can see, the HTML structure is very simple. Or to be more precise, there is no structure at all. Making this animation possible are CSS and JS.

CSS

/*Common use styles*/
        html, body {
	width: 100%;
	height: 100%;
    	padding: 0px;
    	margin: 0px;
	background: #ffffff;
	}
body, td, th, input, select, textarea {
	font-family: Arial, sans-serif;
	font-size: 75%;
	color: #343434;
	}
a, a:visited, a:hover {
	text-decoration: none;
	color: #000000;
	}
/*Structure styles*/
#Body {
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	}
#container {
    	position: relative;
	width: 100%;
   	 height: 100%;
	}
/*.page; styles for browsers that support animated transitions*/
.page {
   	 position: absolute;
    	top: 0;
  	  left: 0;
   	 width: 100%;
    	height: 100%;
    	-webkit-transform: translate(0%, 0%);
   	 transform: translate(0%, 0%);
	}
.page.left {
   	 -webkit-transform: translate(-100%, 0%);
   	 transform: translate(-100%, 0%);
	}
.page.center {
    	-webkit-transform: translate(0%, 0%);
   	 transform: translate(0, 0);/**/
	}
.page.right {
    	-webkit-transform: translate(100%, 0%);
    	transform: translate(100%, 0%);
	}
.page.transition {
   	 -webkit-transition-duration: .75s;
   	 transition-duration: .75s;
	}
/*.ms-page; styles for animated screens for IE*/
.ms-page {
    	position: absolute;
   	 left: 0;
  	 top: 0;
   	 width: 100%;
   	 height: 100%;
	}
.ms-page.ms-left {
	left: -100%;
	}
.ms-page.ms-right {
	left: 100%;
	}

JavaScript — the core part of the trick

var PageTransitions = function(containerId) {
    this.container = document.getElementById(containerId);
    this.currentPage = null;
    this.isDisabled = false;
	this.isMSIE = navigator.userAgent.match(/msie/gi);
}

PageTransitions.prototype.setTransitionEnd = function (e, evt) {//set specific fucntion fire on transitionEnd event of element
	if (!e || !evt) {
		return;
	}
	var This = this,
		call = function (event) {
			e.removeEventListener('webkitTransitionEnd', call, false);
			e.removeEventListener('transitionend', call, false);
			evt.call(This, event);//call function when transitionEnd event fired
		};
	e.addEventListener('webkitTransitionEnd', call);//bind function on event (webkit)
	e.addEventListener('transitionend', call);//bind function on event
};

PageTransitions.prototype.prepareHTML = function(container, page) {
	if (page.nodeType != 1) {
		var e = document.createElement('div');
		e.innerHTML = page;
		page = e;
	}
	container.appendChild(page);
	return page;
};
/*
  * Animate screen transitions
*/
PageTransitions.prototype.transitionFromTo = function(page, from, afterAnimate) {
	var This = this,
		_currentPage;
	if (this.isDisabled) {
		return;
	}
	page = this.prepareHTML(this.container, page);
	if (!this.currentPage || !from) {
		if( this.isMSIE ) {
			page.className = 'ms-page';
		} else {
			page.className = "page center";
		}
		this.currentPage = page;
		this.isDisabled = false;
		return;
	}
	this.isDisabled = true;
	// Position the page at the starting position of the animation
	_currentPage = this.currentPage;
	if( this.isMSIE ) {//animation for IE
		page.className = "ms-page ms-" + from;
		$(this.currentPage).animate({left: (from === "left" ? '100%' : '-100%')}, 750, function() {//animate current screen to left/right 
			_currentPage.parentNode.removeChild(_currentPage);//remove block after animate
			This.isDisabled = false;
			if( afterAnimate ) {
				afterAnimate.call(this);
			}
		});
		$(page).animate({left: '0%'}, 750);
	} else {//animation for FF, Chrome, Safari
		page.className = "page " + from;
		this.setTransitionEnd(this.currentPage, function () {//animate current screen to left/right 
			_currentPage.parentNode.removeChild(_currentPage);//remove block after animate
			This.isDisabled = false;
			if( afterAnimate ) {
				afterAnimate.call(this);
			}
		});
		container.offsetWidth;
		// Position the new page and the current page at the ending position of their animation with a transition class indicating the duration of the animation
		page.className = "page transition center";
		this.currentPage.className = "page transition " + (from === "left" ? "right" : "left");
	}
	this.currentPage = page;
};

var PageTransitionsObject = new PageTransitions('container');

document.onready = function() {
	PageTransitionsObject.transitionFromTo(document.getElementById('template1').innerHTML);
}

Comments

PageTransitions is a small class (prototype) making the animated transition possible. During initialization, an PageTransitions class object receives the 'containerId' parameter — ID of a parent block where all animation occurs.

Below is a short description of methods available for a PageTransitions class object:

setTransitionEnd — method used for listening to the 'transitioned' event by the animated element.

Input parameters:

  • e [HTMLElement] — an animated element;
  • evt [Function] — function that will be launched when animation is over.

prepareHTML — this method creates a block that will be animated and it processes all the content for this block.

Input parameters:

  • container [HTMLElement] — a parent container storing screens between which transition occurs;
  • page [HTMLElement | String] — content of the animated block. It might be an HTML element or a string.

transitionFromTo — method performing animated transition between screens.

Input parameters:

  • page [HTLElement | String] — content of the animated block. It might be an HTML element or a string.
  • from [String] — direction of the transition animation. States from which side a new block should appear. Possible values: right/left.
  • afterAnimate [Function] — a user function that will be performed after the transition. You can define any logic for this function. Parameters are optional.

This script can be further improved by adding animated transitions vertically, requiring only small changes to the animation script and CSS. (You'll just need to add a few new class selectors).

You can click here to see the script in action.

That's all for today! 

VN:F [1.9.22_1171]
Rating: 4.7/5 (6 votes cast)
VN:F [1.9.22_1171]
Rating: +5 (from 7 votes)
Implementing Backwards-Compatible CSS3 Animated Transitions, 4.7 out of 5 based on 6 ratings



Request a Free Quote
 
 
 

Please enter the result and submit the form

Content created by Anton Kavytin