65.9K
CodeProject 正在变化。 阅读更多。
Home

简单的HTML5 Spiro绘图页面

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.96/5 (11投票s)

2011 年 10 月 9 日

CPOL

3分钟阅读

viewsIcon

33527

downloadIcon

587

一个使用JavaScript和Canvas的简单HTM5网页。

引言

HTML5 正迅速普及,所以我认为我应该试用一下,并尝试一下新的 canvas 元素。 canvas 元素基本上是一个矩形区域,您可以在其中绘制常见的 2D 图形元素,如线条、路径、文本等,并且可以指定填充、渐变、线条样式以及推送和弹出变换以进行旋转等操作。它比 SVG 更轻量级,并允许用户操作该矩形区域内的每个像素,使其非常适合编写游戏。

背景

作为使用 canvas 的第一步,我选择了一个非常简单的程序,它是我几十年前编写的,当时我的孩子们正在玩螺旋仪。 我发现最简单的模式本质上是一个圆形路径在另一个圆形路径的末端旋转,两个圆形路径的直径之间以及它们的旋转速度之间存在特定的比率。 考虑到这一点,我创建了一个非常简单的 GDI Windows 应用程序,可以实现类似的功能。 令人惊讶的是,我几乎可以将原始 C++ 代码的绘图部分复制并粘贴到我的 JavaScript 中,经过一些小的修改,就可以运行它(例如,将 int 更改为 var)。 另一个需要很少更改的原因是 GDI 和 canvas 的原点都在左上角,即较大的 X 值位于右侧,较大的 Y 值位于绘图区域的底部。

网页如下所示。 页面顶部有四个选择器。 前两个是我之前提到的比率,第三个设置一个完整电路中的步数,第四个选择器用于颜色。 更改其中任何一个都会立即重新绘制。 我在所有常用的浏览器上测试了该页面:IE9、Chrome、Firefox、Opera、Safari,并且它的工作方式相同 - 唯一的细微差别是 Safari 没有绘制颜色选择器或其下拉列表项的彩色背景。

Using the Code

主要的 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 的 string 参数来获取所有选择器控件。 然后它需要获取所选索引,并使用该索引来索引附加到控件的选项。 然后我们获取所选选项的文本部分,对于前三个选择器,使用 Number() 方法将文本转换为浮点数。 对于第四个选择器,我们获取值而不是文本 - 原因是这些选项没有任何文本,因为我们只想显示背景颜色。 请注意 value 文本的格式是标准颜色格式 #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;// "#5555FF";
	var xOrigin = 350;
	var yOrigin = 350;
	var jSize = 320/(sizeRatio + 1);
	var iSize = sizeRatio * jSize;

	//begin drawing
	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();
}

关注点

我确实学到的一件事是,您需要通过调用上下文的 beginpath() 方法来开始绘图,否则 canvas 将不会被擦除。 我还惊讶于 VS2010 在许多情况下具有的智能提示有多好,但我注意到它在某些区域表现不佳,例如列出所有绘图上下文的方法。

历史

这是我第一次尝试使用 HTML5 的 canvas 元素。 我希望推出更多关于 canvas 和 SVG 的文章。

© . All rights reserved.