JavaScript动画库:Anime.js

前言

今天简单学习一下JavaScript动画库:Anime.js。官网的介绍是:

Anime.js (/ˈæn.ə.meɪ/) 是一个轻量的JavaScript 动画库, 拥有简单而强大的API。
可对 CSS 属性、 SVG、 DOM 和JavaScript 对象进行动画。
开源、免费、极小、简单易用

中文文档:https://www.animejs.cn/

下面会按照官方文档的顺序进行简单学习。

安装及引入

安装

npm install animejs --save

引入

import anime from 'animejs';

如果你像我一样用的是ts 那么你还需要下载

npm i --save-dev @types/animejs

动画的目标对象

CSS选择器

<div class="item"> </div>
<el-button type="primary" @click="move">移动</el-button>

let move = () => {
    
    
    anime({
    
    
        targets: '.item',
        translateX: 250
    })
}

在这里插入图片描述
通过.item 类获取到该元素,让后使其水平移动250px

DOM元素 /元素序列

使用DOM节点或节点的集合作为动画目标

let move = () => {
    
    
    let elements = document.querySelectorAll('.item');
    anime({
    
    
        targets: elements,
        translateX: 250
    })
}

在这里插入图片描述

数组

以数组作为动画目标。

let move = () => {
    
    
    anime({
    
    
        targets: ['.item1', '.item2'],
        translateX: 250
    })
}

在这里插入图片描述

可动画的目标属性

css属性

对目标的CSS属性进行动画

这里官网提示我们:大多数CSS属性都会导致布局更改或重新绘制,并会导致动画不稳定。 因此尽可能优先考虑opacity和CSS transforms。
一些常见的会引起重绘的属性比如:widthheighttopleftrightbottom

let move = () => {
    
    
    anime({
    
    
        targets: '.item',
        left: '240px',
        backgroundColor: 'blue',
        borderRadius: ['0%', '50%'],
        easing: 'easeInOutQuad'
    })
}

在这里插入图片描述

CSS3 TRANSFORMS 属性

针对CSS的transforms属性动画。单位可以省略。

 anime({
    
    
     targets: '.item',
     translateX: 300,
     scale: 2,
     easing: 'easeInOutQuad'
 })

在这里插入图片描述

JAVASCRIPT对象属性

包含数值的任何Object属性都可以设置动画。

    var objPropLogEl = document.querySelector('.item');

    var myObject = {
    
    
        prop1: 0,
        prop2: '0%'
    }

    anime({
    
    
        targets: myObject,
        prop1: 50,
        prop2: '100%',
        easing: 'linear',
        round: 1,
        update: function () {
    
    
            objPropLogEl.innerHTML = myObject.prop1 + '    ' + myObject.prop2;
        }
    });
}

在这里插入图片描述

DOM属性

任何包含数值的DOM属性都可以设置动画。

anime({
    
    
  targets: '.dom-attribute-demo input',
  value: [0, 1000],
  round: 1,
  easing: 'easeInOutExpo'
});

在这里插入图片描述

SVG属性

与任何其他DOM属性一样,包含至少一个数值的所有SVG属性都可以设置动画。

anime({
    
    
  targets: ['.svg-attributes-demo polygon', 'feTurbulence', 'feDisplacementMap'],
  points: '64 128 8.574 96 8.574 32 64 0 119.426 32 119.426 96',
  baseFrequency: 0,
  scale: 1,
  loop: true,
  direction: 'alternate',
  easing: 'easeInOutExpo'
});

在这里插入图片描述

动画基础参数

duration: 持续时间,默认1000毫秒

anime({
    
    
     targets: '.item',
     translateX: 300,
     duration: 3000
 });

delay: 延迟,默认0毫秒

endDelay: 末端延时,默认0毫秒

easing: 时间曲线,默认值easeOutElastic(1, .5),有些值不清楚,可以自己看一下文档
可选值:

  • linear (匀速)

  • 不匀速
    在这里插入图片描述

  • 三次贝塞尔,比如:easing: 'cubicBezier(.5, .05, .1, .3)',这名词是啥我也不清楚。

  • 弹簧,这也不太清楚,具体见:弹簧

  • 弹跳,不清楚,具体见:弹跳

  • 台阶,定义动画到达其结束值所需的跳转次数,例如: easing: 'steps(5)'

  • 自定义,通过函数返回当前动画的时间

anime({
    
    
  targets: '.custom-easing-demo .el',
  translateX: 270,
  direction: 'alternate',
  loop: true,
  duration: 2000,
  easing: function(el, i, total) {
    
    
    return function(t) {
    
    
      return Math.pow(Math.sin(t * (i + 1)), total);
    }
  }
});

在这里插入图片描述

round: 四舍五入,说实话没太弄明白,不过1的时候没有小数点

anime({
    
    
     targets: '.item',
     innerHTML: [0, 100],
     easing: 'linear',
     round: 1,
     duration: 2000
 });

在这里插入图片描述
特殊属性
使用Object作为值为动画的每个属性定义特定参数。未在Object中指定的其他属性继承自主动画。

anime({
    
    
  targets: '.specific-prop-params-demo .el',
  translateX: {
    
    
    value: 250,
    duration: 800
  },
  rotate: {
    
    
    value: 360,
    duration: 1800,
    easing: 'easeInOutSine'
  },
  scale: {
    
    
    value: 2,
    duration: 1600,
    delay: 800,
    easing: 'easeInOutQuart'
  },
  delay: 250 
});

先在800毫秒内平移250px,然后在1800毫秒内旋转360度,最后放大两倍
在这里插入图片描述

函数
为动画的每个目标和属性设置不同的值。函数接收三个参数,分别是:

  • target,目标元素
  • index,动画目标的索引
  • targetsLength,总动画目标数
anime({
    
    
  targets: '.function-based-params-demo .el',
  translateX: 270,
  direction: 'alternate',
  loop: true,
  delay: function(el, i, l) {
    
    
    return i * 100;
  },
  endDelay: function(el, i, l) {
    
    
    return (l - i) * 100;
  }
});

方向和循环

direction: 方向
normal,正方向动画;reverse,反方向动画;alternate往返动画

loop: 循环,可以是具体的次数。如果是true则表示无限循环

autoplay: 自动播放,truefalse

动画赋值方式

无单位赋值

前面已经说过了对于px之类的单位可以省略,例如

anime({
    
    
  targets: '.unitless-values-demo .el',
  translateX: 250, // -> '250px'
  rotate: 540 // -> '540deg'
});

有单位数值
强制动画使用某个单位并自动转换初始目标值。

想对数值
添加,减去或乘以原始值。有+=-=*= 这三个值
例如宽度变为原来的两倍,宽度减少50px

 anime({
    
    
     targets: '.item',
     width: {
    
    
         value: '*=2',
         duration: 1800,
         easing: 'easeInOutSine'
     },
     height: {
    
    
         value: '-=50px',
         duration: 1000,
         delay: 1800,
         easing: 'easeInOutSine'
     }
 });

在这里插入图片描述
颜色
anime.js 接受并转换Haxadecimal(十六进制),RGB,RGBA,HSL和HSLA颜色值。注:不支持颜色名称,比如red

示例

.item {
    
    
    position: relative;
    width: 100px;
    height: 100px;
    margin-bottom: 10px;
    background-color: #61afff;
}

 anime.timeline({
    
    
        endDelay: 1000,
        easing: 'easeInOutQuad',
        direction: 'alternate',
        loop: true
    })
        .add({
    
     targets: '.item', background: '#555851' }, 0)
        .add({
    
     targets: '.item', translateX: 270 }, 0);

在这里插入图片描述
设定动画初始值
强制动画以指定值开始。必须以数组的形式给定,第一个元素是起始值,第二个元素是终止值

anime({
    
    
  targets: '.el.from-to-values',
  translateX: [100, 250], // from 100 to 250
  delay: 500,
  direction: 'alternate',
  loop: true
});

关键帧

动画关键帧
动画关键帧是使用keyframes属性中的数组定义的。如果关键帧内没有指定duration(持续时间),则每个关键帧的持续时间将等于动画总持续时间除以关键帧数。

anime({
    
    
        targets: '.item',
        keyframes: [
            {
    
     translateY: -40, duration: 1000 },
            {
    
     translateX: 250, duration: 1000 },
            {
    
     translateY: 40, duration: 1000 },
            {
    
     translateX: 0, duration: 500 },
            {
    
     translateY: 0, duration: 500 }
        ],
        duration: 4000,
        easing: 'easeOutElastic(1, .8)',
        loop: true
    })

在这里插入图片描述
属性关键帧

与动画关键帧类似,属性关键帧是使用属性对象的Array定义的。 属性关键帧允许重叠动画,因为每个属性都有自己的关键帧数组。
如果关键帧内没有指定duration(持续时间),则每个关键帧的持续时间将等于动画总持续时间除以关键帧数。

官方demo

anime({
    
    
  targets: '.property-keyframes-demo .el',
  translateX: [
    {
    
     value: 250, duration: 1000, delay: 500 },
    {
    
     value: 0, duration: 1000, delay: 500 }
  ],
  translateY: [
    {
    
     value: -40, duration: 500 },
    {
    
     value: 40, duration: 500, delay: 1000 },
    {
    
     value: 0, duration: 500, delay: 1000 }
  ],
  scaleX: [
    {
    
     value: 4, duration: 100, delay: 500, easing: 'easeOutExpo' },
    {
    
     value: 1, duration: 900 },
    {
    
     value: 4, duration: 100, delay: 500, easing: 'easeOutExpo' },
    {
    
     value: 1, duration: 900 }
  ],
  scaleY: [
    {
    
     value: [1.75, 1], duration: 500 },
    {
    
     value: 2, duration: 50, delay: 1000, easing: 'easeOutExpo' },
    {
    
     value: 1, duration: 450 },
    {
    
     value: 1.75, duration: 50, delay: 1000, easing: 'easeOutExpo' },
    {
    
     value: 1, duration: 450 }
  ],
  easing: 'easeOutElastic(1, .8)',
  loop: true
});

在这里插入图片描述

交错动画

基础交错动画

 anime({
    
    
     targets: '.item',
     translateX: 270,
     delay: anime.stagger(1000) // 每个元素的延迟增加1000毫秒。
 })

在这里插入图片描述
设定交错开始值
从特定值开始产生交错效果。

anime({
    
    
  targets: '.staggering-start-value-demo .el',
  translateX: 270,
  delay: anime.stagger(100, {
    
    start: 500}) // 延迟从500ms开始,然后每个元素增加100ms。
});

设定交错范围值
在两个数字之间均匀分配值。

官方demo:

anime({
    
    
  targets: '.range-value-staggering-demo .el',
  translateX: 270,
  rotate: anime.stagger([-360, 360]), // 旋转将在-360deg到360deg之间均匀分布在所有元素之间
  easing: 'easeInOutQuad'
});

在这里插入图片描述

交错动画开始位置
从特定位置开始交错效果。

  • first(默认),从第一个元素开始效果
  • laster,从最后一个元素开始效果
  • center,从中间开始效果
  • index,从指定索引开始效果
anime({
    
    
  targets: '.staggering-from-demo .el',
  translateX: 270,
  delay: anime.stagger(100, {
    
    from: 'center'})   //从中间开始执行效果,然后每个元素增加100毫秒
});

在这里插入图片描述

交错动画方向
更改交错动画的顺序。

  • normal(默认),正常交错方向,从第一个元素到最后一个元素。
  • reverse,倒退交错方向,从最后一个元素到第一个元素
anime({
    
    
  targets: '.staggering-direction-demo .el',
  translateX: 270,
  delay: anime.stagger(100, {
    
    direction: 'reverse'})
});

在这里插入图片描述
交错的时间曲线
使用easing函数设置交错值

anime({
    
    
  targets: '.staggering-easing-demo .el',
  translateX: 270,
  delay: anime.stagger(300, {
    
    easing: 'easeOutQuad'})
});

在这里插入图片描述
网格交错
基于数组的交错值,以产生“波纹”效应。两个值的数组,第一个值是列数,第二个值是行数

anime({
    
    
  targets: '.staggering-grid-demo .el',
  scale: [
    {
    
    value: .1, easing: 'easeOutSine', duration: 500},
    {
    
    value: 1, easing: 'easeInOutQuad', duration: 1200}
  ],
  delay: anime.stagger(200, {
    
    grid: [14, 5], from: 'center'})
});

在这里插入图片描述
网格交错方向
定义网格交错 效果的方向

  • x 沿着x轴
  • y 沿着y轴
anime({
    
    
  targets: '.staggering-axis-grid-demo .el',
  translateX: anime.stagger(10, {
    
    grid: [14, 5], from: 'center', axis: 'x'}),
  translateY: anime.stagger(10, {
    
    grid: [14, 5], from: 'center', axis: 'y'}),
  rotateZ: anime.stagger([0, 90], {
    
    grid: [14, 5], from: 'center', axis: 'x'}),
  delay: anime.stagger(200, {
    
    grid: [14, 5], from: 'center'}),
  easing: 'easeInOutQuad'
});

在这里插入图片描述

时间轴

基础时间轴

时间轴可让你将多个动画同步在一起。
默认情况下,添加到时间轴的每个动画都会在上一个动画结束时开始。

创建时间轴

var myTimeline = anime.timeline(parameters);

将动画添加到时间轴

myTimeline.add(parameters, offset);

基本示例

// 使用默认参数创建时间轴
var tl = anime.timeline({
    
    
  easing: 'easeOutExpo',
  duration: 750
});

// 增加子项
tl
.add({
    
    
  targets: '.basic-timeline-demo .el.square',
  translateX: 250,
})
.add({
    
    
  targets: '.basic-timeline-demo .el.circle',
  translateX: 250,
})
.add({
    
    
  targets: '.basic-timeline-demo .el.triangle',
  translateX: 250,
});

在这里插入图片描述

时间轴偏移量

可以使用时间轴的 .add()函数的第二个可选参数指定时间偏移。它定义动画在时间轴中的开始时间,如果未指定偏移,则动画将在上一个动画结束后开始。
偏移可以相对于最后一个动画,也可以相对于整个时间轴。

在这里插入图片描述

// 使用默认参数创建时间轴
var tl = anime.timeline({
    
    
  easing: 'easeOutExpo',
  duration: 750
});

tl
.add({
    
    
  targets: '.offsets-demo .el.square',
  translateX: 250,
})
.add({
    
    
  targets: '.offsets-demo .el.circle',
  translateX: 250,
}, '-=600') // 相对偏移量
.add({
    
    
  targets: '.offsets-demo .el.triangle',
  translateX: 250,
}, 0); // 绝对偏移量

参数继承

父时间轴实例中设置的参数将由所有子项继承。

可被继承的参数: targetsdurationdelayendDelayround

官方示例
先向右平移250;然后放大两倍,透明度变为0.5;接着三角形渲染180度,最后平移回到0

var tl = anime.timeline({
    
    
  targets: '.params-inheritance-demo .el',
  delay: function(el, i) {
    
     return i * 200 },
  duration: 500,
  easing: 'easeOutExpo',
  direction: 'alternate',
  loop: true
});

tl
.add({
    
    
  translateX: 250,
  // override the easing parameter
  easing: 'spring',
})
.add({
    
    
  opacity: .5,
  scale: 2
})
.add({
    
    
  // override the targets parameter
  targets: '.params-inheritance-demo .el.triangle',
  rotate: 180
})
.add({
    
    
  translateX: 0,
  scale: 1
});

在这里插入图片描述

动画控制

播放与暂停

需要将自动播放autoplay 设置为false

//播放
animation.play();
//暂停
animation.pause();

官方示例

var animation = anime({
    
    
  targets: '.play-pause-demo .el',
  translateX: 270,
  delay: function(el, i) {
    
     return i * 100; },
  direction: 'alternate',
  loop: true,
  autoplay: false,
  easing: 'easeInOutSine'
});

document.querySelector('.play-pause-demo .play').onclick = animation.play;
document.querySelector('.play-pause-demo .pause').onclick = animation.pause;

在这里插入图片描述

重新开始

从动画的初始值重新开始动画。

animation.restart();

反转方向

animation.reverse();

瞬移

跳转到特定时间(以毫秒为单位)。

animation.seek(timeStamp);

回调函数(事件)

更新事件

动画开始播放后,每帧都会触发此回调。函数的返回值是当前动画对象

let update = ref(0)
let progress = ref(0)
let move = () => {
    
    
    anime({
    
    
        targets: '.item',
        translateX: 270,
        duration: 1500,
        update: function (anim) {
    
    
            update.value++;
            progress.value = Math.round(anim.progress)
        }
    })
}

在这里插入图片描述

开始和结束事件

当动画开始播放时,begin()回调被触发一次。
动画完成后,会触发一次complete()回调。
如果动画的持续时间为0,则begin()和complete()都会被调用。

 begin: function(anim) {
    
    
    beginLogEl.value = 'began : ' + anim.began;
  },
  complete: function(anim) {
    
    
    completeLogEl.value = 'completed : ' + anim.completed;
  }

循环开始和结束事件

每次循环开始时都会触发一次loopBegin() 回调。
每次循环结束时,就会触发一次loopComplete()回调函数。

loopBegin: function(anim) {
    
    
    loopBegan++;
    beginLogEl.value = 'loop began : ' + loopBegan;
  },
  loopComplete: function(anim) {
    
    
    loopCompleted++;
    completeLogEl.value = 'loop completed : ' + loopCompleted;
  }

改变事件

在动画的delay和endDelay之间的每个帧上触发此回调。
注: 使用该函数需要设置delayendDelay

**var changes = 0;

anime({
    
    
  targets: '.change-demo .el',
  translateX: 270,
  delay: 1000,
  endDelay: 1000,
  direction: 'alternate',
  loop: true,
  easing: 'easeInOutCirc',
  update: function(anim) {
    
    
    progressLogEl.value = 'progress : '+Math.round(anim.progress)+'%';
  },
  change: function() {
    
    
    changes++;
    changeLogEl.value = 'changes : ' + changes;
  }
});**

改变开始事件和改变结束事件

每次动画改变开始时都会触发changeBegin()回调
每次动画改变结束时都会触发changeComplete()回调
动画方向将影响触发changeBegin()和changeComplete()的顺序

注: 使用该函数需要设置delayendDelay

var changeBegan = 0;
var changeCompleted = 0;

anime({
    
    
  targets: '.changeBegin-chnageComplete-demo .el',
  translateX: 240,
  delay: 1000,
  endDelay: 1000,
  loop: true,
  direction: 'alternate',
  easing: 'easeInOutCirc',
  update: function(anim) {
    
    
    progressLogEl.value = 'progress : '+Math.round(anim.progress)+'%';
  },
  changeBegin: function(anim) {
    
    
    changeBegan++;
    beginLogEl.value = 'change began : ' + changeBegan;
  },
  changeComplete: function(anim) {
    
    
    changeCompleted++;
    completeLogEl.value = 'change completed : ' + changeCompleted;
  }
});

SVG动画

略,具体见:svg动画

ANIME.JS方法

删除目标

从正在运行的动画或时间轴中删除目标。targets参数接受与targets 属性相同的值。

anime.remove(targets)

官方示例

anime({
    
    
  targets: '.remove-demo .el',
  translateX: 270,
  direction: 'alternate',
  loop: true,
  easing: 'easeInOutQuad'
});

document.querySelector('.remove-el-button').addEventListener('click', function() {
    
    
  anime.remove('.remove-demo .line:nth-child(2) .el');
});

在这里插入图片描述

其他

略,具体见 ANIME.JS方法

猜你喜欢

转载自blog.csdn.net/weixin_41897680/article/details/126109622