like2d 2.11.1 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/assets/logo-banner-optimized.svg +15 -27
- package/assets/logo-banner.svg +76 -132
- package/assets/logo-icon.svg +33 -23
- package/assets/logo.svg +78 -123
- package/dist/engine.d.ts +2 -0
- package/dist/engine.js +34 -12
- package/dist/events.d.ts +0 -3
- package/dist/graphics/canvas.d.ts +15 -7
- package/dist/graphics/canvas.js +64 -68
- package/dist/graphics/graphics.d.ts +53 -38
- package/dist/graphics/graphics.js +98 -70
- package/dist/input/controllerdb.json +1 -1
- package/dist/input/gamepad-mapping.js +2 -1
- package/dist/input/input.d.ts +2 -2
- package/dist/input/input.js +2 -2
- package/dist/like.d.ts +36 -5
- package/dist/math/vector2.d.ts +1 -1
- package/dist/prefab-scenes/mapGamepad.d.ts +2 -3
- package/dist/prefab-scenes/mapGamepad.js +17 -23
- package/dist/prefab-scenes/startScreen.d.ts +2 -3
- package/dist/prefab-scenes/startScreen.js +41 -12
- package/dist/scene.d.ts +47 -7
- package/package.json +2 -1
- package/dist/__benchmarks__/vector2.bench.d.ts +0 -2
- package/dist/__benchmarks__/vector2.bench.d.ts.map +0 -1
- package/dist/__benchmarks__/vector2.bench.js +0 -74
- package/dist/audio/audio.d.ts.map +0 -1
- package/dist/audio/index.d.ts.map +0 -1
- package/dist/engine.d.ts.map +0 -1
- package/dist/events.d.ts.map +0 -1
- package/dist/graphics/canvas.d.ts.map +0 -1
- package/dist/graphics/graphics.d.ts.map +0 -1
- package/dist/graphics/image.d.ts.map +0 -1
- package/dist/graphics/index.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/input/gamepad-mapping.d.ts.map +0 -1
- package/dist/input/gamepad.d.ts.map +0 -1
- package/dist/input/index.d.ts.map +0 -1
- package/dist/input/input.d.ts.map +0 -1
- package/dist/input/keyboard.d.ts.map +0 -1
- package/dist/input/mouse.d.ts.map +0 -1
- package/dist/like.d.ts.map +0 -1
- package/dist/math/index.d.ts.map +0 -1
- package/dist/math/rect.d.ts.map +0 -1
- package/dist/math/vector2.d.ts.map +0 -1
- package/dist/prefab-scenes/index.d.ts.map +0 -1
- package/dist/prefab-scenes/mapGamepad.d.ts.map +0 -1
- package/dist/prefab-scenes/startScreen.d.ts.map +0 -1
- package/dist/scene.d.ts.map +0 -1
- package/dist/timer/index.d.ts.map +0 -1
- package/dist/timer/timer.d.ts.map +0 -1
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* - Y increases down
|
|
27
27
|
* - Angles in radians, 0 is right, positive is clockwise
|
|
28
28
|
*/
|
|
29
|
-
import {
|
|
29
|
+
import type { Vector2 } from "../math/vector2";
|
|
30
30
|
import type { Rectangle } from "../math/rect";
|
|
31
31
|
import { ImageHandle } from "./image";
|
|
32
32
|
export type DrawMode = "fill" | "line";
|
|
@@ -36,23 +36,25 @@ export type DrawMode = "fill" | "line";
|
|
|
36
36
|
* - CSS color strings also accepted: `"red"`, `"#ff0000"`, `"rgb(255,0,0)"`
|
|
37
37
|
*/
|
|
38
38
|
export type Color = [number, number, number, number?] | string;
|
|
39
|
+
export type TransformProps = {
|
|
40
|
+
angle?: number;
|
|
41
|
+
scale?: number | Vector2;
|
|
42
|
+
origin?: Vector2;
|
|
43
|
+
};
|
|
39
44
|
export type ShapeProps = {
|
|
40
45
|
lineWidth?: number;
|
|
41
46
|
lineCap?: CanvasLineCap;
|
|
42
47
|
lineJoin?: CanvasLineJoin;
|
|
43
48
|
miterLimit?: number;
|
|
44
|
-
};
|
|
49
|
+
} & TransformProps;
|
|
45
50
|
export type DrawProps = ShapeProps & {
|
|
46
51
|
quad?: Rectangle;
|
|
47
|
-
r?: number;
|
|
48
|
-
scale?: number | Vector2;
|
|
49
|
-
origin?: number | Vector2;
|
|
50
52
|
};
|
|
51
53
|
export type PrintProps = {
|
|
52
54
|
font?: string;
|
|
53
55
|
width?: number;
|
|
54
56
|
align?: CanvasTextAlign;
|
|
55
|
-
};
|
|
57
|
+
} & TransformProps;
|
|
56
58
|
/**
|
|
57
59
|
* LIKE's way of drawing to the screen.
|
|
58
60
|
*
|
|
@@ -71,18 +73,18 @@ export type PrintProps = {
|
|
|
71
73
|
* const pos = Vec2.div(like.canvas.getSize(), 2); // calc center of screen
|
|
72
74
|
* const speed = 0.5; // rotations per second
|
|
73
75
|
*
|
|
74
|
-
* like.gfx.
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
76
|
+
* like.gfx.withTransform(() => {
|
|
77
|
+
* like.gfx.translate(pos);
|
|
78
|
+
* like.gfx.rotate(like.timer.getTime() * Math.PI * 2.0 * speed);
|
|
79
|
+
* like.gfx.scale(size);
|
|
80
|
+
* like.gfx.circle("fill", color1, [0, 0], 2);
|
|
81
|
+
* // use the arc parameter to fill in a semicircle. Note that it's clockwise from {x:1, y:0}.
|
|
82
|
+
* like.gfx.circle("fill", color2, [0, 0], 2, { arc: [Math.PI/2, Math.PI*3/2] });
|
|
83
|
+
* like.gfx.circle("fill", color2, [0, -1], 1);
|
|
84
|
+
* like.gfx.circle("fill", color1, [0, 1], 1);
|
|
85
|
+
* like.gfx.circle("fill", color2, [0, 1], 1/3);
|
|
86
|
+
* like.gfx.circle("fill", color1, [0, -1], 1/3);
|
|
87
|
+
* })
|
|
86
88
|
* }
|
|
87
89
|
*
|
|
88
90
|
* like.draw = (like: Like) => {
|
|
@@ -93,12 +95,6 @@ export type PrintProps = {
|
|
|
93
95
|
export declare class Graphics {
|
|
94
96
|
private ctx;
|
|
95
97
|
constructor(ctx: CanvasRenderingContext2D);
|
|
96
|
-
/**
|
|
97
|
-
* Set the 2d drawing context for graphics.
|
|
98
|
-
*
|
|
99
|
-
* Be aware that that `like` can set this value at any time.
|
|
100
|
-
*/
|
|
101
|
-
setContext(ctx: CanvasRenderingContext2D): void;
|
|
102
98
|
/**
|
|
103
99
|
* Clears the canvas with a solid color.
|
|
104
100
|
* @param color Fill color.
|
|
@@ -121,7 +117,7 @@ export declare class Graphics {
|
|
|
121
117
|
* @param radii Radius (number) or [rx, ry] for ellipse.
|
|
122
118
|
* @param props Optional arc, center, and stroke properties. Center is true by default.
|
|
123
119
|
*/
|
|
124
|
-
circle(mode: DrawMode, color: Color, position: Vector2,
|
|
120
|
+
circle(mode: DrawMode, color: Color, position: Vector2, radius: number, props?: ShapeProps & {
|
|
125
121
|
arc?: [number, number];
|
|
126
122
|
center?: boolean;
|
|
127
123
|
}): void;
|
|
@@ -155,7 +151,6 @@ export declare class Graphics {
|
|
|
155
151
|
*
|
|
156
152
|
* @remarks named "draw" because it draws anything _drawable_
|
|
157
153
|
* in the long run.
|
|
158
|
-
*
|
|
159
154
|
|
|
160
155
|
* @param handle Image handle from newImage.
|
|
161
156
|
* @param position Draw position.
|
|
@@ -164,37 +159,32 @@ export declare class Graphics {
|
|
|
164
159
|
draw(handle: ImageHandle, position: Vector2, props?: DrawProps): void;
|
|
165
160
|
/**
|
|
166
161
|
* Loads an image from a path.
|
|
167
|
-
* Unlike
|
|
162
|
+
* Unlike fetch, this pretends to be synchronous.
|
|
168
163
|
|
|
169
164
|
* @param path Image file path.
|
|
170
165
|
* @returns ImageHandle for use with draw.
|
|
171
166
|
*/
|
|
172
167
|
newImage(path: string): ImageHandle;
|
|
173
|
-
/**
|
|
174
|
-
* Sets the clipping region.
|
|
175
|
-
|
|
176
|
-
* @param rect Clipping rectangle, or full canvas if omitted.
|
|
177
|
-
*/
|
|
178
|
-
clip(rect?: Rectangle): void;
|
|
179
168
|
/**
|
|
180
169
|
* Draws a polygon.
|
|
181
|
-
|
|
170
|
+
|
|
182
171
|
* @param mode Fill or line.
|
|
183
172
|
* @param color Fill or stroke color.
|
|
184
173
|
* @param points Array of [x, y] vertices.
|
|
185
|
-
* @param props Optional stroke properties.
|
|
174
|
+
* @param props Optional stroke and transform properties.
|
|
186
175
|
*/
|
|
187
|
-
polygon(mode: DrawMode, color: Color, points: Vector2[], props?: ShapeProps): void;
|
|
176
|
+
polygon(mode: DrawMode, color: Color, position: Vector2, points: Vector2[], props?: ShapeProps): void;
|
|
188
177
|
/**
|
|
189
178
|
* Draws individual pixels.
|
|
190
179
|
|
|
191
180
|
* @param color Fill color.
|
|
192
181
|
* @param pts Array of [x, y] positions.
|
|
193
182
|
*/
|
|
194
|
-
points(color: Color, pts: Vector2[]): void;
|
|
183
|
+
points(color: Color, pts: Vector2[], props?: TransformProps): void;
|
|
184
|
+
private applyTransform;
|
|
195
185
|
/**
|
|
196
186
|
* Saves canvas state.
|
|
197
|
-
|
|
187
|
+
|
|
198
188
|
*/
|
|
199
189
|
push(): void;
|
|
200
190
|
/**
|
|
@@ -220,5 +210,30 @@ export declare class Graphics {
|
|
|
220
210
|
* @param factor Scale factor (number or [x, y]).
|
|
221
211
|
*/
|
|
222
212
|
scale(factor: number | Vector2): void;
|
|
213
|
+
/**
|
|
214
|
+
* The idiomatic way to render to an external canvas.
|
|
215
|
+
*
|
|
216
|
+
* Within this scope, the target canvas has changed.
|
|
217
|
+
*
|
|
218
|
+
* Outside, it stays the same.
|
|
219
|
+
*
|
|
220
|
+
* @param canvas The canvas to draw to.
|
|
221
|
+
* @param callback Functions that will be called while drawing to the target.
|
|
222
|
+
*/
|
|
223
|
+
withRenderTarget(context: CanvasRenderingContext2D, callback: () => void): void;
|
|
224
|
+
/**
|
|
225
|
+
* _For Expressive Purposes_
|
|
226
|
+
*
|
|
227
|
+
* A simple wrapper around push/pop (save/restore)
|
|
228
|
+
* that clearly allows a set of statements to have their
|
|
229
|
+
* own transform matrix.
|
|
230
|
+
*
|
|
231
|
+
* In other words, any `scale`, `translate`, etc.
|
|
232
|
+
* performed in this block does not affect the
|
|
233
|
+
* outside world.
|
|
234
|
+
*
|
|
235
|
+
* @param callback the drawing logic.
|
|
236
|
+
*/
|
|
237
|
+
withTransform(callback: () => void): void;
|
|
223
238
|
}
|
|
224
239
|
//# sourceMappingURL=graphics.d.ts.map
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
* - Y increases down
|
|
27
27
|
* - Angles in radians, 0 is right, positive is clockwise
|
|
28
28
|
*/
|
|
29
|
-
import { Vec2 } from "../math/vector2";
|
|
30
29
|
import { ImageHandle } from "./image";
|
|
31
30
|
function parseColor(color) {
|
|
32
31
|
if (typeof color === "string")
|
|
@@ -82,18 +81,18 @@ function getFontHeight(ctx) {
|
|
|
82
81
|
* const pos = Vec2.div(like.canvas.getSize(), 2); // calc center of screen
|
|
83
82
|
* const speed = 0.5; // rotations per second
|
|
84
83
|
*
|
|
85
|
-
* like.gfx.
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
84
|
+
* like.gfx.withTransform(() => {
|
|
85
|
+
* like.gfx.translate(pos);
|
|
86
|
+
* like.gfx.rotate(like.timer.getTime() * Math.PI * 2.0 * speed);
|
|
87
|
+
* like.gfx.scale(size);
|
|
88
|
+
* like.gfx.circle("fill", color1, [0, 0], 2);
|
|
89
|
+
* // use the arc parameter to fill in a semicircle. Note that it's clockwise from {x:1, y:0}.
|
|
90
|
+
* like.gfx.circle("fill", color2, [0, 0], 2, { arc: [Math.PI/2, Math.PI*3/2] });
|
|
91
|
+
* like.gfx.circle("fill", color2, [0, -1], 1);
|
|
92
|
+
* like.gfx.circle("fill", color1, [0, 1], 1);
|
|
93
|
+
* like.gfx.circle("fill", color2, [0, 1], 1/3);
|
|
94
|
+
* like.gfx.circle("fill", color1, [0, -1], 1/3);
|
|
95
|
+
* })
|
|
97
96
|
* }
|
|
98
97
|
*
|
|
99
98
|
* like.draw = (like: Like) => {
|
|
@@ -110,14 +109,6 @@ export class Graphics {
|
|
|
110
109
|
value: ctx
|
|
111
110
|
});
|
|
112
111
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Set the 2d drawing context for graphics.
|
|
115
|
-
*
|
|
116
|
-
* Be aware that that `like` can set this value at any time.
|
|
117
|
-
*/
|
|
118
|
-
setContext(ctx) {
|
|
119
|
-
this.ctx = ctx;
|
|
120
|
-
}
|
|
121
112
|
/**
|
|
122
113
|
* Clears the canvas with a solid color.
|
|
123
114
|
* @param color Fill color.
|
|
@@ -135,15 +126,21 @@ export class Graphics {
|
|
|
135
126
|
*/
|
|
136
127
|
rectangle(mode, color, rect, props) {
|
|
137
128
|
const c = applyColor(color);
|
|
129
|
+
this.ctx.save();
|
|
130
|
+
const [x, y, w, h] = rect;
|
|
131
|
+
if (mode === "line") {
|
|
132
|
+
setStrokeProps(this.ctx, props);
|
|
133
|
+
}
|
|
134
|
+
this.applyTransform([x, y], props);
|
|
138
135
|
if (mode === "fill") {
|
|
139
136
|
this.ctx.fillStyle = c;
|
|
140
|
-
this.ctx.fillRect(
|
|
137
|
+
this.ctx.fillRect(0, 0, w, h);
|
|
141
138
|
}
|
|
142
139
|
else {
|
|
143
|
-
setStrokeProps(this.ctx, props);
|
|
144
140
|
this.ctx.strokeStyle = c;
|
|
145
|
-
this.ctx.strokeRect(
|
|
141
|
+
this.ctx.strokeRect(0, 0, w, h);
|
|
146
142
|
}
|
|
143
|
+
this.ctx.restore();
|
|
147
144
|
}
|
|
148
145
|
/**
|
|
149
146
|
* Draws a circle or ellipse.
|
|
@@ -154,23 +151,20 @@ export class Graphics {
|
|
|
154
151
|
* @param radii Radius (number) or [rx, ry] for ellipse.
|
|
155
152
|
* @param props Optional arc, center, and stroke properties. Center is true by default.
|
|
156
153
|
*/
|
|
157
|
-
circle(mode, color, position,
|
|
154
|
+
circle(mode, color, position, radius, props) {
|
|
158
155
|
const center = (props && 'center' in props) ? props.center : true;
|
|
159
156
|
const c = applyColor(color);
|
|
160
|
-
const size = typeof radii === "number" ? [radii, radii] : radii;
|
|
161
157
|
const [startAngle, endAngle] = props?.arc ?? [0, Math.PI * 2];
|
|
158
|
+
this.ctx.save();
|
|
159
|
+
this.applyTransform(position, props);
|
|
162
160
|
if (!center) {
|
|
163
|
-
|
|
161
|
+
this.ctx.translate(radius, radius);
|
|
164
162
|
}
|
|
165
|
-
this.ctx.save();
|
|
166
|
-
this.ctx.translate(...position);
|
|
167
|
-
this.ctx.scale(...size);
|
|
168
163
|
this.ctx.beginPath();
|
|
169
|
-
this.ctx.arc(0, 0,
|
|
164
|
+
this.ctx.arc(0, 0, radius, startAngle, endAngle);
|
|
170
165
|
if (mode == 'fill')
|
|
171
166
|
this.ctx.lineTo(0, 0);
|
|
172
167
|
this.ctx.closePath();
|
|
173
|
-
this.ctx.restore();
|
|
174
168
|
if (mode === "fill") {
|
|
175
169
|
this.ctx.fillStyle = c;
|
|
176
170
|
this.ctx.fill();
|
|
@@ -180,6 +174,7 @@ export class Graphics {
|
|
|
180
174
|
this.ctx.strokeStyle = c;
|
|
181
175
|
this.ctx.stroke();
|
|
182
176
|
}
|
|
177
|
+
this.ctx.restore();
|
|
183
178
|
}
|
|
184
179
|
/**
|
|
185
180
|
* Draws connected line segments.
|
|
@@ -216,10 +211,11 @@ export class Graphics {
|
|
|
216
211
|
* @param props {@link PrintProps} Optional font, text limit, or alignment.
|
|
217
212
|
*/
|
|
218
213
|
print(color, text, position, props) {
|
|
219
|
-
const [x, y] = position;
|
|
220
214
|
const { font = "16px sans-serif" } = props ?? {};
|
|
221
|
-
this.ctx.
|
|
215
|
+
this.ctx.save();
|
|
216
|
+
this.applyTransform(position, props);
|
|
222
217
|
this.ctx.font = font;
|
|
218
|
+
this.ctx.fillStyle = parseColor(color);
|
|
223
219
|
this.ctx.textAlign = props?.align ?? "left";
|
|
224
220
|
if (props && 'width' in props) {
|
|
225
221
|
const { width } = props;
|
|
@@ -227,20 +223,20 @@ export class Graphics {
|
|
|
227
223
|
const lineHeight = getFontHeight(this.ctx);
|
|
228
224
|
this.ctx.textBaseline = "top";
|
|
229
225
|
lines.forEach((line, i) => {
|
|
230
|
-
this.ctx.fillText(line,
|
|
226
|
+
this.ctx.fillText(line, 0, i * lineHeight, width);
|
|
231
227
|
});
|
|
232
228
|
this.ctx.textBaseline = "alphabetic";
|
|
233
229
|
}
|
|
234
230
|
else {
|
|
235
|
-
this.ctx.fillText(text,
|
|
231
|
+
this.ctx.fillText(text, 0, 0);
|
|
236
232
|
}
|
|
233
|
+
this.ctx.restore();
|
|
237
234
|
}
|
|
238
235
|
/**
|
|
239
236
|
* Draws an image.
|
|
240
237
|
*
|
|
241
238
|
* @remarks named "draw" because it draws anything _drawable_
|
|
242
239
|
* in the long run.
|
|
243
|
-
*
|
|
244
240
|
|
|
245
241
|
* @param handle Image handle from newImage.
|
|
246
242
|
* @param position Draw position.
|
|
@@ -252,26 +248,21 @@ export class Graphics {
|
|
|
252
248
|
const element = handle.getElement();
|
|
253
249
|
if (!element)
|
|
254
250
|
return;
|
|
255
|
-
const
|
|
256
|
-
const { r = 0, scale = 1, origin = 0, quad } = props ?? {};
|
|
257
|
-
const [sx, sy] = typeof scale === "number" ? [scale, scale] : scale;
|
|
258
|
-
const [ox, oy] = typeof origin === "number" ? [origin, origin] : origin;
|
|
251
|
+
const { quad } = props ?? {};
|
|
259
252
|
this.ctx.save();
|
|
260
|
-
this.
|
|
261
|
-
this.ctx.rotate(r);
|
|
262
|
-
this.ctx.scale(sx, sy);
|
|
253
|
+
this.applyTransform(position, props);
|
|
263
254
|
if (quad) {
|
|
264
|
-
const [
|
|
265
|
-
this.ctx.drawImage(element,
|
|
255
|
+
const [, , qw, qh] = quad;
|
|
256
|
+
this.ctx.drawImage(element, ...quad, 0, 0, qw, qh);
|
|
266
257
|
}
|
|
267
258
|
else {
|
|
268
|
-
this.ctx.drawImage(element,
|
|
259
|
+
this.ctx.drawImage(element, 0, 0);
|
|
269
260
|
}
|
|
270
261
|
this.ctx.restore();
|
|
271
262
|
}
|
|
272
263
|
/**
|
|
273
264
|
* Loads an image from a path.
|
|
274
|
-
* Unlike
|
|
265
|
+
* Unlike fetch, this pretends to be synchronous.
|
|
275
266
|
|
|
276
267
|
* @param path Image file path.
|
|
277
268
|
* @returns ImageHandle for use with draw.
|
|
@@ -279,34 +270,23 @@ export class Graphics {
|
|
|
279
270
|
newImage(path) {
|
|
280
271
|
return new ImageHandle(path);
|
|
281
272
|
}
|
|
282
|
-
/**
|
|
283
|
-
* Sets the clipping region.
|
|
284
|
-
|
|
285
|
-
* @param rect Clipping rectangle, or full canvas if omitted.
|
|
286
|
-
*/
|
|
287
|
-
clip(rect) {
|
|
288
|
-
this.ctx.beginPath();
|
|
289
|
-
if (rect) {
|
|
290
|
-
const [x, y, w, h] = rect;
|
|
291
|
-
this.ctx.rect(x, y, w, h);
|
|
292
|
-
}
|
|
293
|
-
else {
|
|
294
|
-
this.ctx.rect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
|
|
295
|
-
}
|
|
296
|
-
this.ctx.clip();
|
|
297
|
-
}
|
|
298
273
|
/**
|
|
299
274
|
* Draws a polygon.
|
|
300
|
-
|
|
275
|
+
|
|
301
276
|
* @param mode Fill or line.
|
|
302
277
|
* @param color Fill or stroke color.
|
|
303
278
|
* @param points Array of [x, y] vertices.
|
|
304
|
-
* @param props Optional stroke properties.
|
|
279
|
+
* @param props Optional stroke and transform properties.
|
|
305
280
|
*/
|
|
306
|
-
polygon(mode, color, points, props) {
|
|
281
|
+
polygon(mode, color, position, points, props) {
|
|
307
282
|
if (points.length < 3)
|
|
308
283
|
return;
|
|
309
284
|
const c = applyColor(color);
|
|
285
|
+
this.ctx.save();
|
|
286
|
+
if (mode === "line") {
|
|
287
|
+
setStrokeProps(this.ctx, props);
|
|
288
|
+
}
|
|
289
|
+
this.applyTransform(position, props);
|
|
310
290
|
this.ctx.beginPath();
|
|
311
291
|
const [[x0, y0], ...rest] = points;
|
|
312
292
|
this.ctx.moveTo(x0, y0);
|
|
@@ -317,10 +297,10 @@ export class Graphics {
|
|
|
317
297
|
this.ctx.fill();
|
|
318
298
|
}
|
|
319
299
|
else {
|
|
320
|
-
setStrokeProps(this.ctx, props);
|
|
321
300
|
this.ctx.strokeStyle = c;
|
|
322
301
|
this.ctx.stroke();
|
|
323
302
|
}
|
|
303
|
+
this.ctx.restore();
|
|
324
304
|
}
|
|
325
305
|
/**
|
|
326
306
|
* Draws individual pixels.
|
|
@@ -328,13 +308,27 @@ export class Graphics {
|
|
|
328
308
|
* @param color Fill color.
|
|
329
309
|
* @param pts Array of [x, y] positions.
|
|
330
310
|
*/
|
|
331
|
-
points(color, pts) {
|
|
311
|
+
points(color, pts, props) {
|
|
312
|
+
this.ctx.save();
|
|
313
|
+
this.applyTransform([0, 0], props);
|
|
332
314
|
this.ctx.fillStyle = applyColor(color);
|
|
333
315
|
pts.forEach(([x, y]) => this.ctx.fillRect(x, y, 1, 1));
|
|
316
|
+
this.ctx.restore();
|
|
317
|
+
}
|
|
318
|
+
applyTransform(position, props) {
|
|
319
|
+
const { angle = 0, scale = 1, origin = [0, 0] } = props ?? {};
|
|
320
|
+
this.ctx.translate(...position);
|
|
321
|
+
if (angle !== 0)
|
|
322
|
+
this.ctx.rotate(angle);
|
|
323
|
+
if (scale !== 1) {
|
|
324
|
+
const [sx, sy] = typeof scale === "number" ? [scale, scale] : scale;
|
|
325
|
+
this.ctx.scale(sx, sy);
|
|
326
|
+
}
|
|
327
|
+
this.ctx.translate(-origin[0], -origin[1]);
|
|
334
328
|
}
|
|
335
329
|
/**
|
|
336
330
|
* Saves canvas state.
|
|
337
|
-
|
|
331
|
+
|
|
338
332
|
*/
|
|
339
333
|
push() {
|
|
340
334
|
this.ctx.save();
|
|
@@ -372,5 +366,39 @@ export class Graphics {
|
|
|
372
366
|
const [sx, sy] = typeof factor === "number" ? [factor, factor] : factor;
|
|
373
367
|
this.ctx.scale(sx, sy);
|
|
374
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* The idiomatic way to render to an external canvas.
|
|
371
|
+
*
|
|
372
|
+
* Within this scope, the target canvas has changed.
|
|
373
|
+
*
|
|
374
|
+
* Outside, it stays the same.
|
|
375
|
+
*
|
|
376
|
+
* @param canvas The canvas to draw to.
|
|
377
|
+
* @param callback Functions that will be called while drawing to the target.
|
|
378
|
+
*/
|
|
379
|
+
withRenderTarget(context, callback) {
|
|
380
|
+
const oldCtx = this.ctx;
|
|
381
|
+
this.ctx = context;
|
|
382
|
+
callback();
|
|
383
|
+
this.ctx = oldCtx;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* _For Expressive Purposes_
|
|
387
|
+
*
|
|
388
|
+
* A simple wrapper around push/pop (save/restore)
|
|
389
|
+
* that clearly allows a set of statements to have their
|
|
390
|
+
* own transform matrix.
|
|
391
|
+
*
|
|
392
|
+
* In other words, any `scale`, `translate`, etc.
|
|
393
|
+
* performed in this block does not affect the
|
|
394
|
+
* outside world.
|
|
395
|
+
*
|
|
396
|
+
* @param callback the drawing logic.
|
|
397
|
+
*/
|
|
398
|
+
withTransform(callback) {
|
|
399
|
+
this.ctx.save();
|
|
400
|
+
callback();
|
|
401
|
+
this.ctx.restore();
|
|
402
|
+
}
|
|
375
403
|
}
|
|
376
404
|
;
|