H5动画开发快车道

摘要:
前言过去,动画设计师使用Animatec为H5操作项目设计动画原型,然后将其交给我们进行UI开发。做过动画开发的童鞋都知道,动画开发相对耗时,还需要高质量地还原动画设计师设计的动画,来回沟通的成本也很高。经过一段时间的探索,发现AnimateCC可以导出画布动画,它基于createjs,一个用于开发轻量级游戏的js库。它非常适合在移动终端上制作一些h5动画。CreatejsCreateJS是CreateJS库,可以说是为HTML5游戏开发的引擎。

前言

以往做一些H5的运营项目,都是动画设计师使用Animate cc(原来的Flash)先设计好动画原型,然后交给我们UI开发来实现。做过动画开发的童鞋都知道动画开发都是比较耗费时间精力的,而且还要高质量的还原动画设计师设计好的动画,来回沟通成本也非常高。

那有没有一种高效的方法来改善这种流程,提高开发效率的同时还能完成高品质的动画呢?

经过一段时间的摸索,发现AnimateCC(就是原来的Flash)可以导出canvas动画,而且是基于createjs这个开发轻量级游戏的js库的,非常适合用来做移动端的一些h5动画。不仅缩短制作动画所需要的时间。同时它也是一个可视化的IDE,不需要编写代码就可以完成高品质的动画效果;还可以通过Javascript,为动画效果添加交互性。

比如下面这一页动画,如果使用传统的html css3的动画开发或者是canvas方式来硬写代码来实现,切图加上动画开发没有一天应该是搞不定的;而使用AnimateCC导出配合自己写一点点代码,一两个小时就可以搞定。

H5动画开发快车道第1张

一些需要了解的概念

开始之前先来了解下Animate CC中做动画的概念。

帧频

是指每秒钟放映或显示的帧或图像的数量,这个数值设置越大,动画越快,但同时也是性能消耗大户,一般设置24帧就可以了。

图形与影片剪辑

我们可以将单独的动画,放到一个独立的影片剪辑里,这样可以更好的控制动画。几个独立的剪片剪辑,可以组成一个完整的动画。

当我们把图片从资源库拖到舞台时,它这个时候,只是普通的位图,并不能做补帧动画,所以我们必须把它转换成元件。

图形由矢量图或者是位图组成。

影片剪辑包含在动画影片中的影片片段,有自己的时间轴和属性。具有交互性,是用途最广、功能最多的部分。

时间轴

时间轴是我们创作动画时使用层和帧组织和控制动画内容的窗口,层和帧中的内容随时间的改变而发生变化,从而产生了动画。时间轴主要由层、帧和播放头组成。

Createjs

CreateJS为CreateJS库,可以说是一款为HTML5游戏开发的引擎。目前被Adobe整合到Animate CC中,作为导出canvas动画的基础javascript库。

它是一款为HTML5游戏开发的引擎,包含:

EaselJS:用于 Sprites、动画、位图的绘制,交互体验(包含多点触控)功能。

TweenJS:补间动画”引擎

SoundJS:音频播放引擎

PrloadJS:资源预加载

具体的文档和Demo介绍以及API的使用方法,可以通过官网来了解:http://createjs.com/docs

怎么快速导出canvas动画?

一般动画设计给我们都是单个的使用Animate CC导出的fla源文件,就以我上面说的demo为例,长这样:

H5动画开发快车道第2张

拿到之后我们需要做一点点整理工作,先在Animate CC里面建立一个影片剪辑元件:

H5动画开发快车道第3张

建好之后在Animate CC中的库面板中就会生成刚刚建好的影片剪辑元件,点击刚刚建好影片剪辑元件链接的栏目就会变成可编辑的状态,然后取个名字,比如我这里取名为view1:

H5动画开发快车道第4张

然后双击这个元件,时间轴里面是空白的,这个时候需要做的事情就是打开动画设计师给我们的fla源文件,复制时间轴上所有的图层粘贴到刚刚新建的影片剪辑里时间轴里。

这样我们这个叫page1的影片剪辑就包含了这一页的所有动画,想一想如果你是要做有5页游动画的h5项目,就单独把每一页的动画放到对应的影片剪辑里。这几个单独的影片剪辑就组成了一个完整的动画。

做完这一步整理工作后,就可以点击导出了。

H5动画开发快车道第5张

它会直接把资源导出到你当前fla文件所在的目录:

H5动画开发快车道第6张

images -> 动画所用的图片资源
1.hmt -> html文件
1.js -> canvas所需要的图形全部转成canvas绘制的元件库

打开导出的js文件,可以看到刚刚在影片剪辑里做的类链接已经在js生成了一个view1的方法在里头:

H5动画开发快车道第7张

然后可以发现在导出来的html文件里中混合了js代码,我们可以新建一个main.js文件把html文件中的js代码放进去,专门用来控制动画的播放以及一些交互逻辑的编写,整理代码如下(详细的说明有写注释):

html:

  1. <>charset='UTF-8'>

  2. <>name='viewport'content='width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no'>

  3. 1

  4. <>type='text/css'>

  5. body{

  6. overflow:hidden;

  7. }

  8. <>onload='init();'style='margin:0px;'>

  9. <>id='canvas'width='750'height='1206'>

接下来只要把js中对应的两行代码修改为下面这两句代码就可以运行我们的动画:

  1. varview1;

  2. view1=newlib.view();

  3. stage.addChild(view);

浏览器上就可以显示出刚才在animate cc里面经过类链接的影片剪辑的动画。

但是有时候有些额外的对象或者方法是需要放在view1里面的,那怎么办呢?我们新建一个View1的类把animate cc里的view1给复合进去。

  1. //view1

  2. (function(){

  3. 'use strict';

  4. functionView1(){

  5. this.Container_constructor();

  6. this.back=newlib.view1();

  7. this.addChild(this.back);

  8. this.show=function(){

  9. //这里可以写额外的方法

  10. }

  11. //this.con = new createjs.Container() 这里可以是额外处理的对象

  12. }

  13. varp=createjs.extend(View1,createjs.Container);

  14. cls.View1=createjs.promote(View1,'Container');

  15. }());

然后创建这个类把它放到舞台上就可以了:

js代码:

  1. view=newcls.View();

  2. stage.addChild(view);

最后js代码整理如下,相关代码已经有详细的注释:

  1. // 定义一些需要用到的变量

  2. varcanvas,stage,exportRoot,cls={};

  3. // model来专门处理接收事件,记得要是EventDispatcher类

  4. model=newcreatejs.EventDispatcher();

  5. stageWidth=document.documentElement.clientWidth;

  6. stageHeight=document.documentElement.clientHeight;

  7. stageScale=stageWidth/(750/2);

  8. canvas=document.getElementById('canvas');

  9. if(stageWidth/stageHeight>0.665)

  10. {

  11. stageScale=stageHeight/(1206/2);

  12. }

  13. else

  14. {

  15. stageScale=stageWidth/(750/2);

  16. }

  17. canvas.style.width=750/2*stageScale+'px';

  18. canvas.style.height=1206/2*stageScale+'px';

  19. functioninit(){

  20. canvas=document.getElementById('canvas');

  21. images=images||{};

  22. // LoadQueue是一个预加载类,可以把需要加载的资源提前加载,基本支持大多数的文件预加载。

  23. //我这里主要处理了它的2个事件,fileload,complete。

  24. varloader=newcreatejs.LoadQueue(false);//这里一共可以是3个参数 第一个是是否用XHR模式加载 第二个是基础路径 第三个是跨域

  25. loader.addEventListener('fileload',handleFileLoad);

  26. loader.addEventListener('complete',handleComplete);

  27. loader.loadManifest(lib.properties.manifest);

  28. }

  29. functionhandleFileLoad(evt){

  30. //这是单个文件加载完成的事件,把它保存到一个地方之后可以直接拿来创建对象

  31. if(evt.item.type=='image'){images[evt.item.id]=evt.result;}

  32. }

  33. functionhandleComplete(evt){

  34. varqueue=evt.target;

  35. varssMetadata=lib.ssMetadata;

  36. for(i=0;issMetadata.length;i++){

  37. ss[ssMetadata[i].name]=newcreatejs.SpriteSheet({'images':[queue.getResult(ssMetadata[i].name)],'frames':ssMetadata[i].frames})

  38. }

  39. view1=newcls.View1();

  40. stage=newcreatejs.Stage(canvas);//获取舞台 Stage是我们的舞台类,可以理解为所有canvas内部对象的总容器或者说是根显示对象。

  41. stage.addChild(view1); //将容器放在舞台上

  42. model.addEventListener('complete',function(){

  43. alert('complete');

  44. })

  45. //Ticker是一个计时类,不过他是每过一帧触发一次的,也就是说跟时间其实没关系(因为帧频是会波动的)。

  46. // createjs.Ticker.setFPS();和createjs.Ticker.addEventListener('tick', stageBreakHandler);是必须要加的,stageBreakHandler里面放的是刷新舞台的方法,因为createjs需要不停的刷新舞台来刷新动画,也就是一个重绘的过程。 平时也可以拿Ticker类做动画。

  47. fnStartAnimation=function(){

  48. createjs.Ticker.setFPS(lib.properties.fps);

  49. createjs.Ticker.addEventListener('tick',stageBreakHandler);

  50. }

  51. fnStartAnimation();

  52. }

  53. functionstageBreakHandler(event)

  54. {

  55. if(stageWidth!=document.documentElement.clientWidth||stageHeight!=document.documentElement.clientHeight)

  56. {

  57. stageWidth=document.documentElement.clientWidth;

  58. stageHeight=document.documentElement.clientHeight;

  59. if(stageWidth/stageHeight>0.665)

  60. {

  61. stageScale=stageHeight/(1206/2);

  62. }

  63. else

  64. {

  65. stageScale=stageWidth/(750/2);

  66. }

  67. canvas.style.width=750/2*stageScale+'px';

  68. canvas.style.height=1206/2*stageScale+'px';

  69. }

  70. stage.update();

  71. }

  72. //view1

  73. (function(){

  74. 'use strict';

  75. functionView1(){

  76. this.Container_constructor();

  77. this.back=newlib.view1();

  78. this.addChild(this.back);

  79. }

  80. varp=createjs.extend(View1,createjs.Container);

  81. cls.View1=createjs.promote(View1,'Container');

  82. }());

一个动画效果就完成,当然刚开始的时候可能要花点时间来熟悉。一旦熟悉这个套路后,后面就会越发越熟练了。

比如下面这个小的h5动画,使用上面的animate cc和createjs两天就可以搞定:

怎么来做交互反馈

像我们一般做这些运营项目,都会和用户发生些交互动作或者是监听页面的动画事件来做进一步反馈,这个是还怎么办呢?

这里有一个小诀窍,我们可以在帧上加上dispatchEvent,来告知程序动画结束了,或者播放到哪个关键地方了。
比如这里我们在动画的最后一帧上加上:

  1. this.stop();

  2. if(model)model.dispatchEvent('complete');

H5动画开发快车道第8张

然后在js上新建一个model来专门处理接收事件,记得要是EventDispatcher类:

  1. model=newcreatejs.EventDispatcher();

然后在代码中监听就可以了:

  1. model.addEventListener('complete',function(){

  2. alert('complete');

  3. })

在动画结束的时候就会监听到complete事件了:

H5动画开发快车道第9张

雪碧图功能

如果碰到图片很多的项目怎么办呢?Animate CC也支持导出雪碧图的功能,在发布之前设置下就可以了:

H5动画开发快车道第10张

这里要注意的是在选择的时候选择两者兼有,这样就会把jpg和png格式分别导出;png品质选择32位的就可以了。

H5动画开发快车道第11张

左边是没有选择雪碧图的,右边是选择导出雪碧图的,图片数量瞬间少了很多。导出雪碧图就是这么简单。

性能问题

说到做动画性能是绕不开的话题,同样在使用fla导出canvas动画的时候也会碰到性能问题,这里总结下遇到的性能问题,一般都是在用Animate CC做动画的时候可以规避掉,总结一句话就是:

减少矢量 减少影片剪辑(movie clip) 减少嵌套 减少滤镜特效。

详情如下:

1、嵌套规范

在使用CC设计动画效果时,尽量不要太多的嵌套,比如:影片剪辑里面再嵌套影片剪辑或者是帧里面再嵌套其它帧。

2、滤镜和动画规范

不要使用滤镜特效比如(阴影滤镜和发光滤镜)来做动画,因为这样会非常耗费性能,在移动端上性能不可控。

可以使用逐帧图片来代替相关滤镜特效来实现动画效果。比如下面效果里面的花瓣飘落和萤火虫的效果可以使用逐帧图片来做。

3、素材规范

少用矢量多用位图,Text shape都算矢量(如果是用 flashCC或者animateCC做的,在里面就直接把字和矢量图转成位图)。

使用Animate CC做动画效果的基本知识就介绍到这了,有什么问题可以留言一起交流交流。

各位设计的小伙伴们,可以尝试下使用Animate CC来做动画效果,特别是H5类型的动效。不仅高效还可以高质的还原出设计师的动画效果。

使用Animate CC来设计动效,你好,我好,大家都好!

感谢你的阅读,本文由腾讯ISUX版权所有,转载时请注明出处,违者必究,谢谢你的合作。

注明出处格式:腾讯ISUX (https://isux.tencent.com/card-design-thinking.html)

免责声明:文章转载自《H5动画开发快车道》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?(没有BOM,所以被误判为UTF8。“联通”两个汉字的GB内码,其第一第二个字节的起始部分分别是“110”和“10”,,第三第四个字节也分别是“110”和“10”)函数对象与仿函数(function object and functor)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Android属性动画

## Android属性动画 ### 动画特性 -动画时长:默认为300毫秒。 -时间插值:可以根据动画的当前已播放时间来计算属性值。Interpolator类 -重复次数跟行为:可以为动画设置监听器,设置动画在不同阶段做出不同反映,也可以直接为其设置重复次数,跟重复播放动画的类型如反向播放。 -Animator集:将几个动画,按照一定的播放顺序捆绑在一...

canvas基础—图形变换

1、canvas转换方法 1.1canvas转换方法 二、canvas实现图形的中心点旋转 step1:获取canva元素并指定canvas的绘图环境 var canvas=document.getElementById('canvas'); var context=canvas.getContext('2d'); step2:在画布(1...

Android 三种动画详解

Android 三种动画详解 1 背景 不能只分析源码呀,分析的同时也要整理归纳基础知识,刚好有人微博私信让全面说说Android的动画,所以今天来一发Android应用的各种Animation大集合。英文厉害的请直接移步参考Android Developer。 Android系统提供了很多丰富的API去实现UI的2D与3D动画,最主要的划分可以分为如...

JQuery几种动画效果的方法

下面介绍了几种动画效果的方法,具体如下: 1、show()显示效果 语法:show(speed,callback)  Number/String,Function speend为动画执行时间,单位为毫秒。也可以为slow","normal","fast" callback可选,为当动画完成时执行的函数。 show(speed,[easing],callba...

小程序购物车抛物线动画(通用)

说明:  之前用vue css3写过抛物线动画,但是小程序中,不支持js操作dom元素,所以你无法用js去去除动画的css3,导致你无法进行第二次的动画。 所以,只能用纯js去计算运动的路线,再改变小球的位置,这个写法,估计是没有什么都通用 实例是:https://github.com/WaitForYou/shopcartBeizer.git gith...

CSS3动画(性能篇)

写在前面 高性能移动Web相较PC的场景需要考虑的因素也相对更多更复杂,我们总结为以下几点: 流量、功耗与流畅度。 在PC时代我们更多的是考虑体验上的流畅度,而在Mobile端本身丰富的场景下,需要额外关注对用户基站网络流量使用的情况,设备耗电量的情况。 关于流畅度,主要体现在前端动画中,在现有的前端动画体系中,通常有两种模式:JS动画与CSS3动画。 J...