Javascript在画布上绘制分形,问题是递归保存和恢复

时间:2018-02-20 08:40:02

标签: javascript canvas save restore

我试图在画布上绘制大约8个转换,我正在使用"Sierpniski triangle"中的示例绘制我自己的示例,但每当我将步长增加到大于1时,我似乎都在挣扎。我是个小提琴:Current code

如果您取消注释第43到49行,您会看到它如何被破坏,但是如果您将第14行中的步长减小为:1。那么您将获得它应该如何显示的完美可视化。所以问题是我已经尝试了多种方法来保存画布并将其恢复,但是我以递归方式绘制的事实会让事情破裂。

另一件事,如果你将第43到49行与第40行取消注释并保留步长:2。你几乎可以看到它应该是什么样子的完美可视化,但事实上每个附近都有一个额外的翻转形状转型使它不“完美”。

我已经尝试过HTML5 litten论坛,W3S学校并在这里搜索,但找不到类似的东西。

1 个答案:

答案 0 :(得分:0)

我已通过以下代码解决了这个问题:

<html>
<head>
	<script type="application/javascript">
	function draw(val=1) {
		var canvas = document.getElementById('canvas');
		if (canvas.getContext) {
			var ctx = canvas.getContext("2d");
			ctx.clearRect(0, 0, canvas.width, canvas.height);
			drawT(); //Trait around the canvas (black border)
			drawF(val); //draw Fractal
		}
		function drawF(step,color=null)
		{
			var toDraw=false; //Color management variable to separate 4 transformations
			if (step > 0)
			{
				if(color) { toDraw=true; }
				step = step-1;
				ctx.save();
        
				ctx.transform(0.5, 0, 0, 0.5, 250,0);
				ctx.rotate(90*Math.PI/180);
				if(toDraw) { ctx.fillStyle=color; }
				else { ctx.fillStyle="#FF0000"; color="#FF0000"; }
	
				drawF(step, color);
				ctx.restore();

				ctx.save();
				ctx.transform(0.5, 0, 0, 0.5, 250, 0);
				ctx.scale(-1, 1);
				ctx.rotate(90*Math.PI/180);
				if(toDraw) { ctx.fillStyle=color; }
				else { ctx.fillStyle="#00FF00"; color="#00FF00"; }

				drawF(step, color);
				ctx.restore();
        
				ctx.save();
				ctx.transform(0.5, 0, 0, 0.5, 250, 250);
if(toDraw) { ctx.fillStyle=color; }
else { ctx.fillStyle="#0000FF"; color="#0000FF"; }
				
				drawF(step, color);
				ctx.restore();
				
				ctx.save();
				ctx.transform(0.2, 0, 0, 0.25, 250, 250);
				ctx.scale(1,1);
				ctx.rotate(90*Math.PI/180);
        if(toDraw) { ctx.fillStyle=color; }
        else { ctx.fillStyle="#FFFF00"; color="#FFFF00"; }
        
				drawF(step, color);
				ctx.restore();
			} else {
				drawShape();
			}
		}
		function drawT() {
			ctx.beginPath();
			ctx.moveTo(0, 0);
			ctx.lineTo(500,0);
			ctx.lineTo(500,500);
			ctx.lineTo(300,500);
			ctx.lineTo(300,400);
			ctx.lineTo(150,400);
			ctx.lineTo(150,250);
			ctx.lineTo(0, 250);
			ctx.closePath();
			ctx.stroke();
		}

		function drawShape() {
			ctx.beginPath();
			ctx.moveTo(0,0);
			ctx.lineTo(500,0);
			ctx.lineTo(500,500);
			ctx.lineTo(300,500);
			ctx.lineTo(300,400);
			ctx.lineTo(150,400);
			ctx.lineTo(150,250);
			ctx.lineTo(0, 250);
			ctx.closePath();
			ctx.fill();
		}
	}
	function showVal(newVal){
		draw(newVal);
	}
	</script>
</head>
	<body onload="draw();">
	   <canvas id="canvas" width="500" height="500"></canvas>
	</body>
	<input type="range" min="1" max="7" step="1" value="1"
	oninput="showVal(this.value)" onchange="showVal(this.value)">
</html>

使用滑块进行转换。