We construct some generators to emit a stream of points.
//frame.wiki.dbbs.co/assets/pages/snippet-template/esm.html SOURCE point
To watch the points drawn, see Scribble.
function* genPoints() { const {floor, random} = Math const average = 15 let [x, y] = [0, 0] while (true) { yield {x, y} x += floor(average * (random()-random())) y += floor(average * (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 const average = 200 for (let point of iterator) { yield point let ms = floor(average * (random()-random())) await new Promise(r => setTimeout(r, ms)) } }
We create a few helper functions.
function resize() { window.parent.postMessage({ action: "resize", height: document.body.offsetHeight }, "*") }
function broadcast(point) { window.parent.postMessage({ action: "publishSourceData", name: "point", sourceData: {point} }, "*") }
function updateProgress(el, count) { el.innerHTML = `generated ${count} points` }
Let's broadcast a line.
export async function emit(el) { const now = new Date().toLocaleString("en-US") el.innerHTML = ` <p>started: ${now}</p> <p id="progress"></p>` } export async function bind(el) { const display = el.querySelector("#progress") let progress = 0 updateProgress(display, progress) resize() const line = timejitter(take(1000, genPoints())) for await (let point of line) { broadcast(point) if (progress % 25 == 0) { updateProgress(display, progress) } progress++ } const now = new Date().toLocaleString("en-US") updateProgress(display, progress) display.insertAdjacentHTML("afterend", ` <p>stopped: ${now}</p>`) resize() }