HTML5的定制标签
在HTML5中,<canvas>标签是一个强大的工具,用于在网页上展示图像,并且可以进行高度定制。本质上,它是一个可以通过JavaScript操作的位图(bitmap)。
Canvas API概述
Canvas API 主要用于在网页上实时生成图像,JavaScript 通过该 API 来操作图像内容。使用 Canvas API 具有诸多优点,比如可以减少 HTTP 请求数,降低下载的数据量,从而加快网页的载入时间,同时还能对图像进行实时处理。
使用步骤
1. 创建 Canvas 网页元素
在 HTML 中创建一个 <canvas> 元素,示例代码如下:
<canvas id="myCanvas" width="400" height="200">
您的浏览器不支持 canvas!
</canvas>
如果浏览器不支持 <canvas>,则会显示标签中间的文字“您的浏览器不支持 canvas!”。
2. 获取 Canvas 的 DOM 对象
使用 JavaScript 获取 <canvas> 的 DOM 对象:
var canvas = document.getElementById('myCanvas');
3. 检查浏览器是否支持 Canvas API
通过检查是否部署了 getContext 方法来判断浏览器是否支持 Canvas API:
if (canvas.getContext) {
// 支持 Canvas API,可进行后续操作
}
4. 初始化平面图像的上下文环境
使用 getContext('2d') 方法初始化平面图像的上下文环境:
var ctx = canvas.getContext('2d');
至此,就可以在 <canvas> 中生成平面图像了。
绘图方法
(1)填充颜色
设置填充颜色和笔触颜色:
ctx.fillStyle = "#000000"; // 设置填充色为黑色
ctx.strokeStyle = "#FF6600"; // 设置笔触颜色
(2)绘制矩形
- 绘制实心矩形:
ctx.fillStyle = "#000000"; // 填充颜色,即矩形颜色 ctx.fillRect(x, y, width, height); - 绘制空心矩形:
ctx.strokeStyle = "#FF6600"; // 笔触颜色,即矩形边框颜色 ctx.strokeRect(x, y, width, height); - 清除某个矩形区域的内容:
ctx.clearRect(x, y, width, height);
(3)绘制路径
ctx.beginPath(); // 开始路径绘制
ctx.moveTo(20, 20); // 设置路径起点
ctx.lineTo(200, 20); // 绘制一条到 (200, 20) 的直线
ctx.lineWidth = 1.0; // 设置线宽
ctx.strokeStyle = "#CC0000"; // 设置线的颜色
ctx.stroke(); // 进行线的着色,这时整条线才变得可见
(4)绘制圆形和扇形
- 绘制扇形:
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);arc方法的参数说明:x和y是圆心坐标,radius是半径,startAngle和endAngle是扇形的起始角度和终止角度(以弧度表示),anticlockwise表示作图是应该逆时针画(true)还是顺时针画(false)。 - 绘制实心圆形:
ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI * 2, true); ctx.fillStyle = "#000000"; ctx.fill(); - 绘制空心圆形:
ctx.beginPath(); ctx.arc(60, 60, 50, 0, Math.PI * 2, true); ctx.lineWidth = 1.0; ctx.strokeStyle = "#000"; ctx.stroke();
(5)绘制文本
fillText 方法用于添加文本,strokeText 方法用于添加空心字。使用之前,需设定字体、对齐方向、颜色等属性:
ctx.font = "Bold 20px Arial"; // 设置字体
ctx.textAlign = "left"; // 设置对齐方式
ctx.fillStyle = "#008600"; // 设置填充颜色
ctx.fillText("Hello!", 10, 50); // 设置字体内容,以及在画布上的位置
ctx.strokeText("Hello!", 10, 100); // 绘制空心字
需要注意的是,fillText 方法不支持文本断行,即所有文本出现在一行内。所以如果要生成多行文本,只有调用多次 fillText 方法。
2.1 渐变
设置渐变颜色:
var myGradient = ctx.createLinearGradient(0, 0, 0, 160);
myGradient.addColorStop(0, "#BABABA");
myGradient.addColorStop(1, "#636363");
createLinearGradient 方法的参数是 (x1, y1, x2, y2),其中 x1 和 y1 是起点坐标,x2 和 y2 是终点坐标。通过不同的坐标值,可以生成从上至下、从左至右的渐变等。
addColorStop 方法的参数是 (offset, color),其中 offset 是一个范围在 0.0 到 1.0 之间的浮点值,表示渐变的开始点和结束点之间的一部分,offset 为 0 对应开始点,offset 为 1 对应结束点,color 为 CSS 颜色值的字符串表示。
使用方法如下:
ctx.fillStyle = myGradient;
ctx.fillRect(10, 10, 200, 100);
2.2 阴影
ctx.shadowOffsetX = 10; // 设置水平位移
ctx.shadowOffsetY = 10; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度
ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; // 设置阴影颜色
ctx.fillStyle = "#CC0000";
ctx.fillRect(10, 10, 200, 100);
图像处理方法
3.1 插入图像
<canvas> 允许将图像文件插入画布,做法是读取图片后,使用 drawImage 方法在画布内进行重绘。
var img = new Image();
img.src = "image.png";
// 由于图像的载入需要时间,drawImage 方法只能在图像完全载入后才能调用
img.onload = function () {
if (img.width != canvas.width) {
canvas.width = img.width;
}
if (img.height != canvas.height) {
canvas.height = img.height;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(img, 0, 0);
};
drawImage() 方法接受三个参数,第一个参数是图像文件的 DOM 元素(即 <img> 标签),第二个和第三个参数是图像左上角在 <canvas> 元素中的坐标,上例中的 (0, 0) 就表示将图像左上角放置在 <canvas> 元素左上角。
3.2 读取 Canvas 的内容
getImageData 方法可以用来读取 Canvas 的内容,返回一个对象,包含了每个像素的信息:
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
imageData 对象有一个 data 属性,它的值是一个一维数组。该数组的值,依次是每个像素的红、绿、蓝、alpha 通道值,因此该数组的长度等于图像的像素宽度 图像的像素高度 4,每个值的范围是 0~255。这个数组不仅可读,而且可写,因此通过操作这个数组的值,就可以达到操作图像的目的。修改这个数组后,使用 putImageData 方法将数组内容重新写回 Canvas:
ctx.putImageData(imageData, 0, 0);
3.3 像素处理
以下是几种常见的像素处理方法:
(1)灰度效果
灰度图(grayscale)是取红、绿、蓝三个像素值的算术平均值,将图像转成黑白形式:
function grayscale(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3;
}
return pixels;
}
(2)复古效果
复古效果(sepia)是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使图像有一种古旧的效果:
function sepia(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = (r * 0.393) + (g * 0.769) + (b * 0.189); // red
d[i + 1] = (r * 0.349) + (g * 0.686) + (b * 0.168); // green
d[i + 2] = (r * 0.272) + (g * 0.534) + (b * 0.131); // blue
}
return pixels;
}
(3)红色蒙版效果
红色蒙版指的是让图像呈现一种偏红的效果,算法是将红色通道设为红、绿、蓝三个值的平均值,而将绿色通道和蓝色通道都设为 0:
function red(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = (r + g + b) / 3; // 红色通道取平均值
d[i + 1] = d[i + 2] = 0;
}
return pixels;
}
(4)亮度效果
亮度效果(brightness)是指让图像变得更亮或更暗,算法是将红色通道、绿色通道、蓝色通道,同时加上一个正值或负值:
function brightness(pixels, delta) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
d[i] += delta; // red
d[i + 1] += delta; // green
d[i + 2] += delta; // blue
}
return pixels;
}
(5)反转效果
反转效果(invert)是指图片呈现一种色彩颠倒的效果,算法为红、绿、蓝通道都取各自的相反值(255 - 原值):
function invert(pixels) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
d[i] = 255 - d[i];
d[i + 1] = 255 - d[i + 1];
d[i + 2] = 255 - d[i + 2];
}
return pixels;
}
3.4 将 Canvas 转化为图像文件
对图像数据作出修改以后,可以使用 toDataURL 方法,将 Canvas 数据重新转化成一般的图像文件形式:
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
保存和恢复上下文
save 方法用于保存上下文环境,restore 方法用于恢复到上一次保存的上下文环境:
ctx.save();
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 5;
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.fillStyle = "#CC0000";
ctx.fillRect(10, 10, 150, 150);
ctx.restore();
ctx.fillStyle = "#000000";
ctx.fillRect(180, 10, 150, 100);
上面的代码一共绘制了两个矩形,前一个有阴影,后一个没有。