当前位置: 首页 > 文档资料 > HTML5 Canvas 实战 >

2.7 使用图形操作

优质
小牛编辑
140浏览
2023-12-01

本节,我们将创建一个表格,该表格展示每种组合下图形的变化,通过它来探索组合操作。组合操作在这几种情况下特别有用:创建复杂图形、绘制图形位于其它图形的下面而非上面、创建其它有趣的效果。

创建组合图形
图2-8 创建组合图形

准备工作

下面是对HTML5的画布API所提供的每一种可能的组合操作的说明,其中,红色的圆代表源图形(S),蓝色的矩形代表目标图形(D)。为了加深对组合操作的理解,在阅读每一项说明的同时,看一看相应操作的效果,会有帮助。

图2-1 Canvas的组合操作
操作含义
source-atop (S atop D)在两个图像都是非透明的地方,显示源图像。在目标图像是非透明但源图像是透明的地方,显示目标图像。其他地方透明显示。
source-in (S in D)在源图像和目标图像均透明的地方,显示源图像。其他地方透明显示。
source-out (S out D)在源图像非透明且目标图像为透明的地方,显示源图像。其他地方透明显示。
source-over (S over D, default)在源图像为非透明的地方,显示源图像。其他地方显示目标图像。
destination-atop (S atop D)在源图像和目标图像均为非透明的地方,显示目标图像。在源图像非透明且目标图像为透明的地方,显示源图像。其他地方透明显示。
destination-in (S in D)在源图像和目标图像均为非透明的地方,显示目标图像。其他地方透明显示。
destination -out (S out D)在目标图像为非透明且源图像为透明的地方,显示目标图像。其他地方透明显示。
destination -over (S over D)在目标图像为非透明的地方,显示目标图像。其他地方显示目标图像。
lighter (S plus D)显示源图像和目标图像之和。
xor (S xor D)源图像和目标图像取异或操作。
copy (D is ignored)显示源图像,不显示目标图像。

在本书写作之时,对组合操作的处理还非常棘手,因为五大主流浏览器,如Chrome, Firefox, Safari, Opera, 和IE9,对组合的处理各不相同。如果你想使用图形组合,你应该上网搜索“浏览器对画布组合操作的支持情况”,来了解每个浏览器的当前支持情况,而不是通过一副图,向你展示在本书写作时每个浏览器的支持情况。

绘制步骤

按照以下步骤,创建一个表格,来展示组合操作的当前情况:

1. 定义画布和文本样式:

/* 选择body元素的div子元素 */
body > div  {
  width:  680px;
  height:  430px;
  border:  1px solid black;
  float: left;
  overflow: hidden;
}
canvas  {
  float: left;
  margin-top:  30px;
}
div  {
  font-size:  11px;
  font-family: verdana; 
  height:  15px;
  float: left;
  width:  160px;
}
/* 选择第1个,第5个,第9个div元素*/
body  > div  > div:nth-of-type(4n+1)  {
  margin-left:  40px;
}

2. 定义每个矩形和圆的尺寸及相对距离:

window.onload  = function(){
  var squareWidth  =  55;
  var circleRadius  =  35;
  var rectCircleDistX  =  50;
  var rectCircleDistY  =  50;

3. 构建一个组合操作的数组:

  //定义一个组合操作的数组:
  var operationArray  =  [];
  operationArray.push("source-atop");  //  0
  operationArray.push("source-in");  //  1
  operationArray.push("source-out");  //  2
  operationArray.push("source-over");  //  3
  operationArray.push("destination-atop");  //  4
  operationArray.push("destination-in");  //  5
  operationArray.push("destination-out");  //  6
  operationArray.push("destination-over");  //  7 
  operationArray.push("lighter");  //  8 
  operationArray.push("xor");  //  9
  operationArray.push("copy");  //  10

4. 执行每个操作,并将结果绘制在相应的画布上:

  //绘制11个操作中的每一个
  for  (var n  =  0; n  < operationArray.length; n++)  {
    var thisOperation  = operationArray[n];
    var canvas  = document.getElementById(thisOperation); 
    var context = canvas.getContext("2d");
    //绘制矩形
    context.beginPath();
    context.rect(40,  0, squareWidth, squareWidth); 
    context.fillStyle  = "blue";
    context.fill();
    //设置全局组合操作
    context.globalCompositeOperation  = thisOperation;
    //绘制圆
    context.beginPath();
    context.arc(40 + rectCircleDistX, rectCircleDistY, circleRadius, 0, 2 * Math.PI, false);
    context.fillStyle = "red";
    context.fill();
  }
};

5. 在HTML的body部分,为每个组合嵌入一个canvas标签:

<body>
<div>
<canvas id="source-atop" width="160" height="90"> </canvas>
<canvas id="source-in" width="160" height="90"> </canvas>
<canvas id="source-out" width="160" height="90"> </canvas>
<canvas id="source-over" width="160" height="90"> </canvas>
<div>
source-atop
</div>
<div>
source-in
</div>
<div>
source-out
</div>
<div>
source-over
</div>
<canvas id="destination-atop" width="160" height="90"> </canvas>
<canvas id="destination-in" width="160" height="90"> </canvas>
<canvas id="destination-out" width="160" height="90"> </canvas>
<canvas id="destination-over" width="160" height="90"> </canvas>
<div>
destination-atop
</div>
<div>
destination-in
</div>
<div>
destination-out
</div>
<div>
destination-over
</div>
<canvas id="lighter" width="160" height="90"> </canvas>
<canvas id="xor" width="160" height="90"> </canvas>
<canvas id="copy" width="160" height="90"> </canvas>
<canvas width="160" height="90"> </canvas>
<div>
lighter
</div>
<div>
xor
</div>
<div>
copy
</div>
</div>
</body>

工作原理

我们可以通过画布上下文对象的globalCompositeOperation属性来设置组合操作:

context.globalCompositeOperation=[value];

globalCompositeOperation属性接受11个属性值之一,这些属性值包括source-atop, source-in, source-out, source-over, destination-atop, destination-in, destination-out, destination-over, lighter, xor, copy。Source指的是在操作之后绘制在画布上的任何图形,destination指的是在操作之前绘制在画布上的任何图形。除非另有指定,组合操作的默认值为source-over,其基本含义是每次向画布绘制图形,都绘制在已有的图形之上。

我们可以为每一个组合操作创建一个数组,然后循环遍历每一个组合,将其结果绘制在相应的画布上。每次迭代,我们都绘制矩形、设置组合属性、然后绘制圆形。