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