-
Notifications
You must be signed in to change notification settings - Fork 2
/
node.ts
72 lines (55 loc) · 1.66 KB
/
node.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// A renderable Node used in Animator.
import { get, type MaybeValue } from "./value.js"
import { getVector, type VectorLike } from "./vector.js"
export interface NodeProps {
x?: MaybeValue<number>
y?: MaybeValue<number>
origin?: VectorLike
translate?: VectorLike
scale?: VectorLike
fill?: MaybeValue<string | CanvasGradient | CanvasPattern>
stroke?: MaybeValue<string | CanvasGradient | CanvasPattern>
strokeWidth?: MaybeValue<number>
}
export class Node {
x
y
origin
translate
scale
fill
stroke
strokeWidth
children: Node[] = []
constructor(props: NodeProps = {}) {
this.x = props.x
this.y = props.y
this.origin = props.origin
this.translate = props.translate
this.scale = props.scale || 1
this.fill = props.fill
this.stroke = props.stroke
this.strokeWidth = props.strokeWidth
}
render(context: CanvasRenderingContext2D) {
context.translate(getVector(this.origin).x, getVector(this.origin).y)
context.translate(getVector(this.translate).x, getVector(this.translate).y)
context.scale(getVector(this.scale).x, getVector(this.scale).y)
context.translate(-getVector(this.origin).x, -getVector(this.origin).y)
context.fillStyle = get(this.fill) || "transparent"
context.strokeStyle = get(this.stroke) || "transparent"
context.lineWidth = get(this.strokeWidth) || 0
this.draw?.(context)
if (this.path) {
const path = new Path2D()
this.path(path)
context.fill(path)
context.stroke(path)
}
for (const child of this.children) {
child.render(context)
}
}
draw?(context: CanvasRenderingContext2D): void
path?(path: Path2D): void
}