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 { Random } from "./random.js";
function cloneObject(obj) {
for (let [k, v] of Object.entries(obj)) {
console.log(k, v);
}
}
export class Drawable {
constructor(parent) {
this._parent = parent;
@ -12,24 +18,18 @@ export class Drawable {
this._strokeWeight = parent ? parent._strokeWeight : null;
this._z_index = parent ? parent._z_index : null;
this._posVec = new Vector2(0, 0);
this._register();
}
_register() {
if (this._parent) {
this._parent._register(this);
this._parent.addChild(this);
}
artworld.register(this);
}
copy() {
let obj = Object.assign({}, this);
obj._register();
return obj;
throw new Error("copy() must be implemented on child class");
}
draw() {
// no-op, maybe log?
throw new Error("draw() must be implemented on child class");
}
// setters
@ -73,6 +73,7 @@ export class Drawable {
move(byVec) {
this._posVec = this._posVec.add(byVec);
return this;
}
random() {
@ -110,18 +111,52 @@ export class Group extends Drawable {
}
copy() {
let newobj = super.copy();
// new empty group
let newGroup = new Group();
for (let child of this._children) {
let ccopy = Object.assign({}, child);
ccopy._parent = newobj;
ccopy._register();
// make a copy of each child item
// use child class copy, with forced override of group
// this registers each one as a child of newGroup
// as part of the copy behavior
child.copy({ _parent: newGroup });
}
return newobj;
// attach own parent if present
if (this._parent) {
newGroup._parent = this._parent;
newGroup._parent.addChild(newGroup);
}
return newGroup;
}
add(drawable) {
draw() {}
addChild(drawable) {
this._children.push(drawable);
drawable._parent = 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 { 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 {
constructor(parent) {
super(parent);
this._offsetVec = new Vector2(10, 0);
}
copy(overrides) {
return makeCopy(Line, this, overrides);
}
draw() {
artworld.setStrokeColor(this._stroke);
artworld.setStrokeWeight(this._strokeWeight);
@ -32,6 +48,9 @@ export class Arc extends Drawable {
this._startAngle = 0;
this._endAngle = 180;
}
copy(overrides) {
return makeCopy(Arc, this, overrides);
}
draw() {
artworld.prepareDraw(this);
@ -57,6 +76,9 @@ export class Circle extends Drawable {
super(parent);
this._r = 25;
}
copy(overrides) {
return makeCopy(Circle, this, overrides);
}
draw() {
artworld.prepareDraw(this);
@ -82,6 +104,9 @@ export class Rect extends Drawable {
this._height = Random.between(20, range);
return this;
}
copy(overrides) {
return makeCopy(Rect, this, overrides);
}
draw() {
artworld.prepareDraw(this);

View File

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