Skip to content

Instantly share code, notes, and snippets.

@StartAutomating
Created August 17, 2025 03:17
Show Gist options
  • Save StartAutomating/69818ef4e60f91347a1bedad190193da to your computer and use it in GitHub Desktop.
Save StartAutomating/69818ef4e60f91347a1bedad190193da to your computer and use it in GitHub Desktop.
Gist a tiny turtle
<#
.SYNOPSIS
A Tiny Turtle
.DESCRIPTION
A minimal implementation of Turtle graphics in PowerShell and JavaScript, with and a speed test.
.EXAMPLE
./TinyTurtle.html.ps1 > ./TinyTurtle.html
#>
"<div>"
"<svg width='100%' height='100%' id='stage'>"
"<path id='turtle-path' fill='transparent' stroke='currentColor' stroke-width='1%' stroke-linecap='round'></path>"
"<text id='counter' font-size='12px' x='50%' y='50%' text-anchor='middle' dominant-baseline='middle'></text>"
"</svg>"
"<script>"
@"
let counter = 0;
let time = new Date()
function draw() {
requestAnimationFrame(draw)
let turtle = {
heading: 0.0,
steps: [],
penDown: true,
x: 0.0, y:0.0,
width: 0.0, height: 0.0,
min: {x:0.0, y:0.0}, max: {x:0.0, y:0.0},
rotate: function(angle) { this.heading += Number(angle); return this },
step: function(dx,dy) {
if (this.penDown) { this.steps.push(`` l `${dx} `${dy} ``) }
else { this.steps.push(`` m `${dx} `${dy} ``) }
this.x += dx; this.y += dy ; this.resize()
return this
},
forward: function(distance) {
return this.step(distance * Math.cos(this.heading * Math.PI / 180),
distance * Math.sin(this.heading * Math.PI / 180))
},
goto: function(x,y) { return this.step(x - this.x, y - this.y) },
teleport: function(x,y) {
var penState = this.penDown
this.penDown = false
step(x - this.x, y - this.y)
this.penDown = penState
return this
},
resize: function() {
if (this.x > this.max.x) { this.max.x = this.x }
if (this.y > this.max.y) { this.max.y = this.y }
if (this.x < this.min.x) { this.min.x = this.x }
if (this.y < this.min.y) { this.min.y = this.y }
this.width = this.max.x - this.min.x
this.height = this.max.y - this.min.y
return this
},
path: function() { return ``m `${this.min.x * -1} `${this.min.y * -1} `${this.steps.join(' ')} `` },
polygon: function(size, sides = 6) {
for (let side = 0; side < sides; side++) {
turtle.forward(size).rotate(360/sides)
}
}
}
turtle.rotate(Math.random() * 360).polygon(100, 8)
let svg = document.getElementById('stage')
svg.setAttribute('viewBox', ``0 0 `${turtle.width} `${turtle.height}``)
let path = document.getElementById('turtle-path')
path.setAttribute('d', turtle.path())
counter++
document.getElementById('counter').textContent =
```${Math.round(counter/((new Date() - time)/1000)*100)/100} fps``
}
draw()
"@
"</script>"
"</div>"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment