From c44252a14c892d99c54ad2d575345720e003a964 Mon Sep 17 00:00:00 2001 From: James Turk Date: Sun, 9 Mar 2025 20:52:32 -0500 Subject: [PATCH] dataclock, another take on the clock with Var() instead of animate() to keep w/ declarative mode --- artworld/index.js | 1 + artworld/shapes.js | 6 +++++- artworld/variables.js | 32 ++++++++++++++++++++++++++++ artworld/world.js | 45 ++++++++++++++++++++++++++++----------- examples/dataclock.html | 47 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 artworld/variables.js create mode 100644 examples/dataclock.html diff --git a/artworld/index.js b/artworld/index.js index c1e4cf4..cebaaef 100644 --- a/artworld/index.js +++ b/artworld/index.js @@ -4,3 +4,4 @@ export { Vector2, degToRad, radToDeg } from "./math.js"; export { Line, Rect, Circle, Arc, Polygon } from "./shapes.js"; export { Group } from "./drawable.js"; export { Random } from "./random.js"; +export { Var } from "./variables.js"; diff --git a/artworld/shapes.js b/artworld/shapes.js index 96e8387..1f4ef0e 100644 --- a/artworld/shapes.js +++ b/artworld/shapes.js @@ -1,6 +1,7 @@ import { Vector2 } from "./math.js"; import { Drawable } from "./drawable.js"; import { Random } from "./random.js"; +import { getVal } from "./variables.js"; function makeCopy(Cls, obj, override) { // make new object, will be registered with world, but no _parent yet @@ -32,7 +33,10 @@ export class Line extends Drawable { draw() { artworld.prepareDraw(this); - artworld.drawLine(this.worldPos, this.worldPos.add(this._offsetVec)); + artworld.drawLine( + this.worldPos, + this.worldPos.add(getVal(this._offsetVec)), + ); } to(vec) { diff --git a/artworld/variables.js b/artworld/variables.js new file mode 100644 index 0000000..dbe5a44 --- /dev/null +++ b/artworld/variables.js @@ -0,0 +1,32 @@ +import { artworld } from "./world.js"; + +export function getVal(x) { + return x && x.getValue ? x.getValue() : x; +} + +export class Var { + constructor(value) { + if (typeof value === "function") { + this._updateFunc = value; + this._value = this._updateFunc(0); + } else { + this._value = value; + this._updateFunc = null; + } + artworld.register(this); + } + + updateFunc(func) { + this._updateFunc = func; + } + + update(t) { + if (this._updateFunc) { + this._value = this._updateFunc(t); + } + } + + getValue() { + return this._value; + } +} diff --git a/artworld/world.js b/artworld/world.js index 19cc69c..cdc978c 100644 --- a/artworld/world.js +++ b/artworld/world.js @@ -1,9 +1,11 @@ import { Timer } from "./timer.js"; +import { getVal, Var } from "./variables.js"; export class World { constructor() { this.ctx = null; this.drawables = []; + this.variables = []; this.backgroundColor = "white"; this.timer = new Timer(); this.targetFrameRate = 60; @@ -25,8 +27,13 @@ export class World { } // TODO rename - register(drawable) { - this.drawables.push(drawable); + register(thing) { + if (thing instanceof Var) { + this.variables.push(thing); + } else { + // TODO: check drawable? + this.drawables.push(thing); + } } draw() { @@ -44,6 +51,9 @@ export class World { for (let d of this.drawables) { d.update(this.numTicks); } + for (let v of this.variables) { + v.update(this.numTicks); + } } get updatesPerSecond() { @@ -67,21 +77,21 @@ export class World { prepareDraw(drawable) { this._stroke = false; this._fill = false; - if (drawable._stroke) { - this.ctx.lineWidth = drawable._strokeWeight; - this.ctx.strokeStyle = drawable._stroke.toStr - ? drawable._stroke.toStr() - : drawable._stroke; + let stroke = getVal(drawable._stroke); + let fill = getVal(drawable._fill); + if (stroke) { + this.ctx.lineWidth = getVal(drawable._strokeWeight); + this.ctx.strokeStyle = stroke.toStr ? stroke.toStr() : stroke; this._stroke = true; - } else if (drawable._fill) { - this.ctx.fillStyle = drawable._fill.toStr - ? drawable._fill.toStr() - : drawable._fill; + } else if (fill) { + this.ctx.fillStyle = fill.toStr ? fill.toStr() : fill; this._fill = true; } } drawLine(from, to) { + from = getVal(from); + to = getVal(to); this.ctx.beginPath(); this.ctx.moveTo(from.x, from.y); this.ctx.lineTo(to.x, to.y); @@ -89,13 +99,23 @@ export class World { } drawArc(center, radius, fromAngle, toAngle) { + center = getVal(center); this.ctx.beginPath(); - this.ctx.arc(center.x, center.y, radius, fromAngle, toAngle); + this.ctx.arc( + center.x, + center.y, + getVal(radius), + getVal(fromAngle), + getVal(toAngle), + ); if (this._stroke) this.ctx.stroke(); if (this._fill) this.ctx.fill(); } drawRect(center, width, height) { + center = getVal(center); + width = getVal(width); + height = getVal(height); this.ctx.beginPath(); this.ctx.rect(center.x - width / 2, center.y - height / 2, width, height); if (this._stroke) this.ctx.stroke(); @@ -103,6 +123,7 @@ export class World { } drawPolygon(center, points) { + center = getVal(center); this.ctx.beginPath(); this.ctx.moveTo(center.x + points[0].x, center.y + points[0].y); for (let i = 1; i < points.length; i++) { diff --git a/examples/dataclock.html b/examples/dataclock.html new file mode 100644 index 0000000..ac0d20d --- /dev/null +++ b/examples/dataclock.html @@ -0,0 +1,47 @@ + + + + + + +