HTML5 Canvas, Audio & Video

图形图像和多媒体

Canvas

画布

Canvas

canvas元素的定义:"它是依赖分辨率的位图画布,你可以在canvas上面绘制任意图形,甚至加载照片。"

要使用canvas 元素,首先必须设置width 和height 属性,也就是我们可以绘图的区域的大小。

<canvas width="100" height="100">这里放置后备信息,如果浏览器不支持canvas会显示</canvas>
     	
我们的绘图区域

2D上下文

  • 绘图前需要调用getContext()方法并传入上下文名字,来取得绘图上下文对象的引用。
  • 传入"2d"就可以取得2D上下文对象。
  • 2D上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0, 0)。x值越大表示越靠右,y值越大表示越靠下。
var drawing = document.getElementById("canvas-area");
// 确定浏览器是否支持<canvas>元素
if (drawing.getContext) {
  var context = drawing.getContext("2d");
  ...
}
     	

填充和描边

2D上下文两种基本操作是填充和描边

  • 填充,就是用指定的样式(颜色,渐变或者图形)填充图形;
  • 描边,就是只在图形的边缘画线。

fillStyle和strokeStyle

填充操作的结果取决于fillStyle 属性,而描边操作的结果取决于strokeStyle 属性。

  • 下面的代码将strokeStyle 设置为red(CSS中的颜色名),将fillStyle 设置为#0000ff(蓝色)。
  • 两个属性如果不设置的话,默认值都是"#000000"。
  • 如果把它们指定为表示颜色的字符串值,可以使用CSS中指定颜色的任何格式,包括颜色名,十六进制码,rgb,rgba等。
var drawing = document.getElementById("canvas-area");
// 确定浏览器是否支持<canvas>元素
if (drawing.getContext) {
  var context = drawing.getContext("2d");
  context.fillStyle = "#0000ff";
  context.strokeStyle = "red";
}
     	

绘制矩形

矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括:fillRect(), strokeRect()和clearRect()

这三个方法都能够接收四个参数:矩形的x坐标,矩形的y坐标,矩形宽度和矩形高度。单位都是像素。

var context = document.getElementById("canvas-area").getContext("2d");
context.fillRect(x, y, width, height);
context.strokeRect(x, y, width, height);
context.clearRect(x, y, width, height);
     	

fillRect()

fillRect() 方法在画布上绘制的矩形会填充指定的颜色。填充的颜色通过fillStyle 属性指定。

// 绘制红色矩形
fillrect_context.fillStyle = "#ff0000";
fillrect_context.fillRect(50, 25, 200, 100);
// 绘制半透明的蓝色矩形
fillrect_context.fillStyle = "rgba(0, 0, 255, 0.5)";
fillrect_context.fillRect(150, 75, 200, 100);
     	

strokeRect()

strokeRect() 方法在画布上绘制的矩形会使用指定的颜色描边。描边颜色通过strokeStyle 属性指定。

// 红色描边矩形
strokerect_context.strokeStyle = "#ff0000";
strokerect_context.strokeRect(50, 25, 200, 100);
// 半透明的蓝色描边矩形
strokerect_context.strokeStyle = "rgba(0, 0, 255, 0.5)";
strokerect_context.strokeRect(150, 75, 200, 100);
     	

clearRect()

clearRect() 方法用于清除画布上的矩形区域。通过绘制形状然后再清除指定的区域,就可以生成有意思的效果,比如把某个形状切掉一块。

// 绘制红色矩形
clearrect_context.fillStyle = "#ff0000";
clearrect_context.fillRect(50, 25, 200, 100);
// 绘制半透明的蓝色矩形
clearrect_context.fillStyle = "rgba(0, 0, 255, 0.5)";
clearrect_context.fillRect(150, 75, 200, 100);
// 在两个矩形重叠的区域清除掉一个小矩形
clearrect_context.clearRect(170, 95, 20, 20);
     	

绘制路径

2D绘制上下文支持很多在画布上绘制路径的方法,通过路径可以创造出复杂的形状和线条。

要绘制路径首先必须调用beginPath() 方法, 表示要开始绘制新路径,然后再调用相应的绘制路径方法。

  • moveTo(x, y): 将绘图游标移动到(x,y), 不画线。
  • lineTo(x, y): 从上一点绘制一条直线,到(x,y)为止。
  • arc(x, y, radius, startAngle, endAngle, counterlockwise): 以(x, y)为圆心绘制一条弧线,弧线半径为radius, 起始和结束的角度分别为startAngle和endAngle。最后一个参数表示startAngle和endAngle是否按逆时针计算,值为false表示按顺时针方向计算。
  • arcTo(x1, y1, x2, y2, radius): 表示从上一点开始绘制弧线,到(x2,y2)为止,并且以给定的半径穿过(x1,y1)。
// 开始路径
pathcanvas_context.beginPath();
// 绘制外圆
pathcanvas_context.arc(100, 100, 75, 0, 2*Math.PI, false);
// 绘制内圆
pathcanvas_context.moveTo(170, 100);
pathcanvas_context.arc(100, 100, 70, 0, 2*Math.PI, false);
// 绘制分针
pathcanvas_context.moveTo(100, 100);
pathcanvas_context.lineTo(100, 35);
// 绘制时针
pathcanvas_context.moveTo(100, 100);
pathcanvas_context.lineTo(55, 100);
// 描边路径
pathcanvas_context.stroke();

绘制文本

模拟了在网页中正常显示文本,fillText()方法的三个主要参数:要绘制的字符串,x坐标和y坐标。

context.font = "bold 12px sans-serif";
context.textAlign = "right";
context.textBaseline = "bottom";
context.fillText("x", 248, 43);
context.fillText("y", 58, 165);
      

fillText以下面三个属性为基础:

  • font: 可以是CSS字体规则中的任何值。
  • textAlign:控制文本的对齐方式(和CSS的text-align不完全相同)。start, end, left, right和center。
  • textBaseline: 控制文本相对于起点的位置。可以取值:top, hanging, middle, alphabetic, ideographic和bottom。

Canvas绘制一个坐标系

变换

通过上下文的变化,可以把处理后的图像绘制到画布上。2D绘制上下文支持各种基本的绘制变换。

  • rotate(angle): 围绕原点旋转图像angle角度
  • scale(scaleX, scaleY): 缩放图像,在x方向乘以scaleX, 在y方向乘以scaleY。scaleX和scaleY的默认值都是1.0。
  • translate(x,y): 将坐标原点移动到(x,y)。执行这个变换之后,坐标(0, 0)会变成之前由(x,y)表示的点。

变换 - translate

在前面绘制秒针的例子中,如果我们把原点变换成表盘的中心,那么再绘制表针就容易多了。

context.beginPath();
context.arc(100, 100, 75, 0, 2*Math.PI, false);
context.moveTo(170, 100);
context.arc(100, 100, 70, 0, 2*Math.PI, false);
// 变换原点
context.translate(100, 100);
context.moveTo(0, 0);
context.lineTo(0, -65);
context.moveTo(0, 0);
context.lineTo(-40, 0);
context.stroke();
      

变换 - rotate

// 变换原点
context.translate(100, 100);
//旋转表针
context.rotate(1);
context.moveTo(0, 0);
context.lineTo(0, -65);
context.moveTo(0, 0);
context.lineTo(-40, 0);
context.stroke();
      

颜色渐变

渐变是两种或者更多颜色的平滑过渡。canvas的绘图上下文支持两种类型的渐变:

  • createLinearGradient(x0, y0, x1, y1)沿着直线从(x0, y0)至(x1, y1)绘制渐变。
  • createRadiaGradient(x0, y0, r0, x1, y1, r1)沿着两个圆之间的锥面绘制渐变。前三个参数代表开始的圆,圆心是(x0, y0),半径是r0; 最后三个参数代表结束的圆。
var my_gradient = context.createLinearGradient(0, 0, 500, 0);
my_gradient.addColorStop(0, "black");
my_gradient.addColorStop(1, "white");

context.fillStyle = my_gradient;
context.fillRect(0, 0, 500, 300);
      

线性渐变demo

Gradient渐变Demo

绘制图像

使用drawImage()可以把一幅图像绘制到画布上,根据期望的最终结果的不同,drawImage()提供了三种绘制图片的方法:

  • drawImage( image, dx, dy )接受一个图片,并将之画到canvas中。给出的坐标(dx, dy)代表图片的左上角。
  • drawImage( image, dx, dy, dw, dh )接受一个图片,将其缩放为宽度dw,高度dh,然后把它画到canvas上的(dx, dy)位置。并将之画到canvas中。
  • drawImage( image, sx, sy, sw, sh, dx, dy, dw, dh )接受一个图片,通过参数( sx, sy, sw, sh )指定图片的剪裁的范围,缩放到(dw, dh)的大小, 最后把它画到canvas上的(dx, dy)位置。
var android = new Image();
android.src = "images/android.png";
android.onload = function() {
  for(var x=0, y=0; x<800 & y<500; x+=50, y+=30) {
    context.drawImage(android, x, y, 100, 117);
  }
}
      

图片demo

canvas导成图像

var imgURI = imagedrawing.toDataURL("image/png");
var image = document.createElement("img");
image.src = imgURI;
document.getElementById("canvas-images-export").appendChild(image);
			

<Video> & <Audio>

不依赖插件就能嵌入音频和视频内容

视频容器

  • MPEG-4
  • Flash 视频
  • Ogg
  • WebM
  • 音频视频交错

视频编解码器

  • H.264
  • Theora
  • VP8

音频编解码器

  • MP3
  • AAC
  • VP8
  • Vorbis

MPEG4 编码

  • HandBrake

Ogg 编码

  • Firefogg

WebM 编码

  • Firefogg
  • ffmpeg

基本用法

<video id="myMovie" src="images/sample.m4v" preload controls autoplay>视频播放器不可用。</video>    
<audio id="myAudio" src="images/song.mp3"></audio>    
      
  • 至少要在标签中包含src属性,指向要加载的媒体文件;
  • 可以设置width和height属性以指定视频播放器的大小;
  • 如果标签中有controls属性,则意味着浏览器应该显示UI控件,以便用户直接操作媒体;
  • 用于开始和结束标签之间的任何内容都将作为后备内容,在浏览器不支持这两个媒体元素的情况下显示。

指定不同的媒体来源

因为并非所有的浏览器都支持所有的媒体格式,所以可以指定多个不同的媒体来源。像下面这样使用一个或多个<source>元素。

<video id="videoShowcase" width="848" height="352" poster="/images/poster.jpg" autobuffer="autobuffer" loop="loop" controls>
  <source src="/images/demo.m4v" type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"">
  <source src="/images/demo.webm" type="video/webm; codecs="vp8, vorbis"">
 </video>
      

主要属性

属性数值类型说明
autoplay布尔值取得或设置autoplay标志
controls布尔值取得或者设置controls属性,用于隐藏或者显示浏览器内置的控件
duration浮点数媒体的总播放时间(秒数)
ended布尔值表示媒体是否播放完成
muted布尔值取得或设置媒体文件是否静音
paused布尔值表示播放器是否暂停
readyState布尔值表示媒体文件是否已经就绪
volume浮点数取得或设置当前音量

自定义媒体播放器

使用video和audio的play和pause方法,可以手工控制媒体文件的播放。组合使用属性,事件和这两个方法,很容创建一个自定义的媒体播放器

<div class="mediaplayer">
    <div class="video">
        <video id="player" src="../images/demo.m4v" poster="mymovie.jpg" 
               width="300" height="200">
            Video player not available.
        </video>
    </div>
    <div class="controls">
        <input type="button" value="Play" id="video-btn">
        <span id="curtime">0</span>/<span id="duration">0
    </div>
</div>
      

简单显示和控制

window.onload = function(){
  var player = document.getElementById("player");
  var btn = document.getElementById("video-btn");
  var curtime = document.getElementById("curtime");
  var duration = document.getElementById("duration");
  duration.innerHTML = player.duration;            

  EventUtil.addHandler(btn, "click", function(event){
    if (player.paused){
      player.play();
      btn.value = "Pause";
    } else {
      player.pause();
      btn.value = "Play";
    }
  });
  
  setInterval(function(){
    curtime.innerHTML = player.currentTime;
  }, 250);    
};
      

示例:简单的嵌入音频

<audio id="drums" controls>
  <source src="sounds/ogg/drums.ogg" type="audio/ogg">
  <source src="sounds/mp3/drums.mp3" type="audio/mpeg">
  <a href="sounds/mp3/drums.mp3">下载 drums.mp3  
</audio>
      

示例:简单的嵌入视频

<video controls>
  <source src="video/h264/01_blur.mp4">
  <source src="video/theora/01_blur.ogv">
  <source src="video/webm/01_blur.webm">
</video>
      

Apple 的<video> Demo

Description
http://www.apple.com/html5/showcase/video/

Apple 的<audio> Demo

Description
http://www.apple.com/html5/showcase/audio//

RGraph

RGraph 是用JavaScript写的HTML5 图表库,使用HTML5 canvas进行绘制,并且支持超过20种不同的图表类型。

在浏览器中使用JavaScript绘制图表, 意味着页面大小更小,速度更快和服务器负载更低。

RGraph简单易用

<script type="text/javascript" src="../libraries/RGraph.common.core.js" ></script>
<script type="text/javascript" src="../libraries/RGraph.bar.js" ></script>
...
    <canvas id="cvs" width="600" height="250">[No canvas support]</canvas>
    
<script>
		window.onload = function ()
		{
				var bar = new RGraph.Bar('cvs', [5,4,1,6,8,5,3]);
				bar.Set('chart.labels', ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday']);
				bar.Draw();
		}
</script>
      

扩展阅读

<Thank you!>