kill the singleton

This commit is contained in:
James Turk 2025-03-09 22:57:34 -05:00
parent c44252a14c
commit 90256f617e
6 changed files with 60 additions and 52 deletions

View File

@ -1,4 +1,3 @@
import { artworld } from "./world.js";
import { Vector2 } from "./math.js";
import { Color } from "./color.js";
import { Random } from "./random.js";
@ -10,13 +9,12 @@ export class Drawable {
this._fill = parent ? parent._fill : null;
this._stroke = parent ? parent._stroke : null;
this._strokeWeight = parent ? parent._strokeWeight : null;
this._z_index = parent ? parent._z_index : null;
this._zIndex = parent ? parent._zIndex : null;
this._posVec = new Vector2(0, 0);
this._animations = [];
if (this._parent) {
this._parent.addChild(this);
}
artworld.register(this);
}
copy() {
@ -71,7 +69,7 @@ export class Drawable {
}
z(scalar) {
this._z_index = scalar;
this._zIndex = scalar;
return this;
}
@ -83,10 +81,7 @@ export class Drawable {
}
random() {
this._posVec = new Vector2(
Random.under(artworld.width),
Random.under(artworld.height),
);
this._posVec = new Vector2(Random.under(100), Random.under(100));
this._stroke = new Color(
Random.under(360),
Random.between(30, 60),
@ -137,11 +132,16 @@ export class Group extends Drawable {
return newGroup;
}
draw() {}
draw() {
for (let c of this._children) {
c.draw();
}
}
addChild(drawable) {
this._children.push(drawable);
drawable._parent = this;
drawable._world = this._world;
return this;
}

View File

@ -1,7 +1,7 @@
export { artworld } from "./world.js";
export { Color, Pico8 } from "./color.js";
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";
export { World } from "./world.js";

View File

@ -32,8 +32,8 @@ export class Line extends Drawable {
}
draw() {
artworld.prepareDraw(this);
artworld.drawLine(
this._world.prepareDraw(this);
this._world.drawLine(
this.worldPos,
this.worldPos.add(getVal(this._offsetVec)),
);
@ -70,8 +70,13 @@ export class Arc extends Drawable {
return this;
}
draw() {
artworld.prepareDraw(this);
artworld.drawArc(this.worldPos, this._r, this._startAngle, this._endAngle);
this._world.prepareDraw(this);
this._world.drawArc(
this.worldPos,
this._r,
this._startAngle,
this._endAngle,
);
}
radius(scalar) {
@ -104,8 +109,8 @@ export class Circle extends Drawable {
}
draw() {
artworld.prepareDraw(this);
artworld.drawArc(this.worldPos, this._r, 0, 2 * Math.PI);
this._world.prepareDraw(this);
this._world.drawArc(this.worldPos, this._r, 0, 2 * Math.PI);
}
radius(scalar) {
@ -132,8 +137,8 @@ export class Rect extends Drawable {
}
draw() {
artworld.prepareDraw(this);
artworld.drawRect(this.worldPos, this._width, this._height);
this._world.prepareDraw(this);
this._world.drawRect(this.worldPos, this._width, this._height);
}
size(w, h) {
@ -204,8 +209,8 @@ export class Polygon extends Drawable {
}
draw() {
artworld.prepareDraw(this);
artworld.drawPolygon(this.worldPos, this._points);
this._world.prepareDraw(this);
this._world.drawPolygon(this.worldPos, this._points);
}
point(vector, to_modify = null) {

View File

@ -1,5 +1,3 @@
import { artworld } from "./world.js";
export function getVal(x) {
return x && x.getValue ? x.getValue() : x;
}
@ -13,7 +11,6 @@ export class Var {
this._value = value;
this._updateFunc = null;
}
artworld.register(this);
}
updateFunc(func) {

View File

@ -2,7 +2,7 @@ import { Timer } from "./timer.js";
import { getVal, Var } from "./variables.js";
export class World {
constructor() {
constructor(canvasId) {
this.ctx = null;
this.drawables = [];
this.variables = [];
@ -12,10 +12,7 @@ export class World {
this.stepSize = 1000 / this.targetFrameRate;
this.lastTick = this.timer.time();
this.numTicks = 0;
}
bindCanvas(id) {
this.ctx = document.getElementById(id).getContext("2d");
this.ctx = document.getElementById(canvasId).getContext("2d");
}
get width() {
@ -26,22 +23,24 @@ export class World {
return this.ctx.canvas.height;
}
// TODO rename
register(thing) {
if (thing instanceof Var) {
this.variables.push(thing);
} else {
// TODO: check drawable?
this.drawables.push(thing);
}
var(value) {
let v = new Var(value);
this.variables.push(v);
return v;
}
drawable(thing) {
this.drawables.push(thing);
thing._world = this; // set world for access to renderer (TODO: revisit)
return thing;
}
draw() {
this.ctx.fillStyle = "white";
this.ctx.fillStyle = this.backgroundColor;
this.ctx.beginPath();
this.ctx.fillRect(0, 0, this.width, this.height);
this.ctx.fill();
for (let d of this.drawables.sort((a, b) => a._z_index - b._z_index)) {
for (let d of this.drawables.sort((a, b) => a._zIndex - b._zIndex)) {
d.draw();
}
}
@ -134,6 +133,3 @@ export class World {
if (this._fill) this.ctx.fill();
}
}
// singleton (for now)
export const artworld = new World();

View File

@ -4,7 +4,7 @@
<canvas id="mainCanvas" width="500" height="500"></canvas>
<script type="module">
import {
artworld,
World,
Color,
Pico8,
Group,
@ -16,32 +16,42 @@
Var,
degToRad,
} from "../artworld/index.js";
artworld.bindCanvas("mainCanvas");
window.artworld = artworld;
// declare some time-fluctuation variables
let color = new Var(
let world = new World("mainCanvas");
window.world = world;
// This is an experiment to separate the declaration of
// "what the data does" from "what it looks like".
// First we use `Var` to define "what the data does"
// variables are expected to regularly *vary*!
// Variables are defined as functions that update with time.
// It is also possible to define static variables.
let color = world.var(
(t) =>
[Pico8.RED, Pico8.ORANGE, Pico8.GREEN, Pico8.BLUE][
Math.floor(t / 60) % 4
],
);
let outerR = new Var((t) => Math.sin(t / 100) * 50 + 200);
// simple dependency
let innerR = new Var(() => outerR.getValue() - 10);
// example of a more complex Var that uses other vars
let lineTo = new Var((t) => {
// We can create dependencies between them: here the inner & outer
// radii should be 10 pixels apart.
let outerR = world.var((t) => Math.sin(t / 100) * 50 + 200);
let innerR = world.var(() => outerR.getValue() - 10);
// We take this composition a bit further here, the radius of the clock
// hand grows & shrinks with the edge.
let lineTo = world.var((t) => {
let angle = (t / 6000) * Math.PI * 2;
return Vector2.polar(innerR.getValue(), angle);
});
let g = new Group().pos(new Vector2(250, 250));
world.drawable(g);
new Circle(g).fill(Pico8.BLACK).z(1).radius(outerR);
new Circle(g).z(10).fill(color).radius(innerR);
new Circle(g).radius(20).fill(Pico8.BLACK).z(50);
new Line(g).to(lineTo).z(100);
artworld.loopStep();
world.loopStep();
</script>
</body>
</html>