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.
Puedes situar fragmentos de código dentro de etiquetas <pre></pre> y código HTML o XML entre etiquetas <xmp></xmp>.