@oliversalzburg/js-utils 0.0.9 → 0.0.11

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 (110) hide show
  1. package/README.md +4 -0
  2. package/_site/assets/navigation.js +1 -1
  3. package/_site/assets/search.js +1 -1
  4. package/_site/classes/AbstractError.html +5 -5
  5. package/_site/classes/Canvas.html +36 -25
  6. package/_site/classes/InternalError.html +6 -6
  7. package/_site/classes/InvalidArgumentError.html +5 -5
  8. package/_site/classes/InvalidOperationError.html +5 -5
  9. package/_site/classes/NotImplementedError.html +5 -5
  10. package/_site/classes/PermissionViolationError.html +5 -5
  11. package/_site/classes/Random.html +12 -12
  12. package/_site/classes/RenderLoop.html +31 -18
  13. package/_site/classes/ResourceConflictError.html +5 -5
  14. package/_site/classes/UnexpectedNilError.html +3 -3
  15. package/_site/classes/UnknownError.html +5 -5
  16. package/_site/classes/Vector2.html +32 -29
  17. package/_site/classes/Vector3.html +8 -8
  18. package/_site/functions/addVector2.html +1 -1
  19. package/_site/functions/blend.html +1 -1
  20. package/_site/functions/blendAdditive.html +1 -1
  21. package/_site/functions/blendSubtractive.html +1 -1
  22. package/_site/functions/clamp.html +6 -0
  23. package/_site/functions/cosDeg.html +1 -1
  24. package/_site/functions/deg2rad.html +1 -1
  25. package/_site/functions/difference.html +1 -1
  26. package/_site/functions/distance.html +1 -1
  27. package/_site/functions/errorToJSON.html +1 -1
  28. package/_site/functions/errorToRecord.html +1 -1
  29. package/_site/functions/errorToSimpleSerializable.html +1 -1
  30. package/_site/functions/filterType.html +1 -1
  31. package/_site/functions/formatString.html +1 -1
  32. package/_site/functions/formatStringTemplate.html +1 -1
  33. package/_site/functions/fromRGB.html +1 -1
  34. package/_site/functions/fromRGBA.html +1 -1
  35. package/_site/functions/getA.html +1 -1
  36. package/_site/functions/getB.html +1 -1
  37. package/_site/functions/getDocumentElementTypeById.html +1 -1
  38. package/_site/functions/getG.html +1 -1
  39. package/_site/functions/getR.html +1 -1
  40. package/_site/functions/intersect.html +1 -1
  41. package/_site/functions/is.html +1 -1
  42. package/_site/functions/isError.html +1 -1
  43. package/_site/functions/isInteger.html +1 -1
  44. package/_site/functions/isNil.html +1 -1
  45. package/_site/functions/isqrt.html +1 -1
  46. package/_site/functions/multiplyVector2.html +1 -1
  47. package/_site/functions/mustExist.html +1 -1
  48. package/_site/functions/nextPalette.html +1 -1
  49. package/_site/functions/putPixel32.html +8 -1
  50. package/_site/functions/putPixel32Add.html +8 -1
  51. package/_site/functions/putPixel32Sub.html +8 -1
  52. package/_site/functions/putSubPixel32.html +1 -1
  53. package/_site/functions/rad2deg.html +1 -1
  54. package/_site/functions/randomRange.html +1 -1
  55. package/_site/functions/safeRGBComponent.html +1 -1
  56. package/_site/functions/seedFromString.html +1 -1
  57. package/_site/functions/shuffleArray.html +1 -1
  58. package/_site/functions/sinDeg.html +1 -1
  59. package/_site/functions/sleep.html +1 -1
  60. package/_site/functions/somecolor.html +1 -1
  61. package/_site/functions/subtractVector2.html +1 -1
  62. package/_site/functions/toGrayScale.html +1 -1
  63. package/_site/functions/unknownToError.html +1 -1
  64. package/_site/index.html +5 -1
  65. package/_site/interfaces/CanvasOptions.html +5 -0
  66. package/_site/interfaces/RenderLoopOptions.html +7 -0
  67. package/_site/modules.html +5 -2
  68. package/_site/types/AnyConstructor.html +1 -1
  69. package/_site/types/AnyFunction.html +1 -1
  70. package/_site/types/ConstructorOf.html +1 -1
  71. package/_site/types/FunctionReturning.html +1 -1
  72. package/_site/types/Maybe.html +1 -1
  73. package/_site/types/Mixin.html +1 -1
  74. package/_site/types/Nil.html +1 -1
  75. package/_site/types/RenderLoopCallback.html +1 -1
  76. package/_site/types/SerializedError.html +1 -1
  77. package/_site/variables/PALETTES.html +1 -1
  78. package/_site/variables/TWO_PI.html +1 -1
  79. package/_site/variables/random-1.html +1 -1
  80. package/lib/array.js +1 -1
  81. package/lib/core.d.ts +8 -0
  82. package/lib/core.js +10 -1
  83. package/lib/core.js.map +1 -1
  84. package/lib/dom/core.d.ts +1 -0
  85. package/lib/errors/AbstractError.js +5 -3
  86. package/lib/errors/AbstractError.js.map +1 -1
  87. package/lib/errors/InternalError.js +5 -3
  88. package/lib/errors/InternalError.js.map +1 -1
  89. package/lib/errors/InvalidArgumentError.js +5 -3
  90. package/lib/errors/InvalidArgumentError.js.map +1 -1
  91. package/lib/errors/InvalidOperationError.js +5 -3
  92. package/lib/errors/InvalidOperationError.js.map +1 -1
  93. package/lib/errors/NotImplementedError.js +5 -3
  94. package/lib/errors/NotImplementedError.js.map +1 -1
  95. package/lib/errors/PermissionViolationError.js +5 -3
  96. package/lib/errors/PermissionViolationError.js.map +1 -1
  97. package/lib/errors/ResourceConflictError.js +5 -3
  98. package/lib/errors/ResourceConflictError.js.map +1 -1
  99. package/lib/errors/UnknownError.js +5 -3
  100. package/lib/errors/UnknownError.js.map +1 -1
  101. package/lib/graphics/canvas.d.ts +66 -16
  102. package/lib/graphics/canvas.js +97 -42
  103. package/lib/graphics/canvas.js.map +1 -1
  104. package/lib/graphics/render-loop.d.ts +39 -6
  105. package/lib/graphics/render-loop.js +77 -26
  106. package/lib/graphics/render-loop.js.map +1 -1
  107. package/lib/math/vector2.d.ts +6 -1
  108. package/lib/math/vector2.js +8 -1
  109. package/lib/math/vector2.js.map +1 -1
  110. package/package.json +4 -3
@@ -12,9 +12,11 @@ export class NotImplementedError extends AbstractError {
12
12
  constructor(message, status = 501) {
13
13
  super("ERR_OS_NOT_IMPLEMENTED", message, status);
14
14
  this.name = "NotImplementedError";
15
- // Capture a new stacktrace, otherwise it will include our base-class
16
- // constructor instead of the code location we're actually interested in.
17
- Error.captureStackTrace(this, NotImplementedError);
15
+ if (typeof Error.captureStackTrace !== "undefined") {
16
+ // Capture a new stacktrace, otherwise it will include our base-class
17
+ // constructor instead of the code location we're actually interested in.
18
+ Error.captureStackTrace(this, NotImplementedError);
19
+ }
18
20
  }
19
21
  }
20
22
  //# sourceMappingURL=NotImplementedError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NotImplementedError.js","sourceRoot":"","sources":["../../source/errors/NotImplementedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IACpD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,wBAAwB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEjD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAElC,qEAAqE;QACrE,yEAAyE;QACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;IACrD,CAAC;CACF"}
1
+ {"version":3,"file":"NotImplementedError.js","sourceRoot":"","sources":["../../source/errors/NotImplementedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IACpD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,wBAAwB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEjD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;QAElC,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,WAAW,EAAE;YAClD,qEAAqE;YACrE,yEAAyE;YACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;SACpD;IACH,CAAC;CACF"}
@@ -13,9 +13,11 @@ export class PermissionViolationError extends AbstractError {
13
13
  constructor(message, status = 403) {
14
14
  super("ERR_OS_PERMISSION_VIOLATION", message, status);
15
15
  this.name = "PermissionViolationError";
16
- // Capture a new stacktrace, otherwise it will include our base-class
17
- // constructor instead of the code location we're actually interested in.
18
- Error.captureStackTrace(this, PermissionViolationError);
16
+ if (typeof Error.captureStackTrace !== "undefined") {
17
+ // Capture a new stacktrace, otherwise it will include our base-class
18
+ // constructor instead of the code location we're actually interested in.
19
+ Error.captureStackTrace(this, PermissionViolationError);
20
+ }
19
21
  }
20
22
  }
21
23
  //# sourceMappingURL=PermissionViolationError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionViolationError.js","sourceRoot":"","sources":["../../source/errors/PermissionViolationError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IACzD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,6BAA6B,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QAEvC,qEAAqE;QACrE,yEAAyE;QACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;IAC1D,CAAC;CACF"}
1
+ {"version":3,"file":"PermissionViolationError.js","sourceRoot":"","sources":["../../source/errors/PermissionViolationError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;GAIG;AACH,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IACzD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,6BAA6B,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEtD,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QAEvC,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,WAAW,EAAE;YAClD,qEAAqE;YACrE,yEAAyE;YACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC;SACzD;IACH,CAAC;CACF"}
@@ -12,9 +12,11 @@ export class ResourceConflictError extends AbstractError {
12
12
  constructor(message, status = 409) {
13
13
  super("ERR_OS_RESOURCE_CONFLICT", message, status);
14
14
  this.name = "ResourceConflictError";
15
- // Capture a new stacktrace, otherwise it will include our base-class
16
- // constructor instead of the code location we're actually interested in.
17
- Error.captureStackTrace(this, ResourceConflictError);
15
+ if (typeof Error.captureStackTrace !== "undefined") {
16
+ // Capture a new stacktrace, otherwise it will include our base-class
17
+ // constructor instead of the code location we're actually interested in.
18
+ Error.captureStackTrace(this, ResourceConflictError);
19
+ }
18
20
  }
19
21
  }
20
22
  //# sourceMappingURL=ResourceConflictError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceConflictError.js","sourceRoot":"","sources":["../../source/errors/ResourceConflictError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,0BAA0B,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEnD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QAEpC,qEAAqE;QACrE,yEAAyE;QACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACvD,CAAC;CACF"}
1
+ {"version":3,"file":"ResourceConflictError.js","sourceRoot":"","sources":["../../source/errors/ResourceConflictError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;GAGG;AACH,MAAM,OAAO,qBAAsB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,0BAA0B,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEnD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QAEpC,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,WAAW,EAAE;YAClD,qEAAqE;YACrE,yEAAyE;YACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;SACtD;IACH,CAAC;CACF"}
@@ -16,9 +16,11 @@ export class UnknownError extends AbstractError {
16
16
  constructor(message, status = 500) {
17
17
  super("ERR_OS_UNKNOWN", message, status);
18
18
  this.name = "UnknownError";
19
- // Capture a new stacktrace, otherwise it will include our base-class
20
- // constructor instead of the code location we're actually interested in.
21
- Error.captureStackTrace(this, UnknownError);
19
+ if (typeof Error.captureStackTrace !== "undefined") {
20
+ // Capture a new stacktrace, otherwise it will include our base-class
21
+ // constructor instead of the code location we're actually interested in.
22
+ Error.captureStackTrace(this, UnknownError);
23
+ }
22
24
  }
23
25
  }
24
26
  //# sourceMappingURL=UnknownError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UnknownError.js","sourceRoot":"","sources":["../../source/errors/UnknownError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7C;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEzC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAE3B,qEAAqE;QACrE,yEAAyE;QACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC9C,CAAC;CACF"}
1
+ {"version":3,"file":"UnknownError.js","sourceRoot":"","sources":["../../source/errors/UnknownError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7C;;;;OAIG;IACH,YAAY,OAAe,EAAE,MAAM,GAAG,GAAG;QACvC,KAAK,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAEzC,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAE3B,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,WAAW,EAAE;YAClD,qEAAqE;YACrE,yEAAyE;YACzE,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;SAC7C;IACH,CAAC;CACF"}
@@ -1,14 +1,26 @@
1
1
  /// <reference types="@types/web" />
2
+ /**
3
+ * Construction options for a {@linkcode Canvas}.
4
+ * @group Graphics
5
+ */
6
+ export interface CanvasOptions {
7
+ /**
8
+ * Was this {@linkcode Canvas} created with the ability to copy the front buffer back into
9
+ * the back buffer?
10
+ */
11
+ readonly supportReadBack: boolean;
12
+ }
2
13
  /**
3
14
  * A wrapper around {@linkcode !HTMLCanvasElement}
4
15
  * to provide some convience for double-buffered drawing.
5
16
  * @group Graphics
6
17
  */
7
18
  export declare class Canvas {
19
+ #private;
8
20
  /**
9
- * The {@linkcode !HTMLCanvasElement} we're interacting with.
21
+ * The {@linkcode !HTMLCanvasElement} we're interacting with in the DOM.
10
22
  */
11
- readonly canvas: HTMLCanvasElement;
23
+ readonly canvasDom: HTMLCanvasElement;
12
24
  /**
13
25
  * The width of the canvas.
14
26
  */
@@ -18,37 +30,40 @@ export declare class Canvas {
18
30
  */
19
31
  readonly height: number;
20
32
  /**
21
- * The {@linkcode !CanvasRenderingContext2D} we're using to draw to the canvas.
22
- */
23
- readonly context: CanvasRenderingContext2D;
24
- /**
25
- * The {@linkcode !ImageData} object
26
- * that represents our frontbuffer, which is the canvas itself.
33
+ * The {@linkcode !OffscreenCanvasRenderingContext2D} we're using to draw to the canvas.
27
34
  */
28
- pixMap: ImageData;
35
+ readonly context: OffscreenCanvasRenderingContext2D;
29
36
  /**
30
37
  * Our back buffer.
31
38
  */
32
39
  buffer: Uint8ClampedArray;
33
40
  /**
34
- * Was this {@linkcode Canvas} created with the ability to copy the front buffer back into
35
- * the back buffer?
41
+ * The configuration that was used for this canvas.
36
42
  */
37
- readonly supportReadBack: boolean;
43
+ readonly options: Readonly<Partial<CanvasOptions>>;
38
44
  /**
39
45
  * Constructs a new {@linkcode Canvas}.
40
46
  * @param canvas The canvas to wrap.
41
47
  * @param width The width of the canvas.
42
48
  * @param height The height of the canvas.
43
- * @param supportReadBack Should this canvas support reading back from the front buffer?
44
- * You will need this, if you plan to use regular canvas drawing on the front buffer, and
45
- * read the results back into the back buffer.
49
+ * @param options The configuration for this canvas.
46
50
  */
47
- constructor(canvas: HTMLCanvasElement, width: number, height: number, supportReadBack?: boolean);
51
+ constructor(canvas: HTMLCanvasElement, width: number, height: number, options?: Partial<CanvasOptions>);
48
52
  /**
49
53
  * Draws the back buffer onto the canvas.
50
54
  */
51
55
  update(): void;
56
+ /**
57
+ * Draws the offscreen canvas into the DOM canvas.
58
+ */
59
+ render(): void;
60
+ /**
61
+ * Draws a slightly transparent, black rectangle over the canvas,
62
+ * and then reads the result back into the buffer.
63
+ * @param amount How much the screen should be faded to black. `0` is
64
+ * not at all, `255` makes it instantly black.
65
+ */
66
+ fade(amount?: number): void;
52
67
  /**
53
68
  * Reads the front buffer back into the back buffer.
54
69
  */
@@ -72,9 +87,24 @@ export declare class Canvas {
72
87
  * @param color The color to fill the back buffer with.
73
88
  */
74
89
  clearWith(color: number): void;
90
+ /**
91
+ * Fills the entire back buffer with the given color.
92
+ * @param color The color to fill the back buffer with.
93
+ */
94
+ blendWith(color: number): void;
75
95
  }
76
96
  /**
77
97
  * Linearly blends a new pixel with an existing color value in a {@linkcode Canvas}.
98
+ *
99
+ * As this method is often called many times in render loops, only bounds
100
+ * checking is applied to the given coordinates.
101
+ *
102
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
103
+ * has performance implications. Ensure you're working with integers, or truncate the
104
+ * coordinates before passing them in.
105
+ *
106
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
107
+ * `0` meaning fully transparent, `255` meaning fully opaque.
78
108
  * @param canvas The {@linkcode Canvas} to interact with.
79
109
  * @param x The X coordinate at which to place the pixel.
80
110
  * @param y The Y coordinate at which to place the pixel.
@@ -85,6 +115,16 @@ export declare class Canvas {
85
115
  export declare const putPixel32: (canvas: Canvas, x: number, y: number, color: number, alpha: number) => void;
86
116
  /**
87
117
  * Additively blends a new pixel with an existing color value in a {@linkcode Canvas}.
118
+ *
119
+ * As this method is often called many times in render loops, only bounds
120
+ * checking is applied to the given coordinates.
121
+ *
122
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
123
+ * has performance implications. Ensure you're working with integers, or truncate the
124
+ * coordinates before passing them in.
125
+ *
126
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
127
+ * `0` meaning fully transparent, `255` meaning fully opaque.
88
128
  * @param canvas The {@linkcode Canvas} to interact with.
89
129
  * @param x The X coordinate at which to place the pixel.
90
130
  * @param y The Y coordinate at which to place the pixel.
@@ -95,6 +135,16 @@ export declare const putPixel32: (canvas: Canvas, x: number, y: number, color: n
95
135
  export declare const putPixel32Add: (canvas: Canvas, x: number, y: number, color: number, alpha: number) => void;
96
136
  /**
97
137
  * Subtractively blends a new pixel with an existing color value in a {@linkcode Canvas}.
138
+ *
139
+ * As this method is often called many times in render loops, only bounds
140
+ * checking is applied to the given coordinates.
141
+ *
142
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
143
+ * has performance implications. Ensure you're working with integers, or truncate the
144
+ * coordinates before passing them in.
145
+ *
146
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
147
+ * `0` meaning fully transparent, `255` meaning fully opaque.
98
148
  * @param canvas The {@linkcode Canvas} to interact with.
99
149
  * @param x The X coordinate at which to place the pixel.
100
150
  * @param y The Y coordinate at which to place the pixel.
@@ -8,9 +8,17 @@ import { blend, blendAdditive, blendSubtractive, fromRGBA, getA, getB, getG, get
8
8
  */
9
9
  export class Canvas {
10
10
  /**
11
- * The {@linkcode !HTMLCanvasElement} we're interacting with.
11
+ * The {@linkcode !HTMLCanvasElement} we're interacting with in the DOM.
12
12
  */
13
- canvas;
13
+ canvasDom;
14
+ /**
15
+ * The rendering context for the canvas located in the DOM.
16
+ */
17
+ #canvasDomContext;
18
+ /**
19
+ * The offscreen canvas we use for rendering.
20
+ */
21
+ #canvasOffscreen;
14
22
  /**
15
23
  * The width of the canvas.
16
24
  */
@@ -20,61 +28,78 @@ export class Canvas {
20
28
  */
21
29
  height;
22
30
  /**
23
- * The {@linkcode !CanvasRenderingContext2D} we're using to draw to the canvas.
31
+ * The {@linkcode !OffscreenCanvasRenderingContext2D} we're using to draw to the canvas.
24
32
  */
25
33
  context;
26
34
  /**
27
- * The {@linkcode !ImageData} object
28
- * that represents our frontbuffer, which is the canvas itself.
35
+ * The {@linkcode !ImageData} object in our offscreen canvas. We usually interact with its
36
+ * {@linkcode Canvas.buffer buffer} directly.
29
37
  */
30
- pixMap;
38
+ #imageData;
31
39
  /**
32
40
  * Our back buffer.
33
41
  */
34
42
  buffer;
35
43
  /**
36
- * Was this {@linkcode Canvas} created with the ability to copy the front buffer back into
37
- * the back buffer?
44
+ * The configuration that was used for this canvas.
38
45
  */
39
- supportReadBack;
46
+ options;
40
47
  /**
41
48
  * Constructs a new {@linkcode Canvas}.
42
49
  * @param canvas The canvas to wrap.
43
50
  * @param width The width of the canvas.
44
51
  * @param height The height of the canvas.
45
- * @param supportReadBack Should this canvas support reading back from the front buffer?
46
- * You will need this, if you plan to use regular canvas drawing on the front buffer, and
47
- * read the results back into the back buffer.
52
+ * @param options The configuration for this canvas.
48
53
  */
49
- constructor(canvas, width, height, supportReadBack = false) {
50
- this.canvas = canvas;
54
+ constructor(canvas, width, height, options = {}) {
51
55
  this.width = width;
52
56
  this.height = height;
53
- this.context = mustExist(this.canvas.getContext("2d", {
57
+ this.options = options;
58
+ this.canvasDom = canvas;
59
+ this.#canvasDomContext = mustExist(this.canvasDom.getContext("bitmaprenderer", {
60
+ alpha: false,
61
+ }), "Unable to create rendering context for DOM canvas.");
62
+ this.#canvasOffscreen = new OffscreenCanvas(this.width, this.height);
63
+ this.context = mustExist(this.#canvasOffscreen.getContext("2d", {
54
64
  alpha: false,
55
65
  desynchronized: true,
56
- willReadFrequently: supportReadBack,
57
- }), "Unable to create rendering context.");
58
- this.supportReadBack = supportReadBack;
59
- this.pixMap = this.context.createImageData(width, height);
60
- this.buffer = this.pixMap.data;
66
+ willReadFrequently: this.options.supportReadBack,
67
+ }), "Unable to create rendering context for offscreen canvas.");
68
+ this.#imageData = this.context.createImageData(width, height);
69
+ this.buffer = this.#imageData.data;
61
70
  this.context.font = "12px sans-serif";
62
71
  }
63
72
  /**
64
73
  * Draws the back buffer onto the canvas.
65
74
  */
66
75
  update() {
67
- this.context.putImageData(this.pixMap, 0, 0);
76
+ this.context.putImageData(this.#imageData, 0, 0);
77
+ }
78
+ /**
79
+ * Draws the offscreen canvas into the DOM canvas.
80
+ */
81
+ render() {
82
+ const newFrame = this.#canvasOffscreen.transferToImageBitmap();
83
+ this.#canvasDomContext.transferFromImageBitmap(newFrame);
84
+ }
85
+ /**
86
+ * Draws a slightly transparent, black rectangle over the canvas,
87
+ * and then reads the result back into the buffer.
88
+ * @param amount How much the screen should be faded to black. `0` is
89
+ * not at all, `255` makes it instantly black.
90
+ */
91
+ fade(amount = 1) {
92
+ this.blendWith(fromRGBA(0, 0, 0, amount));
68
93
  }
69
94
  /**
70
95
  * Reads the front buffer back into the back buffer.
71
96
  */
72
97
  bufferReadBack() {
73
- if (!this.supportReadBack) {
74
- throw new InvalidOperationError("To use `bufferReadBack()`, you must construct the `Canvas` with `supportReadBack` set to `true`.");
98
+ if (!this.options.supportReadBack) {
99
+ throw new InvalidOperationError("To use `bufferReadBack()`, you must construct the `Canvas` with `options.supportReadBack` set to `true`.");
75
100
  }
76
- this.pixMap = this.context.getImageData(0, 0, this.width, this.height);
77
- this.buffer = this.pixMap.data;
101
+ this.#imageData = this.context.getImageData(0, 0, this.width, this.height);
102
+ this.buffer = this.#imageData.data;
78
103
  }
79
104
  /**
80
105
  * Returns the color of a pixel in the back buffer.
@@ -83,7 +108,7 @@ export class Canvas {
83
108
  * @returns The color of the pixel at the given local.
84
109
  */
85
110
  getPixel32(x, y) {
86
- const bufferOffset = Math.trunc((x + y * this.width) * 4);
111
+ const bufferOffset = (x + y * this.width) * 4;
87
112
  return fromRGBA(this.buffer[bufferOffset + 0], this.buffer[bufferOffset + 1], this.buffer[bufferOffset + 2], this.buffer[bufferOffset + 3]);
88
113
  }
89
114
  /**
@@ -93,7 +118,7 @@ export class Canvas {
93
118
  * @param color The color to place at the coordinate.
94
119
  */
95
120
  setPixel32(x, y, color) {
96
- const bufferOffset = Math.trunc((x + y * this.width) * 4);
121
+ const bufferOffset = (x + y * this.width) * 4;
97
122
  this.buffer[bufferOffset + 0] = getR(color);
98
123
  this.buffer[bufferOffset + 1] = getG(color);
99
124
  this.buffer[bufferOffset + 2] = getB(color);
@@ -115,9 +140,34 @@ export class Canvas {
115
140
  this.buffer[bufferOffset + 3] = a;
116
141
  }
117
142
  }
143
+ /**
144
+ * Fills the entire back buffer with the given color.
145
+ * @param color The color to fill the back buffer with.
146
+ */
147
+ blendWith(color) {
148
+ const r = getR(color);
149
+ const g = getG(color);
150
+ const b = getB(color);
151
+ const a = getA(color);
152
+ for (let bufferOffset = 0; bufferOffset < this.width * this.height * 4; bufferOffset += 4) {
153
+ this.buffer[bufferOffset + 0] = (a * r + (255 - a) * this.buffer[bufferOffset + 0]) >> 8;
154
+ this.buffer[bufferOffset + 1] = (a * g + (255 - a) * this.buffer[bufferOffset + 1]) >> 8;
155
+ this.buffer[bufferOffset + 2] = (a * b + (255 - a) * this.buffer[bufferOffset + 2]) >> 8;
156
+ }
157
+ }
118
158
  }
119
159
  /**
120
160
  * Linearly blends a new pixel with an existing color value in a {@linkcode Canvas}.
161
+ *
162
+ * As this method is often called many times in render loops, only bounds
163
+ * checking is applied to the given coordinates.
164
+ *
165
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
166
+ * has performance implications. Ensure you're working with integers, or truncate the
167
+ * coordinates before passing them in.
168
+ *
169
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
170
+ * `0` meaning fully transparent, `255` meaning fully opaque.
121
171
  * @param canvas The {@linkcode Canvas} to interact with.
122
172
  * @param x The X coordinate at which to place the pixel.
123
173
  * @param y The Y coordinate at which to place the pixel.
@@ -129,17 +179,22 @@ export const putPixel32 = (canvas, x, y, color, alpha) => {
129
179
  if (canvas.width < x || x < 0 || canvas.height < y || y < 0) {
130
180
  return;
131
181
  }
132
- x = Math.trunc(x);
133
- y = Math.trunc(y);
134
- if (alpha > 255) {
135
- alpha = 255;
136
- }
137
182
  const srcColor = canvas.getPixel32(x, y);
138
183
  const newColor = blend(srcColor, color, alpha);
139
184
  canvas.setPixel32(x, y, newColor);
140
185
  };
141
186
  /**
142
187
  * Additively blends a new pixel with an existing color value in a {@linkcode Canvas}.
188
+ *
189
+ * As this method is often called many times in render loops, only bounds
190
+ * checking is applied to the given coordinates.
191
+ *
192
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
193
+ * has performance implications. Ensure you're working with integers, or truncate the
194
+ * coordinates before passing them in.
195
+ *
196
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
197
+ * `0` meaning fully transparent, `255` meaning fully opaque.
143
198
  * @param canvas The {@linkcode Canvas} to interact with.
144
199
  * @param x The X coordinate at which to place the pixel.
145
200
  * @param y The Y coordinate at which to place the pixel.
@@ -151,17 +206,22 @@ export const putPixel32Add = (canvas, x, y, color, alpha) => {
151
206
  if (canvas.width < x || x < 0 || canvas.height < y || y < 0) {
152
207
  return;
153
208
  }
154
- x = Math.round(x);
155
- y = Math.round(y);
156
- if (alpha > 255) {
157
- alpha = 255;
158
- }
159
209
  const srcColor = canvas.getPixel32(x, y);
160
210
  const newColor = blendAdditive(srcColor, color, alpha);
161
211
  canvas.setPixel32(x, y, newColor);
162
212
  };
163
213
  /**
164
214
  * Subtractively blends a new pixel with an existing color value in a {@linkcode Canvas}.
215
+ *
216
+ * As this method is often called many times in render loops, only bounds
217
+ * checking is applied to the given coordinates.
218
+ *
219
+ * The coordinates are **expected to already be integers**. Supplying numbers with fractions
220
+ * has performance implications. Ensure you're working with integers, or truncate the
221
+ * coordinates before passing them in.
222
+ *
223
+ * The `alpha` value is expected to be an integer in the range from `0` to `255`.
224
+ * `0` meaning fully transparent, `255` meaning fully opaque.
165
225
  * @param canvas The {@linkcode Canvas} to interact with.
166
226
  * @param x The X coordinate at which to place the pixel.
167
227
  * @param y The Y coordinate at which to place the pixel.
@@ -173,11 +233,6 @@ export const putPixel32Sub = (canvas, x, y, color, alpha) => {
173
233
  if (canvas.width < x || x < 0 || canvas.height < y || y < 0) {
174
234
  return;
175
235
  }
176
- x = Math.round(x);
177
- y = Math.round(y);
178
- if (alpha > 255) {
179
- alpha = 255;
180
- }
181
236
  const srcColor = canvas.getPixel32(x, y);
182
237
  const newColor = blendSubtractive(srcColor, color, alpha);
183
238
  canvas.setPixel32(x, y, newColor);
@@ -1 +1 @@
1
- {"version":3,"file":"canvas.js","sourceRoot":"","sources":["../../source/graphics/canvas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"canvas.js","sourceRoot":"","sources":["../../source/graphics/canvas.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,21 @@ import { Canvas } from "./canvas.js";
4
4
  * @group Graphics
5
5
  */
6
6
  export type RenderLoopCallback = (delta: number, timestamp: number) => unknown;
7
+ /**
8
+ * Configuration for a {@linkcode RenderLoop},
9
+ * @group Graphics
10
+ */
11
+ export interface RenderLoopOptions {
12
+ /**
13
+ * Should the current frames per second be rendered onto the canvas
14
+ * each frame?
15
+ */
16
+ drawFps: boolean;
17
+ /**
18
+ * Should the buffer be cleared or faded to black before each frame?
19
+ */
20
+ onRefresh: "clear";
21
+ }
7
22
  /**
8
23
  * Conveniently provides a way to have a render loop called at
9
24
  * a constant frame rate.
@@ -14,15 +29,23 @@ export declare class RenderLoop {
14
29
  /**
15
30
  * The {@linkcode Canvas} we're rendering to.
16
31
  */
17
- readonly canvas: Canvas | undefined;
32
+ readonly canvas: Canvas;
18
33
  /**
19
34
  * A function that we call when a new frame should be drawn.
20
35
  */
21
36
  readonly renderLoop: RenderLoopCallback;
22
37
  /**
23
- * The timestamp we got for the previous frame.
38
+ * The configuration that was used for this render loop.
24
39
  */
25
- private previousTimestamp;
40
+ readonly options: Readonly<Partial<RenderLoopOptions>>;
41
+ /**
42
+ * The time at which we drew the last frame to the offscreen buffer.
43
+ */
44
+ private previousTimestampDraw;
45
+ /**
46
+ * The time at which we rendered the last frame to the DOM.
47
+ */
48
+ private previousTimestampRender;
26
49
  /**
27
50
  * Our `#main` function bound to this classes
28
51
  * for easier invokation through external callers.
@@ -32,13 +55,23 @@ export declare class RenderLoop {
32
55
  * The ID of our {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame requestAnimationFrame} request.
33
56
  */
34
57
  private frameRequestId;
58
+ /**
59
+ * The ID of our {@linkcode https://developer.mozilla.org/en-US/docs/Web/API/setTimeout setTimeout}-based
60
+ * offscreen rendering loop.
61
+ */
62
+ private drawTimeout;
63
+ /**
64
+ * Retrieves the amount of frames drawn to the DOM throughout the loops lifetime.
65
+ * @returns The frame count.
66
+ */
67
+ get frameCounter(): number;
35
68
  /**
36
69
  * Constructs a new {@linkcode RenderLoop}.
37
70
  * @param renderLoop The function to call when a new frame should be drawn.
38
- * @param canvas When provided, the canvas is automatically updated
39
- * after a frame was rendered.
71
+ * @param canvas The {@linkcode Canvas} we're rendering to.
72
+ * @param options The configuration for thie {@linkcode RenderLoop}.
40
73
  */
41
- constructor(renderLoop: RenderLoopCallback, canvas?: Canvas);
74
+ constructor(renderLoop: RenderLoopCallback, canvas: Canvas, options?: Partial<RenderLoopOptions>);
42
75
  /**
43
76
  * Stop the render loop.
44
77
  */