前言
平时上网我经常能在app或者网页上看到很多比较酷的动画效果,这些效果还是比较吸引人的。那么我们自己在写项目时,也都希望能在页面做出一些很酷的动画效果,页面看起来也会更具特色。所以我总结了一些在vue的项目开发中,我们能够实现动画效果的方法,希望能够帮助到大家。以下我已经使用快捷方式创建了一个vue项目,再创建不同页面并引用来展示不同的效果
动画的基本实现
通常我们实现动画效果会用到CSS中的class类,这也是比较基本的方式实现动画。先利用@keyframes
定义一个动画,再在需要实现该动画的DOM结构中使用animation
属性引用该动画。通常我们在animation
属性中会使用到四个值,分别是动画名、动画完成需要的时间、动画的效果、动画循环的次数 ,但其实animation
可以设置的值还有很多,这里我们只使用这四种。@keyframes
定义整个动画的过程,从开始的 0% 到结束的 100% ,中间也能设置其他过程节点,在这些节点上设置不同的属性效果,从而实现动画。这种方式在平时的html中同样适用。
xml
<template>
<div class="box"></div>
</template>
<script>
</script>
<style scoped>
.box{
width: 50px;
height: 50px;
background: rgb(112, 251, 112);
position: relative;
animation: move 2s linear infinite;
}
@keyframes move{
0%{
left:0px;
}
50%{
left:200px;
}
100%{
left: 0px;
}
}
</style>
Vue组件-Transition
<Transition>
是vue的一个内置组件,这意味着它在任意别的组件中都可以直接被使用,无需注册。它可以设置其内部元素进入和离开的动画,主要由 v-if
和 v-show
触发,也可以由特殊元素 <component>
切换的动态组件,或者改变特殊的key属性来触发,原理就是元素的出现和消失,这里我只以v-if
为例。这种方法是由class属性来控制动画的过渡效果,总共有六种用于过渡的class属性(其中 v 指<Transition>
里面的name属性)
markdown
1. `v-enter-from`:进入动画的起始状态。在元素插入之前添加,在元素插入完成后的下一帧移除。
2. `v-enter-active`:进入动画的生效状态。应用于整个进入动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。
3. `v-enter-to`:进入动画的结束状态。在元素插入完成后的下一帧被添加 (也就是 `v-enter-from` 被移除的同时),在过渡或动画完成之后移除。
4. `v-leave-from`:离开动画的起始状态。在离开过渡效果被触发时立即添加,在一帧后被移除。
5. `v-leave-active`:离开动画的生效状态。应用于整个离开动画阶段。在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。
6. `v-leave-to`:离开动画的结束状态。在一个离开动画被触发后的下一帧被添加 (也就是 `v-leave-from` 被移除的同时),在过渡或动画完成之后移除。
xml
<template>
<button @click="toggle">click</button>
<Transition name="fade" >
<h1 v-if="showTitle">你好 vue</h1>
</Transition>
</template>
<script>
import { ref } from 'vue'
export default {
setup () {
let showTitle = ref(true)
const toggle = () =>{
showTitle.value = !showTitle.value
}
return {
showTitle,
toggle
}
}
}
</script>
<style scoped>
.fade-enter-active,.fade-leave-active{
transition: opacity 1s ease;
}
.fade-enter-from,.fade-leave-to{
opacity: 0;
}
.fade-enter-to,.fade-leave-from{
opacity: 1;
}
/* 以下部分在上面动画基础上添加缩放动画效果 */
/* .fade-enter-active{
animation:bounce 1s ease;
}
.fade-leave-active{
animation:bounce 1s ease reverse;
}
@keyframes bounce{
0%{transform:scale(0);}
50%{transform:scale(1.2);}
100%{transform:scale(1);}
} */
</style>
Transition生命周期函数
除了使用class属性控制动画的过渡效果,<Transition>
内还可以使用生命周期方法来控制动画效果,也就是对<Transition>
绑定其特有的事件,事件触发相应的js函数实现动画效果,同样控制元素进入和离开的动画。总共有六个生命周期函数,它们只能被<Transition>
使用:
ini
1. @before-enter=" " //进入前触发
2. @enter=" " //进入期间触发
3. @after-enter=" " //进入后触发
4. @before-leave=" " //离开前触发
5. @leave=" " //离开期间触发
6. @after-leave=" " //离开后触发
(由于js可以设置和控制很多类型的动画,这里没有做详细动画演示,大家可以自己填入设计)
ini
<template>
<button @click="isShow = !isShow">click</button>
<Transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
>
<h1 v-if="isShow">hello vue</h1>
</Transition>
</template>
<script>
import { ref } from 'vue';
export default {
setup () {
const isShow = ref(true)
const beforeEnter = () =>{
}
const enter = () =>{
}
const afterEnter = () =>{
}
const beforeLeave = () =>{
}
const leave = () =>{
}
const afterLeave = () =>{
}
return {
isShow,
beforeEnter,
enter,
afterEnter,
beforeLeave,
leave,
afterLeave
}
}
}
</script>
<style lang="scss" scoped>
</style>
借助第三方库
通过已经封装好的第三方库,我们可以更加方便的实现自己想要的动画效果,这里为大家推荐两个动画库 animate.css 和 GSAP
animate.css
Animate.css | A cross-browser library of CSS animations.
这个动画库里已经封装好了很多可以选择的动画效果,它是通过CSS来实现的。通过 npm 或 yarn 安装就可以引入使用,引入也可以通过 import 或 link 引入,比较方便。使用时,只要在需要动画的元素的class类中加入animate__animated
和相应动画的类名就可以实现动画,也可以配合<Transition>
等使用,达到自己想要的效果。这里配合<Transition>
,直接设置enter-active-class 和 leave-active-class 属性类名,分别表示进入动画和离开动画。
xml
<template>
<button @click="isShow = !isShow">click</button>
<Transition
enter-active-class="animate__animated animate__bounceInDown"
leave-active-class="animate__animated animate__bounce">
<h1 v-if="isShow">hello vue</h1>
</Transition>
</template>
<script>
import { ref } from 'vue';
export default {
setup () {
const isShow = ref(true)
return {
isShow
}
}
}
</script>
<style lang="scss" scoped>
</style>
GSAP
GSAP 中文教程 中文文档 |官方文档 官方教程翻译 |好奇代码出品
和 animate.css 不同,GSAP 是通过js来实现动画的,好处就是一些想到的动画效果是css很难实现的,而js就能更加好地完成。可以通过 npm 安装,也可以直接 CDN 引入,这样就可以在我们的项目中使用这些动画了。这里我们讲里面的 tween 动画类型,也叫补间动画,就是我们常见的两个状态之间的变化的动画方式,比如我们常见的匀速、缓入缓出动画就是Tween类型的动画。总共有四种Tween的动画方式:
-
gsap.to(): 这是一种最常用的tween动画,就是让元素从初始状态变化到目标状态。
-
gsap.from(): 有点像to方法的逆向变化,就是让元素从目标状态变化到初始状态。
-
gsap.fromTo(): 需要自己定义两个状态的数据,然后从前一个变化到后一个。
-
gsap.set():直接设置成想要的状态,没有任何过度与动画效果。本质上就是duration为0的 .to 方法
假如我们创建一个动画,代码为:gsap.to(".box", { x: 200 })
,其中的两个参数分别表示目标和对象参数 ,意思是把带有'.box'类名的元素移动到x为200的位置"(就像transform: translateX(200px))。我们这里配合<Transition>
的生命周期函数完成一个动画:
xml
<template>
<button @click="isShow = !isShow">click</button>
<Transition @enter="enter" @leave="leave">
<h1 v-if="isShow">hello vue</h1>
</Transition>
</template>
<script>
import { ref } from 'vue';
import gsap from 'gsap'
export default {
setup () {
const isShow = ref(true)
const enter = (el,done) =>{
gsap.from(el,{ //el表示目标dom结构,即元素
scale:0, //缩放到0
x:200, // x方向移动200px
onComplete:done //参数done是一个函数,若传入了该参数,就必须调用,表示动画完成,否者看不到动画效果
})
}
const leave = (el,done)=>{
gsap.to(el,{
scale:0,
x:200,
onComplete:done
})
}
return {
isShow,
enter,
leave
}
}
}
</script>
<style lang="scss" scoped>
</style>
再制作一个数字变化加载的动画效果:
xml
<template>
<input type="number" step="100" v-model="counter">
<h1>{{ showNumber }}</h1>
</template>
<script>
import { toRefs, watch, reactive } from 'vue';
import gsap from 'gsap'
export default {
setup () {
const state = reactive({
counter:0,
showNumber:0
})
watch( //监听变量的值的变化
() => state.counter,
(newVal) =>{
gsap.to(state,{duration:1,showNumber:newVal}) //duration的值控制动画的事件
}
)
return {
...toRefs(state)
}
}
}
</script>
<style lang="scss" scoped>
</style>
Transition-group
<transition>
中只能包裹一个元素,当出现需要多个元素时,可以使用<Transition-group>
,下面也简单制作了一个多元素,数据变化的一个动画:
xml
<template>
<div>
<button @click="addNum">add</button>
<button @click="removeNum">remove</button>
<button @click="shuffleNum">shuffle</button>
</div>
<transition-group name="fade">
<span v-for="item in numbers" :key="item">{{ item }}</span>
</transition-group>
</template>
<script setup>
import { ref } from 'vue';
import _ from 'lodash' //先npm安装,再引用
const numbers = ref([0,1,2,3,4,5,6,7,8])
const count = ref(10)
const addNum = ()=>{ //在随机位置添加 count
numbers.value.splice(randomIndex(),0,count.value++)
}
const removeNum = () => { //删除随机一个位置的数
numbers.value.splice(randomIndex(),1)
}
const shuffleNum = () => { //借助lodash库,已经封装的打乱数组的方法
numbers.value = _.shuffle(numbers.value)
}
const randomIndex = () =>{ //随机数方法
return Math.floor(Math.random()*numbers.value.length)
}
</script>
<style scoped>
span{
margin-right: 10px;
display: inline-block;
}
.fade-enter-from,.fade-leave-to{
opacity: 0;
transform: translateY(30px);
}
.fade-enter-active,.fade-leave-active{
transition:all 1s ease
}
.fade-leave-active {
position: absolute;
}
/*移动时的动画效果*/
.fade-move {
transition:transform 1s ease;
}
</style>
总结
制作动画的方法有很多,很多生动的动画效果才能引用人的眼球,希望以上动画的实现方法能够帮助到大家,结合自己的想象,也可以制作更多炫酷的效果。