@vpmedia/phaser 1.124.0 → 1.125.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 (76) hide show
  1. package/dist/index.js +305 -309
  2. package/dist/index.js.map +1 -1
  3. package/dist/phaser/core/animation_parser.d.ts.map +1 -1
  4. package/dist/phaser/core/dom.d.ts.map +1 -1
  5. package/dist/phaser/core/frame_data.d.ts.map +1 -1
  6. package/dist/phaser/core/loader.d.ts.map +1 -1
  7. package/dist/phaser/core/scale_manager.d.ts.map +1 -1
  8. package/dist/phaser/core/sound.d.ts.map +1 -1
  9. package/dist/phaser/core/sound_manager.d.ts.map +1 -1
  10. package/dist/phaser/core/tween.d.ts.map +1 -1
  11. package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
  12. package/dist/phaser/display/display_object.d.ts +2 -2
  13. package/dist/phaser/display/display_object.d.ts.map +1 -1
  14. package/dist/phaser/display/graphics.d.ts +1 -1
  15. package/dist/phaser/display/graphics.d.ts.map +1 -1
  16. package/dist/phaser/display/group.d.ts.map +1 -1
  17. package/dist/phaser/display/image.d.ts.map +1 -1
  18. package/dist/phaser/display/text.d.ts.map +1 -1
  19. package/dist/phaser/display/webgl/earcut.d.ts.map +1 -1
  20. package/dist/phaser/display/webgl/texture.d.ts.map +1 -1
  21. package/dist/phaser/geom/rectangle.d.ts.map +1 -1
  22. package/dist/phaser/geom/util/circle.d.ts.map +1 -1
  23. package/dist/phaser/geom/util/point.d.ts.map +1 -1
  24. package/dist/phaser/util/math.d.ts.map +1 -1
  25. package/package.json +1 -1
  26. package/src/phaser/core/animation.ts +7 -7
  27. package/src/phaser/core/animation_manager.ts +2 -2
  28. package/src/phaser/core/animation_parser.ts +11 -15
  29. package/src/phaser/core/array_set.ts +2 -2
  30. package/src/phaser/core/cache.ts +4 -4
  31. package/src/phaser/core/device_util.ts +4 -4
  32. package/src/phaser/core/dom.ts +23 -19
  33. package/src/phaser/core/frame_data.ts +2 -5
  34. package/src/phaser/core/game.ts +12 -12
  35. package/src/phaser/core/input.ts +2 -2
  36. package/src/phaser/core/input_handler.ts +13 -13
  37. package/src/phaser/core/input_mouse.ts +4 -4
  38. package/src/phaser/core/input_pointer.ts +1 -1
  39. package/src/phaser/core/loader.ts +38 -50
  40. package/src/phaser/core/scale_manager.ts +10 -9
  41. package/src/phaser/core/scene_manager.ts +2 -2
  42. package/src/phaser/core/signal.ts +2 -2
  43. package/src/phaser/core/sound.ts +25 -32
  44. package/src/phaser/core/sound_manager.ts +12 -16
  45. package/src/phaser/core/sound_sprite.ts +1 -1
  46. package/src/phaser/core/stage.ts +3 -3
  47. package/src/phaser/core/timer.ts +1 -1
  48. package/src/phaser/core/tween.ts +6 -11
  49. package/src/phaser/display/bitmap_text.ts +3 -3
  50. package/src/phaser/display/button.ts +12 -12
  51. package/src/phaser/display/canvas/graphics.ts +2 -2
  52. package/src/phaser/display/canvas/pool.ts +3 -3
  53. package/src/phaser/display/canvas/renderer.ts +6 -5
  54. package/src/phaser/display/canvas/tinter.ts +1 -1
  55. package/src/phaser/display/canvas/util.ts +2 -2
  56. package/src/phaser/display/display_object.ts +13 -14
  57. package/src/phaser/display/graphics.test.ts +2 -2
  58. package/src/phaser/display/graphics.ts +9 -11
  59. package/src/phaser/display/group.ts +10 -9
  60. package/src/phaser/display/image.ts +7 -6
  61. package/src/phaser/display/sprite_util.ts +1 -1
  62. package/src/phaser/display/text.ts +35 -44
  63. package/src/phaser/display/webgl/abstract_filter.ts +1 -1
  64. package/src/phaser/display/webgl/earcut.ts +46 -42
  65. package/src/phaser/display/webgl/graphics.ts +1 -1
  66. package/src/phaser/display/webgl/renderer.ts +3 -3
  67. package/src/phaser/display/webgl/shader/normal.ts +6 -6
  68. package/src/phaser/display/webgl/shader_manager.ts +1 -1
  69. package/src/phaser/display/webgl/sprite_batch.ts +2 -2
  70. package/src/phaser/display/webgl/texture.ts +2 -1
  71. package/src/phaser/display/webgl/util.ts +3 -3
  72. package/src/phaser/geom/polygon.ts +2 -2
  73. package/src/phaser/geom/rectangle.ts +1 -2
  74. package/src/phaser/geom/util/circle.ts +6 -10
  75. package/src/phaser/geom/util/point.ts +5 -7
  76. package/src/phaser/util/math.ts +2 -3
@@ -28,6 +28,7 @@ import { detectCapabilities } from './tinter.js';
28
28
  import { getSmoothingPrefix, setSmoothing } from './util.js';
29
29
  import type { DisplayObject } from '../display_object.js';
30
30
  import type { RenderSession } from '../render_session.js';
31
+ import type { StageBackgroundColor } from '../../core/stage.js';
31
32
 
32
33
  export class CanvasRenderer {
33
34
  public type!: number;
@@ -64,7 +65,7 @@ export class CanvasRenderer {
64
65
  willReadFrequently: false,
65
66
  alpha: this.transparent,
66
67
  })!;
67
- if (!this.context) {
68
+ if (!(this.context as CanvasRenderingContext2D | undefined)) {
68
69
  throw new Error(ENGINE_ERROR_CREATING_CANVAS_2D_CONTEXT);
69
70
  }
70
71
  this.refresh = true;
@@ -86,7 +87,7 @@ export class CanvasRenderer {
86
87
  * @param {Stage} root - The root stage to render.
87
88
  */
88
89
  public render(root: Stage): void {
89
- if (!this.context) {
90
+ if (!(this.context as CanvasRenderingContext2D | undefined)) {
90
91
  return;
91
92
  }
92
93
  this.context.setTransform(1, 0, 0, 1, 0, 0);
@@ -98,7 +99,7 @@ export class CanvasRenderer {
98
99
  if (this.clearBeforeRender) {
99
100
  if (this.transparent) {
100
101
  this.context.clearRect(0, 0, this.width, this.height);
101
- } else if (root._bgColor) {
102
+ } else if (root._bgColor as StageBackgroundColor | undefined) {
102
103
  this.context.fillStyle = root._bgColor.rgba;
103
104
  this.context.fillRect(0, 0, this.width, this.height);
104
105
  }
@@ -130,7 +131,7 @@ export class CanvasRenderer {
130
131
  this.view.style.width = `${this.width / this.resolution}px`;
131
132
  this.view.style.height = `${this.height / this.resolution}px`;
132
133
  }
133
- if (this.renderSession.smoothProperty) {
134
+ if (this.renderSession.smoothProperty !== null) {
134
135
  setSmoothing(this.context, this.renderSession.smoothProperty, this.renderSession.scaleMode === SCALE_LINEAR);
135
136
  }
136
137
  }
@@ -151,7 +152,7 @@ export class CanvasRenderer {
151
152
  * Maps blend modes to canvas rendering operations.
152
153
  */
153
154
  public mapBlendModes(): void {
154
- if (globalThis.PhaserRegistry.blendModesCanvas) {
155
+ if (globalThis.PhaserRegistry.blendModesCanvas as GlobalCompositeOperation[] | undefined) {
155
156
  return;
156
157
  }
157
158
  const b: GlobalCompositeOperation[] = [];
@@ -179,7 +179,7 @@ export const canUseNewCanvasBlendModes = (): boolean => {
179
179
  context.globalCompositeOperation = 'multiply';
180
180
  context.drawImage(magenta, 0, 0);
181
181
  context.drawImage(yellow, 2, 0);
182
- if (!context.getImageData(2, 0, 1, 1)) {
182
+ if (context.getImageData(2, 0, 1, 1) === null) {
183
183
  return false;
184
184
  }
185
185
  const { data } = context.getImageData(2, 0, 1, 1);
@@ -141,7 +141,7 @@ export const getSmoothingPrefix = (context: CanvasRenderingContext2D): string |
141
141
  const smoothingFlags = context as unknown as Record<string, boolean | undefined>;
142
142
  for (const vendor of VENDORS) {
143
143
  const flag = `${vendor}mageSmoothingEnabled`;
144
- if (smoothingFlags[flag]) {
144
+ if (smoothingFlags[flag] !== undefined) {
145
145
  return flag;
146
146
  }
147
147
  }
@@ -166,7 +166,7 @@ export const setSmoothing = (context: CanvasRenderingContext2D, property: string
166
166
  */
167
167
  export const setSmoothingEnabled = (context: CanvasRenderingContext2D, value: boolean): CanvasRenderingContext2D => {
168
168
  const s = getSmoothingPrefix(context);
169
- if (s) {
169
+ if (s !== null) {
170
170
  setSmoothing(context, s, value);
171
171
  }
172
172
  return context;
@@ -10,6 +10,7 @@ import type { UserData } from '../core/callback.js';
10
10
  import type { EventManager } from '../core/event_manager.js';
11
11
  import type { Image } from './image.js';
12
12
  import type { RenderSession } from './render_session.js';
13
+ import type { IdentifiedWebGLRenderingContext } from './webgl/util.js';
13
14
 
14
15
  export class DisplayObject {
15
16
  /** @type {boolean} */
@@ -127,7 +128,7 @@ export class DisplayObject {
127
128
  * @param {boolean} _destroyTexture - Whether the subclass should destroy its texture too.
128
129
  */
129
130
  public destroy(_destroyChildren = true, _destroyTexture = false): void {
130
- if (this.children) {
131
+ if (this.children as DisplayObject[] | undefined) {
131
132
  let i = this.children.length;
132
133
  while (i) {
133
134
  i -= 1;
@@ -284,12 +285,12 @@ export class DisplayObject {
284
285
  * @returns {DisplayObject[]} The array of removed child display objects.
285
286
  * @throws {Error} If the range is invalid.
286
287
  */
287
- public removeChildren(beginIndex: number, endIndex: number): DisplayObject[] {
288
- beginIndex ??= 0;
289
- endIndex ??= this.children.length;
290
- const range = endIndex - beginIndex;
291
- if (range > 0 && range <= endIndex) {
292
- const removed = this.children.splice(beginIndex, range);
288
+ public removeChildren(beginIndex?: number, endIndex?: number): DisplayObject[] {
289
+ const begin = beginIndex ?? 0;
290
+ const end = endIndex ?? this.children.length;
291
+ const range = end - begin;
292
+ if (range > 0 && range <= end) {
293
+ const removed = this.children.splice(begin, range);
293
294
  for (const child of removed) {
294
295
  child.parent = null;
295
296
  }
@@ -310,7 +311,7 @@ export class DisplayObject {
310
311
  if (!parent && !this.parent) {
311
312
  return this;
312
313
  }
313
- if (!this.game || !this.visible) {
314
+ if (!(this.game as Game | undefined) || !this.visible) {
314
315
  return this;
315
316
  }
316
317
  const p = parent ?? this.parent ?? this.game.world;
@@ -607,12 +608,10 @@ export class DisplayObject {
607
608
  * @param {DisplayObject} from - The display object to convert from (defaults to this).
608
609
  * @returns {Point} The converted local position.
609
610
  */
610
- public toLocal(position: Point, from: DisplayObject): Point {
611
- if (from) {
612
- position = from.toGlobal(position);
613
- }
611
+ public toLocal(position: Point, from: DisplayObject | null): Point {
612
+ const global = from ? from.toGlobal(position) : position;
614
613
  this.updateTransform();
615
- return this.worldTransform.applyInverse(position);
614
+ return this.worldTransform.applyInverse(global);
616
615
  }
617
616
 
618
617
  /**
@@ -624,7 +623,7 @@ export class DisplayObject {
624
623
  return;
625
624
  }
626
625
  this._cachedSprite.worldAlpha = this.worldAlpha;
627
- if (renderSession.gl) {
626
+ if (renderSession.gl as IdentifiedWebGLRenderingContext | undefined) {
628
627
  renderWebGL(this._cachedSprite, renderSession);
629
628
  } else {
630
629
  renderCanvas(this._cachedSprite, renderSession);
@@ -135,13 +135,13 @@ describe('Graphics', (): void => {
135
135
  describe('drawTriangles', (): void => {
136
136
  it('reads a flat coordinate list as triangles', (): void => {
137
137
  const graphics = createGraphics();
138
- graphics.drawTriangles([0, 0, 10, 0, 0, 10, 20, 20, 30, 20, 20, 30], null as unknown as number[]);
138
+ graphics.drawTriangles([0, 0, 10, 0, 0, 10, 20, 20, 30, 20, 20, 30], null);
139
139
  expect(graphics.graphicsData).toHaveLength(2);
140
140
  });
141
141
 
142
142
  it('reads a point list as triangles', (): void => {
143
143
  const graphics = createGraphics();
144
- graphics.drawTriangles([new Point(0, 0), new Point(10, 0), new Point(0, 10)], null as unknown as number[]);
144
+ graphics.drawTriangles([new Point(0, 0), new Point(10, 0), new Point(0, 10)], null);
145
145
  expect(graphics.graphicsData).toHaveLength(1);
146
146
  });
147
147
 
@@ -343,19 +343,17 @@ export class Graphics extends DisplayObject {
343
343
  if (startAngle === endAngle) {
344
344
  return this;
345
345
  }
346
- if (!anticlockwise && endAngle <= startAngle) {
347
- endAngle += Math.PI * 2;
348
- } else if (anticlockwise && startAngle <= endAngle) {
349
- startAngle += Math.PI * 2;
350
- }
351
- const sweep = anticlockwise ? (startAngle - endAngle) * -1 : endAngle - startAngle;
346
+ const fullTurn = Math.PI * 2;
347
+ const from = anticlockwise && startAngle <= endAngle ? startAngle + fullTurn : startAngle;
348
+ const to = !anticlockwise && endAngle <= startAngle ? endAngle + fullTurn : endAngle;
349
+ const sweep = anticlockwise ? (from - to) * -1 : to - from;
352
350
  const segs = Math.ceil(Math.abs(sweep) / (Math.PI * 2)) * segments;
353
351
  // Sweep check - moved here because we don't want to do the moveTo below if the arc fails
354
352
  if (sweep === 0) {
355
353
  return this;
356
354
  }
357
- const startX = cx + Math.cos(startAngle) * radius;
358
- const startY = cy + Math.sin(startAngle) * radius;
355
+ const startX = cx + Math.cos(from) * radius;
356
+ const startY = cy + Math.sin(from) * radius;
359
357
  if (anticlockwise && this.filling) {
360
358
  this.moveTo(cx, cy);
361
359
  } else {
@@ -371,7 +369,7 @@ export class Graphics extends DisplayObject {
371
369
  const remainder = (segMinus % 1) / segMinus;
372
370
  for (let i = 0; i <= segMinus; i += 1) {
373
371
  const real = i + remainder * i;
374
- const angle = theta + startAngle + theta2 * real;
372
+ const angle = theta + from + theta2 * real;
375
373
  const c = Math.cos(angle);
376
374
  const s = -Math.sin(angle);
377
375
  points.push((cTheta * c + sTheta * s) * radius + cx, (cTheta * -s + sTheta * c) * radius + cy);
@@ -915,10 +913,10 @@ export class Graphics extends DisplayObject {
915
913
  * @param {number[]} indices - The indices of the vertices to use.
916
914
  * @param {boolean} cull - Whether to perform backface culling.
917
915
  */
918
- public drawTriangles(vertices: Point[] | number[], indices: number[], cull = false): void {
916
+ public drawTriangles(vertices: Point[] | number[], indices: number[] | null, cull = false): void {
919
917
  let points: Point[] = [];
920
918
  let i;
921
- if (!indices) {
919
+ if (indices === null) {
922
920
  if (vertices[0] instanceof Point) {
923
921
  const corners = vertices as Point[];
924
922
  for (i = 0; i < corners.length / 3; i += 1) {
@@ -3,6 +3,7 @@ import { Signal } from '../core/signal.js';
3
3
  import { DisplayObject } from './display_object.js';
4
4
  import { Image } from './image.js';
5
5
  import type { Game } from '../core/game.js';
6
+ import type { EventManager } from '../core/event_manager.js';
6
7
 
7
8
  export const SORT_ASCENDING = -1;
8
9
  export const SORT_DESCENDING = 1;
@@ -33,7 +34,7 @@ export class Group extends DisplayObject {
33
34
  super(game);
34
35
  /** @type {number} */
35
36
  this.type = GROUP;
36
- parent ??= game.world;
37
+ const target = parent ?? game.world;
37
38
  /** @type {string} */
38
39
  this.name = name ?? 'group';
39
40
  /** @type {number} */
@@ -41,9 +42,9 @@ export class Group extends DisplayObject {
41
42
  if (addToStage) {
42
43
  this.game.stage.addChild(this);
43
44
  this.z = this.game.stage.children.length;
44
- } else if (parent) {
45
- parent.addChild(this);
46
- this.z = parent.children.length;
45
+ } else if (target as DisplayObject | undefined) {
46
+ target.addChild(this);
47
+ this.z = target.children.length;
47
48
  }
48
49
  /** @type {boolean} */
49
50
  this.ignoreDestroy = false;
@@ -112,10 +113,10 @@ export class Group extends DisplayObject {
112
113
  this.updateZ();
113
114
  }
114
115
  const inputChild = child as T & { input?: unknown; inputEnabled?: boolean };
115
- if (this.inputEnableChildren && (!inputChild.input || inputChild.inputEnabled)) {
116
+ if (this.inputEnableChildren && (inputChild.input === undefined || inputChild.inputEnabled === true)) {
116
117
  inputChild.inputEnabled = true;
117
118
  }
118
- if (!silent && child.events) {
119
+ if (!silent && (child.events as EventManager | undefined)) {
119
120
  child.events.onAddedToGroup$dispatch(child, this);
120
121
  }
121
122
  this.cursor ??= child;
@@ -252,7 +253,7 @@ export class Group extends DisplayObject {
252
253
  this.destroy();
253
254
  return;
254
255
  }
255
- if (!this.exists || !this.parent?.exists) {
256
+ if (!this.exists || this.parent?.exists !== true) {
256
257
  this.renderOrderID = -1;
257
258
  return;
258
259
  }
@@ -292,7 +293,7 @@ export class Group extends DisplayObject {
292
293
  if (this.children.length === 0 || !this.children.includes(child)) {
293
294
  return false;
294
295
  }
295
- if (!silent && child.events) {
296
+ if (!silent && (child.events as EventManager | undefined)) {
296
297
  child.events.onRemovedFromGroup$dispatch(child, this);
297
298
  }
298
299
  const removed = this.removeChild(child);
@@ -318,7 +319,7 @@ export class Group extends DisplayObject {
318
319
  }
319
320
  do {
320
321
  const first = this.children[0]!;
321
- if (!silent && first.events) {
322
+ if (!silent && (first.events as EventManager | undefined)) {
322
323
  first.events.onRemovedFromGroup$dispatch(first, this);
323
324
  }
324
325
  const removed = this.removeChild(first);
@@ -11,6 +11,7 @@ import { Frame } from '../core/frame.js';
11
11
  import type { Matrix } from '../geom/matrix.js';
12
12
  import type { RenderSession } from './render_session.js';
13
13
  import type { AbstractFilter } from './webgl/abstract_filter.js';
14
+ import type { ImageCacheEntry } from '../core/cache.js';
14
15
 
15
16
  export class Image extends DisplayObject {
16
17
  public key!: string | number | Texture | null;
@@ -99,11 +100,11 @@ export class Image extends DisplayObject {
99
100
  this.tintedTexture = null;
100
101
  this.shader = null;
101
102
  this._frame = null;
102
- if (this.events) {
103
+ if (this.events as EventManager | undefined) {
103
104
  this.events.destroy();
104
105
  }
105
106
  this.events = null!;
106
- if (this.animations) {
107
+ if (this.animations as AnimationManager | undefined) {
107
108
  this.animations.destroy();
108
109
  }
109
110
  this.animations = null!;
@@ -118,7 +119,7 @@ export class Image extends DisplayObject {
118
119
  this.destroy();
119
120
  return;
120
121
  }
121
- if (!this.exists || !this.parent?.exists) {
122
+ if (!this.exists || this.parent?.exists !== true) {
122
123
  this.renderOrderID = -1;
123
124
  return;
124
125
  }
@@ -126,7 +127,7 @@ export class Image extends DisplayObject {
126
127
  this.game.stage.currentRenderOrderID += 1;
127
128
  this.renderOrderID = this.game.stage.currentRenderOrderID;
128
129
  }
129
- if (this.animations) {
130
+ if (this.animations as AnimationManager | undefined) {
130
131
  this.animations.update();
131
132
  }
132
133
  for (const child of this.children) {
@@ -162,7 +163,7 @@ export class Image extends DisplayObject {
162
163
  this.setTexture(textureKey);
163
164
  } else {
164
165
  const img = cache.getImage(textureKey ?? undefined, true);
165
- if (img) {
166
+ if (img as ImageCacheEntry | undefined) {
166
167
  this.key = img.key;
167
168
  this.setTexture(new Texture(img.base));
168
169
  this.texture.baseTexture.skipRender = textureKey === '__default';
@@ -283,7 +284,7 @@ export class Image extends DisplayObject {
283
284
  * @param {boolean} copy - Whether to copy the rect or use it directly.
284
285
  */
285
286
  public crop(rect: Rectangle, copy = false): void {
286
- if (rect) {
287
+ if (rect as Rectangle | undefined) {
287
288
  if (copy && this.cropRect !== null) {
288
289
  this.cropRect.setTo(rect.x, rect.y, rect.width, rect.height);
289
290
  } else if (copy && this.cropRect === null) {
@@ -222,7 +222,7 @@ export const renderCanvas = (
222
222
  renderSession.context.globalAlpha = target.worldAlpha;
223
223
 
224
224
  // If smoothingEnabled is supported and we need to change the smoothing property for this texture
225
- if (renderSession.smoothProperty && renderSession.scaleMode !== target.texture.baseTexture.scaleMode) {
225
+ if (renderSession.smoothProperty !== null && renderSession.scaleMode !== target.texture.baseTexture.scaleMode) {
226
226
  renderSession.scaleMode = target.texture.baseTexture.scaleMode;
227
227
  setSmoothing(renderSession.context, renderSession.smoothProperty, renderSession.scaleMode === SCALE_LINEAR);
228
228
  }
@@ -199,16 +199,16 @@ export class Text extends Image {
199
199
  tabs: source.tabs ?? 0,
200
200
  };
201
201
  const components = this.fontToComponents(resolved.font);
202
- if (resolved.fontStyle) {
202
+ if (resolved.fontStyle !== undefined && resolved.fontStyle !== '') {
203
203
  components.fontStyle = resolved.fontStyle;
204
204
  }
205
- if (resolved.fontVariant) {
205
+ if (resolved.fontVariant !== undefined && resolved.fontVariant !== '') {
206
206
  components.fontVariant = resolved.fontVariant;
207
207
  }
208
- if (resolved.fontWeight) {
208
+ if (resolved.fontWeight !== undefined && resolved.fontWeight !== '') {
209
209
  components.fontWeight = String(resolved.fontWeight);
210
210
  }
211
- if (resolved.fontSize) {
211
+ if (resolved.fontSize !== undefined && resolved.fontSize !== '') {
212
212
  const fontSize = typeof resolved.fontSize === 'number' ? `${resolved.fontSize}px` : resolved.fontSize;
213
213
  resolved.fontSize = fontSize;
214
214
  components.fontSize = fontSize;
@@ -302,7 +302,7 @@ export class Text extends Image {
302
302
  }
303
303
  this.canvas.height = height * this._res;
304
304
  this.context.scale(this._res, this._res);
305
- if (this.style.backgroundColor) {
305
+ if (this.style.backgroundColor !== null && this.style.backgroundColor !== '') {
306
306
  this.context.fillStyle = this.style.backgroundColor;
307
307
  this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
308
308
  }
@@ -384,16 +384,17 @@ export class Text extends Image {
384
384
  }
385
385
  }
386
386
  } else {
387
+ let cursor = x;
387
388
  for (const part of text) {
388
389
  const section = Math.ceil(this.context.measureText(part).width);
389
390
  // How far to the next tab?
390
- snap = snapToCeil(x, tabs);
391
+ snap = snapToCeil(cursor, tabs);
391
392
  if (fill) {
392
393
  this.context.fillText(part, snap, y);
393
394
  } else {
394
395
  this.context.strokeText(part, snap, y);
395
396
  }
396
- x = snap + section;
397
+ cursor = snap + section;
397
398
  }
398
399
  }
399
400
  }
@@ -441,24 +442,24 @@ export class Text extends Image {
441
442
  const components = this.fontToComponents(this.context.font);
442
443
  const charFontStyle = this.fontStyles[this._charCount];
443
444
  const charFontWeight = this.fontWeights[this._charCount];
444
- if (charFontStyle) {
445
+ if (charFontStyle !== undefined && charFontStyle !== null && charFontStyle !== '') {
445
446
  components.fontStyle = charFontStyle;
446
447
  }
447
- if (charFontWeight) {
448
+ if (charFontWeight !== undefined && charFontWeight !== null && charFontWeight !== '') {
448
449
  components.fontWeight = charFontWeight;
449
450
  }
450
451
  this.context.font = this.componentsToFont(components);
451
452
  }
452
453
  if (this.style.stroke && this.style.strokeThickness) {
453
454
  const charStrokeColor = this.strokeColors[this._charCount];
454
- if (charStrokeColor) {
455
+ if (charStrokeColor !== undefined && charStrokeColor !== null && charStrokeColor !== '') {
455
456
  this.context.strokeStyle = charStrokeColor;
456
457
  }
457
458
  this.updateShadow(this.style.shadowStroke ?? false);
458
459
  }
459
460
  if (this.style.fill) {
460
461
  const charFillColor = this.colors[this._charCount];
461
- if (charFillColor) {
462
+ if (charFillColor !== undefined && charFillColor !== null && charFillColor !== '') {
462
463
  this.context.fillStyle = charFillColor;
463
464
  }
464
465
  this.updateShadow(this.style.shadowFill ?? false);
@@ -476,36 +477,37 @@ export class Text extends Image {
476
477
  * @param {number} y - The y position to start updating from.
477
478
  */
478
479
  public updateLine(line: string, x: number, y: number): void {
480
+ let cursor = x;
479
481
  for (const letter of line) {
480
482
  if (this.fontWeights.length > 0 || this.fontStyles.length > 0) {
481
483
  const components = this.fontToComponents(this.context.font);
482
484
  const charFontStyle = this.fontStyles[this._charCount];
483
485
  const charFontWeight = this.fontWeights[this._charCount];
484
- if (charFontStyle) {
486
+ if (charFontStyle !== undefined && charFontStyle !== null && charFontStyle !== '') {
485
487
  components.fontStyle = charFontStyle;
486
488
  }
487
- if (charFontWeight) {
489
+ if (charFontWeight !== undefined && charFontWeight !== null && charFontWeight !== '') {
488
490
  components.fontWeight = charFontWeight;
489
491
  }
490
492
  this.context.font = this.componentsToFont(components);
491
493
  }
492
494
  if (this.style.stroke && this.style.strokeThickness) {
493
495
  const charStrokeColor = this.strokeColors[this._charCount];
494
- if (charStrokeColor) {
496
+ if (charStrokeColor !== undefined && charStrokeColor !== null && charStrokeColor !== '') {
495
497
  this.context.strokeStyle = charStrokeColor;
496
498
  }
497
499
  this.updateShadow(this.style.shadowStroke ?? false);
498
- this.context.strokeText(letter, x, y);
500
+ this.context.strokeText(letter, cursor, y);
499
501
  }
500
502
  if (this.style.fill) {
501
503
  const charFillColor = this.colors[this._charCount];
502
- if (charFillColor) {
504
+ if (charFillColor !== undefined && charFillColor !== null && charFillColor !== '') {
503
505
  this.context.fillStyle = charFillColor;
504
506
  }
505
507
  this.updateShadow(this.style.shadowFill ?? false);
506
- this.context.fillText(letter, x, y);
508
+ this.context.fillText(letter, cursor, y);
507
509
  }
508
- x += this.context.measureText(letter).width;
510
+ cursor += this.context.measureText(letter).width;
509
511
  this._charCount += 1;
510
512
  }
511
513
  }
@@ -778,31 +780,20 @@ export class Text extends Image {
778
780
  * @returns {string} The font string.
779
781
  */
780
782
  public componentsToFont(components: FontComponents): string {
781
- const parts = [];
782
- let v;
783
- v = components.fontStyle;
784
- if (v && v !== 'normal') {
785
- parts.push(v);
786
- }
787
- v = components.fontVariant;
788
- if (v && v !== 'normal') {
789
- parts.push(v);
790
- }
791
- v = components.fontWeight;
792
- if (v && v !== 'normal') {
793
- parts.push(v);
794
- }
795
- v = components.fontSize;
796
- if (v && v !== 'medium') {
797
- parts.push(v);
798
- }
799
- v = components.fontFamily;
800
- if (v) {
801
- parts.push(v);
802
- }
783
+ const parts: string[] = [];
784
+ const push = (value: string | number | undefined, skip: string): void => {
785
+ if (value !== undefined && value !== '' && value !== skip) {
786
+ parts.push(String(value));
787
+ }
788
+ };
789
+ push(components.fontStyle, 'normal');
790
+ push(components.fontVariant, 'normal');
791
+ push(components.fontWeight, 'normal');
792
+ push(components.fontSize, 'medium');
793
+ push(components.fontFamily, '');
803
794
  if (parts.length === 0) {
804
795
  // Fallback to whatever value the 'font' was
805
- parts.push(components.font);
796
+ parts.push(components.font ?? '');
806
797
  }
807
798
  return parts.join(' ');
808
799
  }
@@ -966,7 +957,7 @@ export class Text extends Image {
966
957
  * @returns {CanvasRenderingContext2D} The font properties canvas context.
967
958
  */
968
959
  public getFontPropertiesContext(): CanvasRenderingContext2D {
969
- if (!globalThis.PhaserRegistry.fontPropertiesContext) {
960
+ if (globalThis.PhaserRegistry.fontPropertiesContext === undefined) {
970
961
  const canvas = this.getFontPropertiesCanvas();
971
962
  const context = canvas.getContext('2d', { willReadFrequently: true });
972
963
  if (!context) {
@@ -1026,7 +1017,7 @@ export class Text extends Image {
1026
1017
  context.textBaseline = 'alphabetic';
1027
1018
  context.fillStyle = '#000';
1028
1019
  context.fillText('|MÉq', 0, baseline);
1029
- if (!context.getImageData(0, 0, width, height)) {
1020
+ if (context.getImageData(0, 0, width, height) === null) {
1030
1021
  const fallback: FontProperties = {
1031
1022
  ascent: baseline,
1032
1023
  descent: baseline + 6,
@@ -1169,7 +1160,7 @@ export class Text extends Image {
1169
1160
  if (typeof size === 'number') {
1170
1161
  return size;
1171
1162
  }
1172
- if (size && /(?:^0$|px$)/.exec(size)) {
1163
+ if (size !== undefined && size !== '' && /(?:^0$|px$)/.exec(size)) {
1173
1164
  // Number() cannot read the value here: the string carries a px suffix.
1174
1165
  // eslint-disable-next-line unicorn/prefer-number-coercion
1175
1166
  return Number.parseInt(size, 10);
@@ -27,7 +27,7 @@ export class AbstractFilter {
27
27
  this.dirty = true;
28
28
  this.padding = 0;
29
29
  this.uniforms = uniforms ?? {};
30
- this.fragmentSrc = fragmentSrc || [];
30
+ this.fragmentSrc = fragmentSrc;
31
31
  }
32
32
 
33
33
  /**