[Three.js] Глава 6 Анимация Анимация

06.Анимации

представлять

Создаем сцену, которую рендерим один раз в конце кода. Это хороший шаг вперед, но в большинстве случаев вы захотите анимировать свои продукты с помощью некоторых динамических эффектов.
При использовании Three.js анимация выглядит как покадровая анимация. Вы перемещаете объекты, затем визуализируете. Затем еще немного переместите объект и сделайте еще один рендер. и т. д. Чем больше вы перемещаете объекты между рендерами, тем быстрее они кажутся движущимися.
Экран, который вы просматриваете, работает на определенной частоте. Мы называем это частотой кадров. Частота кадров в основном зависит от экрана, но у самого компьютера есть ограничения. Большинство экранов работают со скоростью 60 кадров в секунду. Если посчитать, это означает примерно один кадр каждые 16 миллисекунд. Но некоторые экраны могут работать быстрее, и когда у компьютера возникают проблемы с обработкой данных, он будет работать медленнее.
Мы хотим выполнить функцию, которая будет перемещать объект и отображать его в каждом кадре независимо от частоты кадров.
Нативный способ JavaScript сделать это — использовать window.requestAnimationFrame(...)методы.

настраивать

Как и раньше, все, что у нас есть в лаунчере, это куб в центре сцены.

Использовать запросаниматионфрейм

requestAnimationFrame не может запускать код в каждом кадре.
requestAnimationFrameзаключается в выполнении команды, которую мы предоставляем в следующем кадре. Однако, если мы используем **рекурсивный бесконечный цикл для вызова самого себя**, эта функция requestAnimationFrameтакже используется для повторного выполнения себя в следующем кадре, тогда мы закончим выполнением этой функции в каждом кадре навсегда.
Создайте вызываемую функцию tickи вызовите ее один раз. В этой функции он используется для window.requestAnimationFrame(...)вызова той же функции в следующем кадре:

/**
 * Animate
 */
const tick = () =>
{
    
    
    console.log('tick')

    window.requestAnimationFrame(tick)
}

tick()

Вот и все. Запустил бесконечный цикл.
Как мы видим в консоли, для каждого кадра вызывается тик. Если вы протестируете этот код на компьютере с высокой частотой кадров, «галочка» будет появляться чаще.
Теперь вы можете renderer.render(...)перемещать вызовы внутри этой функции и увеличивать куб rotation:

/**
 * Animate
 */
const tick = () =>
{
    
    
    // Update objects
    mesh.rotation.y += 0.01

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

Поздравляем, теперь у вас есть анимация Three.js.
Проблема в том, что если вы протестируете этот код на компьютере с высокой частотой кадров, куб будет вращаться быстрее, а если вы протестируете его на более низкой частоте кадров, куб будет вращаться медленнее.

Адаптировать частоту кадров Date.now()

Чтобы адаптировать анимацию к частоте кадров, нам нужно знать, сколько времени прошло с момента последнего обновления.
Во-первых, нам нужен способ измерения времени. В собственном JavaScript вы можете получить Date.now()текущую метку времени с помощью:

const time = Date.now()

Временные метки соответствуют времени, прошедшему с 1 января 1970 года, начала времени Unix. В JavaScript это миллисекунды.
Все, что нужно сейчас, это вычесть временную метку предыдущего кадра из текущей временной метки, чтобы получить значение, которое мы можем вызвать и deltaTimeиспользовать при анимации объекта:

/**
 * Animate
 */
let time = Date.now()

const tick = () =>
{
    
    
		// Time
    const currentTime = Date.now()
    const deltaTime = currentTime - time
    time = currentTime

    // Update objects
    mesh.rotation.y += 0.01 * deltaTime

    // ...
}

tick()

Наш поворот основан на времени, прошедшем с момента последнего кадра, поэтому каждый экран и каждый компьютер будут вращаться с одинаковой скоростью независимо от частоты кадров.

Используйте часы Часы

Хотя этот код не так уж сложен, в Three.js есть встроенное решение под названием Clock для обработки расчетов времени.
Вы просто создаете экземпляр переменной Clockclock и используете встроенный метод, getElapsedTime(). поэтому метод возвращает количество секунд, прошедших с момента создания часов.
Вы можете использовать это значение для поворота объектов:

/**
 * Animate
 */
const clock = new THREE.Clock()

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

    // Update objects
    mesh.rotation.y = elapsedTime

    // ...
}

tick()

Вы также можете использовать галочку для перемещения positionэлементов с атрибутами. Если вы хотите объединить эти два свойства, используйте Math.sin(...)геометрию кругового движения:

/**
 * Animate
 */
const clock = new THREE.Clock()

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

    // Update objects
    mesh.position.x = Math.cos(elapsedTime)
    mesh.position.y = Math.sin(elapsedTime)

    // ...
}

tick()

Очевидно, вы можете использовать эти методы для анимации любого Object3D , например камеры:

/**
 * Animate
 */
const clock = new THREE.Clock()

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

    // Update objects
    camera.position.x = Math.cos(elapsedTime)
    camera.position.y = Math.sin(elapsedTime)
    camera.lookAt(mesh.position)

    // ...
}

tick()

Доступен другой метод , но его не следует использовать, если getDelta(...)вы точно не знаете, что происходит в коде класса Clock . Его использование может испортить вашу анимацию, и вы получите нежелательные результаты.

Использование библиотеки анимации GSAP

Иногда вы захотите анимировать свою сцену очень специфическим образом, что потребует использования другой библиотеки. Существует много анимационных библиотек, но самая известная — GSAP .
Чтобы добавить GSAP в наш проект, мы можем использовать диспетчер зависимостей, предоставляемый Node.js, который называется , npmВ
вашем терминале (когда сервер не запущен или используется другое окно терминала в той же папке) запустите npm install --save [email protected]
этот --saveпараметр, чтобы сохранить зависимости в , package.jsonпоэтому, если мы выполним версию npm install.force
@ 3.5.1. Мы используем эту версию, потому что это версия, с которой был написан курс, но если вы предпочитаете, вы можете установить последнюю версию, удалив @ 3.5.1.
GSAP теперь доступен в папке node_modules/, и мы можем импортировать его в нашу script.js:

import './style.css'
import * as THREE from 'three'
import gsap from 'gsap'

// ...

Существует так много способов использования GSAP, что мы могли бы посвятить этому целый курс, но это не цель данного курса. Мы просто создадим демо для тестирования. Если вы уже знаете, как использовать GSAP, он работает так же, как и Three.js.
Закомментируйте код, связанный с предыдущими анимациями, но сохраните tickфункциональность и рендеринг. Затем вы можете создать то, что мы называем анимацией (анимация от A до B), используя gsap.to(...):

/**
 * Animate
 */
gsap.to(mesh.position, {
    
     duration: 1, delay: 1, x: 2 })

const tick = () =>
{
    
    
    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

В GSAP есть встроенный requestAnimationFrame, поэтому вам не нужно обновлять анимацию самостоятельно, однако, если вы хотите увидеть движение куба, вам нужно продолжать рендерить свою сцену в каждом кадре.

выбрать правильное решение

Что касается выбора нативного JS и библиотеки анимации, то это зависит от того, какого эффекта вы хотите добиться. Если вы создаете карусель, которая вращается вечно, вам не нужны никакие библиотеки. Но если вы хотите сделать анимацию, например взмах меча, я рекомендую вам использовать для этого другие библиотеки анимации.

Supongo que te gusta

Origin blog.csdn.net/m0_68324632/article/details/130790448
Recomendado
Clasificación