canvas是html5提供给我们的一个绘图标签,默认大小300X150,背景透明,必须使用脚本来完成绘图。
使用标签
<canvas id="canvas" style="border:1px solid #ddd;display:block;margin:20px auto;">canvas>
控制canvas
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
}
与SVG比较:Canvas基于像素,提供2D绘制函数,是一种HTML元素类型,依赖于HTML,只能通过脚本绘制图形;SVG为矢量,提供一系列图形元素(Rect, Path, Circle, Line …),还有完整的动画,事件机制,本身就能独立使用,也可以嵌入到HTML中。
设置或返回用于笔触的颜色、渐变或模式
context.strokeStyle="red";
设置或返回当前的线条宽度
context.lineWidth=10;
设置或返回线条的结束端点样式
context.lineCap="round";
值 | 含义 |
---|---|
butt | 默认值,正常状态 |
round | 凸出一部分,圆形头 |
square | 凸出一部分,方形头 |
设置或返回两条线相交时,所创建的拐角类型
context.lineJoin="round";
值 | 含义 |
---|---|
miter | 默认值,尖角,context.miterLimit=10 |
bevel | 粗纸带斜接形式,平的 |
round | 圆角形式 |
设置或返回最大斜接长度,只有当 lineJoin 属性为 “miter” 时,miterLimit 才有效。
context.miterLimit=5;
设置或返回用于填充绘画的颜色、渐变或模式
context.fillStyle="yellow";
在指定的区域内平铺图像,参数1:image、canvas、video;参数2:no-repeat、repeat-x、repeat-y和repeat
context.createPattern(backgroundImage,"repeat");
示例
var backgroundImage=new Image();
backgroundImage.src="dow.png";
backgroundImage.onload=function(){
var pattern=context.createPattern(backgroundImage,"repeat");
context.fillStyle=pattern;
context.fillRect(400,400,600,600);
}
设置绘图的透明度,介于0.0-1.0之间,表示完全透明-不透明
context.globalAlpha=1;//默认值
主要控制图形遮挡时怎么处理,谁在上面,重叠部分怎么显示等。
context.globalCompositeOperation="source-over";//默认值
值:先绘制的为目标图像,后绘制的为源图像
先绘制一个区域,然后进行裁剪,再绘制图形时,只有在裁剪区域的部分可见。
context.clip();
示例
// 裁剪矩形区域
context.rect(50,20,200,120);
context.stroke();
context.clip();
// 在 clip() 之后绘制绿色矩形
context.fillStyle="green";
context.fillRect(0,0,150,100);
为绘图添加阴影效果
context.shadowColor="gray";//设置或返回用于阴影的颜色
context.shadowOffsetX=20;//设置或返回阴影距形状的水平距离
context.shadowOffsetY=20;//设置或返回阴影距形状的垂直距离
context.shadowBlur=5;//设置或返回用于阴影的模糊级别
创建线性渐变,参数1、2:渐变起始坐标;参数3、4:渐变结束位置
var linearGrad=context.createLinearGradient(0,0,400,400);
规定该位置的停止颜色,参数一:0.0-1.0,表示起始位置-结束位置;参数2:该位置颜色
linearGrad.addColorStop(0.0,'#fff');
示例
var linearGrad=context.createLinearGradient(0,0,400,400);
linearGrad.addColorStop(0.0,'#fff');//0.0起始位置
linearGrad.addColorStop(1.0,'#000');//1.0结束位置
context.fillStyle=linearGrad;
context.fillRect(0,0,400,400);
创建径向渐变,参数1、2:起始圆心坐标;参数3:起始圆半径;参数4、5:结束圆心坐标;参数6:结束圆半径
var radialGrad=context.createRadialGradient(400,400,0,400,400,200);
示例
var radialGrad=context.createRadialGradient(400,400,0,400,400,200);
radialGrad.addColorStop(0.0,'white');
radialGrad.addColorStop(1.0,'black');
context.fillStyle=radialGrad;
context.fillRect(200,200,400,400);
context.moveTo(100,100);//把笔尖移到该位置
context.lineTo(200,300);//创建从笔尖位置到当前位置的线段
context.stroke();//绘制已定义的路径
创建矩形路径,需调用stroke方法进行绘制。
context.rect(x,y,width,height);
context.stroke();
使用fillStyle属性绘制出填充矩形。
context.fillRect(x,y,width,height);
使用strokeStyle属性绘制出矩形边框。
context.strokeRect(x,y,width,height);
对矩形区域进行清空操作。
context.clearRect(x,y,width,height);
按照绘制线段的方式,计算好每个点的位置,最后使图形封闭即可。
context.moveTo(100,100);
context.lineTo(200,300);
context.lineTo(100,500);
context.lineTo(200,500);
context.lineTo(300,300);
context.lineTo(200,100);
context.lineTo(100,100);
context.stroke();
根据圆心、半径、弧度来绘制圆弧。
context.arc(x,y,r,startAngle,endAngle,anticlockwise=false);
context.stroke();
根据两条切线来绘制圆弧。
context.moveTo(x0,y0);//指定起始点
context.arcTo(x1,y1,x2,y2,R);//控制点、终止点、半径
context.stroke();
将根据(x0,y0)、(x1,y1)、(x2,y2)三个点组成的两条线(x0,y0)-(x1,y1)、(x1,y1)-(x2,y2)画圆弧,使得圆弧与两条线相切。起始点和终止点不一定是圆弧的起始点和终止点。
context.moveTo(x0,y0);//指定起始点
context.quadraticCurveTo(x1,y1,x2,y2);//控制点、终止点
context.stroke();
将根据(x0,y0)、(x1,y1)、(x2,y2)三个点组成的两条线(x0,y0)-(x1,y1)、(x1,y1)-(x2,y2)画曲线,起始点和终止点就是是曲线的起始点和终止点。
context.moveTo(x0,y0);//指定起始点
context.bezierCurveTo(x1,y1,x2,y2,x3,y3);//控制点、控制点、终止点
context.stroke();
将根据(x0,y0)、(x1,y1)、(x2,y2)、(x3,y3)四个点组成的两条线(x0,y0)-(x1,y1)、(x2,y2)-(x3,y3)画曲线,起始点和终止点就是是曲线的起始点和终止点。
自动使图形封闭,否则连接处将会产生空隙。
context.begin();
...
context.closePath();
非零环绕原则:内部图形逆时针,外部图形顺时针,则填充它们之间的区域。
示例
context.beginPath();
context.arc(400,400,100,0,Math.PI*2,false);
context.arc(400,400,300,0,Math.PI*2,true);
context.closePath();
context.fillStyle="blue";
context.shadowColor="gray";
context.shadowOffsetX=5;
context.shadowOffsetY=5;
context.shadowBlur=10;
context.fill();
判断该位置是否在当前路径内。
context.isPointInPath(x,y);
实心文字,参数1:书写的字符串;参数2:书写的位置;参数3:可选参数,文字宽度
context.fillText(string,x,y,[maxlen]);
空心文字,参数1:书写的字符串;参数2:书写的位置;参数3:可选参数,文字宽度
context.strokeText(string,x,y);
context.font=font-style font-variant font-weight font-size font-family
文本左右倚靠方式,start、end、center、left、right
context.textAlign=left;
文本上下基线,alphabetic、top、hanging、middle、ideographic、bottom
context.textBaseline=alphabetic;//default
得到文本的宽度
context.measureText(string).width;
将图像绘制在(x,y)位置
context.drawImage(image,x,y);
示例
var image=new Image();
image.onload=function(){
context.drawImage(image,0,0);
}
image.src="dow.jpg";
更改图像的大小绘制在(x,y)位置
context.drawImage(image,x,y,width,height);
示例
var image=new Image();
image.onload=function(){
context.drawImage(image,0,0,200,100);
}
image.src="dow.jpg";
剪切图像的某一部分绘制在画布中
context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);
(sx, sy, sw, sh):剪切图像上的矩形区域
(dx, dy, dw, dh):绘制在画布上的矩形区域
以指定的尺寸(以像素计)创建新的 ImageData 对象。
var imgData=context.createImageData(width,height);
创建与指定的另一个 ImageData 对象尺寸相同的新 ImageData 对象(不会复制图像数据)。
var imgData=context.createImageData(imageData);
得到ImageDate对象,该对象拷贝了画布指定矩形区域的像素数据。
var imageData=context.getImageData(x, y, width, height);
每个像素存在着四方面信息RGBA,以数组形式存储在ImageData对象的data属性中。
var data=imageDate.data;
var red,green,blue,alpha
for(i = 0; i < data.length; i += 4) {
red=data[i];//0-255
green=data[i + 1];//0-255
blue=data[i + 2];//0-255
alpha=data[i + 3];//0-255
}
将图像数据放在(dx,dy)位置进行显示。
context.putImageData(imagedata,dx,dy);
将图像数据放在(dx,dy)位置,相对于图像左上角位置的矩形区域(dirtyX,dirtyY,dirtyWidth,dirtyHeight)显示图像。
context.putImageData(imagedata,dx,dy,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
功能:将一个画布作为图像绘制在另一个画布上。
得到URL
var dataURL = canvas.toDataURL();
将图像URL绘制在 Canvas 上
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = dataURL;
将原点位移到(x,y)的位置,然后进行绘制
context.translate(x,y);
将下面绘图旋转deg弧度
context.rotate(deg);
将下面绘图横向进行sx倍的缩放,纵向进行sy倍的缩放
context.scale(sx,sy);
副作用:左上角坐标、宽度、高度、边框宽度都会缩放。
进行位移操作后,再进行位移操作,将会根据第一次位移后的状态进行位移,也就是说两次位移会进行叠加。为了每次根据最初的状态进行图像变换,我们可以再每一次位移操作后,再位移回去,即位移一个(-x,-y)。但是每次都这样的话,会比较麻烦,我们需要状态保存,每次位移前先保存当前状态,操作完成后调用恢复函数,就可以恢复到保存之前的状态。
context.save();
...
context.restore();
|a c e|
|b d f|
|0 0 1|
替换变换矩阵为当前矩阵
context.transform(a,b,c,d,e,f);
参数 | 描述 |
---|---|
a | 水平缩放绘图 |
b | 水平倾斜绘图 |
c | 垂直倾斜绘图 |
d | 垂直缩放绘图 |
e | 水平移动绘图 |
f | 垂直移动绘图 |
将变换矩阵重置为单位矩阵,然后替换为当前矩阵。
context.setTransform(a,b,c,d,e,f);
获得鼠标点击的画布位置
canvas.addEventListener("mousemove","detect");//鼠标滑过执行这个方法
function detect(event){
var x=event.clientX-canvas.getBoundingClientRect().left;
var y=event.clientY-canvas.getBoundingClientRect().top;
}
每隔t毫秒执行一次funcName函数
var f=setTimeout("funcName",t)
取消定时事件
clearTimeout(t)