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; | |
| } | |
| } |
👍