Three.js Animation
Animasi membuat scene 3D menjadi hidup. Di Three.js, kita bisa menganimasikan posisi, rotasi, skala, warna, dan hampir semua properti objek.
Animation Loop Dasar
Setiap frame, kita update properti objek dan render ulang:
function animate() {
requestAnimationFrame(animate);
// Rotasi
cube.rotation.x += 0.01;
cube.rotation.y += 0.02;
// Gerakan
sphere.position.y = Math.sin(Date.now() * 0.001) * 2;
// Skala
torus.scale.setScalar(1 + Math.sin(Date.now() * 0.002) * 0.3);
renderer.render(scene, camera);
}
animate();
Menggunakan Clock untuk Waktu Konsisten
THREE.Clock memberikan waktu yang konsisten terlepas dari frame rate:
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const elapsed = clock.getElapsedTime(); // total waktu sejak start
const delta = clock.getDelta(); // waktu sejak frame terakhir
// Orbit — objek mengelilingi titik pusat
cube.position.x = Math.cos(elapsed) * 3;
cube.position.z = Math.sin(elapsed) * 3;
// Floating naik-turun
sphere.position.y = Math.sin(elapsed * 2) * 1.5;
// Rotasi berdasarkan delta (frame-rate independent)
torus.rotation.y += delta * 2; // 2 radian per detik
renderer.render(scene, camera);
}
animate();
getElapsedTime() — total detik sejak clock dimulai (baik untuk posisi periodik)
getDelta() — detik sejak frame terakhir (baik untuk gerakan konstan)
Animasi Kompleks: Mengorbit dan Rotasi
const clock = new THREE.Clock();
// Buat group untuk rotasi gabungan
const group = new THREE.Group();
scene.add(group);
const planet = new THREE.Mesh(
new THREE.SphereGeometry(0.3, 32, 32),
new THREE.MeshStandardMaterial({ color: 0x3498db })
);
planet.position.x = 3;
group.add(planet);
// Bulan mengorbit planet
const moon = new THREE.Mesh(
new THREE.SphereGeometry(0.1, 16, 16),
new THREE.MeshStandardMaterial({ color: 0xbdc3c7 })
);
moon.position.x = 0.8;
planet.add(moon); // child dari planet
function animate() {
requestAnimationFrame(animate);
const elapsed = clock.getElapsedTime();
// Planet mengorbit pusat
group.rotation.y = elapsed * 0.5;
// Bulan mengorbit planet
moon.position.x = Math.cos(elapsed * 3) * 0.8;
moon.position.z = Math.sin(elapsed * 3) * 0.8;
renderer.render(scene, camera);
}
animate();
GSAP + Three.js — Animasi Profesional
GSAP (GreenSock Animation Platform) memberikan kontrol animasi yang sangat halus:
npm install gsap
import gsap from "gsap";
// Animasi posisi dengan easing
gsap.to(cube.position, {
x: 3,
y: 2,
duration: 2,
ease: "power2.inOut",
yoyo: true,
repeat: -1 // infinite
});
// Animasi rotasi
gsap.to(cube.rotation, {
y: Math.PI * 2,
duration: 3,
ease: "none",
repeat: -1
});
// Animasi warna material
gsap.to(cube.material.color, {
r: 1, g: 0, b: 0, // ke merah
duration: 1.5,
yoyo: true,
repeat: -1
});
// Timeline — urutan animasi
const tl = gsap.timeline({ repeat: -1 });
tl.to(cube.position, { y: 2, duration: 0.5 })
.to(cube.rotation, { x: Math.PI, duration: 0.3 })
.to(cube.position, { y: 0, duration: 0.5, ease: "bounce.out" })
.to(cube.scale, { x: 1.5, y: 0.5, z: 1.5, duration: 0.1 })
.to(cube.scale, { x: 1, y: 1, z: 1, duration: 0.3, ease: "elastic.out" });
Scroll-Based Animation
Animasi yang terikat dengan scroll halaman:
let scrollProgress = 0;
window.addEventListener("scroll", () => {
const maxScroll = document.body.scrollHeight - window.innerHeight;
scrollProgress = window.scrollY / maxScroll; // 0 sampai 1
});
function animate() {
requestAnimationFrame(animate);
// Rotasi berdasarkan scroll
cube.rotation.y = scrollProgress * Math.PI * 4;
// Posisi berdasarkan scroll
camera.position.y = scrollProgress * 10;
camera.lookAt(0, scrollProgress * 5, 0);
renderer.render(scene, camera);
}
animate();
Tips Animasi
- Gunakan
clock.getDelta()untuk gerakan yang konsisten di semua device - GSAP lebih baik untuk animasi sekuensial/kompleks
- Untuk performa, animate hanya objek yang terlihat oleh kamera
requestAnimationFrameotomatis pause saat tab tidak aktif- Gunakan
THREE.Groupuntuk menganimasikan banyak objek sebagai satu kesatuan