@Anime

只有想不到,没有动不了 - Animate anything.
除了单独使用外,还可以和 SwiperScrollreveal 配合使用
更多信息,请访问 官网 - animejs
CSS样式动画
通常是根据选择器选中目标 targets 并指定样式 properties
[ ] 旋转并位移标签是 div 的元素
本地下载 - anime.min.js
引入 - 注意路径
<script src="/utils/lib/anime.min.js"></script>
应用动画 - 指定动画目标,设置动画属性、指定背景和动画持续时间
anime({
  targets: 'div',
  translateX: 250,
  rotate: '1turn',
  backgroundColor: '#FFF',
  duration: 800,
  // loop: true,
  // autoplay: true,
  // direction: 'alternate',
  // easing: 'linear'
});
DOM属性动画
DOM元素的任何数值型 Attributes 都可以应用动画 - 仅限于 <input>
[ ] 数值增加 - 利用样式去掉 <input> 的边框
<input type="text" class="num">
anime({
  targets: '.num',
  value: [0, 1000],
  round: 1,
  easing: 'easeInOutExpo'
});
[ ] 改进版数值增加 - 控制动画
封装动画,通过鼠标单击控制播放和停止;封装动画后,可以添加 add 更多动画,参考 时间轴动画 一节
增加循环loop,看看你能不能击中666
const animNum = anime({
  targets: '.num',
  value: [0, 1000],
  round: 1,
  easing: 'easeInOutExpo'
});

let btnPlay = document.querySelector('.btn-play');
let btnPause = document.querySelector('.btn-pause');
btnPlay.addEventListener('click', () => {
  animNum.play();
});
btnPause.addEventListener('click', () => {
  animNum.pause();
});    
关键帧动画 keyframes
通过数组指定若干关键帧实现各帧之间的过渡动画
如果没有指定时间 duration,则每帧动画时间相等
anime({
  targets: '.rect div',
  keyframes: [
    { translateX: 80 },
    { translateY: 170 },
    { translateX: -80 },
    { translateY: 0 }
  ],
  duration: 2000,
  loop: true
})
交错动画 Staggering
适合 多个元素;效果惊人。。。
多用于指定延迟:可以指定起始值 start、从何值开始 from、方向 direction、区间 values[]、网格 grid 和 坐标轴 axis等
[ ] 涟漪 - grid
基于2维数组 based a 2D array
anime.stagger(value, {grid: [rows, columns]}, from: '')
  anime({
    targets: '.grid-anime span',
    scale: [
      { value: .1, easing: 'easeOutSine', duration: 500 },
      { value: 1, easing: 'easeInOutQuad', duration: 1200 }
    ],
    delay: anime.stagger(200, { grid: [14, 9], from: 'center' }),
    loop: true,
  });
时间轴动画 timeline
控制多个元素
默认后面添加的动画在前面播放结束后才开始
[ ]综合动画

创建动画 - 指定基本属性

let timelineAnime = anime.timeline({
  targets: '.timeline-anime span',
  easing: 'easeInOutExpo',
  delay: anime.stagger(200, { grid: [14, 9], from: 'center' }),
  loop: true,
});

添加动画

timelineAnime.add({
  rotateZ: 180,
  translateY: anime.stagger(-10, { grid: [14, 9], from: 'center', axis: 'y' }),
  translateX: anime.stagger(-10, { grid: [14, 9], from: 'center', axis: 'x' }),
})
timelineAnime.add({
  borderRadius: 50
})
timelineAnime.add({
  scale: 0.2,
  opacity: 0.2
})
timelineAnime.add({
  opacity: 1,
  scale: [
    { value: .1, easing: 'easeOutSine', duration: 100 },
    { value: 1, easing: 'easeInOutQuad', duration: 500 }
  ],
  delay: anime.stagger(100, { grid: [14, 9], from: 'center' }),
})
timelineAnime.add({
  rotateZ: 180,
  translateY: anime.stagger(0, { grid: [14, 9], from: 'center', axis: 'y' }),
  translateX: anime.stagger(0, { grid: [14, 9], from: 'center', axis: 'x' }),
})
timelineAnime.add({
  borderRadius: 0
})
[ ] 综合动画
动态生成DOM节点 .bar
在弹性容器内水平垂直居中 - 便于随机分布
封装函数;结束 complete 时,重复调用
获取随机位置 anime.random()
let barAnime = () => {
  anime({
    targets: '.bar',
    translateX: () => anime.random(-1024, 1024),
    translateY: () => anime.random(-120, 120),
    scale: () => anime.random(1, 5),
    easing: 'linear',
    delay: anime.stagger(10),
    duration: 3000,
    complete: barAnime
  })
}
barAnime()
飞翔的文字
如何使用滤镜 filter?