holodepth

Three.js · Hareket

Hareketin estetiği: Lerp, easing ve AnimationMixer

3B bir nesneyi A noktasından B noktasına taşımak kolaydır; o hareketi akıcı, doğal ve profesyonel hissettirmek ise matematik ve zamanlama işidir. Bu sayfada lerp, easing ve AnimationMixer birlikte ele alınır; animasyon döngüsü ile birlikte düşünülür. İyi animasyon yalnızca hareket değil, hissettirme meselesidir: küçük easing farkları bile kullanıcı deneyimini belirgin şekilde değiştirir.

Yumuşak hareket ve zamanlama

Lerp (linear interpolation): doğrusal yumuşatma

Lerp, "lineer interpolasyon"un kısaltmasıdır. İki değer arasında — örneğin iki konum veya iki renk — belirli bir alpha oranında ara değer üretmenizi sağlar.

Çekirdek mantık şu formüle dayanır: mevcut değer, hedefe doğru her adımda fark vektörünün bir kısmı kadar yaklaşır.

current + (target - current) * alpha

Three.js'te mesh.position.lerp(hedef, alpha) bu ilişkiyi Vector3 üzerinde uygular; alpha 0 ile 1 arasında bir karışım oranıdır.

  • Matematiksel mantık: Her karede mevcut değeri hedefe doğru bir miktar kaydırmak için kullanılır.
  • Kullanım alanı: Kameranın veya nesnenin hedefi gecikmeli takip etmesi (smooth follow), imleçe yumuşak yaklaşma.
  • Three.js: Vector3.lerp(), Vector3.lerpVectors() ve ilgili API ile doğrudan kullanılabilir; ek kütüphane şart değildir.

FPS bağımlılığı: alpha sabit bir oran olarak kaldığında, saniyede daha fazla kare çizildiğinde toplam kayma artar — yani hareket kare hızına duyarlıdır. Daha tutarlı sonuçlar için alpha'yı delta time ile ölçeklemek (veya hızı saniye bazında tanımlamak) yaygın pratiktir; ayrıntı için delta time bölümüne bakın.

Örnek — her karede konumu hedefe yaklaştırma:

// Her karede mevcut konumu hedefe %5 oranında yaklaştır (yumuşak takip)
mesh.position.lerp(targetPosition, 0.05);

Easing: hareketin karakteri

Düz lerp, adım oranı sabit kaldığı sürece doğrusal kalır ve bazen mekanik / robotik hissettirebilir. Easing, zamanın nasıl "harcanacağını" belirler: hareketin başında veya sonunda hızlanma / yavaşlama (ör. ease-in, ease-out).

Easing fonksiyonları genellikle normalize edilmiş zaman (t, 0–1) değerini yeniden şekillendirerek hareketin hız profilini değiştirir; böylece aynı başlangıç ve bitiş noktalarında bile "nasıl varılacağı" farklılaşır.

  • Kütüphaneler: Saf matematikle eğri tanımlanabilir; GSAP, web animasyonlarında yaygın olarak kullanılan güçlü bir kütüphanedir. Three.js ekosisteminde hafif tween ihtiyacı için @tweenjs/tween.js gibi küçük paketler de sık seçilir.
  • Karakter: "Ease-in" yavaş başla, "ease-out" yavaş dur; ease-in-out ile hem giriş hem çıkış yumuşar — fiziksel ağırlık hissi verir.

AnimationMixer: karmaşık animasyonların orkestra şefi

Dışarıdan (Blender vb.) aktarılan kemikli / skinned modellerde yürüme, zıplama gibi hareketler için Three.js tarafında merkez bileşen AnimationMixer'dır.

  • Track: Belirli bir özelliğe (ör. kemik dönüşü) ait animasyon kanalı.
  • Clip: Süre ve anahtar karelerle tanımlı bir animasyon parçası (yürüme, koşma vb.).
  • Mixer: Klipleri oynatır, süreleri yönetir; gerektiğinde klipler arasında karıştırma (ör. yürümeden koşuya geçiş) yapılır.

Her karede mixer'ın iç zamanını ilerletmek için mixer.update(delta) çağrısı gereklidir — bu olmadan clip oynatma ve kemik güncellemeleri çalışmaz. delta, iki kare arasındaki süredir ( THREE.Clock ile getDelta()).

Teknik tablo: hangi yöntemi ne zaman?

Yöntem Türü En iyi kullanım Zorluk
Lerp Matematik / API Kamera veya nesne takibi, basit yumuşak geçişler. Kolay (dahili Vector3)
GSAP / tween Kütüphane UI, önceden tanımlı sekanslar, karmaşık easing. Orta (harici bağımlılık)
AnimationMixer Three.js animasyon API Karakter animasyonları, glTF / FBX ile gelen klipler. İleri (sahne ve clip yönetimi)

Uygulama: lerp ile yumuşak takip

Fare konumunu hedef olarak kullanıp nesneyi ekran düzlemine yaklaştıran tipik bir örnek: mesh, scene, camera ve renderer önceden tanımlıdır. THREE.Clock ve getDelta(), ileride mixer.update(delta) ile aynı döngüde kullanılmaya hazır olması için eklenmiştir.

const clock = new THREE.Clock();
const targetPosition = new THREE.Vector3();

window.addEventListener('mousemove', (event) => {
  targetPosition.x = (event.clientX / window.innerWidth) * 2 - 1;
  targetPosition.y = -(event.clientY / window.innerHeight) * 2 + 1;
});

function animate() {
  requestAnimationFrame(animate);

  const delta = clock.getDelta();
  // İleride AnimationMixer ile: mixer.update(delta);

  mesh.position.lerp(targetPosition, 0.1);

  renderer.render(scene, camera);
}

animate();

Holodepth notu: lerp ve easing ayrımı

Lerp ile her karede kalan mesafenin bir yüzdesi alındığı için hareketin sonunda doğal bir yavaşlama (ease-out benzeri) hissi oluşur. Buna karşılık hem başta hem sonda kontrollü eğri (ease-in-out) istiyorsanız, GSAP gibi easing ve zaman çizelgesi sunan bir kütüphane iş akışını ciddi şekilde kolaylaştırır.