Canvas的一花一木

分类栏目:用户体验 - 前端开发

22368

发布于 5 条评论

这段时间都在接触HTML5 Canvas这个绘制图形元素,也搜集了不少这方面的知识,发现有一篇文章写的非常不错,对Canvas讲解的非常清楚,阅读后个人感觉非常有帮助,故把他转载到本站,以便参考。

什么是Canvas?

HTML5 Canvas(画布)是一个非常有用的绘图和动画元素,Canvas使用JavaScript来直接在页面上绘制图形。这是一个由你来定义和控制的长方形区域,该区域允许动态、可脚本渲染的2D图形和位图图像。

在制作用来增强UI、示意图、相册、图表、图形、动画和嵌入式绘图应用的那些非常棒的视觉材料方面,HTML5堪称完美。Canvas元素有一些用来绘制路径、矩形、圆形和字符的方法。

Canvas的坐标

在画布上绘图的一个先决条件是要熟悉网格或是坐标空间,宽度和高度的空间区域测量是以像素为单位给出的。画布是基于x和y坐标的使用来构建的,画布的x=0, y=0坐标位于左上角。

画布的矩形区域的默认属性是300像素的宽度和150像素的高度,但你可以通过指定宽度和高度来确定画布元素的确切大小。图1中的示意图说明了x和y坐标的实现方式。

tu1

(图1)

图1给出了一个100像素X100像素的画布区:

1. 左上角是x=0,y=0。

2. x的值水平增加,y的值垂直增加。

3. 右下角是x=100,y=100。

4. 中间的点是x=50,y=50。

开始第一步

要在画布上放置任何东西的话,你首先必须在HTML文件中定义画布。你必须创建访问<canvas>标签的JavaScript代码,并通过与HTML5 Canvas API通信来绘制你的图像。

<canvas>标签的基本结构如下:

<canvas id="myCanvas" width="200" height="200"></canvas>

canvas元素自身有两个属性:widthheight,除此之外,canvas还拥有所有主要的HTML5属性,比如说class、id和name等。id属性被用在上面所示的代码中,JavaScript使用这里创建的canvas的id来表示要在上面绘画的画布。JavaScript使用document.getElementById()方法来确定正确的画布,如下面代码所示:

var canvas = document.getElementById("myCanvas");

每个画布都必须要有一个context(上下文)的定义,如下面代码所示。就目前的情况来说,官方规范只承认一个2D环境:

var context = canvas.getContext("2d");

在标识画布并指明了它的上下文之后,你就做好了开始绘画的准备了。

绘图工具、效果和转换

在HTML5 Canvas的这一讨论过程中,我们对各种绘图工具、效果和转换都查看一番。绘图工具包括:

  1. 线条
  2. 矩形
  3. 圆弧
  4. 贝塞尔曲线和二次曲线
  5. 圆和半圆

你会用到的Canvas效果包括:

  1. 填充和描边
  2. 线性和径向的渐变

要讨论的转换包括:

  1. 缩放
  2. 旋转
  3. 平移

绘制线段

要在画布上绘制线段的话,你可以使用moveTo()、lineTo()和stroke()方法,此外,你要使用beginPath()方法来重置当前路径:

  • context.beginPath();
  • Context.moveTo(x,y);
  • Context.lineTo(x,y);
  • Context.stroke(x,y);

beginPath()方法开始一条新的路径,在使用不同的子路径绘制一条新的线段之前,你必须要使用beginPath()来标明一个绘制过程要遵循的新起点。在绘制第一条线段时,beginPath()方法的调用不是必须的。

moveTo()方法指明新的子路径从哪里开始,lineTo()方法创建子路径。你可以使用lineWidthstrokeStyle来改变线段的外观,lineWidth元素改变线段的粗细,strokeStyle改变颜色。

在图2中,三条线段分别用蓝色、绿色和紫色画了出来。

tu2

(图2)

图2中的线段由清单1中的代码来创建,蓝色的线段有着圆弧形的端点,该线段是由首个context.beginPath()这一开始新路径的建立的方法来创建的,其后紧跟着:

  • context.moveTo(50, 50),该方法把线路的起点置于(x=50, y=50)
  • context.lineTo(300,50),该方法标识线段的终点
  • context.lineWidth = 10,该属性是线段的宽度
  • context.strokeStyle = “#0000FF”,该属性是线段的颜色
  • context.lineCap = “round”,该属性把端点设成是圆弧状的
  • context.stroke(),该方法真正在画布上绘制该线段

所有线段的长度都是50像素,尽管它们看上去不一样长——这是由线段的线帽(line cap)造成的视觉错觉。可用的线帽有三种:

  • Context.round (blue)
  • Context.square (green)
  • Context.butt (purple)——默认值

对接(butt)线帽是默认值,当你使用圆形(round)或是方形(square)的线帽风格时,线段的长度会增加,加上一段相当于线段宽度的长度。例如,一个长度为200像素,宽度为10像素,有着圆形或是方形线帽风格的线段,其最终的线段长度是210像素,因为每个线帽都都往线段的每一端加上了5个像素的长度。而一个长度为200像素,宽度为20像素,有着圆形或是方形的线帽风格的线段的最终长度是220像素,因为每个线帽都往线段每一端加上了10像素的长度。

通过执行和修改清单1中的代码来更好地理解线段的绘制方式。

清单1. 在画布上创建三条不同颜色的线段

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Line Example</title>

<style>
body {
	margin: 0px;
	padding: 0px;

}
#myCanvas {
  border: 1px solid #9C9898;
}
</style>
<script>
          window.onload = function() {
                var canvas = document.getElementById("myCanvas");
                var context = canvas.getContext("2d");

                // 有着圆形端点的蓝色线段
                context.beginPath();
                context.moveTo(50, 50);
                context.lineTo(300,50);
                context.lineWidth = 10;
                context.strokeStyle = "#0000FF"; 
                context.lineCap = "round";
                context.stroke();

                // 有着方形端点的绿色线段
                context.beginPath();
                context.moveTo(50, 100);
                context.lineTo(300,100);
                context.lineWidth = 20;
                context.strokeStyle = "#00FF00"; 
                context.lineCap = "square";
                context.stroke();

                // 有着对接端点的紫色线段
                context.beginPath();
                context.moveTo(50, 150);
                context.lineTo(300, 150);
                context.lineWidth = 30;
                context.strokeStyle = "#FF00FF"; 
                context.lineCap = "butt";
                context.stroke();
            };
        </script>
</head><body>
<canvas id="myCanvas" width="400" height="200"></canvas>
</body>
</html>

绘制矩形

有三个方法可用来在画布上给出一个矩形的区域:

  • fillRect(x,y,width,height),该方法绘制一个有填充的矩形
  • strokeRect(x,y,width,height),该方法绘制一个矩形的外边框
  • clearRect(x,y,width,height),该方法清空指定的区域,使之变得完全透明

对于这三个方法中的每个来说,x和y表示的都是画布上相对于矩形(x=0, y=0)的左上角的位置,width和height分别是矩形的宽度和高度。

图3显示了由清单2中的代码创建的三个矩形。

tu3

(图3)

fillRect()方法创建了一个以缺省的黑色为填充色的矩形;clearRect()方法在第一个矩形的中心部分清除出一个矩形区域,该区域位于由fillRect()方法产生的矩形的中央位置;strokeRect创建了一个只有可见的黑色边框的矩形。

清单2. 矩形画布的代码

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Rectangle Example</title>
<style>
body {
	margin: 0px;
	padding: 0px;
}
#myCanvas {
	border: 1px solid #000000;
	background-color: #ffff00;
}
</style>
<script type="text/javascript">
function drawShape(){
   var canvas = document.getElementById('myCanvas');
   var context = canvas.getContext('2d');
   context.fillRect(25,25,50,50);
   context.clearRect(35,35,30,30);
   context.strokeRect(100,100,50,50);
}
</script>
</head>
<body onload="drawShape();">
<canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>

绘制圆弧、曲线、圆和半圆

圆和半圆都是使用arc()方法来绘制,arc()方法用到了六个参数:

context.arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);

centerXcenterY参数是圆的中心坐标,radius就是数学上的半径:从圆心到圆周线的一条直线。弧形是作为所定义的圆的一部分来创建的,startAngleendAngle参数分别是圆弧的起点和终点,以弧度为单位。anticlockwise参数是一个布尔(Boolean)值,当其值为true时,弧形按逆时针方向来绘制,当其值为false时,弧形按顺时针方向来绘制。

要使用arc()方法来绘制圆的话,把起始角度定义成0,把结束角度定义成2*PI,如下所示:

context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

要使用arc()方法来绘制半圆的话,把结束角度定义成startingAngle + PI,如下所示:

context.arc(centerX, centerY, radius, startingAngle, startingAngle + Math.PI, false);

二次曲线

quadraticCurveTo()方法被用来创建一条二次曲线,如下所示。二次曲线通过上下文中的点、一个控制点以及一个结束点来定义。控制点确定了线的曲度。

context.moveTo(x, y);
context.quadraticCurveTo(controlX, controlY, endX, endY);

贝塞尔曲线

正和二次曲线一样,贝塞尔曲线也有一个起点和一个终点,但和二次曲线不同的是,它有两个控制点:

context.moveTo(x, y);
context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);

你可使用bezierCurveTo()方法来创建贝塞尔曲线,因为贝塞尔曲线是由两个控制点而不仅是由一个控制点来定义的,所有你可以创造出更加复杂的曲度来。

图4的显示——从左到右——为一条圆弧、一条二次曲线、一条贝塞尔曲线、一个半圆和一个圆。

tu4

(图4)

图4的内容是用清单3中的代码来创建的。

清单3. 圆弧、曲线和圆的代码

<!DOCTYPE HTML>
<html
<head>
<title>Arcs, Curves, Circles, & Semicircles</title>
<style>
body {
	margin: 0px;
	padding: 0px;
}
#myCanvas {
	border: 1px solid #9C9898;
}
</style>
<script>
function drawArc(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    var centerX = 100;
    var centerY = 160;
    var radius = 75;
    var startingAngle = 1.1 * Math.PI;
    var endingAngle = 1.9 * Math.PI;
    var counterclockwise = false;

    context.arc(centerX, centerY, radius, startingAngle, 
        endingAngle, counterclockwise);

    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawQuadratic(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    context.moveTo(200, 150);

    var controlX = 288;
    var controlY = 0;
    var endX = 388;
    var endY = 150;

    context.quadraticCurveTo(controlX, controlY, endX, endY);
    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawBezier(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    context.moveTo(350, 350);

    var controlX1 = 440;
    var controlY1 = 10;
    var controlX2 = 550;
    var controlY2 = 10;
    var endX = 500;
    var endY = 150;

    context.bezierCurveTo(controlX1, controlY1, controlX2, 
        controlY2, endX, endY);

    context.lineWidth = 10;
    context.strokeStyle = "black"; 
    context.stroke();
};

function drawCircle(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    var centerX = 450;
    var centerY = 375;
    var radius = 70;

    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

    context.fillStyle = "#800000";
    context.fill();
    context.lineWidth = 5;
    context.strokeStyle = "black";
    context.stroke();
};

function drawSemicircle(){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");

    var centerX = 100;
    var centerY = 375;
    var radius = 70;
    var lineWidth = 5;

    context.beginPath();
    context.arc(centerX, centerY, radius, 0, Math.PI, false);
    context.closePath();

    context.lineWidth = lineWidth;
    context.fillStyle = "#900000";
    context.fill();
    context.strokeStyle = "black";
    context.stroke();
};

window.onload = function (){
drawArc();
drawQuadratic(); 
drawBezier(); 
drawCircle(); 
drawSemicircle()
}
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="500"> </canvas>
</body>
</html>

转换:平移、缩放和旋转

translate()scale()rotate()方法都会修改当前的矩阵。translate(x, y)方法把画布上的项目移动到网格上的不同点上,在translate(x, y)方法中,(x,y)坐标指明了图像在x方向和y方向上应该移动的像素数。

如果你使用drawImage()方法来在(15,25)这一位置绘制一个图像的话,你可以使用(20,30)作为参数的来调用translate(),该调用把图像放在(15+20, 25+30) = (35, 55)这一位置上。

scale(x,y)方法改变图像的大小,x参数指明水平方向的比例系数,y参数指明垂直方向的比例系数。例如,scale(1.5, .75)将创建一个在x方向加大50%,而在y方向只相当于当前尺寸75%的图像。rotate(angle)方法返回一个基于指定角度的对象。

图5是一个可以使用translate()、scale()和rotate()进行渲染的图像例子。

tu5

(图5)

清单4提供的代码创建了图5中的图像。

清单4. 创建转换的代码

<!DOCTYPE HTML>
<html>
<head>
<Title>Transformations Example</title>
<script>

window.onload = function() {
    var canvas=document.getElementById("myCanvas");
    var context=canvas.getContext("2d");

    var rectWidth = 250;
    var rectHeight = 75;

    // 把context平移到画布的中心
    context.translate(canvas.width/2,canvas.height/2);         

    // y方向的组成减半 
    context.scale(1,0.5);

    // 顺时针旋转45度
    context.rotate(-Math.PI/4); 

    context.fillStyle="blue";
    context.fillRect(-rectWidth/2,-rectHeight/2,
        rectWidth,rectHeight);

    // 水平方向翻转context
    context.scale(-1,1);

    context.font="30pt Calibri";
    context.textAlign="center";
    context.fillStyle="#ffffff";
    context.fillText("Mirror Image",3,10);

}

</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>

渐变

渐变(gradient)是指从一种颜色向另一种颜色变化的填充,在颜色相交的地方做融合。在Canvas中你可以创建两种类型的渐变:线性的和径向的。

createLinearGradient()方法被用来创建线性的渐变。createLinearGradient(x0,y0,x1,y1)沿着一条由两个点(x0,y0)和(x1,y1)来标识的直线产生一个渐变,这两个点分别是渐变的起点和终点。该方法返回一个对象。

颜色的渐变可以有多种颜色,addcolorStop(offset, color) 方法为被标明为在给定的偏移量上渐变的颜色指明了颜色过渡点。addColorStop()方法让你在0和1之间指定一个偏移量,以这一偏移量为依据来开始过渡到下一种颜色。值0是渐变的一端的偏移量,1是另一端的偏移量。在颜色的渐变定义好了之后,渐变对象就可以被赋值给fillStyle()。你也可以使用fillText()方法来绘制出带有渐变的文字来。

径向渐变——createradialGradient(x0,y0,r0,x1,y1,r1)——使用六个参数以一种圆形或是圆锥形的模式来组合两种或多种颜色。

  • (x0,y0):圆锥的第一个圆的中心
  • r0:第一个圆的半径
  • (x1,y1):圆锥的第二个圆的中心
  • r1:第二个圆的半径

图6包含了四种渐变:一个线性渐变、一个文本渐变、一个对角线上的渐变和一个径向渐变。

tu6

(图6)

图6的内容是使用清单5中的代码创建出来的。

清单5. 渐变的例子代码

<!doctype>
<html>
<head>
<title>Gradient Example</title>
<script>
   window.onload = function() {
      var canvas = document.getElementById("myCanvas");

      var context = canvas.getContext("2d");

      //在一个矩形中尝试做渐变

      // 创建一个线性渐变 
      var fillColor = context.createLinearGradient(50,50, 150,50);

      // 设置渐变的颜色
      fillColor.addColorStop(0.15,"red");
      fillColor.addColorStop(0.35,"black");
      fillColor.addColorStop(0.65,"green");
      fillColor.addColorStop(0.87,"yellow");

      // 把渐变对象赋值给fillstyle
      context.fillStyle= fillColor;

      // 绘制矩形
      context.fillRect(50,50,100,100);

      // 使用文本  

      var fillColorText = context.createLinearGradient(300,50,600,50);

      fillColorText.addColorStop(0.2,"red");
      fillColorText.addColorStop(0.4,"black");
      fillColorText.addColorStop(0.6,"green");
      fillColorText.addColorStop(0.8,"yellow");

     context.fillStyle= fillColorText;

      context.font="40px verdana";
      context.textBaseline="top";
      context.fillText("With text too!", 300,50)

      // 对角线上的渐变
      var fillColordiagonal = context.createLinearGradient(50,200, 100,450);

      // 渐变颜色
      fillColordiagonal.addColorStop(0.2,"red");
      fillColordiagonal.addColorStop(0.4,"black");
      fillColordiagonal.addColorStop(0.6,"green");
      fillColordiagonal.addColorStop(0.75,"yellow");

      // 把渐变对象赋值给fillstyle
      context.fillStyle= fillColordiagonal;

      // 绘制矩形
      context.fillRect(50,225, 100,250);

      // 绘制径向渐变
     fillColorRadial = context.createRadialGradient(450,300,0, 450,300,200);
     fillColorRadial.addColorStop(0, "red");
     fillColorRadial.addColorStop(0.2, "black");
     fillColorRadial.addColorStop(0.4, "green");
     fillColorRadial.addColorStop(0.7, "yellow");
     context.fillStyle = fillColorRadial;
     context.rect(300,200,500,400);
     context.fill();

}
</script>
</head>
<body>
<div>
  <p>
    <canvas id="myCanvas" width="600" height="400"></canvas>
  </p>
</div>
</body>
</html>

图像剪裁

你可以通过裁剪出选定的区域来改变图像。在画布上裁剪是一项重载drawImage()方法的功能,drawImage()有三种选择,你可以使用三个、五个或者是九个参数。

  • 三个参数的配置——drawImage(image, dx, dy)——在目标坐标(dx,dy)上绘制图形。坐标构成了图像的左上角。
  • 五个参数的配置——drawImage(image, dx, dy, dw, dh)——提供了目标的宽度和高度,图像会被缩放以适应目标宽度和高度。
  • 九个参数的配置——drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)——用到一个图像,以图像来源的(sx,sy)坐标为开始剪出一个宽度和高度为(sw,sh)的矩形区域,并把它缩放使之适应目标宽度和高度(dw,dh),然后把它放置在画布的(dx,dy)位置上。

图7显示了你将要对其做剪裁的图像。

tu7

(图7)

通过利用图7中给出的图像,可以把一组图像放置在画布上。一个图像有画布大小,被用作背景,另一个被创建的图像较小一些,被插入到画布的右下角上,第三个图像是一个切出来的拿破仑的头像,被放置在画布的左上角上。裁剪后的图像的最后情况如图8所示。

tu8

(图8)

图8中的内容是使用清单6中的代码创建出来的。在执行这一代码之前,确保已下载了这一例子中用到的Napolean.png图像。

清单6. 用来裁剪例子图像的代码

<!doctype>
<html>
<head>
<title>Crop Example</title>
<script type="text/javascript">
  window.onload = function()  {
  var canvas=document.getElementById("cropNapolean");
    var context=canvas.getContext("2d");

    var imageObj = new Image();
    imageObj.onload = function() {
    // 绘制图像覆盖整个画布
        context.drawImage(imageObj,0,0, 600, 400);

    // 在右下角绘制一个小图像
        var sourceX = 0;
        var sourceY = 0;
        var sourceWidth = 1200;
        var sourceHeight = 801;
        var destX = 300;
        var destY = 200;
        var destWidth = sourceWidth - 900;
        var destHeight = sourceHeight - 600;

        context.drawImage(imageObj, sourceX, sourceY, sourceWidth,
            sourceHeight, destX, destY, destWidth, destHeight);

     //只绘制拿破仑的头部
        var sourceNapoleanX = 460;
        var sourceNapoleanY = 25;
        var sourceNapoleanWidth = 250;
        var sourceNapoleanHeight = 175;
        var destNapoleanX = 0;
        var destNapoleanY = 0;
        var destNapoleanWidth = sourceNapoleanWidth - 150 ;
        var destNapoleanHeight = sourceNapoleanHeight - 100;

        context.drawImage(imageObj, sourceNapoleanX, sourceNapoleanY, 
             sourceNapoleanWidth, sourceNapoleanHeight, 
               destNapoleanX, destNapoleanY, 
                 destNapoleanWidth, destNapoleanHeight);
    }
    imageObj.src = "Napoleon.png";    
}
</script>
</head>
<body>
<div>
  <p>
    <canvas id="cropNapolean" width="600" height="400"></canvas>
  </p>
</div>
</body>
</html>

动画和多重画布

要处理动画方面的内容的话,分层问题总是不可避免的。分层允许组件被隔开开来,这使得编码和调试变得更容易且更高效。Canvas API并未有分层的处理,但你可以创建多重的画布。

动画必须是随着时间的推移来做控制的,因此,要创建一个动画的话,你需要处理动画的每一帧内容。Canvas API在动画方面有一个主要的限制是:在某个形状被放置到画布上之后,它就一直保持它的样子不变了,要移动该形状的话,你必须要重新绘制它

要创建一个动画的话:

  1. 清除掉之前在画布上绘制的任何图像。
  2. 保存画布的状态,确保在每次绘制一个帧的时候都是使用最初的状态。
  3. 执行渲染帧的步骤。
  4. 如果你已经保存了状态的话,在绘制新的帧之前恢复该状态。

你可以以两种方式来控制动画:使用setInterval或者setTimeout方法,每个方法都可以用来在超过某个设定时间段时调用一个函数。setInterval函数重复地执行所提供的代码,setTimeout函数只在所提供的时间过去之后执行一次。

图9展示了游泳者的多重画布动画的一帧,水画在一幅画布上,游泳的人则画在另一幅画布上。

tu9

(图9)

清单7中的代码被用来创建游泳者,代码使用一个线性渐变来创建水的效果。水有四种蓝色色调,这提供了一种合理的水的假象。游泳者的动作通过使用positionX和positionY的值来创建,这两个值改变图像所摆放的样子。游泳者的头使用arc()方法来创建,游泳者的腿和双臂则是通过绘制线段然后改变他们的lineTo()位置来创建,躯干则是通过修改moveTo()的位置来发生变化。因为这是一个动画,因此你需要执行这一段代码来看一下游泳者是如何运动的。

清单7. 动画例子

<!DOCTYPE HTML>
<html>
<head>
<title>Animation & Multiple Canvas Example</title>
<script> 
// 水的画布
function drawWater() {
 var canvasWater = document.getElementById("myWaterCanvas");
 var contextWater = canvasWater.getContext("2d");
 contextWater.globalAlpha = .50 ;
 // 创建一个线性渐变的填充
 var linearGrad = contextWater.createLinearGradient(0,0,400,400);
 linearGrad.addColorStop(0, '#0000ff'); // sets the first color
 linearGrad.addColorStop(.25, '#0099ff'); // sets the second color
 linearGrad.addColorStop(.50, '#00ccff'); // sets the third color
 linearGrad.addColorStop(.75, '#00ffff'); // sets the fourth color
 contextWater.fillStyle = linearGrad;
 contextWater.fillRect(0,0,400,400);
 }

// 游泳者的画布
 setInterval(drawSwimmer, 30);
 var positionX = 0;
 var positionY = 0;

function drawSwimmer(){
 var canvasSwimmer = document.getElementById("mySwimmerCanvas");
 var contextSwimmer = canvasSwimmer.getContext("2d");
 contextSwimmer.clearRect(0,0,400,400);

 if (positionX <30)
 {
 positionX += 1;
 positionY += 1;
 }
 else
 {
 positionX = 0;
 positionY = 0;
 }

 contextSwimmer.save();

// 绘制一个圆作为头部
 var centerX = 200;
 var centerY = 50;
 var radius = 20;

 contextSwimmer.beginPath();
 contextSwimmer.arc(centerX, centerY+positionY, 
 radius, 0, 2 * Math.PI, false);

 contextSwimmer.fillStyle = "#000000";
 contextSwimmer.fill();
 contextSwimmer.lineWidth = 5;

 // 躯干部分
 contextSwimmer.beginPath();
 contextSwimmer.moveTo(200,70+positionY);
 contextSwimmer.lineTo(200,175);
 contextSwimmer.lineWidth = 10;
 contextSwimmer.strokeStyle = "#000000"; 
 contextSwimmer.lineCap = "round";
 contextSwimmer.stroke();

 // 画右边的手臂
 contextSwimmer.beginPath();
 contextSwimmer.moveTo(200, 100);
 contextSwimmer.lineTo(175-positionX,140-positionY);
 contextSwimmer.lineWidth = 10;
 contextSwimmer.strokeStyle = "#000000"; 
 contextSwimmer.lineCap = "round";
 contextSwimmer.stroke();

 // 画左边的手臂
 contextSwimmer.beginPath();
 contextSwimmer.moveTo(200, 100);
 contextSwimmer.lineTo(225+positionX,140-positionY);
 contextSwimmer.lineWidth = 10;
 contextSwimmer.strokeStyle = "#000000"; 
 contextSwimmer.lineCap = "round";
 contextSwimmer.stroke();

 // 画右边的腿
 contextSwimmer.beginPath();
 contextSwimmer.moveTo(200, 175);
 contextSwimmer.lineTo(190-positionX,250-positionY);
 contextSwimmer.lineWidth = 10;
 contextSwimmer.strokeStyle = "#000000"; 
 contextSwimmer.lineCap = "round";
 contextSwimmer.stroke();

 // 画左边的腿
 contextSwimmer.beginPath();
 contextSwimmer.moveTo(200, 175);
 contextSwimmer.lineTo(210+positionX,250-positionY);
 contextSwimmer.lineWidth = 10;
 contextSwimmer.strokeStyle = "#000000"; 
 contextSwimmer.lineCap = "round";
 contextSwimmer.stroke();

 contextSwimmer.restore();

};

</script>

</head>
<body onLoad="drawWater();">
<canvas id="myWaterCanvas" width="400" height="400" style="z-index: 2; 
position:absolute;left:0px;top:0px;">
</canvas>
<canvas id="mySwimmerCanvas" width="400" height="400" style="z-index: 1; 
position:absolute;left:0px;top:0px;">
</canvas>

</body>
</html>

查看预览

结论

HTML5的画布是基于浏览器的RIA的结构核心,其提供了一种以JavaScript和你的想像力为驱动力的实用的绘图环境。学习它真的不是很难,并且网络上有许多培训和学习所需的支持工具,其中包括了速查表、博客、在线文章、视频和非视频教程,以及示例应用程序等。

可视化地修改文本和图像以及模拟运动的能力使得Canvas变成了一个极其有价值的工具,无论你是从设计者还是开发者的角度来熟悉它,无论你是使用Canvas来构建运行在移动设备上的游戏应用,还是仅仅想增强屏幕这一整体资源的利用情况,Canvas都是HTML5体验的重要组成部分。

来源:译言

译者:Elaine.Ye

原文作者:Grace Walker

 

全部评论 / 5

  1. 就是一堆JS- –

    大发 2013-04-17
    20
    1. Javin

      现在js 已经越来越重要了。

      1号 Javin 2013-04-17
  2. 看着好高端,这里的内容都是博主原创的吗?收录进我的博客大全

    19
    1. Javin

      这篇文章是转载的。

      1号 Javin 2013-04-17
  3. 这篇文章的确不错,很实用。 :cool:

    阿狸 2013-04-17
    18