背景
一般常用还有Animate.css,但是那个不够灵活,js动画更加灵活,可以动态给组件添加动画,以及动画设置成动态的属性,比如右移100px,这个100px不是写死的而是动态的。
=====================
安装
npm install gsap
引入
在需要使用的页面中引入
使用
一般会在Vue 的内置的 transition 组件,的动画生命周期函数里面使用,如下例子
transition 组件 和 动画生命周期可以查看:https://www.yuque.com/yejielin/mypn47/qyoykq#ZBnFH
使用gsap对象:gsap.方法( 目标组件或元素 , { 选项 })
<template><div class="app"><div><button @click="isShow = !isShow">显示/隐藏</button></div><!-- 这里是Vue内置组件transition --><transition @enter="enter"@leave="leave":css="false"><h2 class="title" v-if="isShow">Hello World</h2></transition></div></template><script>// 引入import gsap from 'gsap';export default {data() {return {isShow: true,}},methods: {// Vue内置组件transition的动画生命周期,这里是组件出现时执行函数enter(el, done) { // 这里的参数el就是h2元素console.log("enter");// 使用gsap,from是定义开始时的状态gsap.from(el, { // el正好可以在这里使用scale: 0,x: 200,onComplete: done // 完成时,调用done方法})},// Vue内置组件transition的动画生命周期,这里是组件消失时执行函数leave(el, done) {console.log("leave");// 使用gsap,to是定义结束时的状态gsap.to(el, {scale: 0,x: 200,onComplete: done})}}}</script><style scoped>.title {display: inline-block;}</style>
选项对象

详细的可以查看 https://greensock.com/docs/v3/GSAP/gsap.from()),里面的Special Properties
====================
效果案例
数字变化
在一些项目中,我们会见到数字快速变化的动画效果,这个动画可以很容易通过gsap来实现:

<template><div class="app"><input type="number" step="100" v-model="counter"><h2>当前计数: {{showNumber.toFixed(0)}}</h2></div></template><script>import gsap from 'gsap';export default {data() {return {counter: 0,showNumber: 0}},watch: {counter(newValue) {gsap.to(this, {duration: 1, showNumber: newValue})}}}</script><style scoped></style>
列表过渡的移动动画

<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" class="item">{{item}}</span></transition-group></div></template><script>import _ from 'lodash'; // lodash库,增加了很多函数、对象、数组的使用方法export default {data() {return {numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],numCounter: 10}},methods: {addNum() {// this.numbers.push(this.numCounter++) // 这样是添加到最后this.numbers.splice(this.randomIndex(), 0, this.numCounter++) // 这里是随机插入元素},removeNum() {this.numbers.splice(this.randomIndex(), 1) // 随机删除元素},shuffleNum() {this.numbers = _.shuffle(this.numbers); // .shuffle 创建一个被打乱值的集合},randomIndex() {return Math.floor(Math.random() * this.numbers.length)}},}</script><style scoped>.item {margin-right: 10px;display: inline-block; /* inline一般会有很多限制,建议使用inline-block */}/* 这样会插入、删除时,会有往上插入和往下消失的效果 */.why-enter-from,.why-leave-to {opacity: 0;transform: translateY(30px);}.why-enter-active,.why-leave-active {transition: all 1s ease;/* ease 是运动曲线,是匀速运动*/}/* 名字-move 的class,是vue定义的位移的动画,方便我们操作,不管怎么位移都可以套用这个动画效果*/.why-move {transition: transform 1s ease; /* 这里是位移时间1秒,而不是瞬间跳过去完成 */}/* 原本移除的时候会有问题,移除动画结束前,元素都会占据DOM空间,因此播放完动画,其他元素才会过来 *//* 移除的动画时,设置成绝对定位,脱离标准流,就没有这个问题 */.why-leave-active {position: absolute;}</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() {// 过滤后的显示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",// 延迟执行,每个li都比上一个多0.5秒// 所有绑定的属性(如例子里li的data-index属性),都会绑定在el.dataset里面delay: el.dataset.index * 0.5,onComplete: done})},leave(el, done) {gsap.to(el, {opacity: 0,height: 0,// 延迟执行,每个li都比上一个多0.5秒// 所有绑定的属性(如例子里li的data-index属性),都会绑定在el.dataset里面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>
