moving Python POC to JS
This commit is contained in:
commit
fc12f05e3a
51
artworld/color.js
Normal file
51
artworld/color.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
export class Color {
|
||||||
|
static defaultColorMode = "hsl";
|
||||||
|
|
||||||
|
constructor(p1, p2, p3, alpha = 1, mode = null) {
|
||||||
|
this.mode = mode || Color.defaultColorMode;
|
||||||
|
this.p1 = p1;
|
||||||
|
this.p2 = p2;
|
||||||
|
this.p3 = p3;
|
||||||
|
this.alpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
toStr() {
|
||||||
|
return `${this.mode}(${this.p1} ${this.p2} ${this.p3} / ${this.alpha})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustHue(delta) {
|
||||||
|
this.p1 += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustSat(delta) {
|
||||||
|
this.p2 += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustLum(delta) {
|
||||||
|
this.p3 += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
adjustAlpha(delta) {
|
||||||
|
this.alpha += alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Palette Source: https://pico-8.fandom.com/wiki/Palette
|
||||||
|
export const Pico8 = {
|
||||||
|
BLACK: "rgb(0, 0, 0)",
|
||||||
|
DARK_BLUE: "rgb(29, 43, 83)",
|
||||||
|
PURPLE: "rgb(126, 37, 83)",
|
||||||
|
DARK_GREEN: "rgb(0, 135, 81)",
|
||||||
|
BROWN: "rgb(171, 82, 54)",
|
||||||
|
DARK_GREY: "rgb(95, 87, 79)",
|
||||||
|
LIGHT_GREY: "rgb(194, 195, 199)",
|
||||||
|
WHITE: "rgb(255, 241, 232)",
|
||||||
|
RED: "rgb(255, 0, 77)",
|
||||||
|
ORANGE: "rgb(255, 163, 0)",
|
||||||
|
YELLOW: "rgb(255, 236, 39)",
|
||||||
|
GREEN: "rgb(0, 228, 54)",
|
||||||
|
BLUE: "rgb(41, 173, 255)",
|
||||||
|
LAVENDER: "rgb(131, 118, 156)",
|
||||||
|
PINK: "rgb(255, 119, 168)",
|
||||||
|
LIGHT_PEACH: "rgb(255, 204, 170)",
|
||||||
|
};
|
101
artworld/drawable.js
Normal file
101
artworld/drawable.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { Vector2 } from "./math.js";
|
||||||
|
import { artworld } from "./world.js";
|
||||||
|
|
||||||
|
export class Drawable {
|
||||||
|
constructor(parent) {
|
||||||
|
this._parent = parent;
|
||||||
|
this._updates = [];
|
||||||
|
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._posVec = new Vector2(0, 0);
|
||||||
|
this._register();
|
||||||
|
}
|
||||||
|
|
||||||
|
_register() {
|
||||||
|
if (this._parent) {
|
||||||
|
this._parent.push(this);
|
||||||
|
}
|
||||||
|
artworld.register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy() {
|
||||||
|
let obj = Object.assign({}, this);
|
||||||
|
obj._register();
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
fill(color) {
|
||||||
|
this._fill = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stroke(color) {
|
||||||
|
this._stroke = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
strokeWeight(scalar) {
|
||||||
|
this._strokeWeight = scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos(vec) {
|
||||||
|
this._posVec = vec;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
x(scalar) {
|
||||||
|
this._posVec.x = scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
y(scalar) {
|
||||||
|
this._posVec.y = scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
z(scalar) {
|
||||||
|
this._z_index = scalar;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifiers ///////////////////////////
|
||||||
|
|
||||||
|
move(byVec) {
|
||||||
|
this._posVec = this._posVec.add(byVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO random()
|
||||||
|
// TODO draw() abstract
|
||||||
|
|
||||||
|
// getters /////////////////////////////
|
||||||
|
|
||||||
|
get worldPos() {
|
||||||
|
return this._parent ? this._parent.worldPos.add(this._pos) : this._pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Group extends Drawable {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._children = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
copy() {
|
||||||
|
let newobj = super.copy();
|
||||||
|
for (let child of this._children) {
|
||||||
|
let ccopy = Object.assign({}, child);
|
||||||
|
ccopy._parent = newobj;
|
||||||
|
ccopy._register();
|
||||||
|
}
|
||||||
|
return newobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(drawable) {
|
||||||
|
this._children.push(drawable);
|
||||||
|
drawable._parent = this;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
4
artworld/index.js
Normal file
4
artworld/index.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export { artworld } from "./world.js";
|
||||||
|
export { Color } from "./color.js";
|
||||||
|
export { Vector2 } from "./math.js";
|
||||||
|
export { Line } from "./shapes.js";
|
37
artworld/math.js
Normal file
37
artworld/math.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
export const TO_RADIANS = 180 / Math.PI;
|
||||||
|
|
||||||
|
export class Vector2 {
|
||||||
|
constructor(x, y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
add(other) {
|
||||||
|
return Vector2(this.x + other.x, this.y + other.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub(other) {
|
||||||
|
return Vector2(this.x - other.x, this.y - other.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
scale(s) {
|
||||||
|
return Vector2(s * this.x, s * this.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static random(x, y) {
|
||||||
|
let theta = random() * 2 * Math.PI;
|
||||||
|
// if neither specified, use (1, 1)
|
||||||
|
if (x === undefined) {
|
||||||
|
x = 1;
|
||||||
|
}
|
||||||
|
// if only x specified, use (x, x)
|
||||||
|
if (y === undefined) {
|
||||||
|
y = x;
|
||||||
|
}
|
||||||
|
return Vector2(x * cos(theta), y * sin(theta));
|
||||||
|
}
|
||||||
|
|
||||||
|
static polar(mag, angle) {
|
||||||
|
return Vector2(mag * Math.cos(angle), mag * Math.sin(angle));
|
||||||
|
}
|
||||||
|
}
|
17
artworld/rect.js
Normal file
17
artworld/rect.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class Rectangle {
|
||||||
|
constructor(x, y, width, height) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
contains(x, y) {
|
||||||
|
return (
|
||||||
|
x > this.x &&
|
||||||
|
x < this.x + this.width &&
|
||||||
|
y > this.y &&
|
||||||
|
y < this.y + this.height
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
29
artworld/shapes.js
Normal file
29
artworld/shapes.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { Vector2 } from "./math.js";
|
||||||
|
import { Drawable } from "./drawable.js";
|
||||||
|
|
||||||
|
export class Line extends Drawable {
|
||||||
|
constructor(parent) {
|
||||||
|
super(parent);
|
||||||
|
this._offsetVec = new Vector2(10, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
artworld.setStrokeColor(this._stroke);
|
||||||
|
artworld.setStrokeWeight(this._strokeWeight);
|
||||||
|
artworld.drawLine(this._posVec, this._offsetVec);
|
||||||
|
}
|
||||||
|
|
||||||
|
to(vec) {
|
||||||
|
this._offsetVec = vec;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
polar(mag, angle) {
|
||||||
|
return this.to(Vector2.polar(mag, angle));
|
||||||
|
}
|
||||||
|
|
||||||
|
angle(angle) {
|
||||||
|
let mag = this._offsetVec.magnitude;
|
||||||
|
return this.to(Vector2.polar(mag, angle));
|
||||||
|
}
|
||||||
|
}
|
52
artworld/world.js
Normal file
52
artworld/world.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
export class World {
|
||||||
|
constructor() {
|
||||||
|
this.drawables = [];
|
||||||
|
this.ctx = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bindCanvas(id) {
|
||||||
|
this.ctx = document.getElementById(id).getContext("2d");
|
||||||
|
}
|
||||||
|
|
||||||
|
register(drawable) {
|
||||||
|
this.drawables.push(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
for (let d of this.drawables) {
|
||||||
|
d.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canvas 2D /////////////////
|
||||||
|
|
||||||
|
setStrokeWeight(scalar) {
|
||||||
|
this.ctx.lineWidth = scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
setStrokeColor(color) {
|
||||||
|
this.ctx.strokeStyle = color.toStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
setFillColor(color) {
|
||||||
|
this.ctx.fillStyle = color.toStr();
|
||||||
|
}
|
||||||
|
|
||||||
|
fillRect(rect) {
|
||||||
|
this.ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
strokeRect(rect) {
|
||||||
|
this.ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawLine(from, to) {
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.moveTo(from.x, from.y);
|
||||||
|
this.ctx.lineTo(to.x, to.y);
|
||||||
|
this.ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// singleton (for now)
|
||||||
|
export const artworld = new World();
|
19
examples/lines.html
Normal file
19
examples/lines.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<html>
|
||||||
|
<head> </head>
|
||||||
|
<body>
|
||||||
|
<canvas id="mainCanvas" width="800" height="800"></canvas>
|
||||||
|
<script type="module">
|
||||||
|
import { artworld, Color, Line, Vector2 } from "../artworld/index.js";
|
||||||
|
artworld.bindCanvas("mainCanvas");
|
||||||
|
window.artworld = artworld;
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
new Line()
|
||||||
|
.pos(new Vector2(5 * i * 14, 5))
|
||||||
|
.to(new Vector2(5 * i * 14, 140))
|
||||||
|
.stroke(new Color(20 * i, 50, 50))
|
||||||
|
.strokeWeight(1 + i);
|
||||||
|
}
|
||||||
|
artworld.draw();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user