认识动画
App.vue
<template>
<div>
//对单个元素,直接用transition进行包裹
//写上name就可以在style写动画了
<transition name="why">
<h2 v-if="isShow">Hello</h2>
</transition>
</div>
</template>
<script>
import
export default{
data(){
return{
isShow:true
}
}
}
</script>
<style scoped>
进来的时候透明度为0,出去的时候透明度为1
.why-enter-from,
.why-leave-to{
透明度
opacity:0; 透明
}
.why-enter-to,
.why-leave-from{
opacity:1; 显示
}
.why-enter-active,
.why-leave-active{
对opacity进行过度,2秒,
transition:opacity 2s ease;
}
</style>
css过渡动画
App.vue
<template>
<div>
//对单个元素,直接用transition进行包裹
//写上name就可以在style写动画了
<transition name="why">
<h2 v-if="isShow">Hello</h2>
</transition>
</div>
</template>
<script>
import
export default{
data(){
return{
isShow:true
}
}
}
</script>
<style scoped>
.why-enter-active,{
动画,1s,动画执行曲线
animation:bounce 1s ease
}
.why-leave-active,{
动画,1s,动画执行曲线,动画翻转,离开和bounce相反的时候
animation:bounce 1s ease reverse
}
//帧动画
@keyframes bounce{
0%{
transform:scale(0) 缩放程度是0
}
50%{
transform:scale(1.2)
}
100%{
transform:scale(1)
}
}
</style>
同时设置过度和动画(transition和animation)
既有大小缩放变化,又有透明度变化
<template>
<div>
//对单个元素,直接用transition进行包裹
//写上name就可以在style写动画了
//根据transition来决定动画时间结束
<transition name="why" type="transition">
<h2 v-if="isShow">Hello</h2>
</transition>
</div>
</template>
<script>
import
export default{
data(){
return{
isShow:true
}
}
}
</script>
<style scoped>
.why-enter-from,
.why-leave-to{
透明度
opacity:0; 透明
}
.why-enter-active,
.why-leave-active{
transition:opacity 1s ease;
}
.why-enter-active,{
动画,1s,动画执行曲线
animation:bounce 1s ease;
}
.why-leave-active,{
动画,1s,动画执行曲线,动画翻转,离开和bounce相反的时候
animation:bounce 1s ease reverse;
}
//帧动画
@keyframes bounce{
0%{
transform:scale(0) 缩放程度是0
}
50%{
transform:scale(1.2)
}
100%{
transform:scale(1)
}
}
</style>
显示的指定动画时间
<transition
name="why"
type="transition"
:duration="1000">
:duration用来设置指定时间,这个时候style里设置的时间就失效了
也可以指定某个动作的时间
过度的模式mode
<template>
<div>
mode="in-out"等到我进入动画结束后,才开始离开动画
out-in:相反
<transition name="why" mode="in-out">
<h2 v-if="isShow">Hello</h2>
</transition>
</div>
</template>
<component>动态组件切换
appear 表示 一打开页面,就展示动画效果
结合三方库
npm install animate.css
<template>
<div>
//对单个元素,直接用transition进行包裹
//写上name就可以在style写动画了
//根据transition来决定动画时间结束
<transition
enter-active-class="animate__animated animate__fadeIndown
"
>
<h2 v-if="isShow">Hello</h2>
</transition>
</div>
</template>
<script>
import
export default{
data(){
return{
isShow:true
}
}
}
</script>
<style scoped>
.why-enter-active{
animation:bounceInUp 1s ease-in;
}
.why-leave-active{
//使用库提供的
animation:bounceInUp 1s ease-in reverse;
}
</style>
gsap库
npm install gsap
<transition @before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@afterLeave="afterLeave"
:css="false" 跳过css的检测
>
<h2></h2>
methods:{
beforeEnter(){}
指:从某一个地方,达到某一个状态
enter(element,done){
gsap.from(element,{
缩放scale:0,
x:200 等价于=> translate=200
当我们动画执行完后,会执行这个回调下一个函数
onComplete:done
})
}
afterEnter(){}
beforeLeave(){}
leave(el,done){
gsap.to(el,{
scale:0,
x:200
onComplete:done
})
}
afterLeave(){}
}
gsap实现数字变化
<template>
<div class="app">
<input type="number" step="100" v-model="counter">
<!-- <h2>当前计数: {{showCounter}}</h2> -->
//toFixed:不保留小数点
<h2>当前计数: {{showNumber.toFixed(0)}}</h2>
</div>
</template>
<script>
import gsap from 'gsap';
export default {
data() {
return {
counter: 0,
showNumber: 0
}
},
// computed: {
// showCounter() {
// return this.showNumber.toFixed(0);
// }
// },
watch: {
counter(newValue) {
gsap.to(this, {duration: 1, showNumber: newValue})
}
}
}
</script>
<style scoped>
</style>
列表的过渡
App.vue
<template>
<div>
<button @click="addNum"></button>
<button @click="removeNum"></button>
<transition-group tag="p" name="why">
<span v-for="item in numbers" :key="item">
{{item}}
</span>
</transition-group>
</div>
</template>
<script>
import
export default{
components:{
}
data(){
return{
numbers:[0,1,2,3,4,5,6,7,8,9]
numCounter:10
}
},
methods:{
addNum(){
//随机添加到某一位置
//1:位置,2:删除几个,3:添加的
this.numbers.splice(
this.randomIndex(),
0,
this.numCounter++)
},
removeNum(){
this.numbers.splice(this.randomIndex(),1)
},
randomIndex(){
return
Math.floor(
Math.random()*this.numbers.length)
}
}
}
</script>
<style>
.item{
margin-right:10px;
//span标签是行内的,所以添加Y动画会限制,需要改为inline-block
display:inline-block;
}
.why-enter-from,
.why-leave-to{
opacity:0;
transform:translateY(30px;)从Y=30的坐标来
},
//因为enter-leave和leave-from的透明效果是1,所以不用写了
.why-enter.active,
.why-leave.active{
transition:all 1s ease;
}
</style>
列表过渡的移动动画
npm install lodash
App.vue
<template>
<div>
<button @click="addNum">添加数字</button>
<button @click="removeNum">删除数字</button>
<button @click="shuffleNum">数字洗牌</button>
<transition-group tag="p" name="why">
<span v-for="item in numbers" :key="item">
{{item}}
</span>
</transition-group>
</div>
</template>
<script>
import
export default{
components:{
}
data(){
return{
numbers:[0,1,2,3,4,5,6,7,8,9]
numCounter:10
}
},
methods:{
addNum(){
//随机添加到某一位置
//1:位置,2:删除几个,3:添加的
this.numbers.splice(
this.randomIndex(),
0,
this.numCounter++)
},
removeNum(){
this.numbers.splice(this.randomIndex(),1)
},
randomIndex(){
return
Math.floor(
Math.random()*this.numbers.length)
},
shuffleNum(){
//数字洗牌,然后生成新数组
this.numbers = _.shuffle(this.numbers)
}
}
}
</script>
<style>
.item{
margin-right:10px;
//span标签是行内的,所以添加Y动画会限制,需要改为inline-block
display:inline-block;
}
.why-enter-from,
.why-leave-to{
opacity:0;
transform:translateY(30px;)从Y=30的坐标来
},
//因为enter-leave和leave-from的透明效果是1,所以不用写了
.why-enter.active,
.why-leave.active{
transition:all 1s ease;
}
.why-leave.active{
移除的时候,其实还在占着位置,其他数字想要移动的时候会卡住
position:absolute 脱离标准流
}
.why-move{
位移动画
transition:transform;
}
</style>
列表的交错过渡案例
<template>
<div>
<input v-model="keyword">
<transition-group tag="ul" name="why" :css="false"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave">
<li v-for="(item, index) in showNames" :key="item" :data-index="index">
{{item}}
</li>
</transition-group>
</div>
</template>
<script>
import gsap from 'gsap';
export default {
data() {
return {
names: ["abc", "cba", "nba", "why", "lilei", "hmm", "kobe", "james"],
keyword: ""
}
},
computed: {
showNames() {
//item为true才会保留在数组中,false的筛选掉
return this.names.filter(item => item.indexOf(this.keyword) !== -1)
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0;
el.style.height = 0;
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
height: "1.5em",
delay: el.dataset.index * 0.5,
onComplete: done
})
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
height: 0,
delay: el.dataset.index * 0.5,
onComplete: done
})
}
}
}
</script>
<style scoped>
/* .why-enter-from,
.why-leave-to {
opacity: 0;
}
.why-enter-active,
.why-leave-active {
transition: opacity 1s ease;
} */
</style>