Generator functions allow you to define an iterative algorithm by writing a single function whose execution is not continuous. Generator functions are written using the function* syntax. See Iterators and Generators: mdn
Our example generator creates an iterator representing an infinite stream of points, roughly simulating a stream of mouse positions.
function* genPoints() { const {floor, random} = Math let [x, y] = [0, 0] while (true) { yield {x, y} x += 20 - floor(20 * (random()+random())) y += 20 - floor(20 * (random()+random())) } }
Infinite streams risk infinite loops. We can construct another generator which limits the range of the stream.
function* take(n, iterator) { let result, i = 0; while (!(result = iterator.next()).done && i++ < n) { yield result.value; } }
Lets introduce a little asynchrony to more closely model a stream of mouse movements.
async function* timejitter(iterator) { const {floor, random} = Math for (let point of iterator) { yield point let ms = 5 + floor(5 * (random()+random())) await new Promise(r => setTimeout(r, ms)) } }
Lets use these tools to draw some lines.
We need something that knows how to convert a sequence of points into graphics instructions.
async function drawLine(ctx, line, color) { let prev = null for await (let {x, y} of line) { // knows iterators ctx.beginPath() ctx.strokeStyle = color ctx.lineWidth = 1 if (prev == null) { ctx.moveTo(x, y) } else { ctx.moveTo(prev.x, prev.y) ctx.lineTo(x, y) } prev = {x, y} ctx.stroke() } }
We need a canvas on which to draw.
let canvas = document.createElement("canvas") canvas.id = "canvas" canvas.style = "border: 1px solid black;" canvas.width = 380 canvas.height = 300 let ctx = canvas.getContext("2d") ctx.translate(190, 150) output.appendChild(canvas)
Lets create a few lines.
let redLine = timejitter(take(200, genPoints())) let blueLine = timejitter(take(200, genPoints())) let greenLine = timejitter(take(200, genPoints()))
Here we draw our lines.
async function main() { drawLine(ctx, redLine, "lightblue") drawLine(ctx, blueLine, "palegreen") drawLine(ctx, greenLine, "green") } main() null
In the frame below we can view the results.
//wiki.dbbs.co/assets/pages/js-snippet-template/basicjs.html HEIGHT 330