1、安装
npm install @tweenjs/tween.js
or
yarn add @tweenjs/tween.js
2、变幻的数字案列
<template>
<div class="compA">
<input v-model.number="num" type="number" step="20">
<p>{{ animatedNumber }}</p>
</div>
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
export default {
data () {
return {
num: 0,
animatedNumber: 0
}
},
watch: {
num: function (newValue, oldValue) {
this.myTween(newValue, oldValue)
}
},
methods: {
myTween (newValue, oldValue) {
new TWEEN.Tween({ tweeningValue: oldValue }) // 初始值
.to({ tweeningValue: newValue }, 500) // 最终值
.onUpdate((object) => {
// 在初始值到最终值的过程中会定时给你返回一个数,把这个数挂在要显示的元素上即可
this.animatedNumber = object.tweeningValue.toFixed(0)
})
.start()
this.animate()
},
animate () {
requestAnimationFrame(this.animate)
TWEEN.update()
}
}
}
</script>
<style scoped>
</style>
3、水平滚动的标题
<template>
<div>
<button @click="move">动画</button>
<div ref="myElement" style="position: absolute; left: 50px; top: 150px; font-size: 100px">你好,Tween.js!</div>
</div>
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
export default {
data () {
return {
}
},
methods: {
move () {
const el = this.$refs.myElement
new TWEEN.Tween({ x: 50 })
.to({ x: 200 }, 1500)
.onUpdate(function (obj) {
el.style.left = `${obj.x}px`
})
.start()
this.animate()
},
animate () {
requestAnimationFrame(this.animate)
TWEEN.update()
}
}
}
</script>
<style scoped>
</style>
4、优雅消失的广告牌
<template>
<div>
<button @click="move" class="btn">动画</button>
<div class="ad" ref="myElement">
<img src="../assets/ad.jpeg" alt="">
</div>
</div>
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
export default {
data () {
return {
}
},
methods: {
move () {
const el = this.$refs.myElement
const tweenB = new TWEEN.Tween({ width: 200 })
.to({ width: 0 }, 500)
.onUpdate(function (obj) {
el.style.width = obj.width + 'px'
})
new TWEEN.Tween({ top: 200 })
.to({ top: 220 }, 500)
.onUpdate(function (obj) {
el.style.top = obj.top + 'px'
})
.start()
.chain(tweenB)
this.animate()
},
animate () {
requestAnimationFrame(this.animate)
TWEEN.update()
}
}
}
</script>
<style scoped>
.ad {
position: fixed;
right: 10px;
top: 200px;
width: 200px;
height: 150px;
}
.ad img {
width: 100%;
height: 100%;
}
.btn {
position: fixed;
right: 10px;
top: 150px;
}
</style>
5、丢不掉的广告牌
<template>
<div class="box" ref="box">
<div class="ad" ref="domElement" style="top: 400px">
<img src="../assets/aside.png" alt="">
</div>
</div>
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
export default {
data () {
return {
scrollTop: 0,
baseTop: 400
}
},
watch: {
scrollTop (newVal, oldVal) {
this.move(newVal + this.baseTop)
}
},
methods: {
scroll () {
this.scrollTop = document.documentElement.scrollTop || document.body.scrollTop
},
move (end) {
if (this.tweenA) {
this.tweenA.stop()
}
const el = this.$refs.domElement
const start = el.style.top
this.tweenA = new TWEEN.Tween({ top: parseInt(start) })
.to({ top: end }, 1500)
// 过渡曲线,源码里有很多,可以随意挑选,也可以自定义
.easing(TWEEN.Easing.Quadratic.InOut)
.onUpdate(function (obj) {
el.style.top = `${obj.top}px`
})
.start()
this.animate()
},
animate () {
requestAnimationFrame(this.animate)
TWEEN.update()
}
},
mounted () {
window.addEventListener('scroll', this.scroll)
}
// beforeDestroy () {
// var that = this
// window.removeEventListener('scroll', that.scroll)
// }
}
</script>
<style scoped>
.box {
width: 100%;
height: 5000px;
}
.ad {
position: absolute;
left: 10px;
width: 300px;
}
.ad img {
width: 100%;
height: 100%;
}
</style>
6、多物体缓动运动
<template>
<div>
<div class="box" v-for="(item, index) in 3" :key="index"></div>
</div>
</template>
<script>
import TWEEN from '@tweenjs/tween.js'
export default {
data () {
return {
}
},
methods: {
bindEvent () {
const that = this
const els = document.querySelectorAll('.box')
for (let i = 0; i < els.length; i++) {
els[i].onmouseover = function () {
that.changeStatus(this, 600)
}
els[i].onmouseout = function () {
that.changeStatus(this, 300)
}
}
},
changeStatus (obj, end) {
if (obj.tween) {
obj.tween.stop()
}
obj.tween = new TWEEN.Tween({ x: parseInt(this.getStyle(obj, 'width')) })
.to({ x: end })
// .easing(TWEEN.Easing.Quadratic.InOut)
.onUpdate((object) => {
obj.style.width = `${object.x}px`
})
.start()
this.animate()
},
animate () {
requestAnimationFrame(this.animate)
TWEEN.update()
},
/**
* 获取元素属性的值
* obj: 当前元素对象
* attr: 当前元素对象属性
*/
getStyle (obj, attr) {
if (obj.currentStyle) {
// 兼容ie
return obj.currentStyle[attr];
} else {
// 主流浏览器
return getComputedStyle(obj, null)[attr]
}
}
},
mounted () {
this.bindEvent()
}
}
</script>
<style scoped>
.box {
width: 300px;
height: 100px;
margin: 10px 0;
background-color: coral;
display: flex;
justify-content: center;
align-items: center;
}
</style>