dataclock, another take on the clock with Var() instead of animate() to keep w/ declarative mode
This commit is contained in:
parent
d42774ad1f
commit
c44252a14c
@ -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";
|
||||
|
@ -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) {
|
||||
|
32
artworld/variables.js
Normal file
32
artworld/variables.js
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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++) {
|
||||
|
47
examples/dataclock.html
Normal file
47
examples/dataclock.html
Normal file
@ -0,0 +1,47 @@
|
||||
<html>
|
||||
<head> </head>
|
||||
<body>
|
||||
<canvas id="mainCanvas" width="500" height="500"></canvas>
|
||||
<script type="module">
|
||||
import {
|
||||
artworld,
|
||||
Color,
|
||||
Pico8,
|
||||
Group,
|
||||
Rect,
|
||||
Random,
|
||||
Vector2,
|
||||
Line,
|
||||
Circle,
|
||||
Var,
|
||||
degToRad,
|
||||
} from "../artworld/index.js";
|
||||
artworld.bindCanvas("mainCanvas");
|
||||
window.artworld = artworld;
|
||||
|
||||
// declare some time-fluctuation variables
|
||||
let color = new 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) => {
|
||||
let angle = (t / 6000) * Math.PI * 2;
|
||||
return Vector2.polar(innerR.getValue(), angle);
|
||||
});
|
||||
|
||||
let g = new Group().pos(new Vector2(250, 250));
|
||||
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();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user