JavaScript & HTML5 Canvas 概览 更新时间2014-0411-1805

HTML Canvas

坐标体系:矩形区域的左上角为坐标原点(0,0),向右为x轴,向下为y轴。

检测浏览器是否支持Canvas(IE系列从IE9开始支持):

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
if(!document.createElement("canvas").getContext){
alert("浏览器不支持Canvas");
}
//]]>
</script>
</head>
<body>
</body>
</html>

检测浏览器是否支持Canvas

Canvas的各种属性表:

属性名称 描述  
fillStyle 填充属性 可以为一个字符串颜色值,也可以为gradient对象,或者pattern对象
strokeStyle 绘制属性 可以为一个字符串颜色值,也可以为gradient对象,或者pattern对象
font 字体样式定义  
globalAlpha 图形透明设置  
globalCompositeOperation 前后绘制的图形组合显示效果  
lineCap 线帽  
lineJoin 两条线段连接处的样式  
lineWidth 线宽 为一个数字
miterLimit 定义斜连接线和线条宽度的最大比率,这个属性只有当lineJoin="miter"时才有用  
shadowBlur 阴影模糊  
shadowColor 阴影色彩  
shadowOffsetX 阴影横向偏移  
shadowOffsetY 阴影纵向偏移  
textAlign 文本水平对齐  "start","end","left","right","center"
textBaseline 文本垂直对齐  "aplhabetic","top","hanging","middle","ideographic","bottom"

对于有global的属性都是全局属性,在使用的时候注意要先save()再restore()配置。

Canvas中的保存和回复

通过save()方法保存渲染上下文,通过restore()方法恢复上次保存的渲染上下文。

Canvas中的线

一个路径绘制通常会在beginPath()和closePath()之间完成;通过stroke()来执行实际的绘制。
弧度:一个圆一周的弧度为2π,一周的角度为360。
绘制弧线的arc()方法需要指定(圆心位置x,圆心位置y,半径,起始弧度,结束弧度,绘图方向),以圆心画弧;
绘制弧线的arcTo()方法需要指定(两条线的交点X,两条线的交点Y,其中一条线的经过点X,其中一条线的经过点Y,弧线半径),以相交线画弧。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
g.strokeStyle="#09f";
g.lineWidth=2; g.beginPath(); g.moveTo(10,10);
g.lineTo(100,100);
g.lineTo(0,100); // 圆心X位置,原型Y位置,半径,起始弧度,结束弧度,是否逆时针.
g.arc(0,100,50,-2*Math.PI*(45/360),2*Math.PI*(270/360),true);
// 以50,50作为两条线的焦点,两条线分别经过上次绘图的结束点和0,0参数点,并以10为半径的曲线.
g.arcTo(50,50,0,0,10); g.stroke();
g.closePath();
}
//]]>
</script>
</head>
<body>
</body>
</html>

Canvas中的lineTo()、arc()、arcTo()的使用

二次方曲线quadraticCurveTo(控制点X坐标,控制点Y坐标,结束点X坐标,结束点Y坐标) 通过一个控制点来绘制曲线:

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
g.strokeStyle="#09f";
g.lineWidth=2; g.beginPath(); g.moveTo(0,100);
g.quadraticCurveTo(50,0,100,100);
g.stroke();
g.closePath();
}
//]]>
</script>
</head>
<body>
</body>
</html>

quadraticCurveTo

贝塞尔曲线bezierCurveTo()方法比quadraticCurveTo()方法多一个控制点:

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
g.strokeStyle="#09f";
g.lineWidth=2; g.beginPath(); g.moveTo(0,100);
g.bezierCurveTo(50,0,75,125,100,100);
g.stroke();
g.closePath();
}
//]]>
</script>
</head>
<body>
</body>
</html>

bezierCurveTo

Canvas没有专门绘制圆的API,可以通过arc()来绘制,再通过filleStyle属性来设置填充,并通过fill()来关闭路径并填充。

Canvas中的矩形

fillRect()指定左上角和右下角指定下矩形,fileRect()调用的时候会星清晰化路径;
strokeRect()可以绘制一个矩形的边框,该方法也会清晰化路径。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
g.strokeStyle="#09f";
g.fillStyle="green";
g.lineWidth=2; g.beginPath();
g.moveTo(0,100);
g.lineTo(50,50);
g.fillRect(100,100,50,50);
// 对于2px像素的线宽,在绘制的时候会两边平分1像素,同时canvas的默认画布大小为300*150px
// 这里可以看到绘制出的矩形边框的右边和下边只有1像素.
g.strokeRect(100,120,200,30);
g.lineTo(50,100);
g.stroke();
g.closePath();
}
//]]>
</script>
</head>
<body>
</body>
</html>

绘制矩形以及Canvas中的线宽绘图对齐位置

Canvas中的图片

在Canvas中可以使用drawImage()方法或者createPattern()方法来绘制图片。

drawImage有3种参数格式:drawImage(img,x,y); drawImage(img,x,y,w,h); drawImage(img,s1x,s1y,s2w,y2h,d1x,d1y,d2w,d2h);
createPattern(img,css-position)方法主要用于背景图片的处理,第二个参数很像CSS中的background-position属性。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
var img=new Image();
img.onload=function(){
g.drawImage(img,10,10,16,16);
}
img.src="http://files.cnblogs.com/xf_z1988/ico.ico";
}
//]]>
</script>
</head>
<body>
</body>
</html>

使用drawImage绘图

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
var img=new Image();
img.onload=function(){
g.fillStyle=g.createPattern(img,'repeat');
g.fillRect(0,0,300,150);
}
img.src="http://files.cnblogs.com/xf_z1988/ico.ico";
}
//]]>
</script>
</head>
<body>
</body>
</html>

使用createPattern绘图

Canvas中的文字

Canvas中文字有两种显示方式,一种用fillText()方法,另一种用strokeText()方法,同绘制矩形的API很像。
绘制前可以设置fonttextAligntextBaseline属性来控制绘制文字。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
g.fillStyle="#09f";
g.strokeStyle="green";
g.font="bold 14px Arial";
g.textBaseline="top";
var textAlign_v=["start","end","left","right","center"];
for(var i=0,j=textAlign_v.length;i<j;++i){
g.fillRect(i*40,0,1,150);
g.textAlign=textAlign_v[i];
g.fillText("ZXF",i*40,i*14);
}
g.textAlign="left";
var textBaseline_v=["aplhabetic","top","hanging","middle","ideographic","bottom"];
g.fillRect(0,100,300,1);
for(var i=0,j=textBaseline_v.length;i<j;++i){
g.textBaseline=textBaseline_v[i];
g.strokeText("ZXF",i*40,100); }
}
//]]>
</script>
</head>
<body>
</body>
</html>

Canvas中的文字绘制以及textAlign属性和textBaseLine属性

JavaScript & HTML5 Canvas 概览 更新时间2014-0411-1805

Canvas中的渐变

通过createLinearGradient(x1,y1,x2,y2)或createRadialGradient(xo1,yo1,r1,xo2,yo2,r2)这两个方法创建渐变。
通过gdt.addColorStop()方法来添加颜色。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
var gradient_l=g.createLinearGradient(0,0,150,100);
gradient_l.addColorStop("0","green");
gradient_l.addColorStop("0.5","red");
gradient_l.addColorStop("1","yellow");
g.fillStyle=gradient_l;
g.fillRect(0,0,150,100);
g.fillRect(150,100,150,50);
}
//]]>
</script>
</head>
<body>
</body>
</html>

线性渐变createLinearGradient

JavaScript & HTML5 Canvas 概览 更新时间2014-0411-1805
 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
// 两圆外切就是色彩范围.
var gradient_r=g.createRadialGradient(40,40,30,50,50,40);
gradient_r.addColorStop("0","green");
gradient_r.addColorStop("0.5","red");
gradient_r.addColorStop("1","yellow");
g.fillStyle=gradient_r;
g.fillRect(0,0,150,150); var n2=document.createElement("canvas");
document.body.appendChild(n2);
var g2=n2.getContext("2d");
var gradient_r2=g2.createRadialGradient(40,40,20,50,50,40);
gradient_r2.addColorStop("0","green");
gradient_r2.addColorStop("0.5","red");
gradient_r2.addColorStop("1","yellow");
g2.fillStyle=gradient_r2;
g2.fillRect(0,0,150,150);
}
//]]>
</script>
</head>
<body>
</body>
</html>

圆周渐变createRadialGradient

JavaScript & HTML5 Canvas 概览 更新时间2014-0411-1805

通过shadowOffsetX属性和shadowOffsetY属性设定阴影在X轴和Y轴的延伸,shadowBlur属性设置模糊,shadowColor属性设置模糊颜色。

Canvas中的坐标转换

通过translate(x,y)方法移动坐标,通过rotate(deg*Math.PI/180)方法来旋转坐标,通过scale(x,y)方法来缩放坐标。
另外一个transform(xscale,rotate,incline,yscale,x,y)方法可以进行变形操作。

translate(x,y)相当于transform(1,0,0,1,x,y);
scale(x,y)相当于transform(x,0,0,y,0,0);
rotate(a)相当于transform(cosA,sinA,-sinA,cosA,0,0)

Canvas中的组合

通过设置上下文的globalCompositeOperation属性来指定新图形绘制时按何种方式和已有图形组合。

copy 只绘制新图形,删除其他所有内容
darker 图形重叠的地方的颜色由两个颜色值相减后的值决定
destination-atop 已有的内容只有在它和新图形重叠的地方保留。新图形绘制在内容之后。
destination-in 新图形以及已有画布重叠的地方,已有内容都保留,所有其他内容成为透明。
destination-out 新图像以及已有画布不重叠的地方,已有内容都保留,所有其他内容成为透明。
destination-over 新图形绘制于已有内容的后面。
lighter 图形重叠的地方的颜色由两个颜色值相加后的值决定
source-atop 重叠的地方绘制新图形。
source-in 新图形以及已有画布重叠的地方,绘制新图形,所有其他内容成为透明。
source-out 新图像以及已有画布不重叠的地方,绘制新图形,所有其他内容成为透明。
source-over 新图形绘制于已有图形的顶部,为默认行为。
xor 在重叠和正常绘制的其他地方,图形都成为透明。

Canvas中的裁剪

使用clip()方法裁剪的区域之外的动画不受影响,该方法通过计算所有的子路径来建立新的剪切区域,
未闭合的子路径在填充区按照闭合方式填充,但并不影响实际的子路径集合,新的剪切区域将替换当前的剪切区域。
裁剪路径其实就是绘图路径,只不过这个路径不是拿来绘图的,而是设定显示区域和遮挡区域的一个分界线。

Canvas中的像素操作

可以通过createImageData(w,h)方法来创建一个全透明黑色的空白像素矩阵。

可以通过putImageData(canvasData,imgX,imgY,toX,toY,toW,toH)方法来将图像渲染到画布上。
当前通过putImageData()到画布上的图像不会受scale()等方法的影响。

可以通过getImageData(x,y,w,h)方法来获取Canvas中某一矩形区域的像素数据,像素数据按照RGBA方式排序。

 <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript">
//<![CDATA[
window.onload=function(){
if(!document.createElement("canvas").getContext){
return;
}
var n=document.createElement("canvas");
document.body.appendChild(n);
var g=n.getContext("2d");
var img=new Image();
img.onload=function(){
g.drawImage(img,0,0,300,150);
var img_new=g.createImageData(300,150);
var img_data=img_new.data;
var data=g.getImageData(0,0,300,150).data;
var wd=300;
for(var i=0,j=data.length;i<j;i+=1){
// 透明度为0则当作255白色
var ckop=(i+1)%4;
// 均值.
var t=(i>=wd*4)?(data[i-wd*4+ckop]==0&&ckop!=0?255:data[i-wd*4]):255;
var b=i<=j-wd*4?(data[i+wd*4+ckop]==0&&ckop!=0?255:data[i+wd*4]):255;
var l=i>=4?(data[i-4+ckop]==0&&ckop!=0?255:data[i-4]):255;
var r=i<=j-4?(data[i+4+ckop]==0&&ckop!=0?255:data[i+4]):255;
var now=data[i+ckop]==0&&ckop!=0?255:data[i];
img_data[i]=Math.floor((t+b+now)/3);
}
n.onclick=function(){
g.clearRect(0,0,300,150);
g.putImageData(img_new,0,0,10,10,300,150);
}
}
// 这里没有加载外域的图片.安全考虑.不能对外域图片进行像素操作.
img.src="data:image/gif;base64,R0lGODlhLAGWANUAAAAAAP///6UtMJ8qNJ0pNZ4qNZooN5knOIkgQoohQoQeRoMeRoAcSHsaS3gZTXcYTnYXT3MWUXIWUXIWUnEVUnAVU28UVG4UVO1OAO5OAOxNAehLBOdLBOVKBuRKBuRJB9xGDNdED9ZDENNCEtJBEtBBE9BAFM4/Fco+GMQ7HMI6HcA5Hr44H744ILU0JbU0JrIzKLEyKLAyKa8yKa4xKqwwK6swLP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADcALAAAAAAsAZYAAAb/wJtwSCwaj8ikcslsOp/QqHRKrVqv2Kx2y+16v+CweEwum8/otHrNbrvf8Lh8Tq/b7/i8fs/v+/+AgYKDhIWGh4iJiouMjY6PQhmSk5SUkJeYZpWbnJuZn6BVnaOkk6GnqEalq6yprpmssa2vtIqyt7O1uoG4vbm7wHi+w7/Bxm/EycXHzGfKz6XN0prQ1Z3T2F/W26PZ3ljc4Zzf5FLi55Xl6kzo7abr8EXu8xnx9vT09uv4+Prl/Pn8eQPYT+A0gvwMNkMIUKGgCxAjSpQ4hWFCh3smatyosYnFhhjtcBxJMqKSjxdDxinJsqUqlClVsmlJ02UkmCBlpqnJ0yXO/5w6y/QcWnLGT6BBwxBdujHCh6Mxk3phSnViAahRpW6pyhWiCaxZtV7pypUB2LBiqZDlauNswbRW1nYV4fYtXClyuTbAUDfg3Sh5uQ7o6/fvk8BVWxAubHgJ4qogFs9r3OQxVQiSJ1NWYpkqgszuNifpTJUA6HaikZBmKuM06tREVjNN4Rod7CGymZKofe62kNxLI/MO5xv40g7Did82TpRDcm7LmQ99Dh229OnUrVm/3tN5dmjbuddE/v1ZePEthZdPlho9zxHrlbV3T5N2fGLz6bOMcR//Zv00mdZfL/kBSNJnA+JSoIEcYZbgLQsyuJF6D64SoYQTsVBhLKJhWP/SYBtG06GHI+0VIikXkhgRXSdeM6KKG9XQ4jgpwmjWjOnUCGMJOFqio4pX9VjPeTBO5JSQ0RW5EQ1IEqlkRA5sgGNxT27E34xUVjnRAx606NsNWm4kwIlfghnmRBWEEGKZZp4ZUQIaVMhmm25C5IKcbNYp0QRqDjgnnXouIOV9fwKq5wF8rVfob3pKBEN8ixpapwUrlBeppHVSgEJ2lzLaaEQRnPBcp55+ClEEm/JGaqmmXkCBCrWtilurEVlwZWayzkprRAYM2leuRewqkQJ9ugVssMJGJMELiWJ1rBHJUuTss9BGC9EQOFE7WrTyfKQtZ8ImgdS3RyS7hGbkMrF/6xPKpXuYqRXJ5+4Un2bB4bxY6IkvIPru+4eb/gYSZsCDKElwITAebAiJCh+CYcOJAAjxIvRN3Ah3FkNiXMaZrMbxKYF9TAtXIh9DU8kop6zyyiy37PLLMMcs88w012zzzTjnrPPOPPfs889ABy300EQXbfTRSCet9NJMNx1PEAA7";
}
//]]>
</script>
</head>
<body>
</body>
</html>

通过像素操作来模糊图片

上一篇:MAC 打开Chrome打开开发者工具的快捷键


下一篇:【BZOJ】【3205】【APIO2013】机器人robot