Three.js journey 05 - Animations (requestAnimationFrame)

크롱·2024년 11월 7일
0

Three.js

목록 보기
3/12

requestAnimationFrame

다음 프레임에 제공할 function을 부르기 위한 목적
... The initial purpose is just to call a function on the next frame


const tick = () => {
    console.log('tick')
    window.requestAnimationFrame(tick)
}

tick()

콘솔창에 보면 계속해서 tick이 늘어난다
약 60개의 tick이 1초에 생성되는것임



항상 동일한 속도로 애니메이션 만들기

deltaTime


const tick = () => {
  // update objs
  mesh.rotation.y += 0.01
  
  // renderer 움직이는 모든 프레임을 찍는다
  renderer.render(scene, camera)

  window.requestAnimationFrame(tick)
}

tick()

👆 위 코드를 실행하면 큐브가 회전목마처럼 도는데, 회전 속도가 컴퓨터 사양마다 다르다. 이를 방지 + 모든 컴퓨터에서 똑같이 도는 속도를 위해서 Date.now() 메소드를 이용하여 현재 timestamp 와 이전 timestamp의 차이를 구하면 deltaTime이 나오는데, 이를 사용하여 위 목표를 이루고자한다.

  • Date.now( )를 콘솔에 찍으면 현재 시간이 밀리세컨드로 나옵니다
  • deltaTime이란? 전 프레임이 완료되기까지 걸린 시간
let time = Date.now()

const tick = () => {
    const currentTime = Date.now()
    const deltaTime = currentTime - time
    time = currentTime
  
    mesh.rotation.y += 0.01 * deltaTime
    
    renderer.render(scene, camera);
    window.requestAnimationFrame(tick);
}

tick()
  • 좋은 사양 컴터: 프레임이 빨리 그려지기 때문에 deltaTime이 작아진다. 그래서 회전 속도가 느리게 느껴질 수 있지만, 많은 프레임을 빠르게 처리하기 때문에 애니메이션이 부드럽게 진행

  • 안 좋은 사양 컴터: 프레임이 느리게 그려지기 때문에 deltaTime이 커진다. 그래서 회전 속도가 더 많이 회전하게 되지만, 프레임이 적게 처리되기 때문에 애니메이션이 덜 부드럽게 보일 수 있다

즉, 좋은 사양 컴터가 여러번 상대적으로 덜 빠른 속도로 여러번 애니메이션이 돌려질때,
사양안좋은 컴퓨터는 상대적으로 빠른 속도로 덜 애니메이션이 돌려져서 결과적으로 같은 속력의 애니메이션이 된다는것
=> 그래서 다양한 사양에서도 비슷한 애니메이션 속도를 유지할 수 있음!

clock.getElapsedTime()

getElapsedTime() => Clock이 생성된 후 몇 초가 지났는지 경과 시간을 나타내므로, 컴퓨터 사양과는 상관없이 동일하게 계산되어 결과적으로 애니메이션 속도를 일관되게 유지할 수 있게 해준다.


const clock = new THREE.Clock()

const tick = () => {
  // clock
  const elapsedTime = clock.getElapsedTime()

  // 1초마다 360도 회전, 360°=2π
  // elapsedTime이 1초가 될 때 전체 회전(360도)이 이루어지는 것이고,
  // 그 이전의 시간 동안에는 그 비율에 맞춰 조금씩 회전하게 되는 것.
  mesh.rotation.y = elapsedTime * Math.PI * 2

  renderer.render(scene, camera)
  window.requestAnimationFrame(tick)
}

tick()


gsap

gsap.to(mesh.position, { duration: 1, delay: 1, x: 2 })
gsap.to(mesh.position, { duration: 1, delay: 3, x: 0 })

const tick = () => {
  renderer.render(scene, camera)
  window.requestAnimationFrame(tick)
}

tick()

delay: 해당 애니메이션 실행되기 전 쉬는 타임
duration: 몇초동안 해당 애니메이션이 실행되는가

  • 첫 번째 애니메이션: mesh.position.x가 2로 이동
    이 과정은 1초 동안 매 프레임마다 조금씩 진행

  • 두 번째 애니메이션: 3초 후에 시작되어 mesh.position.x가 0으로 돌아감
    이 역시 1초 동안 매 프레임마다 조금씩 진행

  • tick 함수: 매 프레임마다 씬을 렌더링하여 애니메이션이 부드럽게 이어지도록 도와줌. GSAP가 애니메이션 상태를 업데이트하고, tick 함수가 이 업데이트를 반영하여 화면에 렌더링

즉, tick함수가 매 프레임 씬을 렌더링해서 첫번째 애니메이션과 두번째 애니메이션이 자연스럽게 이어지는거

profile
👩‍💻안녕하세요🌞

0개의 댓글