Fundamentals
Core
Master
Shaders
Animações
Animações são essenciais para dar vida à sua cena 3D. Elas podem ser acionadas por interações do usuário, baseadas em scroll ou tempo, e aplicadas a objetos 3D, luzes e câmeras.
Dominar as animações é uma habilidade chave para criar experiências imersivas. Quanto mais técnicas você conhece, mais você pode expressar sua criatividade.
Nota: As animações de modelos 3D são cobertas no capítulo de modelos.
Lerp
Lerp é uma função matemática que interpola entre dois valores. É útil para animar um valor de um ponto a outro.
const value = THREE.MathUtils.lerp(start, end, t);
O primeiro parâmetro é o valor inicial, o segundo parâmetro é o valor final e o terceiro parâmetro é o fator de interpolação entre 0 e 1.
Quanto mais próximo o fator de interpolação estiver de 0, mais lenta será a animação. Quanto mais próximo de 1, mais rapidamente a animação atingirá o valor final ou alvo.
Vamos experimentar isso no componente AnimatedBox
do pacote inicial.
O componente possui um array boxPositions
que contém as posições da caixa em diferentes momentos. Vamos adicionar um hook useFrame
para atualizar a posição da caixa com base no tempo:
import { RoundedBox } from "@react-three/drei"; import { useRef } from "react"; export const AnimatedBox = ({ boxPositions, ...props }) => { const box = useRef(); useFrame(({ clock }) => { const seconds = parseInt(clock.getElapsedTime()); const targetPosition = boxPositions[seconds % boxPositions.length]; box.current.position.x = targetPosition.x; box.current.position.y = targetPosition.y; box.current.position.z = targetPosition.z; }); // ... };
Aqui nossa caixa não está animada. Ela se teletransporta de uma posição para outra. Vamos usar a função lerp
para animá-la:
import * as THREE from "three"; // ... export const AnimatedBox = ({ boxPositions, ...props }) => { const box = useRef(); useFrame(({ clock }) => { const seconds = parseInt(clock.getElapsedTime()); const targetPosition = boxPositions[seconds % boxPositions.length]; box.current.position.x = THREE.MathUtils.lerp( box.current.position.x, targetPosition.x, 0.05 ); box.current.position.y = THREE.MathUtils.lerp( box.current.position.y, targetPosition.y, 0.05 ); box.current.position.z = THREE.MathUtils.lerp( box.current.position.z, targetPosition.z, 0.05 ); }); // ... };
A caixa agora está animada. Ela se move suavemente de uma posição para outra.
A classe Vector3
tem um método lerp
que pode ser usado em vez da função THREE.MathUtils.lerp
:
// box.current.position.x = THREE.MathUtils.lerp( // box.current.position.x, // targetPosition.x, // 0.05 // ); // box.current.position.y = THREE.MathUtils.lerp( // box.current.position.y, // targetPosition.y, // 0.05 // ); // box.current.position.z = THREE.MathUtils.lerp( // box.current.position.z, // targetPosition.z, // 0.05 // ); box.current.position.lerp(targetPosition, 0.05);
Muitas linhas economizadas para o mesmo resultado!
Não hesite em brincar com o tempo e interpolar outras propriedades como a rotação
ou a escala
para experimentar efeitos diferentes.
Float
Float é um componente wrapper da biblioteca Drei que simplesmente dá a impressão de que um objeto está flutuando.
Ele contém as seguintes props:
speed
: Velocidade da animação, padrão é 1rotationIntensity
: Intensidade da rotação XYZ, padrão é 1floatIntensity
: Intensidade da flutuação para cima/baixo, funciona como um multiplicador com o floatingRange, padrão é 1floatingRange
: Intervalo de valores no eixo y dentro do qual o objeto irá flutuar, padrão é [-0.1,0.1]
Vamos fazer nosso Duck flutuar em Experience.jsx
:
End of lesson preview
To get access to the entire lesson, you need to purchase the course.