JavaScript之Canvas画布

canvas可以在页面中设定一个区域,再利用JavaScript动态地绘制图像。


基本用法

使用canvas元素,首先设置width和height属性,为其设置绘制区域的大小,   如果没有设置宽度和高度,是看不到元素的,不能在其区域画图,在开始标签和结束标签之间的信息是后备信息,当用户的浏览器不支持canvas元素时会显示,用于友好地提示用户。

<canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

第一步:想要在canvas区域里画图, 第一步需要取得绘图上下文,而取得上下文对象的引用,需要调用getContext()方法,并传入上下文参数"2d",这样就能取得2D上下文对象。

注:在调用getContext()方法,需要检测浏览器是否支持该方法。传入的参数'2d',需要用单引用括起来。
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext('2d'); //2d用单引用括起来
    }
  
</script>
</body>


使用toDataURL()方法,可导出绘制的图像。该方法可以获取绘制的图像的数据URL。并可以将该URL赋值给一个img元素,这样在页面中可以显示用canvas绘制的图像了。

格式:canvas.toDateURL("image/png");

注:浏览器默认将图像编码成png格式(除非另行指定)。
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
      <title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


  
  <script>
      
      var canvas = document.getElementById("canvas");
      //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
      if (canvas.getContext) {
          var context = canvas.getContext('2d'); //2d用单引用括起来
		 
          //获取图像的数据URL
          var imgURL = canvas.toDataURL("image/png"); //默认图片格式为png,也可以自定义设置格式。
		 
          //显示图片
          var image = document.createElement("img"); //添加一个img元素
		 
          image.src = imgURL; //将获取的图像的URL赋值给src属性
          document.body.appendChild(image); //将元素添加到页面中
      }
	  
  </script>
  </body>
</html>


在页面中的代码大概是这样的了:


这样在页面中有了个img标签用于显示canvas绘制出的图像、




2D上下文

2D上下文的坐标起始于canvas的左上角,起始坐标为(0, 0),所有坐标值基于这个坐标原点计算,x越大越向右,越大越向下。

绘制2D图像将进行三步:

1、取得上下文对象(getContext("2d"))。
2、指定填充(fiiStyle)或描边(strokeStyle)颜色。描边的话还可以其线条末端的形状、线条相交的方式。
3、指定是填充绘制矩形(fiiRect())还是描边绘制矩形(strokeRect())。


填充和描边

第二步:

2D上下文的基本的绘图方式有两种:填充和描边。顾名思义,填充就是用指定的颜色来填充图形,描边,就是绘制边缘。这两种方法分别为:fillStyle和strokeStyle。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
      <title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

  
  <script>
      
      var canvas = document.getElementById("canvas");
      //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
      if (canvas.getContext) {
          var context = canvas.getContext('2d'); //2d用单引用括起来
		 
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); //2d用单引用括起来
	      context.fillStyle = "red"; // 填充颜色为红色
	      context.strokeStyle = "blue"; //描边颜色为蓝色		  
	 }
      }
	  
  </script>
  </body>
</html>

当然,像上面的代码还不能绘制图形,这样只能说取得上下文对象、选择好了填充颜色、选择好了描边颜色而已,接下来就是绘制图形了。


绘制矩形

第三步:与绘制矩形有关的方法有:fillRect()、strokeRect()、clearRect()。它们分别接收三个参数:第一个参数表示矩形的x坐标、第二个参数表示矩形的y坐标,第三个参数表示矩形的宽度、第四个参数表示矩形的高度。

fillRect()表示用指定的填充颜色绘制矩形:
  • lineWidth:表示描边线的宽度
  • lineCap:用于控制线条末端的形状是平头(butt)、圆头(round)、方头(square)。
  • lineJoin:用于控制线条相交的方式,圆交(round)、斜交(bevel)、斜接(miter)。


<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");
	context.fillStyle = "red"; // 指定填充颜色为红色
	context.fillRect(10, 10, 150, 150);	//用指定的颜色填充矩形
    }
  
</script>
</body>

效果:



可以看出:红色矩形离canva区域左边10px,离上边10px。大小为150x150。


strokeRect()表示用指定的描边颜色描边绘制出矩形。

  • lineWidth:表示描边线的宽度
  • lineCap:用于控制线条末端的形状是平头(butt)、圆头(round)、方头(square)。
  • lineJoin:用于控制线条相交的方式,圆交(round)、斜交(bevel)、斜接(miter)。
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d"); //2d用单引用括起来
        context.strokeStyoe = "yellow"; // 描边颜色为蓝色
        context.lineWidth = 4; //指定描边线的宽度
        context.strokeRect(50, 50, 120, 120);	//用指定的颜色描边矩形
    }
</script>
</body>

效果:



当然,填充和描边可以一起使用来绘制矩形:当填充矩形和描边矩形的坐标一样时
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d"); //2d用单引用括起来
        //描边矩形
        context.strokeStyoe = "yellow"; // 描边颜色为蓝色
        context.lineWidth = 4; //指定描边线的宽度
        context.strokeRect(50, 50, 120, 120);	//用指定的颜色描边矩形
        //填充矩形
	context.fillStyle = "red";
	context.fillRect(50, 50, 120, 120);

    }
</script>
</body>

效果:





当填充矩形和描边矩形的坐标不一样时,
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d"); //2d用单引用括起来
        //描边矩形
        context.strokeStyoe = "yellow"; // 描边颜色为蓝色
        context.lineWidth = 4; //指定描边线的宽度
        context.strokeRect(50, 50, 120, 120);	//用指定的颜色描边矩形
        //填充矩形
	context.fillStyle = "red";
	context.fillRect(150, 150, 120, 120);

    }
</script>
</body>

效果




注:当指定的填充颜色或指定的描边颜色用“rgba()”形式表示时,可以用于绘制透明形的矩形。






clearRcet()方法可以用于清除canvas区域内的矩形,当然也可以用于消除一部分,生成有意思的形状。

<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d"); //2d用单引用括起来
        //描边矩形
        context.strokeStyoe = "yellow"; // 描边颜色为蓝色
        context.lineWidth = 4; //指定描边线的宽度
        context.strokeRect(50, 50, 120, 120);	//用指定的颜色描边矩形
        //填充矩形
	context.fillStyle = "red";
	context.fillRect(150, 150, 120, 120);

        //消除指定大小的区域
	context.clearRect(110, 110, 30, 30);

    }
</script>
</body>


效果:






绘制路径

绘制路径一般是绘制圆形或者圆弧。

beginPath():表示开始绘制新路径。
closePath():表示关闭绘制路径。


可以通过以下方法绘制路径: var canvas = document.getElementById("canvas"); var context = canvas.getContent("2d");

context.arc(x, y, r, sa, ea, c):表示以(x, y)为圆心,画一个以r为半径,起始角度为sa,结束角度为ea的圆,c表示是否逆时针,默认为true,false表示顺时针。
其中,fill()表示以填充方式绘制圆,stroke()表示以描边方式绘制圆。
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        //开始绘制新路径
	context.beginPath(); 
	context.arc(50, 50, 40, 0, 2*Math.PI, false);
	context.closePath(); //关闭路径
	context.fillStyle = "red";
	//以填充方式绘制圆
	context.fill();

    }
</script>
</body>

效果:





context.artTo(x1, y1, x2, y2, r):表示从上一点开始绘制一条半径为r的弧线,结束坐标为(x2, y2),并且经过(x1, y1)这个坐标。
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        //开始绘制新路径
	context.beginPath();
	context.beginPath();
	context.moveTo(100, 100); //绘制起点
	context.arcTo(50, 50, 10, 200, 200);
	context.closePath();
	context.strokeStyle = "red";
	context.stroke();

    }
</script>
</body>

效果:


以(100, 100)为起点,画一条经过(50, 50)和(200, 200)的圆弧。



context.moveTo(x, y):将绘图起点移动到(x, y),不画线。也就是绘制图形的起点坐标。

context.lineTo(x, y):从上一点绘制一条直线,到(x, y)为止。画线的终点坐标。

<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        //开始绘制新路径
	context.beginPath();
	context.moveTo(30, 30); //画线的起点
	context.lineTo(200, 200); //终点
	context.closePath();
	context.strokeStyle = "red";
	context.stroke();

    }
</script>
</body>


效果:


画一条从起点(30, 30)到终点(200, 200)的直线。



rect(x, y, width, height):从(x, y)为起始点,画一个矩形,此矩形为一条路径,不是一个独立的形状。

<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        //开始绘制新路径
	context.beginPath();
	context.arce(20, 20, 200, 200);
	context.closePath();
	context.strokeStyle = "red";
	context.stroke();

    }
</script>
</body>

效果:

注:这个矩形是路径,不是strokeRect()画的独立的形状。



绘制路径小知识:

如果想画一条连接到起点的路径,可以使用closePath(),即将路径画成一个回路如果想填充绘制,用fillStyle()和fill()方法,如果相描边绘制,用strokeStyle()和stroke()方法。




绘制文本


图形与文本问题如影随形。绘制文本的方法有两个: fillText()和strokeText。
字面意思就是:填充绘制文本和描边绘制文本。
fillText方法使用fillStyle属性绘制文本,strokeText()方法使用strokeStyle属性绘制文本。

这两个方法接收四个参数:第一个参数是要绘制的文本内容,第二个参数是x坐标,第三个参数是y坐标,以及最大像素宽度。

两个方法均以下3个属性为基础:
contxt.font:字体样式、大小、字体。

context.textAlign:对齐方式(start、center、end),相当于向左、中间、向右对齐。

context.textBaseline:文本基线。

<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

	context.fillStyle = "red";
	context.font = "bold 26px"; //字体样式
	context.textAlign = "statr"; //对齐方式为左对齐
	context.textBaseline = "top"; //基线
	context.fillText("你好", 100, 100, 200);

    }
</script>
</body>

效果:




这是要注意:如果"textAlign"设置为"start",则x表示文本左端的位置(从左向右阅读),如果"textAlign"设置为"end",则x表示文本右凋的位置(从右向左阅读)。




变换

通过上下文的变换,可以将处理后的图像绘制到画布上。创建绘制上下文时,会初始化变换矩阵,所有处理按描述直接处理。
变换的几种方式:
1、 rotate(angle):旋转图像angle角度。 注:角度不能带单位。
2、 scale(scaleX, scaleY):缩放图像。在x方向乘以scaleX,在y轴方向上乘以scaleY。
3、 translate(x, y):将坐标原点移动到(x,y)的位置。也就是说原来的(0, 0)位置变成现在的(x, y)位置。
4、transform(a, b, c, d, e, f):直接修改矩阵。矩阵的算法:
a  c  e         x
b  d  f     *   y
0  0  0         0

5、setTransform(a, b, c, d, e, f):将矩阵重置为默认状态,然后再调用矩阵。

6、 skew(x, y):将画布拉伸


以下画一个钟表为例:
<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        context.beginPath();
        //绘制外圆
        context.arc(100, 100, 99, 0, 2*Math.PI, false);
	//绘制内圆
        context.moveTo(194, 100);
        context.arc(100, 100, 94, 0, 2*Math.PI, false);
		  
        context.translate(100, 100); //变换原点,为后面绘制时针、分针做准备
		  
        //绘制分针
        context.moveTo(0, 0); //绘制直线的起点
        context.lineTo(0, -85); //至直线的终点
        //绘制时针
        context.moveTo(0, 0);
        context.lineTo(-65, 0);
        //描边绘制钟表
        context.stroke();

    }
</script>
</body>


效果:




把原点变换到钟表的中心处,这样原点就还在画布的左上角了,而是在钟表的中心处,数学计算是基于(0, 0)计算的,而不是(100, 100)。还可以进一步,将钟表旋转90度等。
<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        context.beginPath();
        //绘制外圆
        context.arc(100, 100, 99, 0, 2*Math.PI, false);
	//绘制内圆
        context.moveTo(194, 100);
        context.arc(100, 100, 94, 0, 2*Math.PI, false);
		  
        context.translate(100, 100); //变换原点,为后面绘制时针、分针做准备
        context.rotate(90); //不用像HTML中的变换一样带单位
		  
        //绘制分针
        context.moveTo(0, 0); //绘制直线的起点
        context.lineTo(0, -85); //至直线的终点
        //绘制时针
        context.moveTo(0, 0);
        context.lineTo(-65, 0);
        //描边绘制钟表
        context.stroke();

    }
</script>
</body>

效果:



因为原点已经到了钟表的中心处,所以旋转是基于该中心为原点旋转的。就像是钟表被固定在墙上,然后被旋转90角一样。




sava()方法和restore()方法可以跟踪上下文的状态变化,如果你想要返回某种属性和状态的组合, 可以使用save()方法,也就是说该方法可以保存你先前设置的上下文的属性和状态,该方法将先前你设置的属性和状态推入一个栈结构,等到你想要用保存的属性和状态后,就使用restore()方法,在保存设置的栈结构后 返回一级,如果连续使用save()方法,可以将多个属性和状态的组合保存在栈结构中,此时再使用restore()方法一级一级向上返回。

设置一次属性和状态,就用save()方法保存一次。这样用restore()方法就可以逐级追溯到每次设置的属性和状态。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

  
  <script>
      
      var canvas = document.getElementById("canvas");
	  //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
	  if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
		  
          context.fillStyle = "blue"; //先将fillStyle设置为蓝色
          context.save(); //保存此时的属性
          
		  context.fillStyle = "yellow"; //再将fillStyle设置为黄色
		  context.translate(100, 100); //变换,将原点设置到(100, 100)这个位置
		  context.save(); //再保存此时的属性
		  
          context.fillStyle = "red"; //  将fillStyle设置为红色
		  context.save();
		  
		  //第一次restore(),此时将矩形绘制为红色,且原点(0, 0)的实际坐标为(100, 100)
		  context.restore(); 
		  //第二次restore(),此时将矩形绘制为黄色,且原点(0, 0)的实际坐标为(100, 100)
		  context.restore();
		  //第三次restore(); 此时将矩形绘制为蓝色,这是最上级设置的属性,且此时的原点(0, 0)的实际坐标为(0, 0)
		  context.restore();
          context.fillRect(50, 50, 300, 300, false);
		  
	 }
	  
  </script>
  </body>
</html>

最终效果:





先将fillStyle设置为蓝色,将用save()保存此时的属性,再将fillStyle设置为黄色,将变换原点的坐标,再次将此时的属性保存,最后再次设置fillStyle的属性为红色将保存。
然后多次使用restore()方法逐级向上返回:

第一次restore(),即追溯到fillStyle属性为红色,此时原点的位置在(100, 100)。





第二次restore(),即追溯到fillStyle属性为黄色,此时原点的位置在(100, 100)。




最后一次restore(),追溯到最初的fillStyle的属性即为蓝色,此时没有变换原点(0, 0)的位置,依然在(0, 0)处。



这也是代码执行后的最终效果。


注:save()方法只能保存设置的属性和变换,不能保存绘制上下文的内容。




阴影


根据以下属性,可以自定义为矩形或者路径添加阴影。

1、context.showColor:为阴影添加颜色。
2、context.showOffsetX:为阴影添加x轴方向上的偏移量。
3、context.showOffsetY:为阴影添加y轴方向上的偏移量。
3、context.showBlur:为阴影添加模糊程度。

<body>

  <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>


<script>
    
    var canvas = document.getElementById("canvas");
    //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
    if (canvas.getContext) {
        var context = canvas.getContext("2d");

        //设置阴影的属性
        context.shadowOffsetX = 10;
        context.shadowOffsetY = 20;
        context.shadowBlur = 2;
        context.shadowColor = "blue";
	
        //绘制矩形	  
        context.fillStyle = "red";
        context.fillRect(10, 10, 109, 109);
    }
</script>
</body>


效果:




这里为红色矩形设置了一个蓝色阴影。 注:设置阴影属性的代码要在绘制矩形的代码之前,不然就不会绘制出阴影




渐变
在canvas画布中使用渐变,需要用一个矩形作为参照来显示这个渐变效果,如线性渐变、径向渐变等都需要绘制一个矩形来显示渐变效果。
线性渐变 (createLinearGradient)
在canvas中使用渐变, 首先可以通过createLinearGradient()方法一创建一个 线性渐变对象,它接收四个参数,分别为:渐变起始位的x、y坐标,渐变结束位的x、y坐标。这样就能创建一个指定大小的渐变。

然后在创建渐变对象后,使用 addColorStop()方法来指定色标(渐变颜色),它接收两个参数:色标位置和css颜色值,色标位置是0(开始的颜色)和1(结束的颜色)之间的数值组成。

最后将fillStyle或者strokeStyle设置为这个渐变对象即可(将渐变对象赋值给它们)。

为了让渐变覆盖整个矩形,需要将矩形的坐标与渐变的坐标相匹配(不一定相等),这个显示的渐变区域不只能矩形的一小部分了。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

  
  <script>
      
      var canvas = document.getElementById("canvas");
	  //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
	  if (canvas.getContext) {
	      var context = canvas.getContext("2d");
		  
		  //定义一个渐变对象
		  var gradient = context.createLinearGradient(30, 30, 200, 200);
		  //为这个对象设置渐变颜色
		  gradient.addColorStop(0, "white");
		  gradient.addColorStop(1, "black");
		  
		  //绘制一个矩形作为参考
		  context.fillStyle = "orange";
		  context.fillRect(20, 20, 200, 200);
		  
		  //把fillStyle或者strokeStyle设置为这个渐变对象
		  context.fillStyle = gradient;
		  context.fillRect(30, 30, 200, 200);
		 	  
	  }
	  
  </script>
  </body>
</html>


效果:



可以看出,绘制了两个矩形,其中一个矩形就是一个参照,而另一个矩形则用来显示渐变效果而绘制的。


径向渐变(createRadialGradient)
使用createRadialGradient()方法来创建渐变对象,该方法接收6个参数,分别是起始圆的x、y坐标和半径。结束圆的x、y坐标和半径。

其中,如果一个圆比另一个圆大,那么就是一个圆锥形状的渐变。

如果想让渐变从圆的中心扩散,可以将其设置为一个同心圆即圆心坐标相同,而半径不同。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

  
  <script>
      
      var canvas = document.getElementById("canvas");
	  //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
	  if (canvas.getContext) {
	      var context = canvas.getContext("2d");
		  
		  //定义一个径向渐变对象
		  var gradient = context.createRadialGradient(57, 57, 10, 57, 57, 30);
		  //为这个对象设置渐变颜色
		  gradient.addColorStop(0, "white");
		  gradient.addColorStop(1, "blue"); //结束颜色也就是矩形的颜色
		  
		   
		  //把fillStyle或者strokeStyle设置为这个渐变对象
		  context.fillStyle = gradient;
		  context.fillRect(10, 10, 100, 100);
		 	  
	  }
	  
  </script>
  </body>
</html>


效果:



绘制图像
2D绘制上下文内置了对图像的支持。如果想要把一张图像绘制在画布上,就需要 drawImage()方法。调用这个方法,可以使用三种不同的参数组合。

格式:drawImage(要绘制的图像, x, y);  其中,x、y表示图像的起点坐标。

第一种,使用最简单的HTML<img>元素直接嵌入到页面中,再将图像绘制到画布上。

这种方法首先需要使用document.images[0]获取页面中的第一个<img>元素。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>
    <img src="1.jpg" width=200 height=200 alt="图片"> <1-- 直接使用HTML<img>元素 -->
  
  <script>
      
      var canvas = document.getElementById("canvas");
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
	       
              var img = document.images[0]; //获取页面中的第一个<img>元素
              img.onload = function () {  //这步很重要,只有在图像加载完成后,才能将其绘制到画布上
                  context.drawImage(img, 5, 5); //起点坐标(5,5)
              };
	 }
	  
  </script>
  </body>
</html>

效果:



从图上可以看出,左边的是画布区域,而右边的是由<img>元素嵌入的一张图像,左边画布上没有笑脸,只有风格是怎么回事呢?原来是因为这张图像太大了,而画布区域太小的原因,使图像不能完全显示出来。在<img>中我们是限制了图像的尺寸的,而在画布上没有限制图像的尺寸。


第二种,此时我们可以给drawImage()方法传入两个参数来控制画布上的图像尺寸。

格式;drawImage(要绘制的图像, x, y, w, h);  其中,w、h分别表示图像的尺寸。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>
    <img src="1.jpg" width=200 height=200 alt="图片">
  
  <script>
      
      var canvas = document.getElementById("canvas");
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
	       
              var img = document.images[0];
              img.onload = function () {
                  context.drawImage(img, 10, 10, 200, 200); //此时,起始坐标为(10, 10),且,画布上的图像尺寸大小为200*200
              };
	 }
	  
  </script>
  </body>
</html>

效果:



此时,将画布上图像的尺寸改了一下,这样就能看见了。当然我们也可以更改图像的起点坐标。起点坐标是基于画布的左边、顶部来计算的,也就是说,画布的左上角是原点即(0, 0)。

像以上例子,直接将页面中的图像绘制到画布中时,需要用 document.Images[?]来获取页面中的第?个<img>元素。


第三种,前二种都是绘制图像的整体,而通过传入不同的参数,也可以只绘制图像的部分区域。

drawImage()方法接收9个参数:要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>
    <img src="1.jpg" width=200 height=200 alt="图片">
  
  <script>
      
      var canvas = document.getElementById("canvas");
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
	       
              var img = document.images[0];
              img.onload = function () {
                  context.drawImage(img, 250, 150, 400, 400, 200, 100, 100, 100); 
              };
	 }
	  
  </script>
  </body>
</html>


效果:



可以看出,我们只绘制了图像的一部分区域。源坐标是为了找到源图像(右边的那个图像),源图像的宽度、高度是为了确定要绘制源图像的多大区域。


除了直接获取页面中的图像外,也可以获取外部的图像资源来将此图像绘制到画布上。

知识点:
var img = new Image(); //表示嵌入一个图像对象实例

img.src = "1.jpg"; //表示获取图像的URL

img.onload = function () {}; //等到图像加载完成后,才能绘制。


<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>
  
  <script>
      
      var canvas = document.getElementById("canvas");
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
	       
              //嵌入一个图像对象
              var img = new Image();
              //并获取图像的URL,当在赋值时,图像才开始加载。
              img.src = "1.jpg";
              //等图像加载完成后,才能将其绘制到画布中,所以要使用img.onload
              img.onload = function () {
                  context.drawImage(img, 20, 20, 250, 270); 
              };
	 }
	  
  </script>
  </body>
</html>

效果:



使用这种方法,无需将图像使用<img>元素嵌入到页面中了。这里要注意的是,"img.src = "1.jpg;  img.onload = function () {};", img.src赋值的时候,图片才开始去加载,需要等到图像加载完成后才能使用drawImage()方法绘制,或者还没加载完,就直接drawImage了,画布上就会显示空白。

注:drawImage()的第一个参数除了可以是图像外,也可以是<canvas>元素。



模式(在canvas中重复显示图像)

可以在画布中绘制重复显示图像的效果,模式就是重复的图像,可以用于填充和描边图像。创建一个模式,要使用createPattern()方法,它接收两个参数:第一个参数是一个HTML<img>元素或者是表示图像的变量,第二个参数是表示如何重复显示的字符串,即“ repeat”、"repeat-x"、"repeat-y"、“no-repeat”。再将此模式赋值给fillStyle()或strokeStyle()。最后画出矩形。

<!doctype html>  
<html>  
  <head>  
    <meta charset="utf-8">  
    <title>JavaScript之Canvas</title>  
  </head>  
  <body>  
      
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>  
    <img src="1.jpg" width=100 height=100 alt="图片">  
    
  <script>  
        
      var canvas = document.getElementById("canvas");  
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象  
          if (canvas.getContext) {  
          var context = canvas.getContext("2d");   
  
              var img = document.images[0]; 

              //在图像加载完成后,才开始绘制矩形
              img.onload = function () {
                  var pattern = context.createPattern(img, "repeat"); //创建模式并重复显示图像  
                  context.fillStyle = pattern; //将模式赋值给填充  
                  context.fillRect(10, 10, 500, 500); //最后画出矩形 
              }; 
                
     }  
        
  </script>  
  </body>  
</html>  


效果:



图像在画布中重复显示了,如果画布足够大,那么显示的图像越多。

注意:在页面中的图像加载完成后,才能开始创建模式和绘制和矩形,即"img.onload = function () {}"。



图像合成
还有两个运用到2D绘制上下文的操作方法:globalAlpha和globalCompositionOperation。

globalAlpha是一个介于0和1之间值,它指定所有绘制的透明度,默认值为0。如果后续的绘制都基于相同的透明度,可以设置为适当的值,最后,再把它设置为默认值0(重置透明度)。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>
  
  <script>
      
      var canvas = document.getElementById("canvas");
          //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
          if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
              //画一个蓝色矩形
              context.fillStyle = "blue";
              context.fillRect(10, 10, 200, 200);

              //修改全局透明度
              context.globalAlpha = 0.5;

              //绘制一个红色矩形,红色矩形在蓝色矩形的上面,这是根据文档流的结果。
              context.fillStyle = "red";
              context.fillRect(50, 50, 200, 200);

              //重置全局透明度 
              context.globalAlpha = 0;
	 }
	  
  </script>
  </body>
</html>

效果:



我们把红色矩形绘制在了蓝色矩形的上面。在绘制红色矩形之前,将globalAlpha设置为0.5,所以透过红色矩形我们可以看见下面的蓝色矩形。


globalCompositionOperation 表示 后绘制的图像  怎样先绘制的图像结合。它的属性值有:

注:这里的 目标图像指后绘制的图形,源图像指前绘制的图像。



举个例子:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
	<title>JavaScript之Canvas</title>
  </head>
  <body>
	
    <canvas id="canvas" width="400" height="300">抱歉,您的浏览器不支持canvas元素</canvas>

  
  <script>
      
      var canvas = document.getElementById("canvas");
	  //检测浏览器是否支持canvas 该方法是否存在 取得上下文对象
	  if (canvas.getContext) {
	      var context = canvas.getContext("2d"); 
	       
              context.fillStyle="red";
              context.fillRect(20,20,75,50);

              context.fillStyle="blue";	
              context.globalCompositeOperation="source-over";
              context.fillRect(50,50,75,50);
	
              context.fillStyle="red";
              context.fillRect(150,20,75,50);

              context.fillStyle="blue";	
              context.globalCompositeOperation="destination-over";
              context.fillRect(180,50,75,50);
	 }
	  
  </script>
  </body>
</html>

效果:



使用这个方法来合成图像,应该多试几个浏览器,因为有一些浏览器显示这个效果还有一些问题,例如谷歌不能显示指定的效果,火狐也是不能显示。



WebGL

WebGL是canvas的3D上下文,关于这部分内容,本人将在以后的文章介绍。


  • 39
    点赞
  • 131
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值