《第10章JavaScript的动画.docx》由会员分享,可在线阅读,更多相关《第10章JavaScript的动画.docx(13页珍藏版)》请在优知文库上搜索。
1、第10章JavaScript的动画.前娉示在Web中,“动画”这个词一向都属于网页动画王者Flasho但并不是说JaVaSCriPt就不能做出动画效果。虽然不借助于VML或者SVG,JaVaSCriPt就没有处理矢量图形的能力,但是对页面元素的控制力却是Flash不可比拟的。通过对页面元素的控制,使用JaVaSCriPt同样可以创造出接近于Flash的动画效果。本章就与读者一起,使用JaVaSCriPt来制作漂亮的动画效果。知识要点 动画基础 定时器 动画的实现 通用接口1.1.1 动画基础简单地说,动画可以理解为能动的图画。这确实很简单,简单到可以使用CSS技术轻松地来实现,在本章的例子中,
2、将介绍一个使用正滤镜效果实现的动画。动画效果的原理就是利用人的视觉暂留,通过快速地播放连续的画面而产生场景中物体的运动效果。当然,连续的画面需要有连贯性一一比如一个完整的走路动作,按照规律一次变化一点点,这样才能产生平滑的运动效果。目前最流行的动画制作工具Flash就是利用这个方式来进行动画制作的。这里涉及到两个关键的概念一一帧和秒。帧可以理解为一幅画,或者电影胶片中的一张,每一帧都记录着一个瞬间的行为状态。比如第一帧,人物准备抬起左手;第二帧,人物左手抬起到了半空;第三帧,人物左手伸了出去。这三帧连续播放的效果就是一个完整的抬手伸出的动作。当然影响最终表现结果的还有一个重要因素,就是秒。通常
3、,电影播放时,在一秒内会播放24幅画面。也就是说,人眼在一秒内看24帧就会觉得很正常,如果在一秒内播放的帧数过少,或者过多,就会造成画面过快或者过慢的效果了。当然这并不是绝对的,这与每帧之间的“间距”有关系,每帧移动的距离不同,那么效果也不同。帧和秒决定了最后动画播出的效果,这个由帧/秒决定的单位被称为FPS,也就是帧每秒(FramePerSecond)o虽然对于看电影来说,24FPS就够了,但是,目前在游戏中经常以高FPS为追求的目标,这是因为高FPS可以使整个过程表现得更细腻。1.1.2 时器说到JaVaSCriPt动画,在本书第6章中就介绍过如何通过改变元素样式来制作动画效果。因为在Ja
4、VaSCriPt中只能控制元素进行改变,而不能创造矢量图形,当然这不包括VML或者SVG。所以只能实现“元素动画”。提示在HTML5中,JaVaSCriPt可以实现矢量绘图,但HTML4.x中的元素动画同样重要。而实现元素动画只有两个要素,元素属性改变量以及完成改变量的时间,如图10.1所示。以元素移动来说,图10.1描述了在指定时间内完成指定移动量的过程。现在有了时间,也有了总量,问题是帧在哪里?这需要我们假定一个常量:FPS,如果使用24FPS,那么完成这个动画的总帧数为:总帧数(FS)=FPSX总时间(三)新的问题是:如何在总时间(三)内完成FS帧?对于JaVaSCriPt来说,这才是重
5、点。答案是:我们需要一个定时器来周期性地驱动动画的改变,也就是帧的更新。(0.0)(200.200)图101元素的移动10.2.1 JavaScript中的定时器在本书第5章中,介绍了两种JavaScript支持的定时器函数:SetTimeout()允许延时执行函数setinterval()/允许在指定的间隔时间后重豆执行函数从函数定义上来看,SeUmerVaI更适合作为定时器来周期性的改变元素属性,看下面的例子:Iblock(width:100px;height:100px;background:#aaa;position:absolute;top:10Opx;left:10Opx;)每秒帧
6、数varFPS=24;每帧间隔varSPF=1000/FPS;总时间3秒varperiod=3;/移动IoO像素vardistance=100;总帧数varframes=parselnt(FPS*period);每帧移动的距离varstep=distance/frames;varblock=ementByld(nblockn);定时器引用,用于结束动画vartimer;/动画处理函数functioncallback()(if(frames=0)当总帧数到0时,停止动画clearinterval(timer);显示完成动画后的坐标alert(tLeft+tTop);)/变更移动量.left=tL
7、eft+step+,px,;.top=tTop+step+,px,;frames;)timer=setinterval(callback,SPF);定时器启动之后,灰色的方块bl。Ck就会沿着对角线的方向往右下角移动。虽然它很简单地只进行了位置的变动,但它确实是一个动画。除了使用SetInterVal来实现周期定时器外,还可以使用SemmeOUt来实现周期调度,看下面的例子:每秒帧数varFPS=24;每帧间隔varSPF=1000/FPS;总时间3秒varperiod=3;移动IOo像素vardistance=100;总帧数varframes=parselnt(FPS*period);每帧移
8、动的距离varstep=distance/frames;varblock=ementByld(blockn);/定时器引用,用于结束动画vartimer;/动画处理函数functioncallback()(if(frames=0)当总帧数到0时,停止动画ClearTimeout(timer);显示完成动画后的坐标alert(tLeft+tTop);)变更移动量.left=tLeft+step+,px,;.top=tTop+step+,px,;frames-;SetTimeout(callback,SPF);)timer=SetTimeout(callback,SPF);这是一个递归调用,看起来
9、比Seumeival要复杂一些,但在实际的使用中,基本都是使用这种方式来处理动画的。为什么呢?答案稍后揭晓。提示在HTML5中,有了新的定时器接口requestAnimationFrame,该接口不需要使用者指定SPF,因为浏览器内部会为60帧的FPS而自动管理。该接口可以获得更低的CPU消耗、更少的电量消耗和更平滑的效果。10.2.2 帧和时间虽然这不是一本关于游戏开发的书籍,但我们仍然想把游戏开发中的一些经验介绍给读者。在本章的开头介绍了帧的概念,帧表示了1秒内定时器的循环次数,而我们使用帧进行动画的更新:在上面的例子中,动画在每帧更新一次block的位置,而在总帧数为0时结束动画。为什么
10、没有说到时间呢?一般情况下,我们都会讲:我要看一个IO秒的广告,或者长达2个小时的动画,从来没人说:我想看一个216000帧(60FPS持续1小时)的动画。这就是我们想说的问题,时间。考虑这样一个场景:我们想在用户进入这个页面的时候显示一个欢迎动画,长度3秒(类似很多门户网站首页的强行广告)。如果动画刚开始播出1秒的时候,页面因为其他计算而导致性能下降,也许是卡住了10秒,那么10秒后动画是否应该消失?还是继续播完剩下的2秒?答案是消失。当然这还取决于程序的目的,是否需要一个与时间同步的动画。与时间同步的好处在于多人联网时,可以得到最小误差的相同体验:比如在一个抢购商品页面开放抢购之前播放了一
11、些动画特效,之后开始抢购商品。如果动画长5秒,而某人从开始就卡了4秒,那他是该继续播完那剩下的1秒就开始抢购商品呢,还是继续等待5秒直到动画结束后才开始抢购商品?你一定已经知道答案了。下面来看看如何在代码中实现根据时间来进行的动画:每秒帧数varFPS=24;每帧间隔varSPF=1000/FPS;/总时间3秒varperiod=3;/移动100像素vardistance=100;/总帧数varframes=parselnt(FPS*period);每帧移动的距离varstep=distance/frames;varblock=ementByld(,block);定时器引用,用于结束动画var
12、timer;动画处理函数functioncallback()(当前时间动画开始时间/如果因为某些原因,只执行了1帧时间就超过了3秒,那么动画同样会停止,因为不能影响后续的处理duration=+newDate()-StartTime;/+相当于.valuef();if(duration=3000)(当时间超过3秒时,停止动画ClearTimeout(timer);显示完成动画后的坐标alert(tLeft+”:”+tTop);)/变更移动量.left=tLeft+step+,px,;.top=tTop+step+,px,;这句很重要SetTimeout(callback,SPF);)开启时间v
13、arStartTime=+newDate();/+相当于.valuef();执行时长varduration=0;timer=SetTimeout(callback,SPF);使用时间来控制动画并不复杂,但是它可以保证你的整个程序流程不会因为图像显示的卡顿而影响后续的逻辑。提示一般来说,在画面需要频繁更新的游戏或者动画中,60FPS可以保证画面过渡看起来更平滑,但这不是必需的,有些类型只需要大于24的FPS就够了。高FPS会提高CPU和电量的消耗。当然在HTML5中,这种情况得到了改善。10.3动起来还不够只移动位置能算得上动画么?虽然从技术上来说,它算是动画,但从视觉上来说,它太简单了,简单到
14、人们认为它不是动画。那现在我们就来完成更多的改变吧。10.3.1线性处理在开始编码之前,首先来构思一个动画场景,比如一个100*100像素的div在5秒的时间内渐变为透明、变小,随之消失。创建上述程序的操作步骤如下。(1)定义元素样式:Iblock(width:100px;height:100px;background:#aaa;position:absolute;top:10Opx;left:100px;overflow:hidden;*初始化透明属性*/opacity:1;*CSS标准方式,1E7以上支持*/filter:Alpha(Opacity=100,);/*滤镜透明方式,工E6支持*/)为元素增加了跨平台的透明属性。(2)定义动画参数:帧每秒varFPS=24;每帧间隔varSPF=1000/FPS;/总时间3秒varperiod=3;移动IOo像素vardistance=100;修改尺寸,从100到0varsize=100;/透明度,从不透明100到透明0varopacity=100;/总帧数varframes=parselnt(FPS*period);/每帧移动距离vardisS