My first self-invented L-system!
A Pen by Johan Karlsson on CodePen.
<div id="result" class="center"></div> | |
<canvas id="canvas" class="center"></canvas> | |
<input id="iterationsSlider" type="range" min="0" max="100" step="1" value="30"> |
/* | |
"Invented" by me, Johan Karlsson | |
Spiral drawn by an L-system | |
Axiom: FmAFmFpFB | |
Rules: (A→FMA), (B→PFB) | |
F: draw forward | |
m: turn left | |
M: turn left, decrease step size | |
p: turn right | |
P: turn right, increase step size | |
Angle: 90deg | |
Side note: | |
* m and M for minus | |
* p and P for plus | |
*/ | |
(function(spiral) { | |
// Private members | |
var canvas = document.getElementById("canvas"); | |
var ctx = canvas.getContext("2d"); | |
var colorBit = false; | |
var stepFactor = 12; | |
var lineWidth = 4; | |
var x; | |
var y; | |
// Axiom | |
var axiom = "FmAFmFpFB"; | |
// Production | |
function produce(iterations) { | |
var result = axiom; | |
for(var i = 0; i < iterations; i++) { | |
// Rules | |
result = result.replace("A", "FMA"); | |
result = result.replace("B", "PFB"); | |
} | |
return result; | |
} | |
function getDirection (direction) { | |
if(direction === -1) { | |
return 3; | |
} else if(direction === 4) { | |
return 0; | |
} else { | |
return direction; | |
} | |
} | |
function drawStep(direction, stepLength) { | |
ctx.strokeStyle = colorBit ? "purple" : "rebeccapurple"; | |
ctx.beginPath(); | |
ctx.moveTo(x, y); | |
switch(direction) { | |
case 0: | |
x += stepLength * stepFactor; | |
break; | |
case 1: | |
y += stepLength * stepFactor; | |
break; | |
case 2: | |
x -= stepLength * stepFactor; | |
break; | |
case 3: | |
y -= stepLength * stepFactor; | |
break; | |
} | |
ctx.lineTo(x, y); | |
ctx.stroke(); | |
colorBit = !colorBit; | |
} | |
// Public members | |
spiral.draw = function (iterations) { | |
var direction = 0; | |
var stepLength = iterations + 1; | |
canvas.width = stepLength * stepFactor + lineWidth; | |
canvas.height = stepLength * stepFactor + lineWidth; | |
ctx.lineWidth = lineWidth; | |
ctx.lineCap = "square"; | |
x = 0 + lineWidth/2; | |
y = canvas.height - lineWidth/2; | |
var result = produce(iterations); | |
for(var stringIndex = 0; stringIndex < result.length; stringIndex++) { | |
switch(result[stringIndex]) { | |
case "F": | |
drawStep(direction, stepLength); | |
break; | |
case "M": | |
stepLength--; | |
// Intentional fall through | |
case "m": | |
direction = getDirection(direction - 1); | |
break; | |
case "P": | |
stepLength++; | |
// Intentional fall through | |
case "p": | |
direction = getDirection(direction + 1); | |
break; | |
} | |
} | |
return result; | |
} | |
})(window.spiral = window.spiral || {}); | |
var resultDiv = document.getElementById("result"); | |
var result = spiral.draw(20); | |
resultDiv.innerHTML = result; | |
document.getElementById("iterationsSlider").addEventListener("change", function () { | |
result = spiral.draw(parseInt(this.value)); | |
resultDiv.innerHTML = result; | |
}); |
My first self-invented L-system!
A Pen by Johan Karlsson on CodePen.
html { | |
margin: 0; | |
height: 100%; | |
background-color: #0F0F0F; | |
} | |
#iterationsSlider { | |
position: absolute; | |
margin: 3vmin; | |
} | |
.center { | |
position: absolute; | |
left: 50%; | |
top: 50%; | |
transform: translate(-50%, -50%); | |
} | |
#result { | |
font-family: monospace; | |
font-size: xx-large; | |
ddisplay: inline-block; | |
color: #121212; | |
hheight: 100%; | |
width: 50%; | |
word-wrap: break-word; | |
} | |
@media (max-width: 600px) { | |
#iterationsSlider { | |
display: none; | |
} | |
} |
👍