前期接到需求的时候,是想做一个强动画的页面,效果参考这个页面。很明显这是一个canvas绘制出来的、带用户交互的页面。
虽然以前没有做过类似这样的页面,不过跟canvas相关的内容还是做过不少,不难想象要想用canvas做一个这样的页面出来,大致需要以下几个方面的内容:
目前市面上有很多2D的canvas库,大多数是用来做游戏的,基本没有提及适用于我们目前的这种需求场景的。看了几个不同的库之后,发现渲染库的原理基本都差不多,都是定义了许多自己的类,从而对不同的实例进行控制从而实现动画和交互。
初步比较之后,选择了easeljs和PIXI.js,来做同一个demo,对比了性能之后,因为easeljs在低端安卓机上的性能问题果断选择了性能较好的PIXI.js作为canvas渲染库。
有了canvas渲染库之后,还需要控制元素动画流程和衔接的动画库。GSAP中有单个动画和Timeline的概念,不仅能对单个元素的动画进行控制,还能定义一整串的动画流程,从而时间动画的穿插、串联等一系列复杂的操作。
AnimateCC是动画师做动画用的软件,它本身内置了导出为Canvas文档的功能,这样理想情况下,页面中有动画的部分都能动画师来做,前端只需要用js在不同交互种类发生的时候来衔接不同页面就行了,但是既然提到了js动画库,说明实际使用中,这种理想情况是不存在的,后面动画部分详细说。
另外,还有一个第三方开发的插件,pixi-animte,能使animateCC直接导出为用PIXI.js的API包装过的代码,直接用PIXI的api就能操作动画元素。
针对这一套技术方案的canvas页面,在开发过程中也主要有三个方面的内容:AnimateCC、动画和页面逻辑。这三个部分的关系如下:
前面说过,在pixi-animate插件的加持下,animateCC可以直接将文稿导出为PIXI.js包装过的元件,可以直接调用PIXI相关API来对元件进行操作。
因为在canvas中渲染跟传统的css布局有本质的区别,因此页面的布局都是在AnimateCC中完成的
可以看做是传统的html元素被PIXI的MovieClip代替了,每个MovieClip就代表一个html元素,可以包含子元素,可以通过js来调用PIXI相关的API,包括位置等属性。这样,不仅可以通过PIXI来播放AnimateCC中定义的元素本身的帧动画,还可以通过GSAP来控制元素的位置实现位移、变形等外部的动画。
关于动画这部分,前面提到过,理想情况下实际上是不需要前端来引入动画库然后去控制元素的属性去实现动画的,而是动画师在AnimateCC这一步就将动画做好一并导出,前端拿到导出的js通过使用PIXI的API来实现动画的控制和播放。
但是,but,however,这样做有几个不太现实的点
综上,放弃了动画师在AnimateCC中做页面元素动画的方案,改为前端包干。在AnimateCC中将某个页面的初始状态布局好之后,导出为PIXI元件,然后通过GSAP来在特定时候操作元件进行动画。
有了页面和动画之后,还需要能够控制页面加载、初始化、切换等一系列操作的逻辑。
PIXI中有自带的load可以用来加载资源,文档里也清楚的写了初始化的方法,但是如果一股脑的将所有页面加载到内存的话,在低端机中会卡死然后崩溃。所以这里的工作主要是怎么保证页面单独加载而又不会影响canvas切换页面的连贯性。
这里的方法是将页面分成几个部分,例如首页、内页1、内页2。每一个部分都由一个根MovieClip元件包裹,也就是每个部分都是一个单独的PIXI应用,互不关联。在页面切换的时候只需要在过渡中加一个连贯的加载页面,就能在销毁上一个页面之后再初始化下一个页面的同时不影响连贯性,并且内存占用也不会过高。
一边摸索一边用这套技术方案做出来的项目最终也上线了(逆水寒移动官网),最终的效果可以接受,不过过程中确实有许多的坑,和一些值得思考的地方。
这套canvas技术方案相较于传统的html+css+js的方案有优点也有缺点
如果没有上门的诸多缺点,单从效果来说的话,canvas渲染还是挺有优势的,尤其是在低端安卓机中css兼容性不容乐观的情况下,又想要做到动画表现的一致性和流畅性。所以如果一个项目能满足以下几点特性,用这一套技术方案也未尝不可:
如果回头看文章开始给的那个例子,可以发现它就满足了上面几个特点,所以看起来毫无违和感。
因为当初动画师做AnimateCC动画前端直接拿来用的美好愿景被打破,如果再让我做一次类似逆水寒移动官网这种不满足以上特点的项目,我会去掉canvas,就用一个GSAP做动画库,用js控制页面元素进行动画。这样开发起来对于前端来说更加直观,并且在动画这部分的工作量基本跟用canvas持平。
这样可以省去后期维护修改的AnimateCC那部分的时间成本。在js控制css动画方面稍微注意一下性能优化在低端安卓上进行动画也不会有太大的问题。同时有GSAP对于动画流程控制上的便利性,传统页面的元素动画也能得到流畅性的保障。最后达到的效果也不会输canvas。
本文来自网易实践者社区,经作者查马纠西授权发布。