I have a gltf scroll animation (a camera moving downwards) set up via a gsap scrolltrigger. The animation itself works like a charm - what I’m struggling with is:
How do I tie in a custom animate() function (to maniuplate the camera on top of the animation)
Any alterations to the camera, i.e. through the camera shake effect from ‘@react-three/postprocessing’, leads to the camera orientation being “offset”, even with all camera shake parameters set to 0.
Ideally, I’d like to implement subtle camera movements according to the mouse input, but I’m at a loss how to make both the scrolltrigger and a custom animate() function play along nicely.
Here’s what I have so far:
Model.jsx
useLayoutEffect(() => {
const animationDuration = animations[0].duration;
const clip = anim.actions[anim.names];
clip.clampWhenFinished = true;
clip.loop = THREE.LoopOnce;
clip.play();
const mixer = clip.getMixer();
let ctx = gsap.context(() => {
let proxy = {
get time() {
return mixer.time;
},
set time(value) {
clip.paused = false;
mixer.setTime(value);
clip.paused = true;
}
};
proxy.time = 0;
// Initializes timeline for scroll animation.
gsap
.timeline({
scrollTrigger: {
trigger: document.getElementById('scroll-wrapper'),
pin: false,
scrub: true,
start: 'top top',
end: 'bottom bottom',
markers: false
}
})
.fromTo(
proxy,
{
time: 0
},
{
time: animationDuration,
ease: 'none',
duration: 3
}
);
}, group);
return () => ctx.revert();
});
Here’s how I tried to implement the custom mouse movement function. It works okay (except for the camera offset) when I don’t scroll. As soon as I scroll the scrolltrigger takes over. Is there a way to combine the two?
// Camera Move
const { camera, scene, gl } = useThree();
const mouse = new THREE.Vector2();
const target = new THREE.Vector2();
const windowHalf = new THREE.Vector2(
window.innerWidth / 2,
window.innerHeight / 2
);
document.addEventListener('mousemove', onMouseMove, false);
function onMouseMove(event) {
mouse.x = event.clientX - windowHalf.x;
mouse.y = event.clientY - windowHalf.x;
}
animate();
function animate() {
target.x = (1 - mouse.x) * 0.0001;
target.y = (1 - mouse.y) * 0.0001;
camera.rotation.x += 0.05 * (target.y - camera.rotation.x);
camera.rotation.y += 0.05 * (target.x - camera.rotation.y);
requestAnimationFrame(animate);
// gl.render(scene, camera);
}