@vpmedia/phaser 1.123.0 → 1.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +339 -323
- package/dist/index.js.map +1 -1
- package/dist/phaser/core/animation.d.ts +3 -3
- package/dist/phaser/core/animation.d.ts.map +1 -1
- package/dist/phaser/core/animation_manager.d.ts.map +1 -1
- package/dist/phaser/core/animation_parser.d.ts +27 -2
- package/dist/phaser/core/animation_parser.d.ts.map +1 -1
- package/dist/phaser/core/array_set.d.ts +11 -11
- package/dist/phaser/core/array_set.d.ts.map +1 -1
- package/dist/phaser/core/cache.d.ts.map +1 -1
- package/dist/phaser/core/callback.d.ts.map +1 -1
- package/dist/phaser/core/dom.d.ts +125 -19
- package/dist/phaser/core/dom.d.ts.map +1 -1
- package/dist/phaser/core/factory.d.ts +3 -2
- package/dist/phaser/core/factory.d.ts.map +1 -1
- package/dist/phaser/core/input.d.ts +3 -2
- package/dist/phaser/core/input.d.ts.map +1 -1
- package/dist/phaser/core/input_handler.d.ts.map +1 -1
- package/dist/phaser/core/input_mouse.d.ts +5 -1
- package/dist/phaser/core/input_mouse.d.ts.map +1 -1
- package/dist/phaser/core/input_pointer.d.ts +3 -3
- package/dist/phaser/core/input_pointer.d.ts.map +1 -1
- package/dist/phaser/core/input_touch.d.ts +8 -8
- package/dist/phaser/core/input_touch.d.ts.map +1 -1
- package/dist/phaser/core/loader.d.ts +11 -2
- package/dist/phaser/core/loader.d.ts.map +1 -1
- package/dist/phaser/core/loader_parser.d.ts +14 -1
- package/dist/phaser/core/loader_parser.d.ts.map +1 -1
- package/dist/phaser/core/raf.d.ts +1 -1
- package/dist/phaser/core/raf.d.ts.map +1 -1
- package/dist/phaser/core/scale_manager.d.ts.map +1 -1
- package/dist/phaser/core/scene_manager.d.ts.map +1 -1
- package/dist/phaser/core/signal.d.ts.map +1 -1
- package/dist/phaser/core/sound.d.ts.map +1 -1
- package/dist/phaser/core/sound_manager.d.ts +1 -1
- package/dist/phaser/core/sound_manager.d.ts.map +1 -1
- package/dist/phaser/core/stage.d.ts +16 -6
- package/dist/phaser/core/stage.d.ts.map +1 -1
- package/dist/phaser/core/time.d.ts.map +1 -1
- package/dist/phaser/core/timer.d.ts +1 -1
- package/dist/phaser/core/timer.d.ts.map +1 -1
- package/dist/phaser/core/tween.d.ts +13 -5
- package/dist/phaser/core/tween.d.ts.map +1 -1
- package/dist/phaser/core/tween_data.d.ts +9 -7
- package/dist/phaser/core/tween_data.d.ts.map +1 -1
- package/dist/phaser/core/tween_manager.d.ts.map +1 -1
- package/dist/phaser/display/button.d.ts +6 -5
- package/dist/phaser/display/button.d.ts.map +1 -1
- package/dist/phaser/display/canvas/buffer.d.ts +1 -1
- package/dist/phaser/display/canvas/buffer.d.ts.map +1 -1
- package/dist/phaser/display/canvas/masker.d.ts +1 -1
- package/dist/phaser/display/canvas/masker.d.ts.map +1 -1
- package/dist/phaser/display/canvas/pool.d.ts +2 -2
- package/dist/phaser/display/canvas/pool.d.ts.map +1 -1
- package/dist/phaser/display/canvas/renderer.d.ts +9 -8
- package/dist/phaser/display/canvas/renderer.d.ts.map +1 -1
- package/dist/phaser/display/display_object.d.ts +3 -1
- package/dist/phaser/display/display_object.d.ts.map +1 -1
- package/dist/phaser/display/graphics.d.ts +1 -1
- package/dist/phaser/display/graphics.d.ts.map +1 -1
- package/dist/phaser/display/group.d.ts +1 -1
- package/dist/phaser/display/group.d.ts.map +1 -1
- package/dist/phaser/display/image.d.ts +6 -5
- package/dist/phaser/display/image.d.ts.map +1 -1
- package/dist/phaser/display/sprite_util.d.ts +3 -2
- package/dist/phaser/display/sprite_util.d.ts.map +1 -1
- package/dist/phaser/display/text.d.ts +2 -16
- package/dist/phaser/display/text.d.ts.map +1 -1
- package/dist/phaser/display/webgl/abstract_filter.d.ts +14 -8
- package/dist/phaser/display/webgl/abstract_filter.d.ts.map +1 -1
- package/dist/phaser/display/webgl/blend_manager.d.ts +2 -3
- package/dist/phaser/display/webgl/blend_manager.d.ts.map +1 -1
- package/dist/phaser/display/webgl/fast_sprite_batch.d.ts +11 -5
- package/dist/phaser/display/webgl/fast_sprite_batch.d.ts.map +1 -1
- package/dist/phaser/display/webgl/filter_manager.d.ts +6 -4
- package/dist/phaser/display/webgl/filter_manager.d.ts.map +1 -1
- package/dist/phaser/display/webgl/filter_texture.d.ts +4 -4
- package/dist/phaser/display/webgl/filter_texture.d.ts.map +1 -1
- package/dist/phaser/display/webgl/graphics.d.ts +2 -2
- package/dist/phaser/display/webgl/graphics.d.ts.map +1 -1
- package/dist/phaser/display/webgl/mask_manager.d.ts +3 -2
- package/dist/phaser/display/webgl/mask_manager.d.ts.map +1 -1
- package/dist/phaser/display/webgl/render_texture.d.ts +11 -8
- package/dist/phaser/display/webgl/render_texture.d.ts.map +1 -1
- package/dist/phaser/display/webgl/renderer.d.ts +8 -4
- package/dist/phaser/display/webgl/renderer.d.ts.map +1 -1
- package/dist/phaser/display/webgl/shader/normal.d.ts +28 -3
- package/dist/phaser/display/webgl/shader/normal.d.ts.map +1 -1
- package/dist/phaser/display/webgl/sprite_batch.d.ts +6 -5
- package/dist/phaser/display/webgl/sprite_batch.d.ts.map +1 -1
- package/dist/phaser/display/webgl/stencil_manager.d.ts +3 -3
- package/dist/phaser/display/webgl/stencil_manager.d.ts.map +1 -1
- package/dist/phaser/display/webgl/texture_util.d.ts +2 -2
- package/dist/phaser/display/webgl/texture_util.d.ts.map +1 -1
- package/dist/phaser/display/webgl/util.d.ts +1 -1
- package/dist/phaser/display/webgl/util.d.ts.map +1 -1
- package/dist/phaser/geom/circle.d.ts.map +1 -1
- package/dist/phaser/geom/line.d.ts +10 -1
- package/dist/phaser/geom/line.d.ts.map +1 -1
- package/dist/phaser/geom/rectangle.d.ts.map +1 -1
- package/dist/phaser/geom/util/circle.d.ts +2 -1
- package/dist/phaser/geom/util/circle.d.ts.map +1 -1
- package/dist/phaser/geom/util/point.d.ts +1 -1
- package/dist/phaser/geom/util/point.d.ts.map +1 -1
- package/dist/phaser/geom/util/rectangle.d.ts +1 -1
- package/dist/phaser/geom/util/rectangle.d.ts.map +1 -1
- package/dist/phaser/util/math.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/phaser/core/animation.ts +4 -4
- package/src/phaser/core/animation_manager.ts +10 -10
- package/src/phaser/core/animation_parser.ts +30 -24
- package/src/phaser/core/array_set.ts +27 -27
- package/src/phaser/core/cache.test.ts +33 -33
- package/src/phaser/core/cache.ts +3 -3
- package/src/phaser/core/callback.ts +1 -0
- package/src/phaser/core/callback_context.test.ts +8 -8
- package/src/phaser/core/dom.ts +15 -5
- package/src/phaser/core/factory.ts +9 -2
- package/src/phaser/core/frame_data.test.ts +23 -23
- package/src/phaser/core/input.ts +9 -8
- package/src/phaser/core/input_handler.test.ts +18 -18
- package/src/phaser/core/input_handler.ts +1 -1
- package/src/phaser/core/input_mouse.ts +9 -8
- package/src/phaser/core/input_pointer.test.ts +26 -26
- package/src/phaser/core/input_pointer.ts +3 -3
- package/src/phaser/core/input_touch.ts +8 -8
- package/src/phaser/core/loader.test.ts +26 -26
- package/src/phaser/core/loader.ts +25 -25
- package/src/phaser/core/loader_parser.test.ts +16 -16
- package/src/phaser/core/loader_parser.ts +16 -6
- package/src/phaser/core/raf.ts +1 -1
- package/src/phaser/core/registry.test.ts +6 -6
- package/src/phaser/core/scale_manager.ts +2 -2
- package/src/phaser/core/scene_manager.test.ts +30 -30
- package/src/phaser/core/scene_manager.ts +1 -1
- package/src/phaser/core/signal.test.ts +8 -8
- package/src/phaser/core/signal.ts +1 -1
- package/src/phaser/core/signal_dispatch.test.ts +30 -30
- package/src/phaser/core/sound.ts +20 -8
- package/src/phaser/core/sound_manager.ts +6 -6
- package/src/phaser/core/stage.ts +19 -9
- package/src/phaser/core/time.ts +1 -1
- package/src/phaser/core/timer.test.ts +47 -47
- package/src/phaser/core/timer.ts +1 -1
- package/src/phaser/core/tween.ts +28 -25
- package/src/phaser/core/tween_data.test.ts +119 -0
- package/src/phaser/core/tween_data.ts +54 -39
- package/src/phaser/core/tween_easing.test.ts +5 -5
- package/src/phaser/core/tween_manager.ts +2 -2
- package/src/phaser/display/bitmap_text.test.ts +30 -30
- package/src/phaser/display/button.ts +8 -6
- package/src/phaser/display/canvas/buffer.ts +2 -2
- package/src/phaser/display/canvas/masker.ts +1 -1
- package/src/phaser/display/canvas/pool.test.ts +20 -20
- package/src/phaser/display/canvas/pool.ts +3 -3
- package/src/phaser/display/canvas/renderer.ts +12 -11
- package/src/phaser/display/canvas/util.test.ts +25 -25
- package/src/phaser/display/display_object.ts +3 -1
- package/src/phaser/display/graphics.test.ts +70 -20
- package/src/phaser/display/graphics.ts +38 -32
- package/src/phaser/display/group.ts +4 -4
- package/src/phaser/display/image.ts +28 -25
- package/src/phaser/display/sprite_util.ts +3 -2
- package/src/phaser/display/text.test.ts +28 -25
- package/src/phaser/display/text.ts +21 -18
- package/src/phaser/display/webgl/abstract_filter.ts +20 -10
- package/src/phaser/display/webgl/blend_manager.ts +4 -5
- package/src/phaser/display/webgl/earcut.test.ts +20 -20
- package/src/phaser/display/webgl/fast_sprite_batch.ts +21 -16
- package/src/phaser/display/webgl/filter_manager.ts +7 -4
- package/src/phaser/display/webgl/filter_texture.ts +5 -5
- package/src/phaser/display/webgl/graphics.ts +2 -2
- package/src/phaser/display/webgl/mask_manager.ts +9 -14
- package/src/phaser/display/webgl/render_texture.ts +15 -14
- package/src/phaser/display/webgl/renderer.ts +7 -6
- package/src/phaser/display/webgl/shader/normal.ts +41 -31
- package/src/phaser/display/webgl/shader/shader.test.ts +24 -24
- package/src/phaser/display/webgl/shader_manager.test.ts +18 -18
- package/src/phaser/display/webgl/sprite_batch.ts +8 -8
- package/src/phaser/display/webgl/stencil_manager.ts +4 -4
- package/src/phaser/display/webgl/texture_util.ts +2 -2
- package/src/phaser/display/webgl/util.ts +1 -1
- package/src/phaser/geom/circle.test.ts +38 -38
- package/src/phaser/geom/circle.ts +7 -7
- package/src/phaser/geom/ellipse.test.ts +12 -12
- package/src/phaser/geom/line.test.ts +15 -15
- package/src/phaser/geom/line.ts +5 -2
- package/src/phaser/geom/matrix.test.ts +31 -31
- package/src/phaser/geom/point.test.ts +31 -31
- package/src/phaser/geom/polygon.test.ts +27 -27
- package/src/phaser/geom/rectangle.test.ts +87 -87
- package/src/phaser/geom/rectangle.ts +11 -11
- package/src/phaser/geom/rounded_rectangle.test.ts +9 -9
- package/src/phaser/geom/util/circle.test.ts +5 -5
- package/src/phaser/geom/util/circle.ts +2 -1
- package/src/phaser/geom/util/ellipse.test.ts +2 -2
- package/src/phaser/geom/util/line.test.ts +2 -2
- package/src/phaser/geom/util/matrix.test.ts +4 -4
- package/src/phaser/geom/util/point.test.ts +2 -2
- package/src/phaser/geom/util/point.ts +1 -1
- package/src/phaser/geom/util/polygon.test.ts +2 -2
- package/src/phaser/geom/util/rectangle.test.ts +2 -2
- package/src/phaser/geom/util/rectangle.ts +1 -1
- package/src/phaser/geom/util/rounded_rectangle.test.ts +2 -2
- package/src/phaser/util/math.test.ts +41 -41
- package/src/phaser/util/math.ts +5 -2
package/src/phaser/core/tween.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { TweenData } from './tween_data.js';
|
|
|
6
6
|
import type { Game } from './game.js';
|
|
7
7
|
import type { TweenManager } from './tween_manager.js';
|
|
8
8
|
import type { AppliedCallback, Callback, EasingFunction, InterpolationFunction } from './callback.js';
|
|
9
|
+
import type { TweenValues } from './tween_data.js';
|
|
9
10
|
|
|
10
11
|
export class Tween {
|
|
11
12
|
public game!: Game;
|
|
@@ -23,7 +24,7 @@ export class Tween {
|
|
|
23
24
|
public onComplete!: Signal;
|
|
24
25
|
public isRunning!: boolean;
|
|
25
26
|
public current!: number;
|
|
26
|
-
public properties!:
|
|
27
|
+
public properties!: TweenValues;
|
|
27
28
|
public chainedTween!: Tween | null;
|
|
28
29
|
public isPaused!: boolean;
|
|
29
30
|
public _onUpdateCallback!: Callback | null;
|
|
@@ -92,7 +93,7 @@ export class Tween {
|
|
|
92
93
|
* @returns {Tween} This Tween object for chaining.
|
|
93
94
|
*/
|
|
94
95
|
public to(
|
|
95
|
-
properties:
|
|
96
|
+
properties: TweenValues,
|
|
96
97
|
duration = 1000,
|
|
97
98
|
ease: string | EasingFunction = 'Linear',
|
|
98
99
|
autoStart = false,
|
|
@@ -100,13 +101,11 @@ export class Tween {
|
|
|
100
101
|
repeat = 0,
|
|
101
102
|
yoyo = false
|
|
102
103
|
): this {
|
|
103
|
-
|
|
104
|
-
ease = this.manager.easeMap[ease]!;
|
|
105
|
-
}
|
|
104
|
+
const easing = this.resolveEasing(ease);
|
|
106
105
|
if (this.isRunning) {
|
|
107
106
|
return this;
|
|
108
107
|
}
|
|
109
|
-
this.timeline.push(new TweenData(this).to(properties, duration,
|
|
108
|
+
this.timeline.push(new TweenData(this).to(properties, duration, easing, delay, repeat, yoyo));
|
|
110
109
|
if (autoStart) {
|
|
111
110
|
this.start();
|
|
112
111
|
}
|
|
@@ -125,7 +124,7 @@ export class Tween {
|
|
|
125
124
|
* @returns {Tween} This Tween object for chaining.
|
|
126
125
|
*/
|
|
127
126
|
public from(
|
|
128
|
-
properties:
|
|
127
|
+
properties: TweenValues,
|
|
129
128
|
duration = 1000,
|
|
130
129
|
ease: string | EasingFunction = 'Linear',
|
|
131
130
|
autoStart = false,
|
|
@@ -133,14 +132,11 @@ export class Tween {
|
|
|
133
132
|
repeat = 0,
|
|
134
133
|
yoyo = false
|
|
135
134
|
): this {
|
|
136
|
-
if (typeof ease === 'string' && this.manager.easeMap[ease]) {
|
|
137
|
-
ease = this.manager.easeMap[ease]!;
|
|
138
|
-
}
|
|
139
135
|
if (this.isRunning) {
|
|
140
136
|
this.game.logger.warn('Tween.from cannot be called after Tween.start');
|
|
141
137
|
return this;
|
|
142
138
|
}
|
|
143
|
-
this.timeline.push(new TweenData(this).from(properties, duration, ease, delay, repeat, yoyo));
|
|
139
|
+
this.timeline.push(new TweenData(this).from(properties, duration, this.resolveEasing(ease), delay, repeat, yoyo));
|
|
144
140
|
if (autoStart) {
|
|
145
141
|
this.start();
|
|
146
142
|
}
|
|
@@ -161,12 +157,9 @@ export class Tween {
|
|
|
161
157
|
// Build our master property list with the starting values
|
|
162
158
|
const keys = Object.keys(tweenData.vEnd);
|
|
163
159
|
for (const property of keys) {
|
|
164
|
-
const targetProperties = this.target as unknown as Record<string, number>;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
// Ensures we're using numbers, not strings
|
|
168
|
-
this.properties[property] *= 1;
|
|
169
|
-
}
|
|
160
|
+
const targetProperties = this.target as unknown as Record<string, number | string | undefined>;
|
|
161
|
+
// Ensures we're using numbers, not strings
|
|
162
|
+
this.properties[property] = Number(targetProperties[property] ?? 0);
|
|
170
163
|
}
|
|
171
164
|
}
|
|
172
165
|
for (const tweenData of this.timeline) {
|
|
@@ -209,7 +202,7 @@ export class Tween {
|
|
|
209
202
|
* @param {number} index - The index in the timeline to update.
|
|
210
203
|
* @returns {Tween} This Tween object for chaining.
|
|
211
204
|
*/
|
|
212
|
-
public updateTweenData(property: string, value:
|
|
205
|
+
public updateTweenData(property: string, value: unknown, index = 0): this {
|
|
213
206
|
if (this.timeline.length === 0) {
|
|
214
207
|
return this;
|
|
215
208
|
}
|
|
@@ -283,6 +276,19 @@ export class Tween {
|
|
|
283
276
|
* @param {number} index - The index in the timeline to apply easing to.
|
|
284
277
|
* @returns {Tween} This Tween object for chaining.
|
|
285
278
|
*/
|
|
279
|
+
public resolveEasing(ease: string | EasingFunction): EasingFunction {
|
|
280
|
+
if (typeof ease !== 'string') {
|
|
281
|
+
return ease;
|
|
282
|
+
}
|
|
283
|
+
return this.manager.easeMap[ease] ?? this.manager.easeMap['Linear']!;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Sets the easing function for a tween in the timeline.
|
|
288
|
+
* @param {string | Function} ease - The easing function or its name.
|
|
289
|
+
* @param {number} index - The index of the tween in the timeline.
|
|
290
|
+
* @returns {Tween} This Tween object for chaining.
|
|
291
|
+
*/
|
|
286
292
|
public easing(ease: string | EasingFunction, index: number): this {
|
|
287
293
|
if (typeof ease === 'string' && this.manager.easeMap[ease]) {
|
|
288
294
|
ease = this.manager.easeMap[ease]!;
|
|
@@ -484,7 +490,7 @@ export class Tween {
|
|
|
484
490
|
* @param {object[]} data - The array to store the generated data in.
|
|
485
491
|
* @returns {object[]} The populated data array.
|
|
486
492
|
*/
|
|
487
|
-
public generateData(frameRate = 60, data:
|
|
493
|
+
public generateData(frameRate = 60, data: Record<string, number>[] = []): Record<string, number>[] | null {
|
|
488
494
|
if (this.game === null || this.target === null) {
|
|
489
495
|
return null;
|
|
490
496
|
}
|
|
@@ -493,12 +499,9 @@ export class Tween {
|
|
|
493
499
|
// Build our master property list with the starting values
|
|
494
500
|
const keys = Object.keys(tweenData.vEnd);
|
|
495
501
|
for (const property of keys) {
|
|
496
|
-
const targetProperties = this.target as unknown as Record<string, number>;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
// Ensures we're using numbers, not strings
|
|
500
|
-
this.properties[property] *= 1;
|
|
501
|
-
}
|
|
502
|
+
const targetProperties = this.target as unknown as Record<string, number | string | undefined>;
|
|
503
|
+
// Ensures we're using numbers, not strings
|
|
504
|
+
this.properties[property] = Number(targetProperties[property] ?? 0);
|
|
502
505
|
}
|
|
503
506
|
}
|
|
504
507
|
for (const tweenData of this.timeline) {
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { TWEEN_COMPLETE, TWEEN_RUNNING } from './const.js';
|
|
3
|
+
import { Signal } from './signal.js';
|
|
4
|
+
import { Tween } from './tween.js';
|
|
5
|
+
import { TweenManager } from './tween_manager.js';
|
|
6
|
+
import type { Game } from './game.js';
|
|
7
|
+
|
|
8
|
+
const createGame = (): Game =>
|
|
9
|
+
({
|
|
10
|
+
time: { time: 0, elapsedMS: 0 },
|
|
11
|
+
logger: { warn: (): void => undefined },
|
|
12
|
+
onPause: new Signal(),
|
|
13
|
+
onResume: new Signal(),
|
|
14
|
+
}) as unknown as Game;
|
|
15
|
+
|
|
16
|
+
const createTween = (target: Record<string, number>): { game: Game; tween: Tween } => {
|
|
17
|
+
const game = createGame();
|
|
18
|
+
const manager = new TweenManager(game);
|
|
19
|
+
return { game, tween: new Tween(target, game, manager) };
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const advance = (game: Game, tween: Tween, ms: number): void => {
|
|
23
|
+
game.time.time += ms;
|
|
24
|
+
game.time.elapsedMS = ms;
|
|
25
|
+
tween.update(game.time.time);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe('TweenData', (): void => {
|
|
29
|
+
describe('resolveEasing', (): void => {
|
|
30
|
+
it('takes a function as-is', (): void => {
|
|
31
|
+
const { tween } = createTween({ x: 0 });
|
|
32
|
+
const ease = (k: number): number => k * k;
|
|
33
|
+
expect(tween.resolveEasing(ease)).toBe(ease);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('looks a named curve up in the manager', (): void => {
|
|
37
|
+
const { tween } = createTween({ x: 0 });
|
|
38
|
+
expect(tween.resolveEasing('Quad.easeIn')).toBe(tween.manager.easeMap['Quad.easeIn']);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('falls back to linear for a name the manager does not know', (): void => {
|
|
42
|
+
const { tween } = createTween({ x: 0 });
|
|
43
|
+
expect(tween.resolveEasing('No.Such.Curve')).toBe(tween.manager.easeMap['Linear']);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('to', (): void => {
|
|
48
|
+
it('drives a numeric property from its start value to the end value', (): void => {
|
|
49
|
+
const target = { x: 0 };
|
|
50
|
+
const { game, tween } = createTween(target);
|
|
51
|
+
tween.to({ x: 100 }, 100, 'Linear', true);
|
|
52
|
+
advance(game, tween, 50);
|
|
53
|
+
expect(target.x).toBeCloseTo(50);
|
|
54
|
+
advance(game, tween, 50);
|
|
55
|
+
expect(target.x).toBeCloseTo(100);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('reads a relative end value against the start', (): void => {
|
|
59
|
+
const target = { x: 20 };
|
|
60
|
+
const { game, tween } = createTween(target);
|
|
61
|
+
tween.to({ x: '+10' }, 100, 'Linear', true);
|
|
62
|
+
advance(game, tween, 100);
|
|
63
|
+
expect(target.x).toBeCloseTo(30);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('interpolates through a list of waypoints', (): void => {
|
|
67
|
+
const target = { x: 0 };
|
|
68
|
+
const { game, tween } = createTween(target);
|
|
69
|
+
tween.to({ x: [0, 50, 100] }, 100, 'Linear', true);
|
|
70
|
+
advance(game, tween, 100);
|
|
71
|
+
expect(target.x).toBeCloseTo(100);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// An empty waypoint list has nothing to interpolate between, so the property goes to NaN.
|
|
75
|
+
it('survives an empty waypoint list', (): void => {
|
|
76
|
+
const target = { x: 7 };
|
|
77
|
+
const { game, tween } = createTween(target);
|
|
78
|
+
tween.to({ x: [] }, 100, 'Linear', true);
|
|
79
|
+
expect((): void => {
|
|
80
|
+
advance(game, tween, 100);
|
|
81
|
+
}).not.toThrow();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('reports the tween running until the duration has passed', (): void => {
|
|
85
|
+
const target = { x: 0 };
|
|
86
|
+
const { game, tween } = createTween(target);
|
|
87
|
+
tween.to({ x: 10 }, 100, 'Linear', true);
|
|
88
|
+
game.time.time += 50;
|
|
89
|
+
game.time.elapsedMS = 50;
|
|
90
|
+
expect(tween.timeline[0]?.update(game.time.time)).toBe(TWEEN_RUNNING);
|
|
91
|
+
game.time.time += 100;
|
|
92
|
+
game.time.elapsedMS = 100;
|
|
93
|
+
expect(tween.timeline[0]?.update(game.time.time)).toBe(TWEEN_COMPLETE);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('from', (): void => {
|
|
98
|
+
it('starts at the given value and lands on the target original', (): void => {
|
|
99
|
+
const target = { x: 100 };
|
|
100
|
+
const { game, tween } = createTween(target);
|
|
101
|
+
tween.from({ x: 0 }, 100, 'Linear', true);
|
|
102
|
+
advance(game, tween, 0);
|
|
103
|
+
expect(target.x).toBeCloseTo(0);
|
|
104
|
+
advance(game, tween, 100);
|
|
105
|
+
expect(target.x).toBeCloseTo(100);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
describe('generateData', (): void => {
|
|
110
|
+
it('produces one frame of values per step', (): void => {
|
|
111
|
+
const { tween } = createTween({ x: 0 });
|
|
112
|
+
tween.to({ x: 100 }, 100, 'Linear');
|
|
113
|
+
tween.start();
|
|
114
|
+
const data = tween.generateData(10) ?? [];
|
|
115
|
+
expect(data.length).toBeGreaterThan(0);
|
|
116
|
+
expect(data.at(-1)?.['x']).toBeCloseTo(100);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -2,15 +2,18 @@ import type { Game } from './game.js';
|
|
|
2
2
|
import * as MathUtils from '../util/math.js';
|
|
3
3
|
import { TWEEN_COMPLETE, TWEEN_LOOPED, TWEEN_PENDING, TWEEN_RUNNING } from './const.js';
|
|
4
4
|
import type { Tween } from './tween.js';
|
|
5
|
-
import type { InterpolationFunction } from './callback.js';
|
|
5
|
+
import type { EasingFunction, InterpolationFunction } from './callback.js';
|
|
6
|
+
|
|
7
|
+
/** The properties a tween drives, each holding either a single target or a list of waypoints. */
|
|
8
|
+
export type TweenValues = Record<string, number | number[] | string>;
|
|
6
9
|
|
|
7
10
|
export class TweenData {
|
|
8
11
|
public parent!: Tween;
|
|
9
12
|
public game!: Game;
|
|
10
|
-
public vStart!:
|
|
11
|
-
public vStartCache!:
|
|
12
|
-
public vEnd!:
|
|
13
|
-
public vEndCache!:
|
|
13
|
+
public vStart!: TweenValues;
|
|
14
|
+
public vStartCache!: TweenValues;
|
|
15
|
+
public vEnd!: TweenValues;
|
|
16
|
+
public vEndCache!: TweenValues;
|
|
14
17
|
public duration!: number;
|
|
15
18
|
public percent!: number;
|
|
16
19
|
public value!: number;
|
|
@@ -71,7 +74,14 @@ export class TweenData {
|
|
|
71
74
|
* @param {boolean} yoyo - Whether to reverse the tween on each repeat.
|
|
72
75
|
* @returns {TweenData} This TweenData object for chaining.
|
|
73
76
|
*/
|
|
74
|
-
public to(
|
|
77
|
+
public to(
|
|
78
|
+
properties: TweenValues,
|
|
79
|
+
duration: number,
|
|
80
|
+
ease: EasingFunction,
|
|
81
|
+
delay: number,
|
|
82
|
+
repeat: number,
|
|
83
|
+
yoyo: boolean
|
|
84
|
+
): this {
|
|
75
85
|
this.vEnd = properties;
|
|
76
86
|
this.duration = duration;
|
|
77
87
|
this.easingFunction = ease;
|
|
@@ -92,7 +102,14 @@ export class TweenData {
|
|
|
92
102
|
* @param {boolean} yoyo - Whether to reverse the tween on each repeat.
|
|
93
103
|
* @returns {TweenData} This TweenData object for chaining.
|
|
94
104
|
*/
|
|
95
|
-
public from(
|
|
105
|
+
public from(
|
|
106
|
+
properties: TweenValues,
|
|
107
|
+
duration: number,
|
|
108
|
+
ease: EasingFunction,
|
|
109
|
+
delay: number,
|
|
110
|
+
repeat: number,
|
|
111
|
+
yoyo: boolean
|
|
112
|
+
): this {
|
|
96
113
|
this.vEnd = properties;
|
|
97
114
|
this.duration = duration;
|
|
98
115
|
this.easingFunction = ease;
|
|
@@ -115,9 +132,9 @@ export class TweenData {
|
|
|
115
132
|
// Reverse them all and instant set them
|
|
116
133
|
const keys = Object.keys(this.vStartCache);
|
|
117
134
|
for (const property of keys) {
|
|
118
|
-
this.vStart[property] = this.vEndCache[property]
|
|
119
|
-
this.vEnd[property] = this.vStartCache[property]
|
|
120
|
-
(this.parent.target as unknown as Record<string,
|
|
135
|
+
this.vStart[property] = this.vEndCache[property]!;
|
|
136
|
+
this.vEnd[property] = this.vStartCache[property]!;
|
|
137
|
+
(this.parent.target as unknown as Record<string, unknown>)[property] = this.vStart[property];
|
|
121
138
|
}
|
|
122
139
|
}
|
|
123
140
|
this.value = 0;
|
|
@@ -134,29 +151,27 @@ export class TweenData {
|
|
|
134
151
|
const keys = Object.keys(this.parent.properties);
|
|
135
152
|
for (const property of keys) {
|
|
136
153
|
// Load the property from the parent object
|
|
137
|
-
|
|
154
|
+
const start = this.parent.properties[property]!;
|
|
155
|
+
this.vStart[property] = start;
|
|
138
156
|
// Check if an Array was provided as property value
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// but we only want to do this once, if the Tween hasn't run before
|
|
145
|
-
this.vEnd[property] = [this.vStart[property], ...this.vEnd[property]];
|
|
146
|
-
}
|
|
157
|
+
const end = this.vEnd[property];
|
|
158
|
+
if (Array.isArray(end) && end.length > 0 && this.percent === 0) {
|
|
159
|
+
// Put the start value at the beginning of the array
|
|
160
|
+
// but we only want to do this once, if the Tween hasn't run before
|
|
161
|
+
this.vEnd[property] = [Number(start), ...end];
|
|
147
162
|
}
|
|
148
|
-
if (
|
|
149
|
-
|
|
163
|
+
if (end === undefined) {
|
|
164
|
+
// Null tween
|
|
165
|
+
this.vEnd[property] = start;
|
|
166
|
+
} else {
|
|
167
|
+
if (typeof end === 'string') {
|
|
150
168
|
// Parses relative end values with start as base (e.g.: +10, -3)
|
|
151
|
-
this.vEnd[property] =
|
|
169
|
+
this.vEnd[property] = Number(start) + Number(end);
|
|
152
170
|
}
|
|
153
|
-
this.parent.properties[property] = this.vEnd[property]
|
|
154
|
-
} else {
|
|
155
|
-
// Null tween
|
|
156
|
-
this.vEnd[property] = this.vStart[property];
|
|
171
|
+
this.parent.properties[property] = this.vEnd[property]!;
|
|
157
172
|
}
|
|
158
|
-
this.vStartCache[property] = this.vStart[property]
|
|
159
|
-
this.vEndCache[property] = this.vEnd[property]
|
|
173
|
+
this.vStartCache[property] = this.vStart[property]!;
|
|
174
|
+
this.vEndCache[property] = this.vEnd[property]!;
|
|
160
175
|
}
|
|
161
176
|
return this;
|
|
162
177
|
}
|
|
@@ -189,11 +204,11 @@ export class TweenData {
|
|
|
189
204
|
this.value = this.easingFunction(this.percent);
|
|
190
205
|
const keys = Object.keys(this.vEnd);
|
|
191
206
|
for (const property of keys) {
|
|
192
|
-
const start = this.vStart[property];
|
|
193
207
|
const end = this.vEnd[property];
|
|
194
|
-
(this.
|
|
208
|
+
const start = Number(this.vStart[property]);
|
|
209
|
+
(this.parent.target as unknown as Record<string, unknown>)[property] = Array.isArray(end)
|
|
195
210
|
? this.interpolationFunction.call(this.interpolationContext, end, this.value)
|
|
196
|
-
: start + (end - start) * this.value;
|
|
211
|
+
: start + (Number(end) - start) * this.value;
|
|
197
212
|
}
|
|
198
213
|
if ((!this.parent.reverse && this.percent === 1) || (this.parent.reverse && this.percent === 0)) {
|
|
199
214
|
return this.repeat();
|
|
@@ -224,11 +239,11 @@ export class TweenData {
|
|
|
224
239
|
const blob: Record<string, number> = {};
|
|
225
240
|
const keys = Object.keys(this.vEnd);
|
|
226
241
|
for (const property of keys) {
|
|
227
|
-
const start = this.vStart[property];
|
|
228
242
|
const end = this.vEnd[property];
|
|
243
|
+
const start = Number(this.vStart[property]);
|
|
229
244
|
blob[property] = Array.isArray(end)
|
|
230
245
|
? this.interpolationFunction(end, this.value)
|
|
231
|
-
: start + (end - start) * this.value;
|
|
246
|
+
: start + (Number(end) - start) * this.value;
|
|
232
247
|
}
|
|
233
248
|
data.push(blob);
|
|
234
249
|
if ((!this.parent.reverse && this.percent === 1) || (this.parent.reverse && this.percent === 0)) {
|
|
@@ -253,8 +268,8 @@ export class TweenData {
|
|
|
253
268
|
// Restore the properties
|
|
254
269
|
const keys = Object.keys(this.vStartCache);
|
|
255
270
|
for (const property of keys) {
|
|
256
|
-
this.vStart[property] = this.vStartCache[property]
|
|
257
|
-
this.vEnd[property] = this.vEndCache[property]
|
|
271
|
+
this.vStart[property] = this.vStartCache[property]!;
|
|
272
|
+
this.vEnd[property] = this.vEndCache[property]!;
|
|
258
273
|
}
|
|
259
274
|
this.inReverse = false;
|
|
260
275
|
return TWEEN_COMPLETE;
|
|
@@ -267,15 +282,15 @@ export class TweenData {
|
|
|
267
282
|
// If inReverse we're going from vEnd to vStartCache
|
|
268
283
|
const keys = Object.keys(this.vStartCache);
|
|
269
284
|
for (const property of keys) {
|
|
270
|
-
this.vStart[property] = this.vEndCache[property]
|
|
271
|
-
this.vEnd[property] = this.vStartCache[property]
|
|
285
|
+
this.vStart[property] = this.vEndCache[property]!;
|
|
286
|
+
this.vEnd[property] = this.vStartCache[property]!;
|
|
272
287
|
}
|
|
273
288
|
} else {
|
|
274
289
|
// If not inReverse we're just repopulating the cache again
|
|
275
290
|
const keys = Object.keys(this.vStartCache);
|
|
276
291
|
for (const property of keys) {
|
|
277
|
-
this.vStart[property] = this.vStartCache[property]
|
|
278
|
-
this.vEnd[property] = this.vEndCache[property]
|
|
292
|
+
this.vStart[property] = this.vStartCache[property]!;
|
|
293
|
+
this.vEnd[property] = this.vEndCache[property]!;
|
|
279
294
|
}
|
|
280
295
|
// -1 means repeat forever, otherwise decrement the repeatCounter
|
|
281
296
|
// We only decrement this counter if the tween isn't doing a yoyo, as that doesn't count towards the repeat total
|
|
@@ -82,22 +82,22 @@ const EXPECTED: Record<string, number[]> = {
|
|
|
82
82
|
],
|
|
83
83
|
};
|
|
84
84
|
|
|
85
|
-
describe('tween_easing', () => {
|
|
86
|
-
it.each(Object.keys(EXPECTED))('%s matches its reference curve', (name) => {
|
|
85
|
+
describe('tween_easing', (): void => {
|
|
86
|
+
it.each(Object.keys(EXPECTED))('%s matches its reference curve', (name): void => {
|
|
87
87
|
const fn = (Easing as unknown as Record<string, (k: number) => number>)[name]!;
|
|
88
|
-
const actual = SAMPLE_POINTS.map((k) => fn(k));
|
|
88
|
+
const actual = SAMPLE_POINTS.map((k): number => fn(k));
|
|
89
89
|
for (const [index, value] of actual.entries()) {
|
|
90
90
|
expect(value).toBeCloseTo(EXPECTED[name]![index]!, 12);
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
it.each(Object.keys(EXPECTED))('%s is anchored at both ends', (name) => {
|
|
94
|
+
it.each(Object.keys(EXPECTED))('%s is anchored at both ends', (name): void => {
|
|
95
95
|
const fn = (Easing as unknown as Record<string, (k: number) => number>)[name]!;
|
|
96
96
|
expect(fn(0)).toBeCloseTo(0, 12);
|
|
97
97
|
expect(fn(1)).toBeCloseTo(1, 12);
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
it.each(Object.keys(EXPECTED))('%s does not mutate beyond its return value', (name) => {
|
|
100
|
+
it.each(Object.keys(EXPECTED))('%s does not mutate beyond its return value', (name): void => {
|
|
101
101
|
const fn = (Easing as unknown as Record<string, (k: number) => number>)[name]!;
|
|
102
102
|
for (const k of SAMPLE_POINTS) {
|
|
103
103
|
expect(fn(k)).toBe(fn(k));
|
|
@@ -106,7 +106,7 @@ export class TweenManager {
|
|
|
106
106
|
* Get all tweens managed by this manager.
|
|
107
107
|
* @returns {Tween[]} An array of all active tweens.
|
|
108
108
|
*/
|
|
109
|
-
public getAll() {
|
|
109
|
+
public getAll(): Tween[] {
|
|
110
110
|
return this._tweens;
|
|
111
111
|
}
|
|
112
112
|
|
|
@@ -128,7 +128,7 @@ export class TweenManager {
|
|
|
128
128
|
*/
|
|
129
129
|
public removeFrom(obj: TweenTarget, children: object[] | null = null): void {
|
|
130
130
|
if (Array.isArray(obj)) {
|
|
131
|
-
for (const entry of obj) {
|
|
131
|
+
for (const entry of obj as object[]) {
|
|
132
132
|
this.removeFrom(entry);
|
|
133
133
|
}
|
|
134
134
|
return;
|
|
@@ -58,35 +58,35 @@ const createGame = (font: BitmapFontData | null = FONT): Game =>
|
|
|
58
58
|
|
|
59
59
|
const createText = (text: string, size = 10): BitmapText => new BitmapText(createGame(), 0, 0, 'test', text, size);
|
|
60
60
|
|
|
61
|
-
describe('BitmapText', () => {
|
|
62
|
-
beforeEach(() => {
|
|
61
|
+
describe('BitmapText', (): void => {
|
|
62
|
+
beforeEach((): void => {
|
|
63
63
|
getRegistry().CACHE_MISSING_IMAGE = new Texture(atlas, new Rectangle(0, 0, 1, 1));
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
describe('updateText', () => {
|
|
67
|
-
it('measures a single line from the glyph advances', () => {
|
|
66
|
+
describe('updateText', (): void => {
|
|
67
|
+
it('measures a single line from the glyph advances', (): void => {
|
|
68
68
|
const bitmapText = createText('AB');
|
|
69
69
|
expect(bitmapText.textWidth).toBe(20);
|
|
70
70
|
expect(bitmapText.textHeight).toBe(12);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
it('scales the metrics with the font size', () => {
|
|
73
|
+
it('scales the metrics with the font size', (): void => {
|
|
74
74
|
const bitmapText = createText('AB', 20);
|
|
75
75
|
expect(bitmapText.textWidth).toBe(40);
|
|
76
76
|
expect(bitmapText.textHeight).toBe(24);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
it('splits on a newline and takes the widest line as the width', () => {
|
|
79
|
+
it('splits on a newline and takes the widest line as the width', (): void => {
|
|
80
80
|
const bitmapText = createText('AB\nA');
|
|
81
81
|
expect(bitmapText.textWidth).toBe(20);
|
|
82
82
|
expect(bitmapText.textHeight).toBe(24);
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
it('creates one glyph sprite per character', () => {
|
|
85
|
+
it('creates one glyph sprite per character', (): void => {
|
|
86
86
|
expect(createText('AB')._glyphs).toHaveLength(2);
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
it('reuses the glyph pool when the text shrinks', () => {
|
|
89
|
+
it('reuses the glyph pool when the text shrinks', (): void => {
|
|
90
90
|
const bitmapText = createText('AB');
|
|
91
91
|
const pooled = bitmapText._glyphs;
|
|
92
92
|
bitmapText.text = 'A';
|
|
@@ -95,115 +95,115 @@ describe('BitmapText', () => {
|
|
|
95
95
|
expect(bitmapText.children).toHaveLength(1);
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
it('drops the glyphs that left the display list when purged', () => {
|
|
98
|
+
it('drops the glyphs that left the display list when purged', (): void => {
|
|
99
99
|
const bitmapText = createText('AB');
|
|
100
100
|
bitmapText.text = 'A';
|
|
101
101
|
expect(bitmapText.purgeGlyphs()).toBe(1);
|
|
102
102
|
expect(bitmapText._glyphs).toHaveLength(1);
|
|
103
103
|
});
|
|
104
104
|
|
|
105
|
-
it('lays out an empty string as a single empty line', () => {
|
|
105
|
+
it('lays out an empty string as a single empty line', (): void => {
|
|
106
106
|
const bitmapText = createText('');
|
|
107
107
|
expect(bitmapText.textWidth).toBe(0);
|
|
108
108
|
expect(bitmapText.textHeight).toBe(12);
|
|
109
109
|
expect(bitmapText._glyphs).toHaveLength(0);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
-
it('does nothing when the font is not in the cache', () => {
|
|
112
|
+
it('does nothing when the font is not in the cache', (): void => {
|
|
113
113
|
const bitmapText = new BitmapText(createGame(null), 0, 0, 'missing', 'AB');
|
|
114
114
|
expect(bitmapText.textWidth).toBe(0);
|
|
115
115
|
expect(bitmapText._glyphs).toHaveLength(0);
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
describe('scanLine', () => {
|
|
120
|
-
it('reports the whole text when nothing forces a wrap', () => {
|
|
119
|
+
describe('scanLine', (): void => {
|
|
120
|
+
it('reports the whole text when nothing forces a wrap', (): void => {
|
|
121
121
|
const line = createText('AB').scanLine(FONT, 1, 'AB');
|
|
122
122
|
expect(line).toMatchObject({ width: 20, text: 'AB', end: true, chars: [0, 10] });
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
it('stops at a newline and reports the line as unfinished', () => {
|
|
125
|
+
it('stops at a newline and reports the line as unfinished', (): void => {
|
|
126
126
|
const line = createText('AB').scanLine(FONT, 1, 'AB\nA');
|
|
127
127
|
expect(line.text).toBe('AB');
|
|
128
128
|
expect(line.end).toBe(false);
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
it('wraps at the last space once maxWidth is exceeded', () => {
|
|
131
|
+
it('wraps at the last space once maxWidth is exceeded', (): void => {
|
|
132
132
|
const bitmapText = createText('A A');
|
|
133
133
|
bitmapText.maxWidth = 20;
|
|
134
134
|
expect(bitmapText.scanLine(FONT, 1, 'A A').text).toBe('A');
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
-
it('substitutes a space for a character the font does not carry', () => {
|
|
137
|
+
it('substitutes a space for a character the font does not carry', (): void => {
|
|
138
138
|
const line = createText('A').scanLine(FONT, 1, 'Z');
|
|
139
139
|
expect(line.width).toBe(5);
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
-
it('skips a character the font cannot even substitute for', () => {
|
|
142
|
+
it('skips a character the font cannot even substitute for', (): void => {
|
|
143
143
|
const spaceless: BitmapFontData = { ...FONT, chars: Object.fromEntries([glyph(65, 10)]) };
|
|
144
144
|
expect(createText('A').scanLine(spaceless, 1, 'AZ').width).toBe(10);
|
|
145
145
|
});
|
|
146
146
|
});
|
|
147
147
|
|
|
148
|
-
describe('cleanText', () => {
|
|
149
|
-
it('drops characters the font does not carry', () => {
|
|
148
|
+
describe('cleanText', (): void => {
|
|
149
|
+
it('drops characters the font does not carry', (): void => {
|
|
150
150
|
expect(createText('A').cleanText('AZB')).toBe('AB');
|
|
151
151
|
});
|
|
152
152
|
|
|
153
|
-
it('replaces them with the given stand-in', () => {
|
|
153
|
+
it('replaces them with the given stand-in', (): void => {
|
|
154
154
|
expect(createText('A').cleanText('AZB', '?')).toBe('A?B');
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
it('keeps line breaks', () => {
|
|
157
|
+
it('keeps line breaks', (): void => {
|
|
158
158
|
expect(createText('A').cleanText('A\nB')).toBe('A\nB');
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
describe('properties', () => {
|
|
163
|
-
it('re-lays out when the alignment changes', () => {
|
|
162
|
+
describe('properties', (): void => {
|
|
163
|
+
it('re-lays out when the alignment changes', (): void => {
|
|
164
164
|
const bitmapText = createText('A\nAB');
|
|
165
165
|
bitmapText.align = 'right';
|
|
166
166
|
expect(bitmapText.align).toBe('right');
|
|
167
167
|
expect(bitmapText._glyphs[0]?.position.x).toBe(10);
|
|
168
168
|
});
|
|
169
169
|
|
|
170
|
-
it('ignores an alignment it does not know', () => {
|
|
170
|
+
it('ignores an alignment it does not know', (): void => {
|
|
171
171
|
const bitmapText = createText('A');
|
|
172
172
|
bitmapText.align = 'sideways';
|
|
173
173
|
expect(bitmapText.align).toBe('left');
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
it('coerces a string font size', () => {
|
|
176
|
+
it('coerces a string font size', (): void => {
|
|
177
177
|
const bitmapText = createText('A');
|
|
178
178
|
bitmapText.fontSize = '20';
|
|
179
179
|
expect(bitmapText.fontSize).toBe(20);
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
it('ignores a font size of zero or less', () => {
|
|
182
|
+
it('ignores a font size of zero or less', (): void => {
|
|
183
183
|
const bitmapText = createText('A');
|
|
184
184
|
bitmapText.fontSize = -5;
|
|
185
185
|
expect(bitmapText.fontSize).toBe(10);
|
|
186
186
|
});
|
|
187
187
|
|
|
188
|
-
it('renders the tint as a padded hex string', () => {
|
|
188
|
+
it('renders the tint as a padded hex string', (): void => {
|
|
189
189
|
const bitmapText = createText('A');
|
|
190
190
|
bitmapText.tint = 0x00ff00;
|
|
191
191
|
expect(bitmapText.fill).toBe('#00FF00');
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
-
it('reads a hex string back into the tint', () => {
|
|
194
|
+
it('reads a hex string back into the tint', (): void => {
|
|
195
195
|
const bitmapText = createText('A');
|
|
196
196
|
bitmapText.fill = '#FF0000';
|
|
197
197
|
expect(bitmapText.tint).toBe(0xff0000);
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
-
it('trims the font key before looking it up', () => {
|
|
200
|
+
it('trims the font key before looking it up', (): void => {
|
|
201
201
|
const bitmapText = createText('A');
|
|
202
202
|
bitmapText.font = ' other ';
|
|
203
203
|
expect(bitmapText.font).toBe('other');
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
it('stringifies whatever the text is set to', () => {
|
|
206
|
+
it('stringifies whatever the text is set to', (): void => {
|
|
207
207
|
const bitmapText = createText('A');
|
|
208
208
|
bitmapText.text = 65;
|
|
209
209
|
expect(bitmapText.text).toBe('65');
|