• HTML5移动开发学习笔记之Canvas基础


    1.第一个Canvas程序 

    看的是HTML5移动开发即学即用这本书,首先学习Canvas基础,废话不多说,直接看第一个例子。

    效果图为:

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 </body>
    18 <script type="text/javascript">
    19   //canvas对象的取得
    20   var canvas=document.getElementById("c1");
    21   //取得绘图用的上下文对象
    22   var ctx=canvas.getContext("2d"); 
    23   //绘图处理
    24   ctx.fillStyle="rgb(255,0,0)";
    25   ctx.fillRect(50,50,200,200);
    26   ctx.fillStyle="rgba(0,0,255,0.5)";
    27   ctx.fillRect(100,100,200,200);
    28   <!--alert("hello");-->
    29 </script>
    30 </html>
    View Code

    知识点:

    Canvas 的基本用法

     1)取得Canvas对象

     2)从Canvas对象中获取绘图用的上下文

     3)使用上下文中的方法与属性进行绘图

     颜色的指定方法

      1)ctx.fillStyle="#FF0000";

      2)ctx.fillStyle="rgb(255,0,0)";

      3)ctx.fillStyle="rgba(0,0,255,0.5)"; 最后这个指透明度的。。。

    2.路径

      绘制一个简单的三角形,效果:

     代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 </body>
    18 <script type="text/javascript">
    19   //canvas对象的取得
    20   var canvas=document.getElementById("c1");
    21   //取得绘图用的上下文对象
    22   var ctx=canvas.getContext("2d"); 
    23   //路径绘制开始
    24   ctx.beginPath();
    25   //路径的绘制
    26   ctx.moveTo(0,0);
    27   ctx.lineTo(0,290);
    28   ctx.lineTo(290,290);
    29   //路径绘制结束
    30   ctx.closePath();
    31   //进行绘图处理
    32   ctx.fillStyle="rgb(200,0,0)"
    33   ctx.fill();
    34   <!--alert("hello");-->
    35 </script>
    36 </html>
    View Code

     知识点:

     控制路径时使用的方法:
      1) beginPath() 重置路径的开始

      2) closePath() 关闭到现在为止的路径

      3) moveTo() 指定绘图开始时的基点(x,y)

      4) lineTo() 绘制从前一次绘图位置到(x,y)的直线

     绘制路径时使用的方法:

     1)stroke() 绘制路径

     2)fill()填充路径

     指定绘图样式时使用的属性

     1)fillStyle 指定填充时使用的颜色与样式

     2)strokeStyle 指定路径的线颜色与样式

     3)lineWidth 指定路径线的粗细

      下面制作一个当用户触摸屏幕时在触摸位置绘制三角形的实例程序 (书上的是用户触摸屏幕时绘制,现在改一下,鼠标移动时在移动的位置绘制三角形)效果:

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <meta name="viewport" content="width=320,user-scalable=no" />
     6 <style type="text/css">
     7      canvas {
     8     border-width: 5px;
     9     border-style: dashed;
    10     border-color: rgba(20, 126, 239, 0.50)
    11 }
    12 </style>
    13 
    14 </head>
    15 <body>
    16 hello HTML5!
    17 <canvas id="c1" width="300" height="300" ></canvas>
    18 </body>
    19 
    20 <script type="text/javascript">
    21 
    22 function getPointOnCanvas(canvas, x, y) {
    23   var bbox = canvas.getBoundingClientRect();
    24   return { x: x - bbox.left * (canvas.width / bbox.width),
    25        y: y - bbox.top * (canvas.height / bbox.height)};
    26 }
    27   //canvas对象的取得
    28   var canvas=document.getElementById("c1");
    29   //取得绘图用的上下文对象
    30   var ctx=canvas.getContext("2d"); 
    31   //设置Canvas的onmouse事件
    32   canvas.onmousemove=function(event)
    33   {
    34       //取得鼠标移动处的坐标
    35       var x=event.pageX;
    36       var y=event.pageY;
    37       var canvas=event.target;
    38       var loc=getPointOnCanvas(canvas,x,y);
    39       console.log("mouse down at point(x:"+loc.x+",y:"+loc.y+")");
    40       
    41       var r=Math.random()*10+25;
    42       //路径指定
    43       
    44       ctx.beginPath();
    45       ctx.moveTo(loc.x,loc.y);
    46       ctx.lineTo(loc.x,loc.y+r);
    47       ctx.lineTo(loc.x+r,loc.y+r);
    48       ctx.lineTo(loc.x,loc.y);
    49       
    50       //绘图
    51       ctx.strokeStyle="red";
    52       ctx.stroke();
    53   };
    54 </script>
    55 </html>
    View Code

    遇到的问题,刚开始取不到鼠标移动处的坐标,借鉴了http://www.jb51.net/html5/89807.html 这里面的方法,把效果做出来了,注意console.log()的运用,看下代码运行时的效果:

     

     3.颜色定义

     这一小节感觉书上分得不太合理,我实现以下这个程序是为了熟练下JS代码

     效果:

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <meta name="viewport" content="width=320,user-scalable=no" />
     6 <style type="text/css">
     7      canvas {
     8     border-width: 5px;
     9     border-style: dashed;
    10     border-color: rgba(20, 126, 239, 0.50)
    11 }
    12 </style>
    13 <script> 
    14 (function(){
    15           window.addEventListener("load",function(){
    16                var ctx=document.getElementById("c1").getContext("2d");
    17                //圆1
    18                ctx.beginPath();
    19                ctx.arc(150,45,35,0,Math.PI*2,false);
    20                ctx.fillStyle='rgba(192,80,77,0.7)';   
    21                ctx.fill();
    22                ctx.strokeStyle='rgba(192,80,77,1)';
    23                ctx.stroke();
    24                
    25                //圆2
    26                ctx.beginPath();
    27                ctx.arc(125,95,35,0,Math.PI*2,false);
    28                ctx.fillStyle='rgba(155,187,89,0.7)';
    29                ctx.fill();
    30                ctx.strokeStyle='rgba(155,187,89,1)';
    31                ctx.stroke();
    32                
    33                //圆3
    34                ctx.beginPath();
    35                ctx.arc(175,95,35,0,Math.PI*2,false);
    36                ctx.fillStyle='rgba(128,100,162,0.7)';
    37                ctx.fill();
    38                ctx.strokeStyle='rgba(128,100,162,1)';
    39                ctx.stroke();},     false);                                                
    40           })();
    41 </script>
    42 </head>
    43 <body>
    44 hello HTML5!
    45 <canvas id="c1" width="300" height="150" ></canvas>
    46 </body>
    47 </html>
    View Code

    知识点:

    1)描绘轮廓线

    ctx.strokeStyle="#ff0000";

    2)填充轮廓

    ctx.fillStyle="#0000ff";

     我自己从中练习的知识点应该是

      1)匿名函数 (function(){})();的使用

      2)window.addEventListener("load",function(){},false);

    4.绘制方法的介绍

      1) 绘制圆弧的arc()方法

          arc()方法的语法如下:context.arc(x,y,半径,开始角度,结束角度,是否逆时针旋转);

          从指定的开始角度开始至结束角度为止,按指定方向进行圆弧绘制。最后的参数为ture时,将按逆时针旋转。角度不是“度”,而是“弧度”。

     效果:

     

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   var canvas=document.getElementById("c1");
    19   var ctx=canvas.getContext("2d");
    20   
    21   //使用颜色填充矩形
    22   ctx.fillStyle="#f00ff0";
    23   ctx.fillRect(0,0,300,300);
    24   //描绘圆弧
    25   //路径开始
    26   ctx.beginPath();
    27   var startAngle=0;
    28   var endAngle=120*Math.PI/180;
    29   ctx.arc(100,100,100,startAngle,endAngle,false);
    30   
    31   //绘制处理
    32   ctx.strokeStyle="#ff0000";
    33   ctx.lineWidth=3;
    34   ctx.stroke();
    35 </script>
    36 </body>
    37 </html>
    View Code

     写完后对arc()方法了解多一点了。x,y是圆心的坐标,现在可以想象得出是怎样画出来的。。。

    2)绘制圆弧的arcTo()方法

      arcTo()方法的语法如下:

      context.arcTo(x1,y1,x2,y2,半径);

      此方法的功能是,从路径的起点和终点分别向坐标(x1,y1)、(x2,y2)绘制直线后,在绘制指定半径的圆弧。

      效果:

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   var canvas=document.getElementById("c1");
    19   var ctx=canvas.getContext("2d");
    20   
    21   //使用颜色填充矩形
    22   ctx.fillStyle="#f00ff0";
    23   ctx.fillRect(0,0,300,300);
    24   //描绘圆弧
    25   //路径开始
    26   ctx.beginPath();
    27   ctx.moveTo(20,20);
    28   ctx.arcTo(290,150,100,280,100);
    29   ctx.lineTo(20,280);
    30   
    31   //绘制处理
    32   ctx.strokeStyle="#ff0000";
    33   ctx.lineWidth=3;
    34   ctx.stroke();
    35 </script>
    36 </body>
    37 </html>
    View Code

    自己改了下坐标,效果加深对这个方法的理解。。。

    3)quadraticCurveTo()与bezierCurveTo()方法

       ① quadraticCurveTo()方法用于绘制二元抛物线,其语法格式如下。

          context.quadraticCurveTo(cpx,cpy,x,y);

          绘制由最后指定的位置开始至坐标(x,y)的曲线。此时,使用控制点为(cpx,cpy)的二元抛物线进行连接,并将位置(x,y)追加到路径中。

       ② bezierCurveTo()方法用于绘制三元抛物线,语法格式为:

          bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);

          绘制由最后指定路径位置至指定位置的曲线。此时,使用控制点分别为(cp1x,cp1y),(cp2x,cp2y)的三元抛物线进行连接,并将位置(x,y)追加到路径中,具体示意图:(qq上对图片的修饰似乎还不够熟练。。。)

       

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   var canvas=document.getElementById("c1");
    19   var ctx=canvas.getContext("2d");
    20   
    21   //使用颜色填充矩形
    22   ctx.fillStyle="#f00ff0";
    23   ctx.fillRect(0,0,300,300);
    24   //描绘圆弧
    25   //路径开始
    26   ctx.beginPath();
    27   ctx.moveTo(20,20);
    28   ctx.bezierCurveTo(100,280,180,280,280,20);
    29   
    30   
    31   //绘制处理
    32   ctx.strokeStyle="#ff0000";
    33   ctx.lineWidth=3;
    34   ctx.stroke();
    35 </script>
    36 </body>
    37 </html>
    View Code

    4)绘制矩形的rect()方法

      语法格式如下:context.rect(x,y,宽度,高度); x,y为矩形左上角坐标

      除此之外,Canvas中还提供了三种特定的矩形绘制方法;

     ① context.strokeRect(x,y,w,h)    绘制矩形的轮廓

     ② context.fillRect(x,y,w,h)   填充矩形

     ③ context.clearRect(x,y,w,h) 清空矩形

     这个比较好理解就不做效果演示及代码。

    5.绘制渐变效果

        线性渐变与圆形渐变

       线性渐变就是从左至右(或自上而下)依次显示逐渐变化的颜色。而圆形渐变自圆心向外围逐渐显示变化的颜色。

     1)线性渐变

        指定线性渐变时使用createLinearGradient()方法,具体语法如下:

       //先创建CanvasGradient对象: CanvasGradient=context.createLinearGradient(x1,y1,x2,y2);  表示由位置(x1,y1)至位置(x2,y2)显示渐变效果

       //然后追加渐变颜色:CanvasGradient.addColorStop(颜色开始的相对位置,颜色);   指定渐变中使用的颜色,第一个参数(开始相对位置)中指定一个数字,从而决定什么位置使用什么颜色。

    举个栗子:

     

      代码为:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   var canvas=document.getElementById("c1");
    19   var ctx=canvas.getContext("2d");
    20   
    21   //绘图
    22   var g=ctx.createLinearGradient(0,0,300,0);
    23   g.addColorStop(0,"rgb(255,0,0)"); //开始位置设置为红色
    24   g.addColorStop(1,"rgb(255,255,0)"); //黄色
    25   ctx.fillStyle=g;
    26   ctx.fillRect(20,20,260,260);
    27 </script>
    28 </body>
    29 </html>
    View Code

     2)圆形渐变

     绘制圆形渐变时,使用createRadialGradient()方法创建对象,同样使用addColorStop()方法追加渐变颜色。具体语法如下

      //创建CanvasGradient对象  CanvasGradient=context.createRadialGradient(x1,y1,r1,x2,y2,r2);  通过参数指定以(x1,y1)为圆心,半径为r1的圆到以(x2,y2)为圆心,半径为r2的圆的渐变效果

      // 追加渐变颜色   CanvasGradient.addColorStop(颜色开始的相对位置,颜色);

     举个栗子

     

     代码为:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   var canvas=document.getElementById("c1");
    19   var ctx=canvas.getContext("2d");
    20   
    21   //绘图
    22   var g=ctx.createRadialGradient(150,150,50,150,150,100);
    23   g.addColorStop(0.3,"red"); //开始位置设置为红色
    24   g.addColorStop(0.7,"yellow");
    25   g.addColorStop(1.0,"blue"); //黄色
    26   ctx.fillStyle=g;
    27   ctx.fillRect(20,20,260,260);
    28 </script>
    29 </body>
    30 </html>
    View Code

     6.绘制图像

    Canvas 中的图像绘制

     图像绘制的基本步骤如下:

      1)读取图像文件

      2)在Canvas中进行绘制

     图像读取前,首先创建Image对象,在Image对象的src属性中指定图像文件所在路径后就可以读取了。读取结束后,触发onload事件,基本语法如下:

      var image=new Image();

      image.src="图像文件路径";

      image.onload=function(){//图像读取时的处理}

     使用Canvas上下文中的drawImage()方法将读取后的Image对象绘制在Canvas上,实际上是将Image对象中的图像数据输出到Canvas中。有三种drawImage()方法用于图像的绘制

      ①直接绘制 context.drawImage(image,dx,dy)

      ②尺寸修改(resize) context.drawImage(image,dx,dy,dw,dh)

      ③图像截取 context.drawImage()

     第①种方法直接将读取的图像绘制在坐标(dx,dy)处。第②种方法按照新的宽度dw与高度dh将图像绘制在坐标(dx,dy)处。第③种方法是将原图像的一部分截取出后再按指定尺寸绘制在Canvas上,从原图像的坐标(sx,sy)开始截取宽(sw),高(sh)的部分图像,然后绘制在Canvas上的坐标(dx,dy)处,宽度为dw,高度为dh。

    像素处理

     Canvas与SVG以及Flash稍有不同,绘制的图形/图像并不能作为对象操作。也就是说使用stroke()或者fill()方法绘制的图形,既不能移动它也不能删除它。如果想操作绘制的图形/图像,使用SVG或者Flash实现比使用Canvas要好。

     Canvas中绘制的图形/图像作为一个整体的位图保存,因此可以访问各个像素信息。也就是说,可以使用JavaScript处理Canvas上绘制的图像像素信息。这是Canvas的一个特色

    1)像素处理的API

     imagedata=ctx.getImageData(sx,sy,sw,sh) 返回以(sx,sy)为左上顶点,宽为sw,高为sh的矩形图像-imagedata对象。

     ctx.putImageData(imagedata,dx,dy) 将imagedata所表示的图像绘制在顶点坐标为(dx,dy)处。

    简述之,使用getImageData()方法取出Canvas上图像的像素数据,通过JavaScript加工过这些像素数据后,使用putImageData方法,重新绘制到Canvas中。

     ImageData对象是代表图像像素数据的对象。此对象定义了三种属性:

       ①imagedata.width  图像数据的宽度

       ②imagedata.height 图像数据的高度

       ③imagedata.data  图像数据(CanvasPixelArray类型)

    在JavaScript中进行像素数据读取,并进行加工与输出时的具体操作是,从imagedata.data中得到CanvasPixelArray类型的对象。此对象是保存像素信息的一元数组。但是与JavaScript的Array对象不同,不可对其进行与通常数组一样的操作。

    举个栗子:(本例中,当用户将桌面上的图像文件拖动到浏览器中后,首先读取图像文件并在浏览器中显示,接着对图像进行黑白变换,在原图的旁边显示变换后的图像)

     用户将桌面上的图像文件拖动到浏览器中的界面:

     进行黑白变换后的效果:

    代码如下:

      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8" />
      5 <style type="text/css">
      6 body{
      7     font-family:宋体,Arial,Helvetica,sans-serif;
      8     font-size:80%;
      9     }
     10 #dp{
     11    width:200px;
     12    min-height:70px;
     13    border:1px solid #000000;
     14    background-color:#eeeeee;
     15    padding:len;
     16    margin:2em;
     17     }
     18 #dp img{
     19         margin-right:lem;
     20         }
     21 </style>
     22 <script>
     23 (function(){
     24           
     25           //拖动区域的div元素
     26           var dp=null;
     27           //FileReader接口对象
     28           var reader=null;
     29           
     30           //页面导入时的处理
     31           window.addEventListener("load",function(){
     32                  //获取拖动区域的div元素
     33                  dp=document.getElementById("dp");
     34                  //设置dragover事件的事件侦听
     35                  dp.addEventListener("dragover",function(evt){
     36                                                          evt.preventDefault();},false);
     37                  //设置drop事件的事件侦听
     38                  dp.addEventListener("drop",function(evt){
     39                                                      evt.preventDefault();
     40                                                      file_droped(evt);},false);
     41                                                   },false);
     42           
     43           //文件被拖入时的处理
     44           function file_droped(evt)
     45           {
     46             //清空显示区域
     47             while(dp.firstChild)
     48             {
     49                 dp.removeChild(dp.firstChild);
     50             }
     51             //拖动文件的File接口对象
     52             var file=evt.dataTransfer.files[0];
     53             //FileReader接口对象
     54             reader=new FileReader();
     55             //非图像文件画像时报错
     56             if(!/^image/.test(file.type)){alert("请拖入图像文件");}
     57             //导入拖入图像
     58             reader.readAsDataURL(file);
     59             reader.onload=prepare_image;
     60           }
     61             
     62          //显示拖入图像文件
     63          function prepare_image(evt)
     64          {
     65              //创建img元素,显示拖入的图像
     66              var image=document.createElement("img");
     67              image.setAttribute("src",reader.result);
     68              dp.appendChild(image);
     69              //img元素中导入图像文档后进行后续处理
     70              image.onload=function(){
     71                  //获取图像的尺寸
     72                  var w=parseInt(image.width);
     73                  var h=parseInt(image.height);
     74                  //创建canvas对象,导入图像
     75                  var canvas=document.createElement("canvas");
     76                  canvas.width=w;
     77                  canvas.height=h;
     78                  var ctx=canvas.getContext("2d");
     79                  ctx.drawImage(image,0,0);
     80                  //取得canvas像素数据
     81                  var imagedata=ctx.getImageData(0,0,w,h);
     82                  
     83                  //进行黑白转换
     84                  convert_image_to_gray_scale(imagedata.data);
     85                  
     86                  //替换canvas中的像素数据
     87                  ctx.putImageData(imagedata,0,0);
     88                  
     89                  //显示canvas
     90                  dp.appendChild(canvas);
     91                  }
     92          }
     93          
     94          //黑白变换函数
     95          function convert_image_to_gray_scale(data)
     96          {
     97              var len=data.length;
     98              var pixels=len/4;
     99              for(var i=0;i<pixels;i++){
    100                  //取出R,G,B值
    101                  var r=data[i*4];
    102                  var g=data[i*4+1];
    103                  var b=data[i*4+2];
    104                  
    105                  //进行黑白变换
    106                  var t=parseInt((11*r+16*g+5*b)/32);
    107                  //将变换后的像素数据设置到原来数组元素中
    108                  data[i*4]=t;
    109                  data[i*4+1]=t;
    110                  data[i*4+2]=t;
    111                  }
    112          }
    113                  
    114     })();
    115 </script>
    116 
    117 </head>
    118 <body>
    119 <div id="dp">
    120 <p>将桌面图像文件拖动到此处。</p>
    121 </div>
    122 </body>
    123 </html>
    View Code

    7.绘制数据图表

    1)绘制方格图

      绘制方格图是为了最终绘制折线数据图表做准备的,方格将作为折线图的基准线。绘制方格图的逻辑很简单,只要在Canvas上绘制一系列的横线和竖线。

     效果:

     

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   //获取上下文
    19   var canvas=document.getElementById("c1");
    20   var ctx=canvas.getContext("2d");
    21   
    22   //描绘背景
    23   var gradient=ctx.createLinearGradient(0,0,0,300);
    24   gradient.addColorStop(0,"#e0e0e0");
    25   gradient.addColorStop(1,"#ffffff");
    26   ctx.fillStyle=gradient;
    27   ctx.fillRect(0,0,canvas.width,canvas.height);
    28   
    29   //描绘边框
    30   var grid_cols=10;
    31   var grid_rows=10;
    32   var cell_height=canvas.height/grid_rows;
    33   var cell_width=canvas.width/grid_cols;
    34   ctx.lineWidth=1;
    35   ctx.strokeStyle="#a0a0a0";
    36   
    37   ctx.beginPath();
    38   
    39   //准备画竖线
    40   for( var col=0;col<=grid_cols;col++)
    41   {
    42     var x=col*cell_width; 
    43      ctx.moveTo(x,0);
    44      ctx.lineTo(x,canvas.height);
    45   }
    46   
    47   //准备画横线
    48   for( var row=0;row<=grid_rows;row++)
    49   {
    50     var y=row*cell_height; 
    51      ctx.moveTo(0,y);
    52      ctx.lineTo(canvas.width,y);
    53   }
    54   
    55   //完成描绘
    56   ctx.stroke();
    57 </script>
    58 </body>
    59 </html>
    View Code

    接着我们在方格图中追加绘制数据图表,此处用到的数据为某种商品12个月内的销售数量,涉及的实例数据如下:

    1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月
    80 92 104 110 68 50 45 90 74 68 98 103

    效果图为:

    代码如下:

      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8" />
      5 <style type="text/css">
      6      canvas {
      7     border-width: 5px;
      8     border-style: dashed;
      9     border-color: rgba(20, 126, 239, 0.50)
     10 }
     11 </style>
     12 
     13 </head>
     14 <body>
     15 hello HTML5!
     16 <canvas id="c1" width="300" height="300" ></canvas>
     17 <script type="text/javascript">
     18   //获取上下文
     19   var canvas=document.getElementById("c1");
     20   var ctx=canvas.getContext("2d");
     21   
     22   //定义图表数据
     23   var uriage=[80,92,104,110,68,50,45,90,74,68,98,103];
     24   
     25   //描绘背景
     26   var gradient=ctx.createLinearGradient(0,0,0,300);
     27   gradient.addColorStop(0,"#e0e0e0");
     28   gradient.addColorStop(1,"#ffffff");
     29   ctx.fillStyle=gradient;
     30   ctx.fillRect(0,0,canvas.width,canvas.height);
     31   
     32   //描绘边框
     33   var grid_cols=uriage.length+1;
     34   var grid_rows=4;
     35   var cell_height=canvas.height/grid_rows;
     36   var cell_width=canvas.width/grid_cols;
     37   
     38   ctx.beginPath();
     39   
     40   //准备画竖线
     41   for( var col=0;col<=grid_cols;col++)
     42   {
     43     var x=col*cell_width; 
     44      ctx.moveTo(x,0);
     45      ctx.lineTo(x,canvas.height);
     46   }
     47   
     48   //准备画横线
     49   for( var row=0;row<=grid_rows;row++)
     50   {
     51     var y=row*cell_height; 
     52      ctx.moveTo(0,y);
     53      ctx.lineTo(canvas.width,y);
     54   }
     55   
     56   //完成描绘
     57   ctx.lineWidth=1;
     58   ctx.strokeStyle="#a0a0a0";
     59   ctx.stroke();
     60   
     61   //获取数据中最大值
     62   var max_v=0;
     63   for(var i=0;i<uriage.length;i++)
     64   {
     65       if(uriage[i]>max_v)
     66       max_v=uriage[i];
     67   }
     68   //为了能让最大值容纳在图表内,计算坐标
     69   max_v=max_v*1.1;
     70   //将数据换算为坐标
     71   var points=[];
     72   for(var i=0;i<uriage.length;i++)
     73   {
     74       var v=uriage[i];
     75       var px=cell_width*(i+1);
     76       var py=canvas.height-canvas.height*(v/max_v);
     77       points.push({"x":px,"y":py});
     78   }
     79   //描绘折线
     80   ctx.beginPath();
     81   ctx.moveTo(points[0].x,points[0].y);
     82   for(var i=1;i<points.length;i++)
     83   {
     84       ctx.lineTo(points[i].x,points[i].y);
     85   }
     86   ctx.lineWidth=2;
     87   ctx.strokeStyle="#ee0000";
     88   ctx.stroke();
     89   
     90   //绘制坐标图形
     91   for(var i in points)
     92   {
     93       var p=points[i];
     94       ctx.beginPath();
     95       ctx.arc(p.x,p.y,6,0,2*Math.PI);
     96       ctx.fillStyle="#ee0000";
     97       ctx.fill();
     98    } 
     99 </script>
    100 </body>
    101 </html>
    View Code
    8.旋转与变形
     1)变形方法
      ① 变形方法中的旋转/移动相关方法
      setTransform(m11,m12,m21,m22,dx,dy)    变形矩阵的指定(清空先前的指定)
      Transform(m11,m12,m21,m22,dx,dy)    变形矩阵的指定(可重复指定)
      rotate(angle)    旋转
      scale(x,y)   扩大/缩小   说明:参数x为长度缩放的比例,y为宽度缩放的比例
      translate(x,y)   移动/变形    说明:(x,y)为基点移动后的坐标
      setTransform()与transform()的区别是,是否对已经设置的变形矩阵清空。transform()方法可重复指定不同效果的变形矩阵,而setTransform()方法被调用将清空原先设置的变形矩阵。另外,提供旋转或扩大/缩小功能的方法都支持重叠变形矩阵。
     ② 变形矩阵进行保存/恢复的方法
     save()    记录变形矩阵的状态
     restore()    恢复变形矩阵的状态
     
    先看移动,扩大/缩小的栗子:
       在Canvas中实现模拟时钟的程序
     效果:
      
    代码:
      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8" />
      5 <style type="text/css">
      6      canvas {
      7     border-width: 5px;
      8     border-style: dashed;
      9     border-color: rgba(20, 126, 239, 0.50)
     10 }
     11 </style>
     12 <script>
     13 (function(){
     14           //canvas元素对象
     15           var canvas=null;
     16           //canvas的2D上下文
     17           var ctx=null;
     18           //canvas的尺寸
     19           var cw=0;
     20           var ch=0;
     21           
     22           //页面导入时的事件处理
     23           window.addEventListener("load",function(){
     24                                 //canvas元素的对象
     25                                 canvas=document.getElementById("c1");
     26                                 //canvas的2D上下文
     27                                 ctx=canvas.getContext("2d");
     28                                 // 获取canvas的尺寸
     29                                 cw=parseInt(canvas.width);
     30                                 ch=parseInt(canvas.height);
     31                                 //将坐标平面向右下移动
     32                                 ctx.translate(cw/2,ch/2);
     33                                 //绘制时钟
     34                                 draw_watch();
     35                          }
     36                                                   ,false);
     37           
     38           function draw_watch()
     39           {
     40               //清空Canvas
     41               ctx.clearRect(-cw/2,-ch/2,cw,ch);
     42               //计算针的最大长度
     43               var len=Math.min(cw,ch)/2;
     44               //绘制刻度盘
     45               var tlen=len*0.85;
     46               ctx.font="14px 'Arial'";
     47               ctx.fillStyle="black";
     48               ctx.textAlign="center";
     49               ctx.textBaseline="middle";
     50               for(var i=0;i<12;i++)
     51               {
     52                   var tag1=Math.PI*2*(3-i)/12;
     53                   var tx=tlen*Math.cos(tag1);
     54                   var ty=-tlen*Math.sin(tag1);
     55                   ctx.fillText(i,tx,ty);
     56              }
     57              
     58              //获取当前时刻的时,分,秒
     59              var d=new Date();
     60              var h=d.getHours();
     61              var m=d.getMinutes();
     62              var s=d.getSeconds();
     63              if(h>12)
     64              {h=h-12;}
     65              //绘制时针,短
     66              var angle1=Math.PI*2*(3-(h+m/60))/12;
     67              var length1=len*0.5;
     68              var width1=5;
     69              var color1="#000000";
     70              drawhand(angle1,length1,width1,color1);
     71              //绘制分针,长
     72              var angle2=Math.PI*2*(15-(m+s/60))/60;
     73              var length2=len*0.5;
     74              var width2=5;
     75              var color2="#000000";
     76              drawhand(angle2,length2,width2,color2);
     77              //绘制秒针
     78              var angle3=Math.PI*2*(15-s)/60;
     79              var length3=len*0.5;
     80              var width3=5;
     81              var color3="#000000";
     82              drawhand(angle3,length3,width3,color3);
     83              
     84              //设置timer
     85              setTimeout(draw_watch,1000);
     86               }
     87               
     88               //针绘制函数
     89               function drawhand(angle,len,width,color)
     90               {
     91                   //计算针端的坐标
     92                   var x=len*Math.cos(angle);
     93                   var y=-len*Math.sin(angle);
     94                   
     95                   //绘制针
     96                   ctx.strokeStyle=color; //设置颜色
     97                   ctx.lineWidth=width; //设置线的粗细
     98                   ctx.lineCap="round";//将针尖设置为圆形
     99                   ctx.beginPath();
    100                   ctx.moveTo(0,0);
    101                   ctx.lineTo(x,y);
    102                   ctx.stroke();
    103               }
    104 })();
    105 </script>
    106 </head>
    107 <body>
    108 hello HTML5!
    109 <canvas id="c1" width="300" height="300" ></canvas>
    110 </body>
    111 </html>
    View Code
     代码解释:
      首先看页面导入时的事件处理代码:
      window.addEventListener("load",function()
      {
        ...
        //将坐标平面向右下移动
        ctx.translate(cw/2,ch/2);
        //绘制时钟
        draw_watch();
      },false);
      上述代码中,使用translate()方法将绘图基点移动到Canvas的中心(向右移动一半宽度距离,向下移动一半高度距离)。后面进行绘图处理时,坐标(0,0)就变成Canvas的中心,将大大简化时钟坐标的计算。(巧妙之处)
      再看下draw_watch()函数
      第一行是清空Canvas区域,因为程序中将每隔1秒钟重新绘制整个模拟时针,以实现动态时针的动画效果,如果不清空,上次的秒针将一直被保留
      ctx.clearRect(-cw/2,-ch/2,cw,ch);
      clearRect()方法的参数依次为区域左上角x,y坐标,区域宽度,区域高度。因为坐标平面已经移动,所以作为基点的左上角的坐标变成(-cw/2,-ch/2)
      然后是,绘制刻度盘的代码
      for(var i=0;i<12;i++)
      {
       var tag1=Math.PI*2*(3-i)/12;
       var tx=tlen*Math.cos(tag1);
       var ty=-tlen*Math.sin(tag1);
       ctx.fillText(i,tx,ty);
      }  
     从0时到11时的时刻数字由fillText()完成绘制
     这里终点关注坐标的计算,因中心坐标是(0,0),所以只要确定好角度和半径,就可以计算出各个时刻的坐标来(注意在刻度盘数字3的位置的角度是0度)
      所以这个计算公式 var angle1=Math.PI*2*(3-(h+m/60))/12;也就好理解了。同理分针和秒针也一样。
      然后要完成没过1秒要更新的效果,这时用到定时函数setTimeout(draw_watch,1000);表示每过一秒钟循环调用draw_watch函数自身。
    上述代码的解释

     2)变形的保存于恢复

      ① 变形的保存与恢复的方法save()与restore()的语法格式如下

      context.save();

      context.restore();

     这两种方法都是基于同一堆栈(stack)构造。调用save()方法后,将变形结果保存于堆栈顶端,调用restore()方法后,从堆栈顶端取出上次保存的结果用于恢复。

     看一个栗子,结合了save(),restore(),及rotate()方法

    效果:

    代码如下:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   //获取上下文
    19   var canvas=document.getElementById("c1");
    20   var ctx=canvas.getContext("2d");
    21   
    22   
    23   //定义绘制矩形的方法
    24    function drawRect(context,color)
    25    {
    26       context.fillStyle=color;
    27       context.fillRect(0,0,100,30);
    28    }
    29   
    30   //定义旋转函数
    31   function rorateDeg(context,deg)
    32   {
    33       alert(context);
    34       alert(deg);
    35       var rad=deg*Math.PI/180;
    36       context.rotate(rad);
    37   }
    38   
    39   //绘制普通的矩形  ---1 画出第一个矩形
    40   drawRect(ctx,"red");
    41   
    42   //指定移动、旋转后绘图
    43   ctx.save();
    44   ctx.translate(100,30);//旋转基点
    45   rorateDeg(ctx,45);//旋转45度
    46   drawRect(ctx,"blue"); //---2 画出第二个矩形
    47   ctx.restore();//恢复状态
    48   
    49   //指定移动,旋转后绘图
    50   ctx.save();
    51   ctx.translate(200,50);//旋转基点
    52   rorateDeg(ctx,90);//旋转45度
    53   drawRect(ctx,"green");//---3 画出第三个矩形
    54   ctx.restore();//恢复状态
    55 </script>
    56 </body>
    57 </html>
    View Code

    ②变形矩阵

      与变形矩阵相关的方法有两个,即transform()与setTransform()方法。

      语法为:

      setTransform(m11,m12,m21,m22,dx,dy)    变形矩阵的指定(清空先前的指定)

      Transform(m11,m12,m21,m22,dx,dy)    变形矩阵的指定(可重复指定)
     其中的参数可变换为如下矩阵,这正是变形矩阵这个名称的由来
     m11   m21   dx
     m12   m22   dy
      0        0       1
    简单介绍下各个参数:
     1)m11的默认值为1,当此值越大时,以canvas区域的左侧面为基准,向右延伸坐标空间。相反当值比1小时,向左侧收缩坐标空间。为0时,实际坐标空间完全消失。但是当为负数时,坐标空间变成以右侧为基准,向左侧延伸。
    2)m12的默认值为1,当此值越大时,以canvas区域的左侧面为基准,坐标空间向右下方倾斜。相反为负数时,坐标空间向右上方倾斜。
    3)m21的默认值为1,当此值越大时,以canvas区域的上侧面为基准,坐标空间向右下方倾斜。相反为负数时,坐标空间向右上方倾斜。
    4)m21的默认值为1,当此值越大时,以canvas区域的上侧面为基准,向下延伸坐标空间。向上侧收缩坐标空间。为0时,实际坐标空间完全消失。但是当为负数时,坐标空间变成以下侧为基准,向上侧延伸。
    5)参数dx的默认值为0.当此值越大时,Canvas的坐标空间向右移动。相反为负数时,向左移动。
    6)参数dy的默认值为0.当此值越大时,Canvas的坐标空间向下移动。相反为负数时,向上移动。
     
    然后看一个使用setTransform()方法实现图标图像立体旋转的动画效果的栗子(效果正是太赞了,看着效果,我欣慰地笑了好久,哎呦,不错哦。。。)
     效果:
    代码:
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <img src="XiaoKeAi.jpg" width="200" height="200" alt="小可爱" id="xka"/>
    17 <script type="text/javascript">
    18   (function(){
    19             //不支持window.addEventListener的浏览器不执行代码
    20             if(!window.addEventListener)
    21             {
    22                 return;
    23             }
    24             //Canvas对象
    25             var canvas=null;
    26             //canvas的上下文对象
    27             var ctx=null;
    28             //动画的帧率
    29             var fps=60;
    30             //图像对象
    31             var image=null;
    32             //旋转角度
    33             var deg=0;
    34             
    35             //页面导入时的事件处理
    36             window.addEventListener("load",function(){
    37                             //img元素
    38                             image=document.getElementById("xka");
    39                             //图像尺寸
    40                             var w=parseInt(image.width);
    41                             var h=parseInt(image.height);
    42                             //创建canvas对象
    43                             canvas=document.createElement("canvas");
    44                             canvas.width=w;
    45                             canvas.height=h;
    46                             //canvas的上下文对象
    47                             ctx=canvas.getContext("2d");
    48                             //不支持canvas的浏览器返回
    49                             if(!ctx)
    50                             {
    51                                 return;
    52                             }
    53                             //将图像绘制入canvas中
    54                             ctx.drawImage(image,0,0);
    55                             //用canvas替换img元素
    56                             image.parentNode.replaceChild(canvas,image);
    57                             //canvas的动画开始
    58                             move();
    59                         }
    60                         ,false);
    61             function move()
    62             {
    63                 //canvas尺寸
    64                 var cw=parseInt(canvas.width);
    65                 var ch=parseInt(canvas.height);
    66                 //初始化变形矩阵
    67                 ctx.setTransform(1,0,0,1,0,0);
    68                 //清空canvas
    69                 ctx.clearRect(0,0,cw,ch);
    70                 //计算变形矩阵
    71                 var m11=Math.cos(deg*Math.PI/180);
    72                 var dx=(cw/2)-(cw*m11/2);
    73                 //变形矩阵设置
    74                 ctx.setTransform(m11,0,0,1,dx,0);
    75                 //将变形后的图像绘制入canvas中
    76                 ctx.drawImage(image,0,0);
    77                 //旋转角度递增
    78                 deg++;
    79                 deg=deg%360;
    80                 //使用timer定时绘制下一副图
    81                 setTimeout(move,1000/fps);
    82                 }
    83             })();
    84 </script>
    85 </body>
    86 </html>
    View Code
    代码解释:
         //页面导入时的事件处理
                window.addEventListener("load",function(){
                                ...
                                //将图像绘制入canvas中
                                ctx.drawImage(image,0,0);
                                //用canvas替换img元素
                                image.parentNode.replaceChild(canvas,image);
                                //canvas的动画开始
                                move();
                            }
                            ,false);
            首先将显示图标的img元素的根对象作为参数传递给drawImage()方法,将图像粘贴到canvas上,随后调用repalceChild()方法将img元素替换为Canvas元素。此时img元素并没有从文档中消失,img元素的跟对象可以用于绘制各桢,可以无限多次使用。
            然后再看下move()函数
                    //初始化变形矩阵
                    ctx.setTransform(1,0,0,1,0,0);
                    //清空canvas
                    ctx.clearRect(0,0,cw,ch);
            首先将变形矩阵恢复为默认值,這是为了下一个清空Canvas区域时便于坐标计算。
            接着计算将向setTransform()方法中传入的各参数值。为了Canvas坐标平面看起来像在立体的旋转,只需要变动m11和dx即可。
            var m11=Math.cos(deg*Math.PI/180);
            var dx=(cw/2)-(cw*m11/2);
            然后再设置
            ctx.setTransform(0,1,m11,0,dx,0);
            最后
            //将变形后的图像绘制入canvas中
            ctx.drawImage(image,0,0);
            就OK啦。。。
            需要连续处理所以又借助了setTimeout函数。。这个不解释了。。。
    上述代码的解释
    9.绘制文本
     绘制文本相关的方法和属性
    方法 说明
    context.fillText(text,x,y) 描绘文本,参数text是将要描绘的文本,参数x与y指定了描绘位置的坐标。默认情况下以描绘对象文本的左下为基准
    context.fillText(text,x,y,maxWidth) 描绘文本,参数maxWidth是可选的,指定数值后,文本将显示在指定的宽度内,可缩小显示。
    context.strokeText(text,x,y) 描绘文件的轮廓
    context.strokeText(text,x,y,maxWidth) 描绘文件的轮廓
                                        
    属性 说明
    context.font 定义文本的样式。与CSS的font属性设置的内容相同
    context.textAlign 定义文本的对齐方式,可指定start,end,left,right,center等,水平方向的基准
    context.textBaseline 定义文件的基准线。可指定top,hanging(罗马字上缘),middle,alphabetic(罗马字基线),bottom,ideographic(罗马字下缘)等,垂直方向的基准
     举个栗子,绘制一个简单的图表,效果如下:
     
    代码:
      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8" />
      5 <style type="text/css">
      6      canvas {
      7     border-width: 5px;
      8     border-style: dashed;
      9     border-color: rgba(20, 126, 239, 0.50)
     10 }
     11 </style>
     12 
     13 </head>
     14 <body>
     15 hello HTML5!
     16 <canvas id="c1" width="400" height="300" ></canvas>
     17 <table id="tb1">
     18  <caption>会员数的变化</caption>
     19  <thead>
     20    <tr>
     21    <th>公元</th>
     22    <th>2003年</th>
     23    <th>2004年</th>
     24    <th>2005年</th>
     25    <th>2006年</th>
     26    <th>2007年</th>
     27    <th>2008年</th>
     28    <th>2009年</th>
     29    </tr>
     30  </thead>
     31  <tbody>
     32  <tr>
     33    <th>会员数</th>
     34    <th>230</th>
     35    <th>360</th>
     36    <th>459</th>
     37    <th>654</th>
     38    <th>834</th>
     39    <th>956</th>
     40    <th>1,085</th>
     41  </tr>
     42  </tbody>
     43 </table>
     44 
     45 <script type="text/javascript">
     46   (function(){
     47             //不支持window.addEventListener的浏览器不执行代码
     48             if(!window.addEventListener)
     49             {
     50                 return;
     51             }
     52             //Canvas对象
     53             var canvas=null;
     54             //canvas的上下文对象
     55             var ctx=null;
     56             
     57             //页面导入时的事件处理
     58             add_event_listener(window,"load",function(){
     59                                 //取得canvas对象
     60                                var canvas=document.getElementById("c1");
     61                                
     62                                //取得table元素的根对象
     63                                var mytb=document.getElementById("tb1");
     64                               
     65                                //绘制图表
     66                                draw_graph(mytb,canvas);
     67                                }
     68                                );
     69             
     70             //图表绘制
     71             function draw_graph(tb,canvas)
     72             {
     73                 //获取canvas的上下文
     74                 var ctx=canvas.getContext("2d");
     75                  
     76                 //取得横轴的显示文字
     77                 var head_cells=tb.tHead.rows[0].cells;
     78                 
     79                 var heads=[];
     80                 for(var i=1;i<head_cells.length;i++)
     81                 {
     82                     heads.push(head_cells[i].innerHTML);
     83                 }
     84                 //取得值,计算最大值
     85                 var max=0;
     86                 var value_cells=tb.tBodies[0].rows[0].cells;
     87                 var values=[];
     88                 for( var i=1;i<head_cells.length;i++)
     89                 {
     90                     var v=value_cells[i].innerHTML;
     91                     v=parseInt(v.replace(/[^d]/g,"")); //正则表达式,将非数字的字符替换为空格
     92                     values.push(v);
     93                     if(v>max)
     94                     {
     95                         max=v;
     96                         
     97                     }
     98                 }
     99                 //定义图表原点
    100                 var basex=parseInt(canvas.width*0.1);
    101                 var basey=parseInt(canvas.height*0.8);
    102                 //计算图表的宽度与高度
    103                 var gw=parseInt(canvas.width*0.8);
    104                 var gh=parseInt(canvas.height*0.7);
    105                 //绘制图表区域的背景
    106                 ctx.fillStyle="#eeeeee";
    107                 ctx.fillRect(basex,basey-gh,gw,gh);
    108                 //显示轴
    109                 ctx.beginPath();
    110                 ctx.moveTo(basex,basey-gh);
    111                 ctx.lineTo(basex,basey);
    112                 ctx.lineTo(basex+gw,basey);
    113                 ctx.strokeStyle="#666666";
    114                 ctx.stroke();
    115                 //定义文字的字型
    116                 ctx.font="12px '黑体'";
    117                 //描绘图表
    118                 for(var i=0;i<heads.length;i++)
    119                 {
    120                     //取得图表的值
    121                     var v=values[i];
    122                     //竖线中心x坐标
    123                 var x=basex+(gw/heads.length)*i+((gw/heads.length)/2);
    124                     //定义竖线的宽度
    125                     var barw=(gw/heads.length)*0.7;
    126                     //定义竖线的高度
    127                     var barh=gh*0.9*(v/max);
    128                     //绘制竖线
    129                     ctx.fillStyle="green";
    130                     ctx.fillRect(x-barw/2,basey-barh,barw,barh);
    131                     //检查fillText()方法是否存在
    132                     if(!ctx.fillText)
    133                     {
    134                         continue;
    135                     }
    136                     //间隔与值显示宽度的最大值
    137                     var tw=(gw/heads.length)*0.9;
    138                     //将文本的坐标基准设置为center
    139                     ctx.textAlign="center";
    140                     //绘制X轴
    141                     ctx.textBaseline="top";
    142                     ctx.fillStyle="black";
    143                     ctx.fillText(heads[i],x,basey+3,tw);
    144                     //绘制值
    145                     ctx.textBaseline="ideographic";
    146                     ctx.fillStyle="black";
    147                     ctx.fillText(v,x,basey-barh-3,tw);
    148                     }
    149             }
    150             function  add_event_listener(elm,type,func)
    151             {
    152                 if(!elm)
    153                 {
    154                     return false;
    155                 }
    156                 if(elm.addEventListener)
    157                 {
    158                     elm.addEventListener(type,func,false);
    159                 }
    160                 else if(elm.attachEvent)
    161                 {
    162                     elm.attachEvent('on'+type,func);
    163                 }
    164                 else
    165                 {
    166                     return false;
    167                 }
    168                     return true;
    169             }
    170             })();
    171 </script>
    172 </body>
    173 </html>
    View Code

    10.动画效果

     介绍两种动画的实现实例

     1)圆球跳动的动画

      效果:

     

    代码:
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   //获取上下文
    19   var canvas=document.getElementById("c1");
    20   var ctx=canvas.getContext("2d");
    21   
    22   //记录圆球的状态
    23   var ball={x:10,y:100,dir_x:5,dir_y:5};
    24   //动画
    25   setInterval(drawBall,100);//每个100毫秒调用一次drawBall()函数
    26   function drawBall()
    27   {
    28       //绘制背景
    29       ctx.fillStyle="yellow";
    30       ctx.fillRect(0,0,300,300);
    31       //绘制圆球
    32       ctx.beginPath();
    33       ctx.arc(ball.x,ball.y,15,0,2*Math.PI,true);
    34       ctx.fillStyle="red";
    35       ctx.fill();
    36       //让圆球运动起来
    37       ball.x+=ball.dir_x;
    38       ball.y+=ball.dir_y;
    39       if(ball.x<0||ball.x>300)
    40       {
    41           ball.dir_x*=-1;
    42       }
    43       if(ball.y<0||ball.y>300)
    44       {
    45           ball.dir_y*=-1;  
    46       }  
    47   }
    48 </script>
    49 </body>
    50 </html>
    View Code

     2)待机动画

       效果:

      

    代码:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4 <meta charset="utf-8" />
     5 <style type="text/css">
     6      canvas {
     7     border-width: 5px;
     8     border-style: dashed;
     9     border-color: rgba(20, 126, 239, 0.50)
    10 }
    11 </style>
    12 
    13 </head>
    14 <body>
    15 hello HTML5!
    16 <canvas id="c1" width="300" height="300" ></canvas>
    17 <script type="text/javascript">
    18   //获取上下文
    19   var canvas=document.getElementById("c1");
    20   var ctx=canvas.getContext("2d");
    21   
    22   //动画绘制开始
    23   var ci=0;
    24   anim();
    25   //定义动画函数
    26   function anim()
    27   {
    28       ctx.clearRect(0,0,300,300);//清空Canvas
    29       //循环绘制36根长方形棒棒
    30       for(var i=0;i<36;i++)
    31       {
    32           ctx.save();
    33           //旋转
    34           var r=(i*10)*Math.PI/180;
    35           ctx.translate(150,150);//移动中心点
    36           ctx.rotate(r);
    37           //绘制细长方形
    38           if(i==ci)
    39           {
    40               ctx.globalAlpha=1.0;//半透明效果
    41           }
    42           else
    43           {
    44               ctx.globalAlpha=0.3
    45           }
    46           ctx.beginPath();
    47           ctx.fillStyle="red";
    48           ctx.rect(0,0,50,6);
    49           ctx.fill();
    50           ctx.restore();
    51     }
    52     ci=(ci+1)%36;
    53     setTimeout(anim,20);//每隔20微秒调用anim函数,实现动画效果
    54   }
    55 </script>
    56 </body>
    57 </html>
    View Code

                                  结语:终于将Canvas这章知识点学完,HTML5很好,很强大,很好玩~~

  • 相关阅读:
    k8s dashboard 配置使用kubeconfig文件登录
    Spring Cloud 专题之七:Sleuth 服务跟踪
    Spring Cloud 专题之六:bus 消息总线
    Spring Cloud专题之五:config 配置中心
    Docker Storage Driver:存储驱动
    Docker引擎升级教程
    Docker介绍及安装详解
    Autowired和Resource的区别和联系
    OLTP与OLAP
    转载-JAVA 关于JNI本地库加载
  • 原文地址:https://www.cnblogs.com/wj204/p/3614806.html
Copyright © 2020-2023  润新知