Canvas元素是HTML5中新增的一个强大功能,它允许开发者在网页上绘制2D图形。Canvas本质上是一个矩形区域,可以在其中绘制线条、路径、文本等常规2D图形元素,并能够指定填充、渐变、线条样式以及进行旋转等变换操作。与SVG相比,Canvas更加轻量级,并且允许用户操作矩形区域内的每一个像素点,非常适合用于游戏开发。
在开始探索Canvas之前,选择了一个非常简单的程序,这个程序是几十年前写的,当时孩子们在玩Spirograph。可以看到最简单的图案本质上是一个圆形路径在另一个圆形路径的末端旋转,两个圆形路径的直径之间以及它们的旋转速度之间存在特定的比例关系。基于这个想法,创建了一个简单的GDI Windows应用程序,可以实现类似的效果。令人惊讶的是,几乎可以将原始C++代码的绘图部分复制粘贴到JavaScript中,并且只需进行一些小的修改,就可以运行(例如将int更改为var)。另一个需要的修改很少的原因是,GDI和Canvas的原点都在左上角,即较大的X值在右侧,较大的Y值朝向绘图区域的底部。
下面的网页展示了四个选择器。前两个是前面提到的比例,第三个设置了完成一个完整循环的步数,第四个选择器用于颜色。更改任何一个选择器都会立即重新绘制。在所有常见的浏览器上测试了这个页面:IE9、Chrome、Firefox、Opera、Safari,它在所有浏览器上的工作方式都是相同的——唯一的小区别是Safari没有绘制颜色选择器或其下拉列表项的彩色背景。
主要的HTML代码如下所示。将所有的选择器放在一个div中,这样就可以通过CSS调整间距和外观。如果不知道,在IE9中按下F12会打开一个不错的“开发者工具”,允许检查HTML、CSS、脚本等,并允许实时修改CSS。Chrome有一个类似的工具(使用右键单击“检查元素”),在某些方面发现它更好。关于选择器的主要注意事项是它们都必须有一个id(因为JavaScript需要这个来找到元素并读取其属性),并且它们的onchange处理程序都设置为调用'updateCanvas()'。
<div id="params">
Size Ratio:
<select id="sizeratio" onchange="updateCanvas()">
<option>1</option>
<option>2</option>
<option>3</option>
<option selected="selected">4</option>
<option>5</option>
</select>
Speed Ratio:
<select id="speedratio" onchange="updateCanvas()">
<option>2</option>
<option>3</option>
<option selected="selected">4</option>
<option>5</option>
</select>
Steps:
<select id="steps" onchange="updateCanvas()">
<option>100</option>
<option>200</option>
<option selected="selected">300</option>
<option>400</option>
<option>500</option>
</select>
Colour:
<select id="color_menu0" name="color_menu0" onchange="updateCanvas();" style="width: 60px">
<option style="background-color:#5f9ea0" value="#5f9ea0" selected="selected"/>
<option style="background-color:#d2691e" value="#d2691e"/>
<option style="background-color:#ffd700" value="#ffd700"/>
<option style="background-color:#7fff00" value="#7fff00"/>
<option style="background-color:#006400" value="#006400"/>
<option style="background-color:#a52a2a" value="#a52a2a"/>
<option style="background-color:#ff1493" value="#ff1493"/>
</select>
</div>
<div>
<canvas id="canvas1" width="700" height="700">Canvas is not supported by this browser.</canvas>
</div>
<script type="text/javascript">
updateCanvas();
</script>
updateCanvas()函数的JavaScript代码如下所示。代码首先使用document.getElementById()获取所有的选择器控件,使用字符串参数作为HTML元素的id。然后需要获取所选项的索引,并使用该索引来索引与控件相关联的选项。然后获取所选项的文本部分,对于前三个选择器,使用Number()方法将文本转换为浮点数。对于第四个选择器,获取值而不是文本——原因是选项中没有文本,只想显示背景颜色。注意值文本的格式是标准颜色格式#rrggbb,这与HTML中用于设置canvas值如fillstyle的颜色格式相同。
function updateCanvas() {
var c = document.getElementById("canvas1");
var ctlSpeedRatio = document.getElementById("speedratio");
var ctlSizeRatio = document.getElementById("sizeratio");
var ctlSteps = document.getElementById("steps");
var ctlColour = document.getElementById("color_menu0");
var speedRatio = Number(ctlSpeedRatio.options[ctlSpeedRatio.selectedIndex].text);
var sizeRatio = Number(ctlSizeRatio.options[ctlSizeRatio.selectedIndex].text);
var steps = Number(ctlSteps.options[ctlSteps.selectedIndex].text);
var colour = ctlColour.options[ctlColour.selectedIndex].value;
var cxt = c.getContext("2d");
cxt.beginPath();
cxt.fillStyle = "#FFEEEE";
cxt.clearRect(0, 0, 700, 700);
cxt.fillRect(0, 0, 700, 700);
cxt.strokeStyle = colour;
var xOrigin = 350;
var yOrigin = 350;
var jSize = 320/(sizeRatio + 1);
var iSize = sizeRatio * jSize;
var n = steps * speedRatio;
for (var i = 0; i <= n; i++) {
var f = i * 3.14159265358979 * 2;
var xi = (iSize * Math.sin(f / n)) + xOrigin;
var yi = (iSize * Math.cos(f / n)) + yOrigin;
var xj = (jSize * Math.sin(f / speedRatio));
var yj = (jSize * Math.cos(f / speedRatio));
if (i == 0)
cxt.moveTo(xi + xj, yi + yj);
else
cxt.lineTo(xi + xj, yi + yj);
}
cxt.stroke();
}