如何在 three.js 中使用 gasp 动画
简介
GSAP(GreenSock Animation Platform)是一款强大的 JavaScript 动画库,广泛应用于网页和应用程序中实现高性能的动画效果。GSAP 的特点是速度快、API 丰富、兼容性好,并且非常适合与各种 Web 技术栈结合使用,包括 Three.js 这样的 3D 渲染库。
在 Three.js 项目中,GSAP 可以用来创建平滑的动画和复杂的时间线管理,使得 3D 场景中的对象动画更加流畅和具有吸引力。例如,通过 GSAP,开发者可以轻松实现摄像机的移动、物体的旋转、缩放等动态效果,这些都是在 3D 视觉表现中不可或缺的元素。
GSAP 核心 API 介绍
GSAP 提供了多种工具和函数,用于创建和控制动画。其中最核心的 API 包括:
- TweenLite/TweenMax: 这是 GSAP 中最基础的组件,用于创建单个动画。TweenMax 是 TweenLite 的扩展,包含更多功能如重复、延迟、yoyo 效果等。
- TimelineLite/TimelineMax: 时间线工具,用于将多个动画按顺序或同时控制。TimelineMax 同样是 TimelineLite 的扩展,提供更复杂的控制功能,如时间标签、最大重复次数等。
- Ease: 缓动函数,GSAP 内置多种缓动选项,允许动画以非线性的速度发生,使动画更自然。
安装
npm install gsap
结合 Three.js 的案例
接下来,我们将通过三个具体的例子来展示 GSAP 在 Three.js 中的应用。
先准备一个 threejs 的基础场景,如下:
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 添加轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真实感
controls.enableDamping = true;
// 创建一个立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 更新控制器
controls.update();
renderer.render(scene, camera);
}
animate();
// 响应窗口调整
window.addEventListener("resize", onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
摄像机动画
在 Three.js 中,通过 GSAP 动画库平滑地移动摄像机,可以带来更加动态的视角变换。
使用 gsap.to 方法来对摄像机的位置进行动画处理。在这里,camera.position 是被动画的对象,动画的持续时间设置为 2 秒。目标位置是 z: 10,表示摄像机沿 z 轴向前移动。ease: 'power1.inOut'是缓动函数,使得动画在开始和结束时速度较慢,中间速度较快。
import { PerspectiveCamera } from "three";
import { gsap } from "gsap";
// 初始化摄像机
const camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 50;
// 使用GSAP动画摄像机移动
gsap.to(camera.position, { duration: 2, z: 10, ease: "power1.inOut" });
物体旋转动画
利用 GSAP 对 Three.js 场景中的物体进行旋转动画,可以增加场景的互动性和视觉效果。
通过 gsap.to 来动画立方体的 rotation 属性。动画目标是使立方体绕 Y 轴旋转 360 度(Math.PI * 2)。动画持续时间为 5 秒,并使用 elastic.out 缓动函数,让旋转动作完成时有弹性的感觉。
// 使用GSAP让立方体旋转
gsap.to(cube.rotation, { duration: 5, y: Math.PI * 2, ease: "elastic.out" });
多物体组合动画
使用 GSAP 的 Timeline 功能,可以同时控制场景中多个物体的动画。
- 创建时间线:TimelineMax 是一个时间线类,允许我们添加多个动画到一个时间线中,并且可以控制动画的顺序和时间重叠。
- 添加动画序列: tl.to(cube.position, { duration: 1, x: 100 }):移动立方体的位置,使其在 1 秒内沿 X 轴移动到 100 的位置。 .to(sphere.position, { duration: 1, y: 200 }, '-=0.5'):在时间线上,接着上一个动画开始前 0.5 秒开始,球体沿 Y 轴移动到 200 的位置。 .to(camera.position, { duration: 1, z: 50, ease: 'power2.inOut' }):同时,摄像机沿 Z 轴移动到 50 的位置,使用 power2.inOut 缓动效果。
// 添加更平滑的动画序列
tl.to(cube.position, { duration: 2, x: 2, ease: "power2.inOut" })
.to(sphere.position, { duration: 2, y: 2, ease: "elastic.out(1, 0.3)" }, "-=1.5")
.to(camera.position, { duration: 3, z: 8, ease: "power1.inOut" }, "-=1");
// 添加自动旋转
gsap.to(cube.rotation, { duration: 8, y: Math.PI * 2, epeat: -1, ease: "none" });
gsap.to(sphere.rotation, { duration: 6, x: Math.PI * 2, repeat: -1, ease: "none" });
总结
我们通过 gsap 库实现了在 three.js 中的动画效果,通过 gsap.to 方法实现了摄像机的移动和物体的旋转,通过 TimelineMax 类实现了多个物体的组合动画。GSAP 提供了丰富的 API,可以实现更多复杂的动画效果,开发者可以根据实际需求选择合适的 API 来实现动画效果。
代码
github
https://github.com/calmound/threejs-demo/tree/main/gsap (opens in a new tab)
gitee
https://gitee.com/calmound/threejs-demo/tree/main/gsap (opens in a new tab)