Skip to content

41. Tween.js 常用 API

Published:

上节我们学了用 Tween.js 实现缓动动画。

但只是入了下门,还有很多问题。比如:

这节我们就来全面深入下 Tween.js

创建项目:

npx create-vite tween-all-feature

image.png

进入项目,安装依赖:

npm install
npm install --save three
npm install --save-dev @types/three

改下 src/main.js

import './style.css';
import * as THREE from 'three';
import {
    OrbitControls
} from 'three/addons/controls/OrbitControls.js';

const scene = new THREE.Scene();

const directionLight = new THREE.DirectionalLight(0xffffff, 2);
directionLight.position.set(500, 400, 300);
scene.add(directionLight);

const ambientLight = new THREE.AmbientLight();
scene.add(ambientLight);

const width = window.innerWidth;
const height = window.innerHeight;

const helper = new THREE.AxesHelper(1000);
scene.add(helper);

const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 10000);
camera.position.set(500, 600, 800);
camera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height)

function render() {
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

render();

document.body.append(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);

创建 Scene、Light、Camera、Renderer。

改下 style.css

body {
  margin: 0;
}

写下 src/mesh.js

import * as THREE from 'three';

const geometry = new  THREE.BoxGeometry(200, 200, 200);
const material = new THREE.MeshPhongMaterial({
    color: 'orange'
});
const mesh = new THREE.Mesh(geometry, material);

export default mesh;

画了一个立方体。

跑一下:

npm run dev

image.png

image.png

安装下 tween.js,我们来写个动画:

npm install --save @tweenjs/tween.js

首先让立方体运动到 x 600 的位置:

image.png

import { Easing, Tween } from '@tweenjs/tween.js';
const tween = new Tween(mesh.position)
    .to({ x: 600 }, 2000)
    .easing(Easing.Quadratic.InOut)
    .repeat(0)
    .start();

function render() {
    tween.update();
    renderer.render(scene, camera);
    requestAnimationFrame(render);
}

2025-04-19 18.40.45.gif

再写一个旋转动画:

image.png

const tween2 = new Tween(mesh.rotation)
    .to({ x: Math.PI / 6 }, 2000)
    .easing(Easing.Quadratic.InOut)
    .repeat(0)
    .start();

两个动画并行执行,看下效果:

2025-04-19 18.50.28.gif

如果 tween 动画有十多个呢?也都要单独在渲染循环里 update 么?

这种就可以用 Group 了。

image.png

import { Easing, Group, Tween } from '@tweenjs/tween.js';
const tweenGroup = new Group();
tweenGroup.add(tween, tween2);

这个 Group 是 tweenjs 的,用于管理多个 tween 动画。

tweenGroup.add 把 tween 动画添加到 group,然后 twenGroup.update 统一更新。

2025-04-19 18.50.28.gif

那如果是想让两个动画串行执行呢?

用 chain 方法,比如先执行 tween2 再执行 tween,就是 tween2.chain(tween)

image.png

tween2.chain(tween);
tween2.start();

两个串联成一个,那就只调用 tween2.start 就可以了。

2025-04-19 19.03.44.gif

可以看到,是先执行旋转动画再执行位移动画。

前面我们都是用 Easing.Quadratic.InOut 的缓动效果

其他的所有缓动效果可以从这里查:

image.png

比如 Bounce.Out

image.png

试一下:

image.png

2025-04-19 19.45.54.gif

可以看到,在结束的时候有一个明显的弹动效果。

再试下 Elastic.Out

image.png

image.png

2025-04-19 19.48.09.gif

中间那段动画明显特别快,后面也有个弹动效果。

案例代码上传了小册仓库

总结

这节我们过了一下 Tween.js 的常用特性。

后面我们做很多动画都会用到 tween.js,就会用到 Group、chain、各种缓动函数。

评论