Shattering Images

I’ve been messing around with css3 transitions and seeing how many can run simultaneously without noticeable performance lag. So, inspired by this cool bit of canvas wizardry I thought I’d create some image shattering effects to test how well css transitions could cope.

Below are two videos of the results. The first is doing simultaneously animating 25 elements in 3d and cope fine without any lag at all. The second is animating 256 elements and although there is some lag after clicking the image, the animation itself is remarkably smooth. You can view the first for yourself at http://superted.me/stuff/shatter.html on any webkit browser although the 3d effect only works on the iphone.

There were three key steps in creating this effect. The first was a function to create the image, which is essentially a collection of divs with the same background image positioned to look like a single image:

shatter.createMozaic = function(uid, first){
		var w = 320 / PANELS;
		var h = w;
		for(var i = 0, l = PANELS; i < l; i++){
			for(var j = 0; j < PANELS; j++){
				//create a div for each panel
				var div = document.createElement('div');
				div.className = 'imgSection '+uid;
				//offset each panel
				div.style.top = (j * h) + 50 + 'px';
				div.style.left = (i * w) + 'px';
				div.style.width = w + 'px';
				div.style.height = h  + 'px';
				//offset the background relative to the position of the div
				div.style.backgroundPosition = (-i * w) +'px '+(-j * h )+'px';
				var matrix = new WebKitCSSMatrix();
				//if it is the first image
				if(first){
					//no image rotation and full opacity
					div.style.webkitTransform	= matrix.rotate(0, 0, 0);
					div.style.opacity = 1;
				}
				else{
					//random X and Y rotation and a Z translation
					var newX = Math.random() * 360;
					var newY = Math.random() * 360;
					div.style.webkitTransform	= matrix.rotate(newX, newY, 0).translate(0, 0, 380);
				}
				document.body.appendChild(div);

			}
		}

	};

The second function was to break up the image by changing the rotation and translation of each div:

	shatter.shatter = function(uid){
		var sections = document.getElementsByClassName(uid);
		//loop through each panel of this image
		for(var i = 0, l = sections.length; i < l; i++){
			var theTransform = window.getComputedStyle(sections[i]).webkitTransform;
			var matrix = new WebKitCSSMatrix(theTransform);
			var newX = Math.random() * 360;
			var newY = Math.random() * 360;
			//give each panel a random X and Y rotation and set opacity to 0
			sections[i].style.webkitTransform	= matrix.rotate(newX, newY, 0).translate(0, 0, 380);
			sections[i].style.opacity = 0;
		}
	};

And finally a function to reassemble an image:

	shatter.unShatter = function(uid){
		var sections = document.getElementsByClassName(uid);
		//loop through each panel of this image
		for(var i = 0, l = sections.length; i < l; i++){
			var matrix = new WebKitCSSMatrix();
			sections[i].style.webkitTransform	= matrix.rotate(0, 0, 0).translate(0, 0, 0);
			sections[i].style.opacity = 1;
		}

	};

And of course some css was needed to handle the transitions

.imgSection {
	position: absolute;
	-webkit-transition-property: -webkit-transform, left, opacity;
	-webkit-transition-duration: 1000ms, 1000ms, 1000ms;
	-webkit-transition-timing-function : ease-out, ease-out, linear;
	-webkit-transition-delay: 0, 500ms, 0;
	-webkit-backface-visibility: hidden;
	-webkit-transform-style: preserve-3d;
	opacity:0;
}
.img1{
	background: url(../img/cb1.jpg) no-repeat 0 0;
}

One Response to “Shattering Images”

  1. [...] This post was mentioned on Twitter by ted littledale. ted littledale said: Experimenting with multiple simultaneous CSS3 transitions http://superted.me/shattering-images [...]

Leave a Reply