高程3总结#第15章使用Canvas绘图
使用Canvas绘图
基本用法
要使用<canvas>元素,必须先设置其width和height属性,指定可以绘图的区域大小。出现在开始和结束标签中的内容是后备信息,如果浏览器不支持<canvas>元素,就会显示这些信息
<canvas id="drawing" width="200" height="200">A drawing of something</canvas>
要在这块画布上绘图,需要取得绘图上下文,而取得绘图上下文对象的引用,需要调用getContext()方法并传入上下文的名字,传入"2d",就可以取得2D上下文的对象
var drawing=document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if(drawing.getContext){ var context=drawing.getContext("2d"); //更多代码 }
在使用<canvas>元素之前,首先要检测getContext()方法是否存在
var drawing=document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if(drawing.getContext){ //取得图像的数据URI var imgURI=drawing.toDataURL("image/png"); //显示图像 var image=document.createElement("img"); image.src=imgURI; document.body.appendChild(image); }
2D上下文
- 2D上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0,0)。所有坐标的值都基于这个原点计算,x值越大表示越靠右,y值越大表示越靠下。默认情况下,width和height表示水平和垂直两个方向上可用的像素数目
填充和描边
- 操作得结果取决于两个属性,fillStyle和strokeStyle
这两个属性的值可以是字符串,渐变对象或模拟对象,而且它们的默认值都是"#000000"
var drawing=document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if(drawing.getContext){ var content=drawing.getContext("2d"); context.strokeStyle="red"; context.fillStyle="#0000ff" }
绘制矩形
与矩形相关的方法包括fillRect()、strokeRect()、clearRect()三个方法接收4个参数,矩形的x坐标、矩形的y坐标、矩形的宽度和矩形的高度。这些参数的单位都是像素
fillRect()方法在画布上绘制的矩形会填充指定的颜色
var drawing = document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); // 绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); // 绘制半透明的蓝色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50); }
strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边,描边颜色通过strokeStyle属性指定
var drawing=document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if(drawing.getContext){ var context=drawing.getContext("2d"); //绘制红色描边矩形 context.strokeStyle="#ff0000"; context.strokeRect(10,10,50,50); //绘制半透明的蓝色描边矩形 context.strokeStyle="rgba(0,0,255,0.5)"; context.strokeRect(30,30,50,50) }
clearRect()方法用于清除画布上的矩形区域,本质上,这个方法可以把绘制上下文中的某一矩形区域变透明
var drawing = document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); //绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //绘制半透明的蓝色矩形 context.fillStyle = "rgba(0,0,255,0.5)"; context.fillRect(30, 30, 50, 50); // 在两个矩形重叠的地方清除一个小矩形 context.clearRect(40, 40, 10, 10); }
绘制路径
要绘制路径,首先必须调用beginPath()方法,表示要开始绘制的新路径
- arc(x, y, radius, startAngle, endAngle, counterclockwise),以 (x,y) 为圆心绘制一条弧线,弧线半径为 radius ,起始和结束角度(用弧度表示)分别为 startAngle 和endAngle 。最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false表示按顺时针方向计算。
- arcTo(x1, y1, x2, y2, radius),从上一点开始绘制一条弧线,到 (x2,y2) 为止,并且以给定的半径 radius 穿过 (x1,y1) 。
- bezierCurveTo(c1x, c1y, c2x, c2y, x, y),从上一点开始绘制一条曲线,到 (x,y) 为止,并且以 (c1x,c1y) 和 (c2x,c2y) 为控制点。
- lineTo(x, y),从上一点开始绘制一条直线,到 (x,y) 为止。
- moveTo(x, y),将绘图游标移动到 (x,y) ,不画线。
- quadraticCurveTo(cx, cy, x, y),从上一点开始绘制一条二次曲线,到 (x,y) 为止,并且以 (cx,cy) 作为控制点。
- rect(x, y, width, height),从点 (x,y) 开始绘制一个矩形,宽度和高度分别由 width 和height 指定。这个方法绘制的是矩形路径,而不是 strokeRect() 和 fillRect() 所绘制的独立的形状。
var drawing = document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); // 开始路径 context.beginPath(); // 绘制外圆 context.arc(100, 100, 99, 0, 2 * Math.PI, false); // 绘制内圆 context.moveTo(194, 100); context.arc(100, 100, 94, 0, 2 * Math.PI, false); // 绘制分针 context.moveTo(100, 100); context.lineTo(100, 15); // 绘制时针 context.moveTo(100, 100); context.lineTo(35, 100); // 描边路径 context.stroke(); }
绘制文本
- 绘制文本主要两个方法:fillText()和strokeText()。这两个方法都可以接收4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度
这两个方法以3个属性为基础
- font,表示文本样式、大小及字体,用 CSS 中指定字体的格式来指定,例如 "10px Arial" 。
- textAlign,表示文本对齐方式。可能的值有 "start" 、 "end" 、 "left" 、 "right" 和 "center" 。建议使用 "start" 和 "end" ,不要使用 "left" 和 "right" ,因为前两者的意思更稳妥,能同时适合从左到右和从右到左显示(阅读)的语言。
- textBaseline,表示文本的基线。可能的值有 "top" 、 "hanging" 、 "middle" 、 "alphabetic" 、"ideographic" 和 "bottom" 。
//正常 context.font = "bold 14px Arial"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText("12", 100, 20); // 起点对齐 context.textAlign = "start"; context.fi llText("12", 100, 40); // 终点对齐 context.textAlign = "end"; context.fi llText("12", 100, 60);
变换
修改变换矩阵
- rotate(angle),围绕原点旋转图像 angle 弧度。
- scale(scaleX, scaleY),缩放图像,在 x 方向乘以 scaleX ,在 y 方向乘以 scaleY 。 scaleX和 scaleY 的默认值都是 1.0。
- translate(x, y),将坐标原点移动到 (x,y) 。执行这个变换之后,坐标(0,0)会变成之前由 (x,y)表示的点。
- transform(m1_1, m1_2, m2_1, m2_2, dx, dy),直接修改变换矩阵,方式是乘以如下矩阵。
m1_1 m1_2 dx
m2_1 m2_2 dy
0 0 1 - setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy),将变换矩阵重置为默认状态,然后再调用 transform()
var drawing = document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"); //开始路径 context.beginPath(); //绘制外圆 context.arc(100, 100, 99, 0, 2 * Math.PI, false); //绘制内圆 context.moveTo(194, 100); context.arc(100, 100, 94, 0, 2 * Math.PI, false); //变换原点 context.translate(100, 100); // 旋转表针 context.rotate(1); //绘制分针 context.moveTo(0,0); context.lineTo(0, -85); //绘制时针 context.moveTo(0, 0); context.lineTo(-65, 0); //描边路径 context.stroke(); }
绘制图像
使用drawImage()将图像绘制到画布上,三种不同的参数组合
- 3个参数:传入HTML<img>元素,绘制图像的起点的x和y坐标
- 5个参数:3个参数+目标宽度和目标高度
- 9个参数:要绘制的图像,源图像的x坐标,源图像的y坐标,源图像的宽度,源图像的高度,目标图像的x坐标,目标图像的y坐标,目标图像的宽度,目标图像的高度
阴影
2D上下文根据属性值自动绘制阴影
- shadowColor,用 CSS 颜色格式表示的阴影颜色,默认为黑色。
- shadowOffsetX,形状或路径 x 轴方向的阴影偏移量,默认为 0。
- shadowOffsetY,形状或路径 y 轴方向的阴影偏移量,默认为 0。
- shadowBlur,模糊的像素数,默认 0,即不模糊。
var context = drawing.getContext("2d"); // 设置阴影 context.shadowOffsetX = 5; context.shadowOffsetY = 5; context.shadowBlur = 4; context.shadowColor = "rgba(0, 0, 0, 0.5)"; //绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //绘制蓝色矩形 context.fillStyle = "rgba(0,0,255,1)"; context.fillRect(30, 30, 50, 50);
渐变
要创建一个新的线性渐变,可以调用createLinearGradient()方法,这个方法接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标
//绘制红色矩形 context.fillStyle="#ff0000"; context.fillRect(10,10,50,50); //绘制渐变矩形 context.fillStyle=gradient; context.fillRect(30,30,50,50);
模式
var image=document.images[0], pattern=context.createPattern(image,"repeat"); //绘制矩形 context.fillStyle=pattern; context.fillRect(10,10,150,150);
使用图像数据
getImageData()取得原始图像数据,这个方法接收4个参数:要取得其数据的画面区域的x和y坐标以及该区域的像素宽度和高度
var drawing = document.getElementById("drawing"); //确定浏览器支持<canvas>元素 if (drawing.getContext){ var context = drawing.getContext("2d"), image = document.images[0], imageData, data, i, len, average, red, green, blue, alpha; //绘制原始图像 context.drawImage(image, 0, 0); //取得图像数据 imageData = context.getImageData(0, 0, image.width, image.height); data = imageData.data; for (i=0, len=data.length; i < len; i+=4){ red = data[i]; green = data[i+1]; blue = data[i+2]; alpha = data[i+3]; //求得 rgb 平均值 average = Math.floor((red + green + blue) / 3); //设置颜色值,透明度不变 data[i] = average; data[i+1] = average; data[i+2] = average; } //回写图像数据并显示结果 imageData.data = data; context.putImageData(imageData, 0, 0); }
合成
应用到2D上下文所有绘制操作得属性。globalAlpha和globalCompositionOperation
globalAlpha是一个介于0和1之间的值,用于指定所有绘制的透明度,默认值为0,如果所有后续操作都要基于相同的透明度,就可以先把globalAlpha设置为适当值,然后绘制,最后再把它设置回默认值0
//绘制红色矩形 context.fillStyle = "#ff0000"; context.fillRect(10, 10, 50, 50); //修改全局透明度 context.globalAlpha = 0.5; //绘制蓝色矩形 context.fillStyle = "rgba(0,0,255,1)"; context.fillRect(30, 30, 50, 50); //重置全局透明度 context.globalAlpha = 0
globalCompositionOperation表示绘制的图形怎样与先绘制的图形结合,这个属性的值是字符串
- source-over默认值,后绘制的图形位于先绘制的图形上方。
- source-in,后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明。
- source-out,后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明。
- source-atop,后绘制的图形与先绘制的图形重叠的部分可见,先绘制图形不受影响。
- destination-over,后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见。
- destination-in,后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明。
- destination-out,后绘制的图形擦除与先绘制的图形重叠的部分。
- destination-atop,后绘制的图形位于先绘制的图形下方,在两者不重叠的地方,先绘制的图形会变透明。
- lighter,后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮。
- copy,后绘制的图形完全替代与之重叠的先绘制图形。
- xor,后绘制的图形与先绘制的图形重叠的部分执行“异或”操作。
WebGL
类型化数组
- 类型化数组也是数组,只不过其元素被设置为特定类型的值
- 类型化数组的核心就是一个名为ArrayBuffer的类型。
WebGL上下文
支持
- Firefox 4+和 Chrome 都实现了 WebGL API。Safari 5.1 也实现了 WebGL,但默认是禁用的。