Gitee 人节活动动画开发日志

需求

红薯在愚人节前一天突发奇想,想在 Gitee 上也整一个活动,活动内容就是让仓库页面有个破碎的动画然后显示“愚人节快乐!”。

实现

第一次搞动画有点慌,没用过 Canvas API,不知道一天内能不能搞出来。一开始是想用类似于 Google 在灭霸搜索结果页面加的彩蛋,点击无限手套就会触发灰飞烟灭效果,但仔细想了一下,直接照搬网上现成的动画的话会拉低用户对 Gitee 的评价,于是决定用其它效果。

碎片化

页面变成碎片的效果比较容易实现,大致思路是根据屏幕宽高计算 x 和 y 轴上的碎片数量,然后计算每个碎片的坐标,伪代码如下:

1
2
3
4
5
6
7
8
const size = 32;

for (let x = 0; x < Math.ceil(canvas.width / size); ++x) {
for (let y = 0; x < Math.ceil(canvas.height / size); ++y) {
// 四个参数对应 x, y, width, height
new Piece(x * size, y * size, size, size)
}
}

随机分布

碎片该在什么时候掉落?短时间内让全部碎片掉落的话,对渲染性能要求较高,动画会卡顿。按顺序逐个开始掉落的话,观感过于普通,得搞点不一样的效果。

最终决定采用如下方式:

  1. 在生成碎片列表后,用随机算法将它打乱,参考:如何将一个 JavaScript 数组打乱顺序? - 知乎
  2. 在渲染时分批激活掉落的碎片,并计时
  3. 在碎片激活后的一段时间内,只给碎片渲染边框,表示这个碎片将要掉落
  4. 开始掉落

掉落

碎片要有个掉落动画,每个碎片的掉落路线应该随机,掉到底下后会弹起。掉落路线的计算方法需要花时间查资料和写代码,就目前的情况而言,可没那么多时间能够静下心来自己动手实现,那么,只能找现成的代码来用了。

花了点时间,找到了这个动画:HTML5 Canvas实现会跳舞的时间动画,数字变化后会变成一堆小球掉落,挺符合需求的,但下载源码包后发现要关注这个网站的微信公众号才给解压密码,这种拿别人的开源项目不注明出处还加上解压密码的行为挺让人反感的。

这个问题本质是如何实现自由落体动画,用相关关键词可以搜索到这个动画:HTML5/Canvas 物理学自由落体动画 - 踏得网,代码比较简单,可以直接拿来用。

颜色渐变

动画内容只有碎片掉落还不够,可以给碎片加上颜色渐变效果,在碎片动画播放一段时间后开始加入颜色渐变效果,大致流程是:

  1. 创建碎片,随机分配一个颜色
  2. 在碎片激活后一段时间,开始渲染渐变色

填充渐变色可以用 fillRect(),在 Canvas API 首页就有它的示例代码。

调整渲染顺序

当掉落的碎片增加到一定量时,未掉落的碎片会遮住掉落中的碎片,碎片看上去像是向屏幕后面掉落,观感不太好。由于掉落的碎片是在未掉落的碎片之前绘制的,先绘制的内容会被后绘制的内容覆盖,为解决这问题,需要再加一个数组,按碎片的生成顺序倒序,然后在渲染时遍历该数组即可。

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×