Turtle Code Walkthrough

Our simplified "turtle graphics" implementation does just enough to be interesting. wikipedia

TICK 9 FORWARD 60 TURN 140 FORWARD 60 TURN -100

FORWARD to move the "turtle" leaving a line.

TURN rotate the "turtle" to move in a new direction.

Each block has an "emit" handler that will interpret inputs and report decisions that it has made. The two turtle blocks each has a handler to be run in either order. github

Both blocks can instantiate a shared Turtle which creates and manages an inline SVG element and draws under the direction of blocks as they run. github

# Emit

The emit handler is called once for each time the block runs. It is called with a variety of parameters all bundle in an object that is conventionally destructured into variables need to run the block: {elem,command,args,state}

- elem — the dom element that surrounds the block - command — the string for the block as written - args — the block's arguments as an array - state — the persistent state to be read and written

function forward_emit ({elem,command,args,state}) {

We report trouble (clickable red x) if no argument

if(args.length < 1) return trouble(elem,`...`)

Create Turtle object if not already present.

if(!('turtle' in state)) state.turtle = new Turtle(elem)

Retrieve the first argument, a string.

const steps = args[0]

Delegate action to Turtle object with numeric argument.

const position = state.turtle.forward(+steps)

Update dom with position relative to starting point.

elem.innerHTML = command + ` ⇒ ${ position.map(n => (n-200).toFixed(1)).join(', ') }`

Repeat this logic substituting angle for distance.

function turn_emit ({elem,command,args,state}) {

# SVG

An object shared between emit handlers creates a drawing area in the object constructor.

class Turtle { constructor(elem) {

const div = document.createElement('div') elem.closest('.item').firstElementChild.prepend(div)

Add and configure an SVG element.

...

The object's forward method computes line endpoints.

forward(steps) { const theta = this.direction*2*Math.PI/360 const [x1,y1] = this.position const [x2,y2] = [ x1+steps*Math.sin(theta), y1+steps*Math.cos(theta) ]

Add and configure an SVG line element.

...

Record and return the new endpoint position.

this.position = [x2,y2] return this.position