补间动画Tween应用
代码
js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
// 导入 tween
import * as TWEEN from 'three/examples/jsm/libs/tween.module.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
45,
window.innerWidth / window.innerHeight,
0.1,
1000
)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
camera.position.z = 15;
camera.position.y = 2;
camera.position.x = 2;
camera.lookAt(0, 0, 0)
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
function animate() {
requestAnimationFrame(animate)
controls.update()
renderer.render(scene, camera)
// 更新 tween
TWEEN.update()
}
animate()
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, innerHeight)
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
})
let eventObj = {
Fullscreen: function () {
document.body.requestFullscreen()
},
ExitFullscreen: function () {
document.exitFullscreen()
}
}
const gui = new GUI()
gui.add(eventObj, 'Fullscreen').name('全屏')
gui.add(eventObj, 'ExitFullscreen').name('退出全屏')
// 创建球
const sphere1 = new THREE.Mesh(
new THREE.SphereGeometry(1, 32, 32),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
)
sphere1.position.x = -4
scene.add(sphere1)
// 创建补间动画
const tween = new TWEEN.Tween(sphere1.position)
tween.to({ x: 4 }, 2000).onUpdate(() => {
// console.log(sphere1.position.x)
})
// tween.onUpdate(() => {
// console.log(sphere1.position.x)
// })
// 循环往复
// tween.yoyo(true)
// 延时1秒运行
tween.delay(1000)
// 设置缓动函数
tween.easing(TWEEN.Easing.Quadratic.InOut)
// 循环无数次
// tween.repeat(Infinity)
// 循环2次
tween.repeat(2)
const tween2 = new TWEEN.Tween(sphere1.position)
tween2.to({ y: 4 }, 2000)
// 动画间的链接 动画1 链接 动画2
tween.chain(tween2)
// 动画间的链接 动画2 链接 动画1
tween2.chain(tween)
tween2.start()
// 启动补间动画
tween.start()
tween.onStart(() => {
console.log('动画开始')
})
tween.onComplete(() => {
console.log('动画结束')
})
tween.onStop(() => {
console.log('动画停止')
})
tween.onUpdate(() => {
console.log('动画更新')
})
let params = {
stop: function () {
tween.stop()
}
}
gui.add(params, 'stop').name('停止动画')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132