Canvas(画布)用于在网页实时生成图像,而且能够操做图像内容,基本上它是一个能够用JavaScript操做的位图(bitmap)。css
<canvas>
网页元素。<canvas id="myCanvas" width="400" height="200">
你的浏览器不支持canvas!
</canvas>
复制代码
<canvas>
的浏览器将会忽略在容器中包含的内容,正常渲染canvas。<canvas>
的浏览器会显示代替内容width
和height
html
属性设置width/height
时只影响画布自己不影画布内容css
属性设置width/height
时不但会影响画布自己的高宽,还会使画布中的内容等比例缩放(缩放参照于画布默认的尺寸)<canvas>
元素只是创造了一个固定大小的画布,要想在它上面去绘制内容,须要用getContext()
方法找到它的渲染上下文。//获取canvas容器
var canvas = document.getElementById('myCanvas');
//建立一个渲染上下文
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
}
复制代码
上面代码中,getContext
方法指定参数2d
,表示该canvas
节点用于生成2D图案(即平面图案)。若是参数是webgl
,就表示用于生成3D图像(即立体图案),这部分实际上单独叫作WebGL API。html
canvas
画布提供了一个用来做图的平面空间,该空间的每一个点都有本身的坐标,x表示横坐标,y表示竖坐标。原点(0, 0)位于图像左上角,x轴的正向是原点向右,y轴的正向是原点向下前端
fillStyle
:设置填充颜色,默认黑色strokeStyle
:设置轮廓颜色,默认黑色lineWidth
:设置线条宽度,属性值为任意正整数,默认值是1.0。lineJoin
:控制线条相交的方式(默认是miter
)
round
: 圆角bevel
: 斜角miter
: 直角lineCap
:线段末端的形状(默认值是 butt
)
butt
:线段末端以方形结束。round
:线段末端以圆形结束square
:线段末端以方形结束,可是增长了一个宽度和线段相同,高度是线段厚度一半的矩形区域save()
时,将样式容器中的状态压栈,保存上下文环境restore()
时,将样式栈的栈顶状态弹出到样式容器中,恢复到上一次保存的上下文环境//用save方法,保存了当前设置
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,100);
//使用restore方法,恢复了保存前的设置
ctx.restore();
//绘制了一个没有阴影的矩形
ctx.fillStyle = '#000000';
ctx.fillRect(180,10,150,100);
复制代码
beginPath
时,清空整个路径容器ctx.save();
//关于样式的设置
ctx.beginPath();
//关于路径的设置
ctx.restore();
复制代码
translate(x, y)
:将canvas坐标原点移动到(x,y),translate是累加的rotate(angle)
:围绕原点旋转图像angle弧度(顺时针),rotate是累加的scale(x, y)
:缩放图像;x和y分别是横轴和纵轴的缩放因子(正值),scale是累加的
//填充矩形(x, y是横纵坐标,原点在canvas的左上角)
ctx.fillRect(x, y, width, height);
//边框矩形,默认1px 黑色。
ctx.strokeRect(x, y, width, height);
//清除指定的矩形区域,变为透明
ctx.clearRect(x, y, width, height); //绘制动态效果时,经常使用来清除整个画布
复制代码
rect(x, y, width, height)
:绘制矩形路径//新建路径,beginPath是绘制新图形的开始
ctx.beginPath()
//路径(线)的起点,通常在上面这条命令后执行
ctx.moveTo(x, y)
//线的终点
ctx.lineTo(x, y)
//闭合路径,不是必须的,若是线的终点跟起点同样,会自动闭合。
ctx.closePath()
//经过线条绘制轮廓(边框)
ctx.stroke() //不会自动调用closePath()
//经过路径填充区域(实心)
ctx.fill() //自动调用closePath()
复制代码
例:绘制一个三角形web
ctx.beginPath();
ctx.moveTo(75, 50); //路径起点
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill(); //自动将路径闭合,并默认填充黑色。
复制代码
quadraticCurveTo(cp1x, cp1y, x, y)
:绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,起始点为moveto时指定的点,x,y为结束点。bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
:绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,起始点为moveto时指定的点,x,y为结束点。ctx.isPointInPath(x, y)
:判断在当前路径中是否包含检测点
fillText(string, x, y)
:在指定的(x,y)位置填充指定的文本
strokeText(string, x, y)
:在指定的(x,y)位置填充指定的文本// 设置字体,必需要有大小和字体
ctx.font = "Bold 20px Arial";
// 设置对齐方式,可选值包括: left, right center
ctx.textAlign = "left";
// 设置填充颜色
ctx.fillStyle = "#008600";
// 设置字体内容,以及在画布上的位置
ctx.fillText("Hello!", 10, 50);
// 绘制空心字
ctx.strokeText("Hello!", 10, 100);
复制代码
measureText()
方法:返回一个TextMetrics 对象,包含关于文本尺寸的信息(例如文本的宽度)//绘制圆形
ctx.arc(x, y, r, start, end, true/false) //(x, y)圆心,r半径,start和end是开始和结束角度,false表示顺时针(默认),true表示逆时针。
//绘制弧线
ctx.arcTo(x1, y1, x2, y2, r); //当前端点、(x1,y1)和(x2,y2)这三个点连成的弧线,r是半径。
复制代码
例:绘制实心的圆形算法
ctx.beginPath();
ctx.arc(60, 60, 50, 0, Math.PI*2, true);
ctx.fillStyle = "#000000";
ctx.fill();
复制代码
例:绘制空心圆形canvas
ctx.beginPath();
ctx.arc(60, 60, 50, 0, Math.PI*2, true);
ctx.lineWidth = 1.0;
ctx.strokeStyle = "#000";
ctx.stroke();
复制代码
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);
复制代码
createLinearGradient(x1, y1, x2, y2)
:建立一个canvas渐变(线性渐变)
gradient.addColorStop(position, color)
gradient
:createLinearGradient
的返回值addColorStop
方法接受 2 个参数:
position
参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置,例如,0.5 表示颜色会出如今正中间。color
参数必须是一个有效的 CSS 颜色值,如 #FFF, rgba(0,0,0,1)等等//建立一个canvas线性渐变,返回`CanvasGradient`对象的实例
var myGradient = ctx.createLinearGradient(0, 0, 0, 160);
myGradient.addColorStop(0, "#BABABA");
myGradient.addColorStop(1, "#636363");
//绘制渐变填充的矩形
ctx.fillStyle = myGradient;
ctx.fillRect(10,10,200,100);
复制代码
createRadialGradient(x1, y1, r1, x2, y2, r2)
:canvas渐变(径向渐变)
Canvas API 容许将图像文件插入画布,作法是读取图片后,使用
drawImage
方法在画布内进行重绘。api
drawImage(image, x, y, width, height)
image
:图像文件的DOM元素x
和 y
:绘制该图像的起始坐标width
和 height
:目标宽高var image = new Image();
image.src = 'image.png';
image.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext('2d').drawImage(image, 0, 0);
// 插入页面底部
document.body.appendChild(image);
return canvas;
}
复制代码
createPattern(image, repetition)
image
:图像源epetition
repeat
repeat-x
repeat-y
no-repeat
通常状况下,咱们都会将fillstyle
的值设置为createPattern
返回的对象,只表示在某个特定的区域内显示重复的图像。数组
经过
getImageData
方法和putImageData
方法,能够处理每一个像素,进而操做图像内容。浏览器
ctx.getImageData(sx, sy, sw, sh)
:得到一个包含画布场景像素数据的ImageData
对象,它表明了画布区域的对象数据
ImageData
对象中存储着canvas对象真实的像素数据,它包含如下几个只读属性:
width
:图片宽度,单位是像素height
:图片高度,单位是像素data
:Uint8ClampedArray类型的一维数组, 包含着RGBA
格式的整型数据,范围在0至255之间(包括255)var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
复制代码
putImageData(myImageData, dx, dy)
:把图像数据绘制到画布上context.putImageData(imageData, 0, 0);
复制代码
假定filter是一个处理像素的函数,那么整个对Canvas的处理流程,能够用下面的代码表示。bash
if (canvas.width > 0 && canvas.height > 0) {
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
filter(imageData);
context.putImageData(imageData, 0, 0);
}
复制代码
ctx.createImageData(width, height)
:建立一个ImageData对象
globalAlpha = value
:设置全局透明度,这个属性影响到 canvas 里全部图形的透明度
globalCompositeOperation
:覆盖合成(source--->新的图像(源);destination--->已经绘制过的图形(目标))
source-over
(默认值):源在上面,新的图像层级比较高source-in
:只留下源与目标的重叠部分(源的那一部分)source-out
:只留下源超过目标的部分source-atop
:砍掉源溢出的部分destination-over
:目标在上面,旧的图像层级比较高destination-in
:只留下源与目标的重叠部分(目标的那一部分)destination-out
:只留下目标超过源的部分destination-atop
:砍掉目标溢出的部分注意是canvas元素接口上的方法
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL('image/png');
return image;
}
复制代码
上面的代码将Canvas数据,转化成PNG data URI。
灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。
grayscale = function (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;
};
复制代码
复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。
sepia = function (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;
};
复制代码