Hoạt ảnh

Starter pack

Hoạt ảnh là chìa khóa để mang lại sự sống cho bối cảnh 3D của bạn. Chúng có thể được kích hoạt bởi tương tác của người dùng, cuộn hoặc dựa trên thời gian và áp dụng cho các đối tượng 3D, đèncamera.

Thành thạo hoạt ảnh là một kỹ năng quan trọng để tạo ra những trải nghiệm đắm chìm. Càng nhiều kỹ thuật bạn biết, bạn càng có thể thể hiện sự sáng tạo.

Lưu ý: Các hoạt ảnh mô hình 3D được đề cập trong chương mô hình.

Lerp

Lerp là một hàm toán học dùng để nội suy giữa hai giá trị. Nó rất hữu ích để tạo hoạt ảnh cho một giá trị từ điểm này đến điểm khác.

const value = THREE.MathUtils.lerp(start, end, t);

Tham số đầu tiêngiá trị bắt đầu, tham số thứ haigiá trị kết thúctham số thứ bayếu tố nội suy giữa 01.

Yếu tố nội suy càng gần 0, hoạt ảnh sẽ càng chậm. Yếu tố nội suy càng gần 1, hoạt ảnh càng nhanh đạt tới giá trị cuối hoặc giá trị mục tiêu.

Hãy thử nghiệm điều này với thành phần AnimatedBox từ gói khởi động.

Thành phần có một mảng boxPositions chứa các vị trí của hộp tại các thời điểm khác nhau. Hãy thêm một hook useFrame để cập nhật vị trí của hộp dựa trên thời gian:

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;
  });
  // ...
};

Ở đây, hộp của chúng ta không được hoạt ảnh. Nó dịch chuyển từ vị trí này sang vị trí khác. Hãy sử dụng hàm lerp để làm nó chuyển động:

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
    );
  });
  // ...
};

Giờ đây, hộp đã được hoạt ảnh. Nó di chuyển mượt mà từ vị trí này đến vị trí khác.

Lớp Vector3 có một phương thức lerp có thể được sử dụng thay vì hàm 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);

Điều này tiết kiệm rất nhiều dòng mã mà vẫn cho kết quả như nhau!

Đừng ngần ngại thử nghiệm với thời gian và sử dụng lerp trên các thuộc tính khác như rotation hoặc scale để thử các hiệu ứng khác nhau.

Float

Float là một thành phần bao bọc từ thư viện Drei để đơn giản mang lại cảm giác rằng một đối tượng đang nổi.

Nó chứa các thuộc tính sau:

  • speed: Tốc độ hoạt hình, mặc định là 1
  • rotationIntensity: Cường độ xoay XYZ, mặc định là 1
  • floatIntensity: Cường độ nổi lên/xuống, hoạt động như một hệ số nhân với floatingRange, mặc định là 1
  • floatingRange: Phạm vi các giá trị trục y mà đối tượng sẽ nổi trong đó, mặc định là [-0.1, 0.1]

Hãy làm cho Duck của chúng ta nổi trong Experience.jsx:

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.