@al8b/screen 0.1.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.
Files changed (68) hide show
  1. package/README.md +23 -0
  2. package/dist/core/base-screen.d.mts +84 -0
  3. package/dist/core/base-screen.d.ts +84 -0
  4. package/dist/core/base-screen.js +419 -0
  5. package/dist/core/base-screen.js.map +1 -0
  6. package/dist/core/base-screen.mjs +396 -0
  7. package/dist/core/base-screen.mjs.map +1 -0
  8. package/dist/core/index.d.mts +10 -0
  9. package/dist/core/index.d.ts +10 -0
  10. package/dist/core/index.js +1208 -0
  11. package/dist/core/index.js.map +1 -0
  12. package/dist/core/index.mjs +1183 -0
  13. package/dist/core/index.mjs.map +1 -0
  14. package/dist/core/screen.d.mts +15 -0
  15. package/dist/core/screen.d.ts +15 -0
  16. package/dist/core/screen.js +1209 -0
  17. package/dist/core/screen.js.map +1 -0
  18. package/dist/core/screen.mjs +1184 -0
  19. package/dist/core/screen.mjs.map +1 -0
  20. package/dist/drawing/primitives-screen.d.mts +28 -0
  21. package/dist/drawing/primitives-screen.d.ts +28 -0
  22. package/dist/drawing/primitives-screen.js +685 -0
  23. package/dist/drawing/primitives-screen.js.map +1 -0
  24. package/dist/drawing/primitives-screen.mjs +662 -0
  25. package/dist/drawing/primitives-screen.mjs.map +1 -0
  26. package/dist/drawing/sprite-screen.d.mts +41 -0
  27. package/dist/drawing/sprite-screen.d.ts +41 -0
  28. package/dist/drawing/sprite-screen.js +853 -0
  29. package/dist/drawing/sprite-screen.js.map +1 -0
  30. package/dist/drawing/sprite-screen.mjs +830 -0
  31. package/dist/drawing/sprite-screen.mjs.map +1 -0
  32. package/dist/drawing/text-screen.d.mts +19 -0
  33. package/dist/drawing/text-screen.d.ts +19 -0
  34. package/dist/drawing/text-screen.js +909 -0
  35. package/dist/drawing/text-screen.js.map +1 -0
  36. package/dist/drawing/text-screen.mjs +884 -0
  37. package/dist/drawing/text-screen.mjs.map +1 -0
  38. package/dist/index.d.mts +10 -0
  39. package/dist/index.d.ts +10 -0
  40. package/dist/index.js +1210 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/index.mjs +1184 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/tri/index.d.mts +3 -0
  45. package/dist/tri/index.d.ts +3 -0
  46. package/dist/tri/index.js +231 -0
  47. package/dist/tri/index.js.map +1 -0
  48. package/dist/tri/index.mjs +203 -0
  49. package/dist/tri/index.mjs.map +1 -0
  50. package/dist/tri/triangle-screen.d.mts +16 -0
  51. package/dist/tri/triangle-screen.d.ts +16 -0
  52. package/dist/tri/triangle-screen.js +1147 -0
  53. package/dist/tri/triangle-screen.js.map +1 -0
  54. package/dist/tri/triangle-screen.mjs +1122 -0
  55. package/dist/tri/triangle-screen.mjs.map +1 -0
  56. package/dist/tri/ttri.d.mts +71 -0
  57. package/dist/tri/ttri.d.ts +71 -0
  58. package/dist/tri/ttri.js +229 -0
  59. package/dist/tri/ttri.js.map +1 -0
  60. package/dist/tri/ttri.mjs +203 -0
  61. package/dist/tri/ttri.mjs.map +1 -0
  62. package/dist/types/index.d.mts +64 -0
  63. package/dist/types/index.d.ts +64 -0
  64. package/dist/types/index.js +19 -0
  65. package/dist/types/index.js.map +1 -0
  66. package/dist/types/index.mjs +1 -0
  67. package/dist/types/index.mjs.map +1 -0
  68. package/package.json +37 -0
@@ -0,0 +1,662 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/drawing/primitives-screen.ts
5
+ import { APIErrorCode as APIErrorCode2, reportRuntimeError as reportRuntimeError2 } from "@al8b/diagnostics";
6
+
7
+ // src/core/base-screen.ts
8
+ import { APIErrorCode, createDiagnostic, formatForBrowser, reportRuntimeError } from "@al8b/diagnostics";
9
+
10
+ // src/tri/ttri.ts
11
+ var ZBuffer = class {
12
+ static {
13
+ __name(this, "ZBuffer");
14
+ }
15
+ buffer;
16
+ width;
17
+ height;
18
+ constructor(width, height) {
19
+ this.width = width;
20
+ this.height = height;
21
+ this.buffer = new Float32Array(width * height);
22
+ }
23
+ clear() {
24
+ this.buffer.fill(0);
25
+ }
26
+ get(x, y) {
27
+ return this.buffer[y * this.width + x] || 0;
28
+ }
29
+ set(x, y, z) {
30
+ this.buffer[y * this.width + x] = z;
31
+ }
32
+ resize(width, height) {
33
+ if (this.width !== width || this.height !== height) {
34
+ this.width = width;
35
+ this.height = height;
36
+ this.buffer = new Float32Array(width * height);
37
+ }
38
+ }
39
+ };
40
+
41
+ // src/core/base-screen.ts
42
+ var BaseScreen = class {
43
+ static {
44
+ __name(this, "BaseScreen");
45
+ }
46
+ canvas;
47
+ context;
48
+ runtime;
49
+ width;
50
+ height;
51
+ // Drawing state
52
+ alpha = 1;
53
+ pixelated = 1;
54
+ line_width = 1;
55
+ font = "BitCell";
56
+ // Transformations
57
+ translation_x = 0;
58
+ translation_y = 0;
59
+ rotation = 0;
60
+ scale_x = 1;
61
+ scale_y = 1;
62
+ screen_transform = false;
63
+ // Object transformations
64
+ object_rotation = 0;
65
+ object_scale_x = 1;
66
+ object_scale_y = 1;
67
+ anchor_x = 0;
68
+ anchor_y = 0;
69
+ // Blending + font caches
70
+ blending = {};
71
+ font_load_requested = {};
72
+ font_loaded = {};
73
+ // Interface cache
74
+ interfaceCache = null;
75
+ // Cursor management
76
+ cursor = "default";
77
+ cursor_visibility = "auto";
78
+ last_mouse_move = Date.now();
79
+ // 3D helper
80
+ zBuffer;
81
+ constructor(options = {}) {
82
+ this.runtime = options.runtime;
83
+ if (options.canvas) {
84
+ this.canvas = options.canvas;
85
+ if (this.canvas.width === 0 || this.canvas.height === 0) {
86
+ this.canvas.width = options.width || 1080;
87
+ this.canvas.height = options.height || 1920;
88
+ }
89
+ } else {
90
+ this.canvas = document.createElement("canvas");
91
+ this.canvas.width = options.width || 1080;
92
+ this.canvas.height = options.height || 1920;
93
+ }
94
+ this.initContext();
95
+ this.blending = {
96
+ normal: "source-over",
97
+ additive: "lighter"
98
+ };
99
+ const blendModes = [
100
+ "source-over",
101
+ "source-in",
102
+ "source-out",
103
+ "source-atop",
104
+ "destination-over",
105
+ "destination-in",
106
+ "destination-out",
107
+ "destination-atop",
108
+ "lighter",
109
+ "copy",
110
+ "xor",
111
+ "multiply",
112
+ "screen",
113
+ "overlay",
114
+ "darken",
115
+ "lighten",
116
+ "color-dodge",
117
+ "color-burn",
118
+ "hard-light",
119
+ "soft-light",
120
+ "difference",
121
+ "exclusion",
122
+ "hue",
123
+ "saturation",
124
+ "color",
125
+ "luminosity"
126
+ ];
127
+ for (const mode of blendModes) {
128
+ this.blending[mode] = mode;
129
+ }
130
+ this.loadFont(this.font);
131
+ this.zBuffer = new ZBuffer(this.canvas.width, this.canvas.height);
132
+ this.cursor = "default";
133
+ this.canvas.addEventListener("mousemove", () => {
134
+ this.last_mouse_move = Date.now();
135
+ if (this.cursor !== "default" && this.cursor_visibility === "auto") {
136
+ this.cursor = "default";
137
+ this.canvas.style.cursor = "default";
138
+ }
139
+ });
140
+ this.canvas.addEventListener("contextrestored", () => {
141
+ this.initContext();
142
+ });
143
+ setInterval(() => this.checkMouseCursor(), 1e3);
144
+ this.cursor_visibility = "auto";
145
+ }
146
+ initContext() {
147
+ const ctx = this.canvas.getContext("2d", {
148
+ alpha: false
149
+ });
150
+ if (!ctx) {
151
+ const diagnostic = createDiagnostic(APIErrorCode.E7001);
152
+ const formatted = formatForBrowser(diagnostic);
153
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7001, {});
154
+ throw new Error(formatted);
155
+ }
156
+ if (ctx !== this.context) {
157
+ this.context = ctx;
158
+ } else {
159
+ this.context.restore();
160
+ }
161
+ this.context.save();
162
+ this.context.translate(this.canvas.width / 2, this.canvas.height / 2);
163
+ const ratio = Math.min(this.canvas.width / 200, this.canvas.height / 200);
164
+ this.context.scale(ratio, ratio);
165
+ this.width = this.canvas.width / ratio;
166
+ this.height = this.canvas.height / ratio;
167
+ this.context.lineCap = "round";
168
+ }
169
+ /**
170
+ * Initialize draw state (called before each draw frame)
171
+ */
172
+ initDraw() {
173
+ this.alpha = 1;
174
+ this.line_width = 1;
175
+ }
176
+ /**
177
+ * Update interface dimensions (called before each draw frame)
178
+ */
179
+ updateInterface() {
180
+ if (this.interfaceCache) {
181
+ this.interfaceCache.width = this.width;
182
+ this.interfaceCache.height = this.height;
183
+ }
184
+ }
185
+ clear(color) {
186
+ this.context.globalAlpha = 1;
187
+ this.context.globalCompositeOperation = "source-over";
188
+ this.context.fillStyle = color || "#000";
189
+ this.context.strokeStyle = color || "#000";
190
+ this.context.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);
191
+ this.zBuffer.clear();
192
+ }
193
+ setColor(color) {
194
+ if (!color) return;
195
+ if (!Number.isNaN(Number.parseInt(String(color)))) {
196
+ const num = Number.parseInt(String(color));
197
+ const r = Math.floor(num / 100) % 10 / 9 * 255;
198
+ const g = Math.floor(num / 10) % 10 / 9 * 255;
199
+ const b = num % 10 / 9 * 255;
200
+ const c = 4278190080 + (r << 16) + (g << 8) + b;
201
+ const hex = "#" + c.toString(16).substring(2, 8);
202
+ this.context.fillStyle = hex;
203
+ this.context.strokeStyle = hex;
204
+ } else if (typeof color === "string") {
205
+ const isValidColor = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(color) || /^rgb\(|^rgba\(|^hsl\(|^hsla\(/.test(color) || /^(red|green|blue|yellow|cyan|magenta|black|white|gray|grey|orange|pink|purple|brown|transparent)$/i.test(color);
206
+ if (!isValidColor) {
207
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7003, {
208
+ color
209
+ });
210
+ return;
211
+ }
212
+ this.context.fillStyle = color;
213
+ this.context.strokeStyle = color;
214
+ }
215
+ }
216
+ setAlpha(alpha) {
217
+ this.alpha = alpha;
218
+ }
219
+ setPixelated(pixelated) {
220
+ this.pixelated = pixelated;
221
+ }
222
+ setBlending(blending) {
223
+ const blend = this.blending[blending || "normal"];
224
+ if (!blend) {
225
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7007, {
226
+ blendMode: blending
227
+ });
228
+ this.context.globalCompositeOperation = "source-over";
229
+ return;
230
+ }
231
+ this.context.globalCompositeOperation = blend;
232
+ }
233
+ setLineWidth(width) {
234
+ this.line_width = width;
235
+ }
236
+ setLineDash(dash) {
237
+ if (!Array.isArray(dash)) {
238
+ this.context.setLineDash([]);
239
+ } else {
240
+ this.context.setLineDash(dash);
241
+ }
242
+ }
243
+ setLinearGradient(x1, y1, x2, y2, c1, c2) {
244
+ const grd = this.context.createLinearGradient(x1, -y1, x2, -y2);
245
+ grd.addColorStop(0, c1);
246
+ grd.addColorStop(1, c2);
247
+ this.context.fillStyle = grd;
248
+ this.context.strokeStyle = grd;
249
+ }
250
+ setRadialGradient(x, y, radius, c1, c2) {
251
+ const grd = this.context.createRadialGradient(x, -y, 0, x, -y, radius);
252
+ grd.addColorStop(0, c1);
253
+ grd.addColorStop(1, c2);
254
+ this.context.fillStyle = grd;
255
+ this.context.strokeStyle = grd;
256
+ }
257
+ setFont(font) {
258
+ this.font = font || "Verdana";
259
+ this.loadFont(this.font);
260
+ }
261
+ loadFont(font = "BitCell") {
262
+ if (this.font_load_requested[font]) {
263
+ return;
264
+ }
265
+ this.font_load_requested[font] = true;
266
+ try {
267
+ document.fonts?.load?.(`16pt ${font}`).catch(() => {
268
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7006, {
269
+ font
270
+ });
271
+ });
272
+ } catch {
273
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7006, {
274
+ font
275
+ });
276
+ }
277
+ }
278
+ isFontReady(font = this.font) {
279
+ if (this.font_loaded[font]) {
280
+ return 1;
281
+ }
282
+ try {
283
+ const ready = document.fonts?.check?.(`16pt ${font}`) ?? true;
284
+ if (ready) {
285
+ this.font_loaded[font] = true;
286
+ }
287
+ return ready ? 1 : 0;
288
+ } catch {
289
+ return 1;
290
+ }
291
+ }
292
+ setTranslation(tx, ty) {
293
+ this.translation_x = isFinite(tx) ? tx : 0;
294
+ this.translation_y = isFinite(ty) ? ty : 0;
295
+ this.updateScreenTransform();
296
+ }
297
+ setScale(x, y) {
298
+ this.scale_x = isFinite(x) && x !== 0 ? x : 1;
299
+ this.scale_y = isFinite(y) && y !== 0 ? y : 1;
300
+ this.updateScreenTransform();
301
+ }
302
+ setRotation(rotation) {
303
+ this.rotation = isFinite(rotation) ? rotation : 0;
304
+ this.updateScreenTransform();
305
+ }
306
+ updateScreenTransform() {
307
+ this.screen_transform = this.translation_x !== 0 || this.translation_y !== 0 || this.scale_x !== 1 || this.scale_y !== 1 || this.rotation !== 0;
308
+ }
309
+ setDrawAnchor(ax, ay) {
310
+ this.anchor_x = typeof ax === "number" ? ax : 0;
311
+ this.anchor_y = typeof ay === "number" ? ay : 0;
312
+ }
313
+ setDrawRotation(rotation) {
314
+ this.object_rotation = rotation;
315
+ }
316
+ setDrawScale(x, y = x) {
317
+ this.object_scale_x = x;
318
+ this.object_scale_y = y;
319
+ }
320
+ initDrawOp(x, y, object_transform = true) {
321
+ let res = false;
322
+ if (this.screen_transform) {
323
+ this.context.save();
324
+ res = true;
325
+ this.context.translate(this.translation_x, -this.translation_y);
326
+ this.context.scale(this.scale_x, this.scale_y);
327
+ this.context.rotate(-this.rotation / 180 * Math.PI);
328
+ this.context.translate(x, y);
329
+ }
330
+ if (object_transform && (this.object_rotation !== 0 || this.object_scale_x !== 1 || this.object_scale_y !== 1)) {
331
+ if (!res) {
332
+ this.context.save();
333
+ res = true;
334
+ this.context.translate(x, y);
335
+ }
336
+ if (this.object_rotation !== 0) {
337
+ this.context.rotate(-this.object_rotation / 180 * Math.PI);
338
+ }
339
+ if (this.object_scale_x !== 1 || this.object_scale_y !== 1) {
340
+ this.context.scale(this.object_scale_x, this.object_scale_y);
341
+ }
342
+ }
343
+ return res;
344
+ }
345
+ closeDrawOp() {
346
+ this.context.restore();
347
+ }
348
+ /**
349
+ * Check mouse cursor visibility
350
+ * Auto-hides cursor after 4 seconds of inactivity
351
+ */
352
+ checkMouseCursor() {
353
+ if (Date.now() > this.last_mouse_move + 4e3 && this.cursor_visibility === "auto") {
354
+ if (this.cursor !== "none") {
355
+ this.cursor = "none";
356
+ this.canvas.style.cursor = "none";
357
+ }
358
+ }
359
+ }
360
+ /**
361
+ * Set cursor visibility
362
+ */
363
+ setCursorVisible(visible) {
364
+ this.cursor_visibility = visible ? "default" : "none";
365
+ if (visible) {
366
+ this.cursor = "default";
367
+ this.canvas.style.cursor = "default";
368
+ } else {
369
+ this.cursor = "none";
370
+ this.canvas.style.cursor = "none";
371
+ }
372
+ }
373
+ getCanvas() {
374
+ return this.canvas;
375
+ }
376
+ getContext() {
377
+ return this.context;
378
+ }
379
+ resize(width, height) {
380
+ if (width && height) {
381
+ if (width <= 0 || height <= 0 || !isFinite(width) || !isFinite(height)) {
382
+ reportRuntimeError(this.runtime?.listener, APIErrorCode.E7002, {
383
+ width,
384
+ height
385
+ });
386
+ return;
387
+ }
388
+ this.canvas.width = width;
389
+ this.canvas.height = height;
390
+ this.initContext();
391
+ this.zBuffer.resize(width, height);
392
+ this.updateInterface();
393
+ }
394
+ }
395
+ };
396
+
397
+ // src/drawing/primitives-screen.ts
398
+ var PrimitiveScreen = class extends BaseScreen {
399
+ static {
400
+ __name(this, "PrimitiveScreen");
401
+ }
402
+ fillRect(x, y, w, h, color) {
403
+ if (!this.context) {
404
+ reportRuntimeError2(this.runtime?.listener, APIErrorCode2.E7092, {});
405
+ return;
406
+ }
407
+ if (!isFinite(x) || !isFinite(y) || !isFinite(w) || !isFinite(h) || w <= 0 || h <= 0) {
408
+ reportRuntimeError2(this.runtime?.listener, APIErrorCode2.E7093, {
409
+ error: `Invalid parameters: x=${x}, y=${y}, w=${w}, h=${h}`
410
+ });
411
+ return;
412
+ }
413
+ if (color) this.setColor(color);
414
+ this.context.globalAlpha = this.alpha;
415
+ if (this.initDrawOp(x, -y)) {
416
+ this.context.fillRect(-w / 2 - this.anchor_x * w / 2, -h / 2 + this.anchor_y * h / 2, w, h);
417
+ this.closeDrawOp();
418
+ } else {
419
+ this.context.fillRect(x - w / 2 - this.anchor_x * w / 2, -y - h / 2 + this.anchor_y * h / 2, w, h);
420
+ }
421
+ }
422
+ fillRoundRect(x, y, w, h, round = 10, color) {
423
+ if (color) this.setColor(color);
424
+ this.context.globalAlpha = this.alpha;
425
+ const transform = this.initDrawOp(x, -y);
426
+ const rx = (transform ? -w / 2 : x - w / 2) - this.anchor_x * w / 2;
427
+ const ry = (transform ? -h / 2 : -y - h / 2) + this.anchor_y * h / 2;
428
+ this.context.beginPath();
429
+ if (this.context.roundRect) {
430
+ this.context.roundRect(rx, ry, w, h, round);
431
+ } else {
432
+ const r = Math.min(round, w / 2, h / 2);
433
+ this.context.moveTo(rx + r, ry);
434
+ this.context.lineTo(rx + w - r, ry);
435
+ this.context.quadraticCurveTo(rx + w, ry, rx + w, ry + r);
436
+ this.context.lineTo(rx + w, ry + h - r);
437
+ this.context.quadraticCurveTo(rx + w, ry + h, rx + w - r, ry + h);
438
+ this.context.lineTo(rx + r, ry + h);
439
+ this.context.quadraticCurveTo(rx, ry + h, rx, ry + h - r);
440
+ this.context.lineTo(rx, ry + r);
441
+ this.context.quadraticCurveTo(rx, ry, rx + r, ry);
442
+ this.context.closePath();
443
+ }
444
+ this.context.fill();
445
+ if (transform) this.closeDrawOp();
446
+ }
447
+ fillRound(x, y, w, h, color) {
448
+ if (color) this.setColor(color);
449
+ this.context.globalAlpha = this.alpha;
450
+ w = Math.abs(w);
451
+ h = Math.abs(h);
452
+ if (this.initDrawOp(x, -y)) {
453
+ this.context.beginPath();
454
+ this.context.ellipse(-this.anchor_x * w / 2, this.anchor_y * h / 2, w / 2, h / 2, 0, 0, Math.PI * 2, false);
455
+ this.context.fill();
456
+ this.closeDrawOp();
457
+ } else {
458
+ this.context.beginPath();
459
+ this.context.ellipse(x - this.anchor_x * w / 2, -y + this.anchor_y * h / 2, w / 2, h / 2, 0, 0, Math.PI * 2, false);
460
+ this.context.fill();
461
+ }
462
+ }
463
+ drawRect(x, y, w, h, color) {
464
+ if (color) this.setColor(color);
465
+ this.context.globalAlpha = this.alpha;
466
+ this.context.lineWidth = this.line_width;
467
+ if (this.initDrawOp(x, -y)) {
468
+ this.context.strokeRect(-w / 2 - this.anchor_x * w / 2, -h / 2 + this.anchor_y * h / 2, w, h);
469
+ this.closeDrawOp();
470
+ } else {
471
+ this.context.strokeRect(x - w / 2 - this.anchor_x * w / 2, -y - h / 2 + this.anchor_y * h / 2, w, h);
472
+ }
473
+ }
474
+ drawRoundRect(x, y, w, h, round = 10, color) {
475
+ if (color) this.setColor(color);
476
+ this.context.globalAlpha = this.alpha;
477
+ this.context.lineWidth = this.line_width;
478
+ const transform = this.initDrawOp(x, -y);
479
+ const rx = (transform ? -w / 2 : x - w / 2) - this.anchor_x * w / 2;
480
+ const ry = (transform ? -h / 2 : -y - h / 2) + this.anchor_y * h / 2;
481
+ this.context.beginPath();
482
+ if (this.context.roundRect) {
483
+ this.context.roundRect(rx, ry, w, h, round);
484
+ } else {
485
+ const r = Math.min(round, w / 2, h / 2);
486
+ this.context.moveTo(rx + r, ry);
487
+ this.context.lineTo(rx + w - r, ry);
488
+ this.context.quadraticCurveTo(rx + w, ry, rx + w, ry + r);
489
+ this.context.lineTo(rx + w, ry + h - r);
490
+ this.context.quadraticCurveTo(rx + w, ry + h, rx + w - r, ry + h);
491
+ this.context.lineTo(rx + r, ry + h);
492
+ this.context.quadraticCurveTo(rx, ry + h, rx, ry + h - r);
493
+ this.context.lineTo(rx, ry + r);
494
+ this.context.quadraticCurveTo(rx, ry, rx + r, ry);
495
+ this.context.closePath();
496
+ }
497
+ this.context.stroke();
498
+ if (transform) this.closeDrawOp();
499
+ }
500
+ drawRound(x, y, w, h, color) {
501
+ if (color) this.setColor(color);
502
+ this.context.globalAlpha = this.alpha;
503
+ this.context.lineWidth = this.line_width;
504
+ w = Math.abs(w);
505
+ h = Math.abs(h);
506
+ if (this.initDrawOp(x, -y)) {
507
+ this.context.beginPath();
508
+ this.context.ellipse(-this.anchor_x * w / 2, this.anchor_y * h / 2, w / 2, h / 2, 0, 0, Math.PI * 2, false);
509
+ this.context.stroke();
510
+ this.closeDrawOp();
511
+ } else {
512
+ this.context.beginPath();
513
+ this.context.ellipse(x - this.anchor_x * w / 2, -y + this.anchor_y * h / 2, w / 2, h / 2, 0, 0, Math.PI * 2, false);
514
+ this.context.stroke();
515
+ }
516
+ }
517
+ drawLine(x1, y1, x2, y2, color) {
518
+ if (color) this.setColor(color);
519
+ this.context.globalAlpha = this.alpha;
520
+ this.context.lineWidth = this.line_width;
521
+ const transform = this.initDrawOp(0, 0, false);
522
+ this.context.beginPath();
523
+ this.context.moveTo(x1, -y1);
524
+ this.context.lineTo(x2, -y2);
525
+ this.context.stroke();
526
+ if (transform) this.closeDrawOp();
527
+ }
528
+ drawPolygon(args) {
529
+ const { color, points } = this.extractPoints(args);
530
+ if (!points || points.length < 4) return;
531
+ if (color) this.setColor(color);
532
+ this.context.globalAlpha = this.alpha;
533
+ this.context.lineWidth = this.line_width;
534
+ const len = Math.floor(points.length / 2);
535
+ const transform = this.initDrawOp(0, 0, false);
536
+ this.context.beginPath();
537
+ this.context.moveTo(points[0], -points[1]);
538
+ for (let i = 1; i < len; i++) {
539
+ this.context.lineTo(points[i * 2], -points[i * 2 + 1]);
540
+ }
541
+ this.context.closePath();
542
+ this.context.stroke();
543
+ if (transform) this.closeDrawOp();
544
+ }
545
+ drawPolyline(args) {
546
+ const { color, points } = this.extractPoints(args);
547
+ if (!points || points.length < 4) return;
548
+ if (color) this.setColor(color);
549
+ this.context.globalAlpha = this.alpha;
550
+ this.context.lineWidth = this.line_width;
551
+ const len = Math.floor(points.length / 2);
552
+ const transform = this.initDrawOp(0, 0, false);
553
+ this.context.beginPath();
554
+ this.context.moveTo(points[0], -points[1]);
555
+ for (let i = 1; i < len; i++) {
556
+ this.context.lineTo(points[i * 2], -points[i * 2 + 1]);
557
+ }
558
+ this.context.stroke();
559
+ if (transform) this.closeDrawOp();
560
+ }
561
+ fillPolygon(args) {
562
+ const { color, points } = this.extractPoints(args);
563
+ if (!points || points.length < 4) return;
564
+ if (color) this.setColor(color);
565
+ this.context.globalAlpha = this.alpha;
566
+ const len = Math.floor(points.length / 2);
567
+ const transform = this.initDrawOp(0, 0, false);
568
+ this.context.beginPath();
569
+ this.context.moveTo(points[0], -points[1]);
570
+ for (let i = 1; i < len; i++) {
571
+ this.context.lineTo(points[i * 2], -points[i * 2 + 1]);
572
+ }
573
+ this.context.fill();
574
+ if (transform) this.closeDrawOp();
575
+ }
576
+ drawQuadCurve(args) {
577
+ const { color, points } = this.extractPoints(args);
578
+ if (!points || points.length < 4) return;
579
+ if (color) this.setColor(color);
580
+ this.context.globalAlpha = this.alpha;
581
+ this.context.lineWidth = this.line_width;
582
+ const transform = this.initDrawOp(0, 0, false);
583
+ this.context.beginPath();
584
+ this.context.moveTo(points[0], -points[1]);
585
+ let index = 2;
586
+ while (index <= points.length - 4) {
587
+ this.context.quadraticCurveTo(points[index], -points[index + 1], points[index + 2], -points[index + 3]);
588
+ index += 4;
589
+ }
590
+ this.context.stroke();
591
+ if (transform) this.closeDrawOp();
592
+ }
593
+ drawBezierCurve(args) {
594
+ const { color, points } = this.extractPoints(args);
595
+ if (!points || points.length < 4) return;
596
+ if (color) this.setColor(color);
597
+ this.context.globalAlpha = this.alpha;
598
+ this.context.lineWidth = this.line_width;
599
+ const transform = this.initDrawOp(0, 0, false);
600
+ this.context.beginPath();
601
+ this.context.moveTo(points[0], -points[1]);
602
+ let index = 2;
603
+ while (index <= points.length - 6) {
604
+ this.context.bezierCurveTo(points[index], -points[index + 1], points[index + 2], -points[index + 3], points[index + 4], -points[index + 5]);
605
+ index += 6;
606
+ }
607
+ this.context.stroke();
608
+ if (transform) this.closeDrawOp();
609
+ }
610
+ drawArc(x, y, radius, angle1, angle2, ccw, color) {
611
+ if (color) this.setColor(color);
612
+ this.context.globalAlpha = this.alpha;
613
+ this.context.lineWidth = this.line_width;
614
+ if (this.initDrawOp(x, -y)) {
615
+ this.context.beginPath();
616
+ this.context.arc(0, 0, radius, -angle1 / 180 * Math.PI, -angle2 / 180 * Math.PI, ccw);
617
+ this.context.stroke();
618
+ this.closeDrawOp();
619
+ } else {
620
+ this.context.beginPath();
621
+ this.context.arc(x, -y, radius, -angle1 / 180 * Math.PI, -angle2 / 180 * Math.PI, ccw);
622
+ this.context.stroke();
623
+ }
624
+ }
625
+ fillArc(x, y, radius, angle1, angle2, ccw, color) {
626
+ if (color) this.setColor(color);
627
+ this.context.globalAlpha = this.alpha;
628
+ if (this.initDrawOp(x, -y)) {
629
+ this.context.beginPath();
630
+ this.context.arc(0, 0, radius, -angle1 / 180 * Math.PI, -angle2 / 180 * Math.PI, ccw);
631
+ this.context.fill();
632
+ this.closeDrawOp();
633
+ } else {
634
+ this.context.beginPath();
635
+ this.context.arc(x, -y, radius, -angle1 / 180 * Math.PI, -angle2 / 180 * Math.PI, ccw);
636
+ this.context.fill();
637
+ }
638
+ }
639
+ extractPoints(args) {
640
+ let color;
641
+ let points;
642
+ if (args.length > 0 && args.length % 2 === 1 && typeof args[args.length - 1] === "string") {
643
+ color = args[args.length - 1];
644
+ points = args.slice(0, -1);
645
+ } else if (Array.isArray(args[0])) {
646
+ if (args[1] && typeof args[1] === "string") {
647
+ color = args[1];
648
+ }
649
+ points = args[0];
650
+ } else {
651
+ points = args;
652
+ }
653
+ return {
654
+ color,
655
+ points
656
+ };
657
+ }
658
+ };
659
+ export {
660
+ PrimitiveScreen
661
+ };
662
+ //# sourceMappingURL=primitives-screen.mjs.map