rotate mesh on page scroll in three.js

Viewed 1756

I'd like to rotate an object when the page scrolls, but I cant make it work properly. What I have so far and updates the rotation of the object on page load is:

mesh.rotation.y = window.pageYOffset;

this however only updates the object on page load and not updating it further on scroll. I know that for the camera you have to update the projection matrix to be able to have an interactive camera, on objects/meshes however this seems to be on by default (mesh.updateMatrix), I still cant make it work. What am I doing wrong?

1 Answers

I know that for the camera you have to update the projection matrix to be able to have an interactive camera,

I'm afraid this is not right. In many applications the projection matrix is actually static. A camera in three.js is a 3D object like a mesh. You can modify the position or rotation properties in order to transform it.

Check out the following live example that shows how to animate a cube on scroll via GSAP:

let camera, scene, renderer;

init();
animate();

function init() {

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(40, window.innerWidth / ( window.innerHeight * 2 ), 0.1, 10);
  camera.position.set(0, 0, 7);

  const geometry = new THREE.BoxBufferGeometry();
  const material = new THREE.MeshNormalMaterial();

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({antialias: true});
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize(window.innerWidth, window.innerHeight * 2);
  document.body.appendChild(renderer.domElement);

  // gsap

  gsap.registerPlugin(ScrollTrigger);

  gsap.to(mesh.rotation, {
    scrollTrigger: {
    trigger: "#trigger",
    start: "top top",
    end: "bottom top",
    scrub: true,
    toggleActions: "restart pause resume pause"
  },
    y: Math.PI
  });

}


function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  
}
body {
    margin: 0px;
}
canvas {
    display: block;
}
#trigger {
    position: absolute;
    height: 100%;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.122/build/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/ScrollTrigger.min.js"></script>  

<div id="trigger">

</div>

Related