gsap动画在vue中使用(绿袜子)

602 阅读5分钟

一、基本使用

官网:Easing | GSAP | Docs & Learning
中文文档:GSAP 中文教程 中文文档 |官方文档 官方教程翻译 |好奇代码出品

1、安装

npm install gsap

2、引入

import gsap  from 'gsap';

3、基本使用

注意:将GSAP代码放在mounted 钩子中

<div class="regin"></div>

const gsap_animation = () => {
    gsap.from('.region', { rotation: 360, x: 100, duration: 1 })
}

onMounted(() => {
    gsap_animation()
})  

二、动画属性

属性名属性
xx 轴位移
rotation旋转
transformOrigin旋转中心(50% 50%)
duration持续时间(秒)
delay延迟(秒)
stagger交错时间(秒)(0.1:表示每个元素启动时间为0.1秒)
yPercent根据自己大小,向y轴移动的百分比
pausedtrue:时间线创建时处于暂停状态
repeat重复次数(-1:无限循环)
scale缩放
yoyotrue:动画将来回播放,即在达到终点后反向播放
ease运动方式

easa 运动方式详见:Easing | GSAP | Docs & Learning


ease属性
elastic弹性
strong.inOut强烈的先快后慢
power1.out渐缓(默认值)

三、时间线

1、时间线

// create a timeline  
let tl = gsap.timeline()  
//var tl = gsap.timeline({defaults: {duration: 1}});默认所有动画持续时间为1秒
  
// add the tweens to the timeline - Note we're using tl.to not gsap.to  
tl.to(".green", { x: 600, duration: 2 });  
tl.to(".purple", { x: 600, duration: 1 });  
tl.to(".orange", { x: 600, duration: 1 });
tl.to(".purple", { x: 600, duration: 1 }, "<"); //"<"详细见下文解释
  • "1":过一秒开始
  • "<":上一个动画开始处
  • "+=1":上一个动画结束后1秒
  • "-=1":上一个动画结束前1秒
  • "+=50%":
  • "-=25%":

2、控制

let tween = gsap.to("#logo", {duration: 1, x: 100});
tween.play(); //开始
tween.pause(); //暂停
tween.resume(); //重新开始
tween.reverse(); //反方向(回到起点)
tween.seek(0.5); //将时间线上的动画播放位置移动到0.5秒的位置
tween.progress(0.25); //在动画开始的25%处停止
tween.timeScale(1); //时间线缩放比例,等于1原速,大于1加速,小于1减速
tween.kill(); //立即停止,重置到初始状态
tween.revert(); // 清除动画,回到初始位置常在onMounted中使用

tween.timeScale(2).reverse(); //可以多个连用

3、回调

-   **onComplete**: 动画结束时,执行的回调
-   **onStart**: 动画开始
-   **onUpdate**: 动画更新
-   **onRepeat**: 重复调用时
-   **onReverseComplete**: 动画反转时调用

gsap.to(".class", {  duration: 1,  x: 100,  
onComplete: () => console.log("the tween is complete")   });  
  
//使用时间线的写法
gsap.timeline({onComplete: tlComplete}); 

function tlComplete() {  
console.log("the tl is complete");  
}

四、插件使用(学习中。。。。。。)

  • ScrollTrigger:用于创建滚动相关的触发动画。
  • Draggable:拖拽。
  • MorphSVGPlugin:用于创建SVG形状之间的平滑过渡动画,沿着路径的动画。
  • 使用 motionPath 可以规定任何对象沿路径运动。motionPath可以为:一个 SVG <path> 元素
ScrollTrigger属性属性值
trigger元素进入视口时触发
scrub动画速度(2表示正常速度的两倍)
markers开发期间,显示动画开始结束位置(true / false)
start动画开始位置(top 30%)
end动画结束位置(top 20%)
Draggable属性属性值
bounds拖动元素(限制在body内)
inertia惯性效果(true)
type表示拖动操作会导致元素比变化(rotation:旋转/)
motionPath属性属性值
path定义动画轨迹([{ x: 0, y: 0 }, { x: 80, y: 0 }, { x: 80, y: 100 }, { x: 100, y: 100 }])
type指定路径的类型,(cubic:路径将被视为三次贝塞尔曲线)
align指定路径的对齐方式(#lineAB)
distance控制当前元素基于 offset-path 运动的距离
position指定初始位置
anchor定义锚点。 运动的元素可能不是一个点,需要指定元素中的哪个点附着在路径上进行运动
rotate定位时元素的方向
offsetX / offsetY微调,(、start / end 开始和结束,控制进度、resolution增加 resolution 的值会增加分解的精度,默认值为 12、)
curviness(1.5)弯曲的程度
resolution增加值会增加分解的精度,默认值为 12
//可在官网文档中查看引入方法,挺好用的
import gsap from 'gsap'
import { ScrollTrigger } from "gsap/ScrollTrigger";
//注册插件
gsap.registerPlugin(MotionPathPlugin, ScrollTrigger, MorphSVGPlugin);
//使用插件(参考官网案例)
<div class="box green">123</div>
///////滚动
gsap.to(".greeen"{
  rotation: 900,
  duration: 1,
  ScrollTrigger:{
     trigger: '.box', 
     scrub: 2,
     markers: true,
  }
})

///////拖动
Draggable.create(".orange", { inertia: true, type: "rotation", bounds: "body" });

////////使用MotionPathPlugin 沿 SVG 路径制作动画元素
gsap.to('div',{
        duration: 2,
        motionPath: {
            path: [{ x: 0, y: 0 }, { x: 20, y: 0 }, { x: 30, y: 50 }, { x: 50, y: 50 }],
            type: "cubic",
            align: "#lineAB"
        }
})




五、案例

案例一(参考gsap官网案例):鼠标移入出现,移出消失

dinolloss.event.com.cn/movie/gsap%… image.png 思路:

  1. 布局:两张图作为父子元素的背景,标题和内容用兄弟元素排列
  2. 初始状态:内容隐藏掉 { yPercent: 100 };
  3. icon改变父元素透明度,内容改变位移
  4. 移出时 反向
<template>
    <div class="pages">
        <div class="region" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
            <div class="icon-bg">
                <div class="icon" id="icon"></div>
            </div>
            <div class="card">
                <div class="title">标题</div>
                <div class="content" id="content">这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</div>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">
import gsap from 'gsap'
import { ref, onMounted } from 'vue'

// 鼠标移入事件
const handleMouseEnter = () => {
    console.log("移入");
    gsap_animation().timeScale(1).play()
}
//鼠标移出事件
const handleMouseLeave = () => {
    console.log("移出");
    gsap_animation().timeScale(3).reverse()
}
// 写一个方法
let tl = gsap.timeline()
const gsap_animation = () => {
    tl.to('#icon', {
        opacity: 0
    })
    tl.to('#content', { yPercent: 0 })
    return tl
}

onMounted(() => {
    //gsap.set 设置元素初始状态
    gsap.set("#content", { yPercent: 100 });
})



</script>
<style scoped lang="scss">
.pages {
    display: flex;
    // justify-content: center;
    align-items: center;
    flex-direction: column;

    .region {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        // width: 100px;
        // background-color: red;
    }

    .region2 {
        width: 100px;
        height: 100px;
        background-color: rgb(0, 134, 7);
    }

    .icon-bg {
        width: 20vw;
        height: 25vw;
        // border: 1px solid red;
        background-size: 100% 100%;
        background-image: url('https://assets.pokemon.com/assets/cms2/img/pokedex/full/001.png');

        .icon {
            width: 20vw;
            height: 25vw;
            background-size: 100% 100%;
            background-image: url('https://assets.codepen.io/16327/001-silhouette.png');
        }
    }

    .card {
        width: 40vw;
        height: 60vw;
        // border: 1px solid red;
        overflow: hidden;
        position: relative;
        box-shadow: 0px 0px 12px -1px black;

        .title {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 100%;
            font-size: 30px;
            font-weight: 600;
            background-color: antiquewhite;
        }

        .content {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            font-size: 20px;
            font-weight: 400;
            background-color: rgb(255, 152, 16);
            z-index: 2;
        }
    }
}
</style>
案例二:使用svg(学习中。。。。。。)