补间动画gsap与tween
# 一.GSAP 是什么
GSAP 是一个十分强大的 动画脚本 ,可以实现大部分的动画需求。
如果你想制作一款十分炫酷、复杂的动画,那么 GSAP 将是很好的选择,如果只是简单的动画,显然 animate 等可能会更适合。
# 二、GSAP 制作动画
# 1.下载导入
npm i gsap
import { gsap } from 'gsap'
1
2
3
4
5
2
3
4
5
# 2. gsap.to
函数签名
gsap.to(targets, second, options)
将一个或多个元素 targets 在指定时间 second 内按一定的速率函数变化至某个指定的 options 状态
可以理解为 ‘到哪里去’ 过程
例 1: 操作变量
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
<div id="animated-number-demo">
<input v-model.number="number" type="number" step="20" />
<p>{{ animatedNumber }}</p>
</div>
1
2
3
4
5
6
2
3
4
5
6
new Vue({
el: '#animated-number-demo',
data: {
number: 0,
tweenedNumber: 0
},
computed: {
animatedNumber: function () {
return this.tweenedNumber.toFixed(0)
}
},
watch: {
number: function (newValue) {
gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue })
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
效果:
例 2: 操作 dom
<h1 class="view">第一行文字</h1>
<h2 class="view">第二行文字</h2>
<h3 class="view">第三行文字</h3>
<!-- 此处定义原状态: -->
<style>
.view {
opacity: 0;
transform: scale(0, 0);
}
</style>
<script>
gsap.to('.view', 0.3, {
autoAlpha: 1, // autoAlpha 为 1 时元素可见,为 0 时元素 visibility: hidden; ,该选项性能优于 opacity 的变化
scale: 1, // 缩放由 0 达到 1
transformOrigin: 'center center', // 动画中心
stagger: 0.1 // 当有多个元素时,可以交错 0.1 秒(如果只有一个元素,无需该项)
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
目的:选择所有 .view 的元素,在 0.3 秒内达到相应的状态。
效果:
# gsap.from
gsap.from 是 gsap.to 的逆过程
上例中也可以用 gsap.from 实现
gsap.from('.view', 0.3, {
autoAlpha: 0,
opacity: 0,
scale: 0,
transformOrigin: 'center center',
stagger: 0.1
})
1
2
3
4
5
6
7
2
3
4
5
6
7
更多用法可以看看 GSAP 官方文档 (opens new window)
# 三、tween
和 gasp.js 类似的还有 tween.js (opens new window)也很适合做动画
这里用 Vue 官方文档的过渡组件例子来演示下
补间动画组间
// 任何整数都可以执行动画
// 组件化使我们的界面十分清晰
// 可以支持更多更复杂的动态过渡策略。
Vue.component('animated-integer', {
template: '<span>{{ tweeningValue }}</span>',
props: {
value: {
type: Number,
required: true
}
},
data: function () {
return {
tweeningValue: 0
}
},
watch: {
value: function (newValue, oldValue) {
this.tween(oldValue, newValue)
}
},
mounted: function () {
this.tween(0, this.value)
},
methods: {
tween: function (startValue, endValue) {
var vm = this
function animate() {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
new TWEEN.Tween({ tweeningValue: startValue })
.to({ tweeningValue: endValue }, 500)
.onUpdate(function () {
vm.tweeningValue = this.tweeningValue.toFixed(0)
})
.start()
animate()
}
}
})
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
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
父组件
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<div id="example-8">
<input v-model.number="firstNumber" type="number" step="20" /> +
<input v-model.number="secondNumber" type="number" step="20" /> = {{ result }}
<p>
<animated-integer v-bind:value="firstNumber"></animated-integer> +
<animated-integer v-bind:value="secondNumber"></animated-integer> =
<animated-integer v-bind:value="result"></animated-integer>
</p>
</div>
<script>
new Vue({
el: '#example-8',
data: {
firstNumber: 20,
secondNumber: 40
},
computed: {
result: function () {
return this.firstNumber + this.secondNumber
}
}
})
</script>
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
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
效果:
上次更新: 2023/04/05, 09:41:10