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>.