copy logic ported over, JS doesn't make this easy

This commit is contained in:
James Turk 2024-07-07 00:16:21 -05:00
parent 6532e64e14
commit 6b8b20d286
4 changed files with 105 additions and 17 deletions

View File

@ -3,6 +3,12 @@ import { Vector2 } from "./math.js";
import { Color } from "./color.js"; import { Color } from "./color.js";
import { Random } from "./random.js"; import { Random } from "./random.js";
function cloneObject(obj) {
for (let [k, v] of Object.entries(obj)) {
console.log(k, v);
}
}
export class Drawable { export class Drawable {
constructor(parent) { constructor(parent) {
this._parent = parent; this._parent = parent;
@ -12,24 +18,18 @@ export class Drawable {
this._strokeWeight = parent ? parent._strokeWeight : null; this._strokeWeight = parent ? parent._strokeWeight : null;
this._z_index = parent ? parent._z_index : null; this._z_index = parent ? parent._z_index : null;
this._posVec = new Vector2(0, 0); this._posVec = new Vector2(0, 0);
this._register();
}
_register() {
if (this._parent) { if (this._parent) {
this._parent._register(this); this._parent.addChild(this);
} }
artworld.register(this); artworld.register(this);
} }
copy() { copy() {
let obj = Object.assign({}, this); throw new Error("copy() must be implemented on child class");
obj._register();
return obj;
} }
draw() { draw() {
// no-op, maybe log? throw new Error("draw() must be implemented on child class");
} }
// setters // setters
@ -73,6 +73,7 @@ export class Drawable {
move(byVec) { move(byVec) {
this._posVec = this._posVec.add(byVec); this._posVec = this._posVec.add(byVec);
return this;
} }
random() { random() {
@ -110,18 +111,52 @@ export class Group extends Drawable {
} }
copy() { copy() {
let newobj = super.copy(); // new empty group
let newGroup = new Group();
for (let child of this._children) { for (let child of this._children) {
let ccopy = Object.assign({}, child); // make a copy of each child item
ccopy._parent = newobj; // use child class copy, with forced override of group
ccopy._register(); // this registers each one as a child of newGroup
} // as part of the copy behavior
return newobj; child.copy({ _parent: newGroup });
} }
add(drawable) { // attach own parent if present
if (this._parent) {
newGroup._parent = this._parent;
newGroup._parent.addChild(newGroup);
}
return newGroup;
}
draw() {}
addChild(drawable) {
this._children.push(drawable); this._children.push(drawable);
drawable._parent = this; drawable._parent = this;
return this; return this;
} }
fill(color) {
for (let child of this._children) {
child.fill(color);
}
return this;
}
stroke(color) {
for (let child of this._children) {
child.stroke(color);
}
return this;
}
strokeWeight(scalar) {
for (let child of this._children) {
child.strokeWeight(scalar);
}
return this;
}
} }

View File

@ -2,12 +2,28 @@ import { Vector2 } from "./math.js";
import { Drawable } from "./drawable.js"; import { Drawable } from "./drawable.js";
import { Random } from "./random.js"; import { Random } from "./random.js";
function makeCopy(Cls, obj, override) {
// make new object, will be registered with world, but no _parent yet
let newObj = new Cls();
// overwrite fields of newObj with obj
Object.assign(newObj, obj, override);
// attach to parent
if (newObj._parent) {
newObj._parent.addChild(newObj);
}
return newObj;
}
export class Line extends Drawable { export class Line extends Drawable {
constructor(parent) { constructor(parent) {
super(parent); super(parent);
this._offsetVec = new Vector2(10, 0); this._offsetVec = new Vector2(10, 0);
} }
copy(overrides) {
return makeCopy(Line, this, overrides);
}
draw() { draw() {
artworld.setStrokeColor(this._stroke); artworld.setStrokeColor(this._stroke);
artworld.setStrokeWeight(this._strokeWeight); artworld.setStrokeWeight(this._strokeWeight);
@ -32,6 +48,9 @@ export class Arc extends Drawable {
this._startAngle = 0; this._startAngle = 0;
this._endAngle = 180; this._endAngle = 180;
} }
copy(overrides) {
return makeCopy(Arc, this, overrides);
}
draw() { draw() {
artworld.prepareDraw(this); artworld.prepareDraw(this);
@ -57,6 +76,9 @@ export class Circle extends Drawable {
super(parent); super(parent);
this._r = 25; this._r = 25;
} }
copy(overrides) {
return makeCopy(Circle, this, overrides);
}
draw() { draw() {
artworld.prepareDraw(this); artworld.prepareDraw(this);
@ -82,6 +104,9 @@ export class Rect extends Drawable {
this._height = Random.between(20, range); this._height = Random.between(20, range);
return this; return this;
} }
copy(overrides) {
return makeCopy(Rect, this, overrides);
}
draw() { draw() {
artworld.prepareDraw(this); artworld.prepareDraw(this);

View File

@ -32,10 +32,10 @@ export class World {
this._stroke = false; this._stroke = false;
this._fill = false; this._fill = false;
if (drawable._stroke) { if (drawable._stroke) {
this.ctx.lineWidth = drawable._strokeWidth; this.ctx.lineWidth = drawable._strokeWeight;
this.ctx.strokeStyle = drawable._stroke.toStr this.ctx.strokeStyle = drawable._stroke.toStr
? drawable._stroke.toStr() ? drawable._stroke.toStr()
: drawble._stroke; : drawable._stroke;
this._stroke = true; this._stroke = true;
} else if (drawable._fill) { } else if (drawable._fill) {
this.ctx.fillStyle = drawable._fill.toStr this.ctx.fillStyle = drawable._fill.toStr

28
examples/copies.html Normal file
View File

@ -0,0 +1,28 @@
<html>
<head> </head>
<body>
<canvas id="mainCanvas" width="500" height="500"></canvas>
<script type="module">
import {
artworld,
Color,
Pico8,
Group,
Circle,
Random,
Vector2,
} from "../artworld/index.js";
artworld.bindCanvas("mainCanvas");
window.artworld = artworld;
let g = new Group().pos(new Vector2(0, 0));
let c = new Circle(g).radius(80).stroke(Pico8.RED).strokeWeight(5);
for (let i = 0; i < 15; i++) {
c = c.copy().move(new Vector2(45, 45));
}
g.copy().move(new Vector2(200, 0)).stroke(Pico8.GREEN);
g.copy().move(new Vector2(-200, 0)).stroke(Pico8.BLUE);
artworld.draw();
</script>
</body>
</html>