八、动画
帧:动画中的最小单位,是静态的图像。帧频:一秒播放的帧的数量。
一个完整的动画由很多帧组成,人眼有视觉暂留效果,当一系列相似的图像用时间轴串联,如果时间间隔足够小,人眼感知的就是流畅的动画(1s30帧以上)。
实现方式:gif以图像形式存储,容量较大,需借助第三方制图工具;flash借助编码实现;CSS3有一定局限性;用js实现动画。
js动画三要素:DOM对象、属性(width、height、opacity、left等)、定时器。
1、定时器
通过定时器不断改变对象的属性,构成动画。
(1)setInterval
var intervalID=setInterval(func,delay[,param1,param2,…]);
clearInterval(intervalID); //清除定时器
三个参数分别为:改变属性的函数、触发的时间间隔(ms)、可选参数作为函数的实参。
(2)setTimeout
var timeoutID=setTimeout(func[,delay,param1,param2,…]);
clearTimeout(timeoutID); //在定时器触发之前清除
delay默认为0,不传入delay参数则立即触发,但是是异步过程。
setTimeout在指定的触发时间之后只执行一次,setInterval每隔指定时间执行一次。
(3)requestAnimationFrame
var requestID=requestAnimationFrame(func);
cancelAnimationFrame(requestID);
只有一个参数,间隔时间由显示器的刷新频率控制,通常1s刷新60次。用户不用关心间隔时间,且比之前的两个方式更流畅,不会出现掉帧情况。
2、常见动画
形变:改变宽高;位移:改变相对位置;旋转;透明度;…。
简单动画可以组合复杂动画。
//适用于以px为单位的形变、位移等,旋转、透明度需要调整代码
var animation=function(ele,attr,from,to){
//作动画的元素,属性,属性初始值,属性目标值
var distance=Math.abs(to-from);
var stepLength=distance/100;
var sign=(to-from)/distance; //从大到小-1或从小到大1
var offset=0;
var step=function(){
var tmpOffset=offset+stepLength;
if(tmpOffset<distance){//如果当前偏移加一个步长<距离
ele.style[attr]=from+tmpOffset*sign+'px';
offset=tmpOffset;
}else{//否则直接到达目的地to
ele.style[attr]=to+'px';
clearInterval(intervalID);
}
}
ele.style[attr]=from+'px';
var intervalID=setInterval(step,10);
}
九、多媒体和图形编程
1、多媒体<audio><video>
(1)多媒体的属性和方法
|
方法或属性 |
说明 |
方法 |
canPlayType() |
检测浏览器是否支持某种媒体类型 支持返回”maybe/probably”,不支持返回”” |
load() |
重新加载媒体内容 |
|
play() |
开始播放 |
|
pause() |
暂停播放 |
|
可读可写 |
playbackRate |
播放速度(0-1慢速1常速1-4快速) |
currentTime |
当前播放位置,以秒计 |
|
volume |
音量(0-1) |
|
muted |
是否静音(true/false) |
|
paused |
是否暂停(true/false) |
|
只读 |
seeking |
是否正在跳转 |
ended |
是否播放结束 |
|
duration |
当前视频长度 |
|
initialTime |
媒体开始时间 |
var a=new Audio();
a.canPlayType('audio/nav');
没有实现video构造函数,只能通过js获取video标签的DOM对象,再使用该方法。
(2)多媒体事件
事件类型 |
说明 |
loadstart |
开始请求媒体内容 |
loadmetadata |
媒体元数据已加载完成 |
canplay |
加载了一些内容,可以开始播放 |
play |
调用play(),或设置了autoplay |
waiting |
缓存数据不够,播放暂停 |
playing |
正在播放 |
元数据指媒体元信息,如时长、编码格式,但不包括媒体具体内容。
(3)Web Audio API
相当于音频的ps,进行更高级的音频处理,比如在Web页面上做游戏、音效或音频解码器。
W3C官方定义:http://webaudio.github.io/web-audio-api/
mozilla官方教程:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API
第三方教程:http://www.html5rocks.com/en/tutorials/webaudio/intro/,http://webaudioapi.com/
2、图形编程<canvas>
<canvas id="tutorial" width="300" height="150"></canvas>
width和height属性指定宽高,如果不指定默认为300和150。不建议使用CSS指定宽高,在渲染速度上有差异。
var canvas=document.getElementById('tutorial');
var ctx=canvas.getContext('2d');//返回渲染上下文的对象(含canvas大部分API)
//画每一帧图像前设置,默认source-over后面画的东西覆盖前面画的
ctx.globalCompositeOperation='destination-over';
每一帧的基本绘图步骤:获取 canvas画布,清除画布,循环绘制图形、保存渲染上下文状态、绘制图形、恢复渲染上下文状态。画完之后用时间轴将每一帧连起来。https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
太阳系动画。
//生成三个image对象
var sun=new Image();
var moon=new Image();
var earth=new Image();
function init(){
//将三张图片加载进内存,绘画时可以直接从内存读取
sun.src='Canvas_sun.png';
moon.src='Canvas_moon.png';
earth.src='Canvas_earth.png';
window.requestAnimationFrame(draw);
}
function draw(){//绘制每一帧
var ctx=document.getElementById('canvas').getContext('2d');
ctx.globalCompositeOperation='destination-over';//后画的在先画的后面
ctx.clearRect(0,0,300,300); //清空画布
ctx.fillStyle='rgba(0,0,0,0.4)';
ctx.strokeStyle='rgba(0,153,255,0.4)';
ctx.save(); //保存画布状态
ctx.translate(150,150);
//Earth
var time=new Date();
ctx.rotate(((2*Math.PI)/60)*time.getSeconds()+((2*Math.PI)/60000)*time.getMilliseconds());
ctx.translate(105,0);
ctx.fillRect(0,-12,50,24); //Shadow
ctx.drawImage(earth,-12,-12);
//Moon
ctx.rotate(((2*Math.PI)/6)*time.getSeconds()+((2*Math.PI)/6000)*time.getMilliseconds());
ctx.translate(0,28.5);
ctx.drawImage(moon,-3.5,-3.5);
ctx.restore(); //恢复画布状态
ctx.beginPath();
ctx.arc(150,150,105,0,Math.PI*2,false); //Earth orbit
ctx.stroke();
ctx.drawImage(sun,0,0,300,300);
}
init();