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

HTML Canvas

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

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 if(!document.createElement("canvas").getContext){
 8     alert("浏览器不支持Canvas");
 9 }
10 //]]>
11 </script>
12 </head>
13 <body>
14 </body>
15 </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,弧线半径),以相交线画弧。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     g.strokeStyle="#09f";
15     g.lineWidth=2;
16 
17     g.beginPath();
18 
19     g.moveTo(10,10);
20     g.lineTo(100,100);
21     g.lineTo(0,100);
22 
23     // 圆心X位置,原型Y位置,半径,起始弧度,结束弧度,是否逆时针.
24     g.arc(0,100,50,-2*Math.PI*(45/360),2*Math.PI*(270/360),true);
25     // 以50,50作为两条线的焦点,两条线分别经过上次绘图的结束点和0,0参数点,并以10为半径的曲线.
26     g.arcTo(50,50,0,0,10);
27 
28     g.stroke();
29     g.closePath();
30 }
31 //]]>
32 </script>
33 </head>
34 <body>
35 </body>
36 </html>
Canvas中的lineTo()、arc()、arcTo()的使用

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     g.strokeStyle="#09f";
15     g.lineWidth=2;
16 
17     g.beginPath();
18 
19     g.moveTo(0,100);
20     g.quadraticCurveTo(50,0,100,100);
21     g.stroke();
22     g.closePath();
23 }
24 //]]>
25 </script>
26 </head>
27 <body>
28 </body>
29 </html>
quadraticCurveTo

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     g.strokeStyle="#09f";
15     g.lineWidth=2;
16 
17     g.beginPath();
18 
19     g.moveTo(0,100);
20     g.bezierCurveTo(50,0,75,125,100,100);
21     g.stroke();
22     g.closePath();
23 }
24 //]]>
25 </script>
26 </head>
27 <body>
28 </body>
29 </html>
bezierCurveTo

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

 

Canvas中的矩形

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     g.strokeStyle="#09f";
15     g.fillStyle="green";
16     g.lineWidth=2;
17 
18     g.beginPath();
19     g.moveTo(0,100);
20     g.lineTo(50,50);
21     g.fillRect(100,100,50,50);
22     // 对于2px像素的线宽,在绘制的时候会两边平分1像素,同时canvas的默认画布大小为300*150px
23     // 这里可以看到绘制出的矩形边框的右边和下边只有1像素.
24     g.strokeRect(100,120,200,30);
25     g.lineTo(50,100);
26     g.stroke();
27     g.closePath();
28 }
29 //]]>
30 </script>
31 </head>
32 <body>
33 </body>
34 </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属性。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     var img=new Image();
15     img.onload=function(){
16         g.drawImage(img,10,10,16,16);
17     }
18     img.src="https://files.cnblogs.com/xf_z1988/ico.ico";
19 }
20 //]]>
21 </script>
22 </head>
23 <body>
24 </body>
25 </html>
使用drawImage绘图
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     var img=new Image();
15     img.onload=function(){
16         g.fillStyle=g.createPattern(img,'repeat');
17         g.fillRect(0,0,300,150);
18     }
19     img.src="https://files.cnblogs.com/xf_z1988/ico.ico";
20 }
21 //]]>
22 </script>
23 </head>
24 <body>
25 </body>
26 </html>
使用createPattern绘图

 

Canvas中的文字

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     g.fillStyle="#09f";
15     g.strokeStyle="green";
16     g.font="bold 14px Arial";
17     g.textBaseline="top";
18     var textAlign_v=["start","end","left","right","center"];
19     for(var i=0,j=textAlign_v.length;i<j;++i){
20         g.fillRect(i*40,0,1,150);
21         g.textAlign=textAlign_v[i];
22         g.fillText("ZXF",i*40,i*14);
23     }
24     g.textAlign="left";
25     var textBaseline_v=["aplhabetic","top","hanging","middle","ideographic","bottom"];
26     g.fillRect(0,100,300,1);
27     for(var i=0,j=textBaseline_v.length;i<j;++i){
28         g.textBaseline=textBaseline_v[i];
29         g.strokeText("ZXF",i*40,100);
30         
31     }
32 }
33 //]]>
34 </script>
35 </head>
36 <body>
37 </body>
38 </html>
Canvas中的文字绘制以及textAlign属性和textBaseLine属性


Canvas中的渐变

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

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     var gradient_l=g.createLinearGradient(0,0,150,100);
15     gradient_l.addColorStop("0","green");
16     gradient_l.addColorStop("0.5","red");
17     gradient_l.addColorStop("1","yellow");
18     g.fillStyle=gradient_l;
19     g.fillRect(0,0,150,100);
20     g.fillRect(150,100,150,50);
21 }
22 //]]>
23 </script>
24 </head>
25 <body>
26 </body>
27 </html>
线性渐变createLinearGradient
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     // 两圆外切就是色彩范围.
15     var gradient_r=g.createRadialGradient(40,40,30,50,50,40);
16     gradient_r.addColorStop("0","green");
17     gradient_r.addColorStop("0.5","red");
18     gradient_r.addColorStop("1","yellow");
19     g.fillStyle=gradient_r;
20     g.fillRect(0,0,150,150);
21 
22     var n2=document.createElement("canvas");
23     document.body.appendChild(n2);
24     var g2=n2.getContext("2d");
25     var gradient_r2=g2.createRadialGradient(40,40,20,50,50,40);
26     gradient_r2.addColorStop("0","green");
27     gradient_r2.addColorStop("0.5","red");
28     gradient_r2.addColorStop("1","yellow");
29     g2.fillStyle=gradient_r2;
30     g2.fillRect(0,0,150,150);
31 }
32 //]]>
33 </script>
34 </head>
35 <body>
36 </body>
37 </html>
圆周渐变createRadialGradient

通过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方式排序。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <script type="text/javascript">
 6 //<![CDATA[
 7 window.onload=function(){
 8     if(!document.createElement("canvas").getContext){
 9         return;
10     }
11     var n=document.createElement("canvas");
12     document.body.appendChild(n);
13     var g=n.getContext("2d");
14     var img=new Image();
15     img.onload=function(){
16         g.drawImage(img,0,0,300,150);
17         var img_new=g.createImageData(300,150);
18         var img_data=img_new.data;
19         var data=g.getImageData(0,0,300,150).data;
20         var wd=300;
21         for(var i=0,j=data.length;i<j;i+=1){
22             // 透明度为0则当作255白色
23             var ckop=(i+1)%4;
24             // 均值.
25             var t=(i>=wd*4)?(data[i-wd*4+ckop]==0&&ckop!=0?255:data[i-wd*4]):255;
26             var b=i<=j-wd*4?(data[i+wd*4+ckop]==0&&ckop!=0?255:data[i+wd*4]):255;
27             var l=i>=4?(data[i-4+ckop]==0&&ckop!=0?255:data[i-4]):255;
28             var r=i<=j-4?(data[i+4+ckop]==0&&ckop!=0?255:data[i+4]):255;
29             var now=data[i+ckop]==0&&ckop!=0?255:data[i];
30             img_data[i]=Math.floor((t+b+now)/3);
31         }
32         n.onclick=function(){
33             g.clearRect(0,0,300,150);
34             g.putImageData(img_new,0,0,10,10,300,150);
35         }
36     }
37     // 这里没有加载外域的图片.安全考虑.不能对外域图片进行像素操作.
38     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";
39 }
40 //]]>
41 </script>
42 </head>
43 <body>
44 </body>
45 </html>
通过像素操作来模糊图片

 

 

posted @ 2014-04-11 18:07  xf_z1988  阅读(722)  评论(0编辑  收藏  举报