朋友,这里有个仓库需要你 PR 一下

前段时间,发布了一篇文章:学不动了,来点有趣的吧。发现 github 仓库被 frok 了很多次,因此下定决心要好好的把代码整理一下,方便大家查看代码以及更加愉快的 Pull Request

简介

该项目名叫 matrixchange ,编写的目的在于方便开发者实现矩阵动画,当然该项目已经发布到 npm ,使用 npm/yarn 安装即可。

该库为开发者提供了一个数组和一个函数,具体的文档可以查看上一篇文章,或是在 github 上查看更为详细的内容。

ok 简介到此完毕。虽然这个简介有点短,但是该篇的目的并不在于让大家了解这个矩阵动画,而是想让大家一起来丰富这个仓库。

接下来进入正题。

动画形式

何为矩阵动画?

简单来说就是有一个矩阵,然后让它动起来,效果如下:

gif

这就是一个简单的矩阵动画,动画形式如何?

从右上到左下按照斜线进行运动

那么动画效果呢?

翻转消失,然后翻转呈现

animite.css 可以解决绝大多数的动画效果,而且 animite.css 中的动画也大致可以分为入场动画好出场动画两个大类,既然如此,我们实现矩阵动画中需要的动画效果迎刃而解,我们仅需要丰富动画形式即可。

抽象

既然我们准备批量实现我们的动画形式,那么抽象是必要的,按照之前给的效果图,这个是我抽象出来的对象:

{
  interval: 140,
  duration: 1000,
  init(row, col) {
    this.row = row;
    this.col = col;
    this.count = col;
  },
  check(i, j) {
    return j - i === this.count;
  },
  next() {
    this.count--;
  },
  end() {
    return this.count === -this.row;
  }
}
复制代码
字段名 类型 代表的含义
interval number 每次(获取需要运动的点)的时间间隔
duration number transition 动画专用,用于设置 transition 的持续时间,animate 动画不需要
init Function 每次动画开始前会调用,用于初始化对象信息
check Function 用于确定每次需要运动的点
next Function 每次(获取需要运动的点)后都会调用该函数,用于重置判断条件
end Function 判断该动画是否结束

动画具体的执行流程为

  1. 将矩阵的行列传入 init 函数
  2. 设置以 interval 为时间间隔的定时器
  3. 遍历矩阵中所有的点,传入 check 函数,确定该点是否需要运动
  4. 执行 next 函数
  5. 执行 end 函数,若函数返回 true 则取消定时器,动画结束

结合上面的内容,不难想象出,刚刚的对象触发矩阵中的点如下(以 row = 7; col = 9 为例)

  • 定时器第一次触发时,运动的块为 [0, 8]
  • 定时器第二次触发时,运动的块为 [0, 7],[1, 8]
  • 定时器第三次触发时,运动的块为 [0, 6],[1, 7],[2, 8]
  • ...

也就是从右上到左下,每一次动一条斜线。也是实现 gif 图中的动画形式,配合 animate.css 就能完成效果图展示的效果。

注意点

  • init/check/next/end 函数中的 this 代表本对象,也就是拥有该方法的对象
  • this 下也可设置任意值,这是 js 的特性,所以设置任意值都 ok
  • 最好不要将值设置到对象外部,避免互相影响,所以为了方便调用,最好都设置在 this 对象下,如上述的 row/col/count
  • 由于动画效果会被调用 n 次,所以要记得在 init 方法内将自定义设置在 this 下的值进行初始化。避免由于上次动画修改了某值,但没有初始化导致动画效果在第 2 次时有变化。

定义

既然我们是用 typescript 进行开发,该对象的完整定义如下:

export type modeType = {
  interval: number;
  duration?: number;
  [propName: string]: any;
  init(row: number, col: number): void;
  check(i: number, j: number): boolean;
  next(): void;
  end(): boolean;
}
复制代码

只要符合该定义的对象,就可以认为是一个符合要求的动画形式,但是动画的执行是否完整(动画执行是否将所有矩阵中的点都触发了一遍),不在库的考虑范围内,这点需要你,也就是该动画形式的编写者确定。

开发环境

ok 看到这里是否已经有些骚气的一批的动画在你的脑海中呈现,很想实现它吧~

那么如何来验证你的动画是否完整呢?

方式一

安装好 matrixchange 后,按照 github 上提供的文档,先将矩阵初始化好,然后调用 movePoint 将你写好的对象传入即可。

什么?麻烦?对!

确实挺麻烦的,还要自己写个 html 可能还要配置 webpack 开发环境等一系列杂七杂八的东西,写个动画形式为什么还要配置这么多无关紧要的步骤呢?其实我都已经给你配置好啦~

方式二

按照以下步骤

git clone https://github.com/acccco/matrixChange.git 
复制代码

先将项目克隆到本地,当然可以先 fork 然后克隆你自己的项目,推荐先 fork

npm i
# or
yarn
复制代码

安装项目依赖。

npm run dev
复制代码

运行程序,然后浏览器打开 http://localhost:8080/ 即可。

对了,那该在哪里编写你的运动形式呢?

项目下有 dev 文件夹,在文件夹内,我已经写好了布局,写好了初始化方法,你所要做的就是找到 movePoint 这个方法,然后将该方法的第一次参数改成你所写好的对象即可。

什么?我原来文件中 movePoint 的第一个参数 line.rt2lb 是什么鬼?

说明一下,我将已经实现的效果按照分类放在了 src/mode 文件夹,四个方向分别使用缩写代替。

l - 左
r - 右
t - 上
b - 下
i - 内部
o - 外部
R - 代表前面所表示运动的反向
Anti - 逆时针
复制代码

line.rt2lb 所代表的运动形式为:从右上到左下的线性运动。

src/mode 文件夹中已经实现的有 6 大类,32 种动画形式。大概说明一下

文件名 代表意思 例子 说明
line.js 线性运动 line.r2l line.rt2lb 每次运动一条直线
L.js L 形运动 L.lt2rb L.lt2rbR 每次运动一个 L 形状的区域
circle.js 回字形运动 circle.i2o 每次运动一圈
spread.js 扩散运动 spread.random 由一个中心点进行扩散,每次扩散一圈
loop.js 绕圈运动 loop.lt 由某个顶点进行绕圈运动
random.js 随机运动 random.t2b 线性随机运动

更为详细的介绍可以查看 src/mode 中的具体文件,大家可以将动画形式放入 movePoint 中查看具体的动画效果。

当然,已经实现的运动形式大家也可以看看有没有更加简单的编写方式,优化原本的代码。

总之,有了想法那就开始行动吧,不管是新想法,还是优化我原本的实现,都欢迎 Pull Request。当然可能有了想法,但时间上不允许,也可以在 Issues 上记录,大家可以一起帮你实现。

最后

最后再次提供 github 地址,欢迎大家 Pull Request

喜欢的话 可以点个 star 哦,感谢~