Animación 3D de un plano usando CSS3

Hace unos días respondí una pregunta en Stack Overflow en la cual se pedía traducir una animación 3D de un plano, realizada con Popmotion a GreenSock.

Respondiendo a dicha pregunta resultó el siguiente código JavaScript que replica el mismo efecto de la animación original, pero usando para ello solo cálculos en JavaScript y transformaciones CSS3, dejando la librería GreenSock solo para regresar el plano a su sitio una vez se suelte.

Código HTML

<div id="container">

	<div class="box"></div>

</div>

Código CSS

html {
	height: 100%;
}

body {
	background: #232b2b;
	margin: 0;
	padding: 0;
	height: 100%;
}

#container {
	height: 100%;
	perspective: 700;
	perspective-origin: 50% 50%;
	position: relative;
	transform-style: preserve-3d;
	width: 100%;
}

.box {
	background: #E87A24;
	border-radius: 4px;
	height: 150px;
	left: 50%;
	margin-left: -75px;
	margin-top: -75px;
	position: absolute;
	cursor: pointer;
	top: 50%;
	will-change: transform;
	width: 150px;
}

Código JavaScript

//---Variables
var doc    = document;

doc.addEventListener("DOMContentLoaded", function () {

	var box    = doc.querySelector(".box"),
	    startX = 0,
	    startY = 0,
	    posX   = 0,
	    posY   = 0,
	    speedX = 0,
	    speedY = 0,
	    obj    = {x: 0, y: 0, speedX: 0, speedY: 0};

	//---Main Events
	box.addEventListener("mousedown", startMove);
	box.addEventListener("touchstart", startMove);
	doc.addEventListener("mouseup", stopMove);
	box.addEventListener("touchend", stopMove);

	//---Start the movement
	function startMove (evt) {

		var touch = evt.touches || evt.targetTouches;

		startX = (touch) ? touch[0].pageX : evt.pageX;
		startY = (touch) ? touch[0].pageY : evt.pageY;

		//---Add the mouse move events
		doc.addEventListener("mousemove", updatePosition);
		box.addEventListener("touchmove", updatePosition);

	}

	//---Update variables
	function updatePosition (evt) {
	  
		var touch = evt.touches || evt.targetTouches;
		var pageX = (touch) ? touch[0].pageX : evt.pageX;
		var pageY = (touch) ? touch[0].pageY : evt.pageY;

		speedX = (pageX - posX) * 5;
		speedY = (pageY - posY) * 5;

		if (speedX < -45) { speedX = -45 }
		if (speedX > 45) { speedX = 45 }
		if (speedY < -45) { speedY = -45 }
		if (speedY > 45) { speedY = 45 }

		posX = pageX;
		posY = pageY;

		obj.x += (posX - startX - obj.x) * .15;
		obj.y += (posY - startY - obj.y) * .15;
		obj.speedX += (speedX - obj.speedX) * .15;
		obj.speedY += (speedY - obj.speedY) * .15; 

		updateTransform();

	}

	//---Stop movement, returns the box to its place
	function stopMove () {

		TweenLite.to(obj, 0.75, {
			ease: Elastic.easeOut.config(1, 0.3),
			x: 0,
			y: 0,
			speedX: 0,
			speedY: 0,
			onUpdate: updateTransform
		});

		doc.removeEventListener("mousemove", updatePosition);

	}

	//---Update the box transformations
	function updateTransform () {

		var transformStr = "translate(" + obj.x + "px, " + obj.y + "px) rotateX(" + (-obj.speedY) + "deg) rotateY(" + obj.speedX + "deg)";

		box.style.oTransform = transformStr;
		box.style.MozTransform = transformStr;
		box.style.MozTransform = transformStr;
		box.style.WebkitTransform = transformStr;
		box.style.transform = transformStr;

	}

});

Resultado (arrastra el cuadro rápidamente)

Descarga los ficheros de ejemplo de animación 3D de un plano usando JavaScript y transformaciones CSS3.

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInShare on StumbleUpon

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes situar fragmentos de código dentro de etiquetas <pre></pre> y código HTML o XML entre etiquetas <xmp></xmp>.

Time limit is exhausted. Please reload CAPTCHA.