@datamoc/mw_games 0.42.0 → 0.43.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 (139) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +62 -1
  3. package/REFERENCE.md +57 -5
  4. package/api-surface.json +672 -0
  5. package/data/microgm-essential.PROVENANCE.md +13 -0
  6. package/data/microgm-essential.sf2 +0 -0
  7. package/data/soundfont-catalog.json +8 -0
  8. package/dist/audio/AudioLoader.d.ts +28 -0
  9. package/dist/audio/AudioLoader.d.ts.map +1 -0
  10. package/dist/audio/AudioLoader.js +53 -0
  11. package/dist/audio/AudioLoader.js.map +1 -0
  12. package/dist/audio/Channels.d.ts +1 -0
  13. package/dist/audio/Channels.d.ts.map +1 -1
  14. package/dist/audio/Channels.js +2 -1
  15. package/dist/audio/Channels.js.map +1 -1
  16. package/dist/audio/MidiRender.d.ts +16 -0
  17. package/dist/audio/MidiRender.d.ts.map +1 -1
  18. package/dist/audio/MidiRender.js +21 -0
  19. package/dist/audio/MidiRender.js.map +1 -1
  20. package/dist/audio/MusicPlayer.d.ts +80 -0
  21. package/dist/audio/MusicPlayer.d.ts.map +1 -0
  22. package/dist/audio/MusicPlayer.js +147 -0
  23. package/dist/audio/MusicPlayer.js.map +1 -0
  24. package/dist/audio/SampleDecoder.d.ts +16 -2
  25. package/dist/audio/SampleDecoder.d.ts.map +1 -1
  26. package/dist/audio/SampleDecoder.js +10 -6
  27. package/dist/audio/SampleDecoder.js.map +1 -1
  28. package/dist/audio/Sound.d.ts +2 -0
  29. package/dist/audio/Sound.d.ts.map +1 -1
  30. package/dist/audio/Sound.js +3 -0
  31. package/dist/audio/Sound.js.map +1 -1
  32. package/dist/audio/SoundFont.d.ts +5 -3
  33. package/dist/audio/SoundFont.d.ts.map +1 -1
  34. package/dist/audio/SoundFont.js +10 -8
  35. package/dist/audio/SoundFont.js.map +1 -1
  36. package/dist/audio/Synth.d.ts +1 -1
  37. package/dist/audio/Synth.d.ts.map +1 -1
  38. package/dist/audio/Synth.js +4 -0
  39. package/dist/audio/Synth.js.map +1 -1
  40. package/dist/audio/index.d.ts +6 -2
  41. package/dist/audio/index.d.ts.map +1 -1
  42. package/dist/audio/index.js +3 -1
  43. package/dist/audio/index.js.map +1 -1
  44. package/dist/mw_games.global.js +22 -22
  45. package/dist/mwl/index.d.ts +2 -0
  46. package/dist/mwl/index.d.ts.map +1 -1
  47. package/dist/mwl/index.js +1 -0
  48. package/dist/mwl/index.js.map +1 -1
  49. package/dist/mwl/objects.d.ts +31 -0
  50. package/dist/mwl/objects.d.ts.map +1 -0
  51. package/dist/mwl/objects.js +83 -0
  52. package/dist/mwl/objects.js.map +1 -0
  53. package/dist/mwl/schema.d.ts +1 -1
  54. package/dist/mwl/schema.d.ts.map +1 -1
  55. package/dist/mwl/tables.d.ts +2 -0
  56. package/dist/mwl/tables.d.ts.map +1 -1
  57. package/dist/mwl/tables.js +13 -0
  58. package/dist/mwl/tables.js.map +1 -1
  59. package/dist/physics/XpbdWorld.d.ts +23 -5
  60. package/dist/physics/XpbdWorld.d.ts.map +1 -1
  61. package/dist/physics/XpbdWorld.js +90 -6
  62. package/dist/physics/XpbdWorld.js.map +1 -1
  63. package/dist/testing/index.d.ts +16 -0
  64. package/dist/testing/index.d.ts.map +1 -1
  65. package/dist/testing/index.js +21 -0
  66. package/dist/testing/index.js.map +1 -1
  67. package/dist/three-d/Collision3D.d.ts +46 -2
  68. package/dist/three-d/Collision3D.d.ts.map +1 -1
  69. package/dist/three-d/Collision3D.js +46 -2
  70. package/dist/three-d/Collision3D.js.map +1 -1
  71. package/dist/three-d/Grid.d.ts +12 -1
  72. package/dist/three-d/Grid.d.ts.map +1 -1
  73. package/dist/three-d/Grid.js +12 -1
  74. package/dist/three-d/Grid.js.map +1 -1
  75. package/dist/three-d/Vox.d.ts +13 -1
  76. package/dist/three-d/Vox.d.ts.map +1 -1
  77. package/dist/three-d/Vox.js +13 -1
  78. package/dist/three-d/Vox.js.map +1 -1
  79. package/dist/two-d/Game.d.ts +21 -1
  80. package/dist/two-d/Game.d.ts.map +1 -1
  81. package/dist/two-d/Game.js +73 -6
  82. package/dist/two-d/Game.js.map +1 -1
  83. package/dist/two-d/Scene2D.d.ts +24 -0
  84. package/dist/two-d/Scene2D.d.ts.map +1 -1
  85. package/dist/two-d/Scene2D.js +30 -0
  86. package/dist/two-d/Scene2D.js.map +1 -1
  87. package/dist/two-d/render/SceneTransition.d.ts +272 -0
  88. package/dist/two-d/render/SceneTransition.d.ts.map +1 -0
  89. package/dist/two-d/render/SceneTransition.js +431 -0
  90. package/dist/two-d/render/SceneTransition.js.map +1 -0
  91. package/dist/two-d/render/index.d.ts +2 -0
  92. package/dist/two-d/render/index.d.ts.map +1 -1
  93. package/dist/two-d/render/index.js +1 -0
  94. package/dist/two-d/render/index.js.map +1 -1
  95. package/dist/two-d/ui/Button.d.ts +23 -0
  96. package/dist/two-d/ui/Button.d.ts.map +1 -1
  97. package/dist/two-d/ui/Button.js +37 -0
  98. package/dist/two-d/ui/Button.js.map +1 -1
  99. package/dist/two-d/ui/DropdownView.d.ts +49 -3
  100. package/dist/two-d/ui/DropdownView.d.ts.map +1 -1
  101. package/dist/two-d/ui/DropdownView.js +150 -9
  102. package/dist/two-d/ui/DropdownView.js.map +1 -1
  103. package/dist/two-d/ui/ScrollBox.d.ts +90 -0
  104. package/dist/two-d/ui/ScrollBox.d.ts.map +1 -1
  105. package/dist/two-d/ui/ScrollBox.js +206 -4
  106. package/dist/two-d/ui/ScrollBox.js.map +1 -1
  107. package/dist/two-d/ui/ScrollText.d.ts +122 -0
  108. package/dist/two-d/ui/ScrollText.d.ts.map +1 -0
  109. package/dist/two-d/ui/ScrollText.js +202 -0
  110. package/dist/two-d/ui/ScrollText.js.map +1 -0
  111. package/dist/two-d/ui/Tooltip.d.ts +70 -1
  112. package/dist/two-d/ui/Tooltip.d.ts.map +1 -1
  113. package/dist/two-d/ui/Tooltip.js +115 -3
  114. package/dist/two-d/ui/Tooltip.js.map +1 -1
  115. package/dist/two-d/ui/Window.d.ts +35 -2
  116. package/dist/two-d/ui/Window.d.ts.map +1 -1
  117. package/dist/two-d/ui/Window.js +58 -3
  118. package/dist/two-d/ui/Window.js.map +1 -1
  119. package/dist/two-d/ui/index.d.ts +7 -5
  120. package/dist/two-d/ui/index.d.ts.map +1 -1
  121. package/dist/two-d/ui/index.js +3 -2
  122. package/dist/two-d/ui/index.js.map +1 -1
  123. package/dist/version.d.ts +1 -1
  124. package/dist/version.js +1 -1
  125. package/package.json +7 -3
  126. package/sbom.cdx.json +19 -260
  127. package/tools/browser-driver.mjs +3 -3
  128. package/tools/browser-smoke.mjs +19 -2
  129. package/tools/build-tablebases.mjs +7 -3
  130. package/tools/compile-openings.mjs +7 -3
  131. package/tools/compile-resources.d.mts +2 -0
  132. package/tools/compile-resources.mjs +13 -1
  133. package/tools/emit-page.d.mts +6 -0
  134. package/tools/emit-page.mjs +43 -3
  135. package/tools/find-chrome.mjs +4 -2
  136. package/tools/init.mjs +11 -3
  137. package/tools/play-uci.mjs +9 -5
  138. package/tools/vite.mjs +9 -1
  139. package/tools.md +1 -0
@@ -16,11 +16,88 @@ import { theme, themeChanged } from './theme.js';
16
16
  export function scrollOffset(offset, contentSize, viewportSize) {
17
17
  return Math.max(0, Math.min(Math.max(0, contentSize - viewportSize), offset));
18
18
  }
19
+ /**
20
+ * Touch scrolling as plain numbers: feed it pointer positions and it says how far the content moves
21
+ * while the finger is down, then keeps coasting after release with a friction that decays the speed.
22
+ * No pointer events or clock of its own, so it is the same under a test as under a finger.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { ScrollDrag } from '@datamoc/mw_games/two-d/ui';
27
+ *
28
+ * const drag = new ScrollDrag();
29
+ * drag.start(200, 0);
30
+ * console.log(drag.move(170, 0.1)); // 30: the content follows the finger up
31
+ * drag.end();
32
+ * console.log(drag.step(1 / 60) > 0); // true: it keeps coasting
33
+ * ```
34
+ */
35
+ export class ScrollDrag {
36
+ /**
37
+ * @param friction fraction of the speed lost per second of coasting; 0.92 when omitted
38
+ * @param minSpeed the speed, in pixels per second, below which it counts as at rest; 8 when omitted
39
+ */
40
+ constructor(friction = 0.92, minSpeed = 8) {
41
+ /** content pixels per second the content keeps moving at after release; 0 when at rest */
42
+ this.velocity = 0;
43
+ this.dragging = false;
44
+ /** how far the pointer has travelled since `start`, to tell a drag from a tap */
45
+ this.travelled = 0;
46
+ this.lastY = 0;
47
+ this.lastTime = 0;
48
+ this.friction = friction;
49
+ this.minSpeed = minSpeed;
50
+ }
51
+ start(y, time) {
52
+ this.dragging = true;
53
+ this.velocity = 0;
54
+ this.travelled = 0;
55
+ this.lastY = y;
56
+ this.lastTime = time;
57
+ }
58
+ /** @returns how far the content should move for this pointer position */
59
+ move(y, time) {
60
+ if (!this.dragging)
61
+ return 0;
62
+ const delta = this.lastY - y;
63
+ const dt = time - this.lastTime;
64
+ if (dt > 0)
65
+ this.velocity = this.velocity * 0.4 + (delta / dt) * 0.6;
66
+ this.travelled += Math.abs(delta);
67
+ this.lastY = y;
68
+ this.lastTime = time;
69
+ return delta;
70
+ }
71
+ end() {
72
+ this.dragging = false;
73
+ if (Math.abs(this.velocity) < this.minSpeed)
74
+ this.velocity = 0;
75
+ }
76
+ /** @returns how far the content coasts in `dt` seconds, 0 once it has stopped */
77
+ step(dt) {
78
+ if (this.dragging || this.velocity === 0)
79
+ return 0;
80
+ const delta = this.velocity * dt;
81
+ this.velocity *= (1 - this.friction) ** dt;
82
+ if (Math.abs(this.velocity) < this.minSpeed)
83
+ this.velocity = 0;
84
+ return delta;
85
+ }
86
+ /** stops coasting, for when the content hit an end */
87
+ stop() {
88
+ this.velocity = 0;
89
+ }
90
+ }
19
91
  /**
20
92
  * A clipped viewport with a scrollbar: put rows in `content` and they scroll inside the box,
21
93
  * everything outside it hidden by a mask. The scrollbar is drawn from the theme; the wheel,
22
94
  * `scrollBy` and `scrollIntoView` all run through `scrollOffset`, so they clamp the same way.
23
95
  *
96
+ * `touch: true` lets a finger drag the content (a drag ends the tap on the rows under it) and coast
97
+ * on release, `keyboard: true` makes `handleKey` scroll by line, page and to the ends, the scrollbar's
98
+ * thumb can be dragged and its track clicked, and `autoHeight` sizes the viewport to the content up
99
+ * to `height`. Call `update(dt)` each frame for the coasting.
100
+ *
24
101
  * @example
25
102
  * ```ts
26
103
  * import { ScrollBox } from '@datamoc/mw_games/two-d/ui';
@@ -39,13 +116,19 @@ export class ScrollBox extends Container {
39
116
  this.maskShape = new Graphics();
40
117
  this.track = new Graphics();
41
118
  this.thumb = new Graphics();
119
+ this.dragMoved = false;
120
+ this.thumbGrab = null;
42
121
  this.themeListener = () => this.draw();
43
122
  this.handleWheel = (event) => {
44
123
  this.scrollBy(event.deltaY);
45
124
  };
46
125
  this.width_ = options.width;
47
- this.height_ = options.height;
126
+ this.maxHeight_ = options.height;
127
+ this.auto = options.autoHeight ?? false;
128
+ this.lineHeight = options.lineHeight ?? 24;
129
+ this.drag = options.touch ? new ScrollDrag() : null;
48
130
  this.contentHeight_ = Math.max(0, options.contentHeight ?? 0);
131
+ this.height_ = this.fit();
49
132
  this.offset_ = scrollOffset(options.offset ?? 0, this.contentHeight_, this.height_);
50
133
  this.addChild(this.content);
51
134
  this.addChild(this.maskShape);
@@ -54,6 +137,30 @@ export class ScrollBox extends Container {
54
137
  this.content.mask = this.maskShape;
55
138
  this.eventMode = 'static';
56
139
  this.on('wheel', this.handleWheel);
140
+ if (this.drag) {
141
+ this.on('pointerdown', (event) => this.dragStart(event.global.y, performance.now() / 1000));
142
+ this.on('globalpointermove', (event) => this.dragMove(event.global.y, performance.now() / 1000));
143
+ this.on('pointerup', () => this.dragEnd());
144
+ this.on('pointerupoutside', () => this.dragEnd());
145
+ //a drag that ended over a row is not a click on that row
146
+ this.on('pointerupcapture', (event) => {
147
+ if (this.dragMoved)
148
+ event.stopPropagation();
149
+ });
150
+ }
151
+ this.track.eventMode = 'static';
152
+ this.thumb.eventMode = 'static';
153
+ this.thumb.on('pointerdown', (event) => {
154
+ event.stopPropagation();
155
+ this.thumbDragStart(event.global.y);
156
+ });
157
+ this.thumb.on('globalpointermove', (event) => this.thumbDragMove(event.global.y));
158
+ this.thumb.on('pointerup', () => (this.thumbGrab = null));
159
+ this.thumb.on('pointerupoutside', () => (this.thumbGrab = null));
160
+ this.track.on('pointerdown', (event) => {
161
+ event.stopPropagation();
162
+ this.scrollToThumbCentre(this.toLocal(event.global).y);
163
+ });
57
164
  this.draw();
58
165
  themeChanged.add(this.themeListener);
59
166
  }
@@ -66,6 +173,10 @@ export class ScrollBox extends Container {
66
173
  get viewportHeight() {
67
174
  return this.height_;
68
175
  }
176
+ /** the viewport's height: the content's, capped at the maximum, when `autoHeight` is on */
177
+ fit() {
178
+ return this.auto ? Math.min(this.maxHeight_, this.contentHeight_) : this.maxHeight_;
179
+ }
69
180
  /** how far the content can scroll; 0 when it all fits */
70
181
  get maxOffset() {
71
182
  return Math.max(0, this.contentHeight_ - this.height_);
@@ -75,11 +186,13 @@ export class ScrollBox extends Container {
75
186
  }
76
187
  setContentHeight(height) {
77
188
  this.contentHeight_ = Math.max(0, height);
189
+ this.height_ = this.fit();
78
190
  this.setOffset(scrollOffset(this.offset_, this.contentHeight_, this.height_));
79
191
  }
80
192
  resize(width, height) {
81
193
  this.width_ = width;
82
- this.height_ = height;
194
+ this.maxHeight_ = height;
195
+ this.height_ = this.fit();
83
196
  this.setOffset(scrollOffset(this.offset_, this.contentHeight_, this.height_));
84
197
  }
85
198
  scrollBy(delta) {
@@ -95,6 +208,96 @@ export class ScrollBox extends Container {
95
208
  else if (top + height > this.offset_ + this.height_)
96
209
  this.scrollTo(top + height - this.height_);
97
210
  }
211
+ /**
212
+ * Scrolls for a key a keyboard-driven list was handed (`KeyboardEvent.key`).
213
+ *
214
+ * @returns true when the key is one this box scrolls by, so a caller can stop it going further
215
+ */
216
+ handleKey(key) {
217
+ const page = Math.max(this.lineHeight, this.height_ - this.lineHeight);
218
+ switch (key) {
219
+ case 'ArrowUp':
220
+ this.scrollBy(-this.lineHeight);
221
+ return true;
222
+ case 'ArrowDown':
223
+ this.scrollBy(this.lineHeight);
224
+ return true;
225
+ case 'PageUp':
226
+ this.scrollBy(-page);
227
+ return true;
228
+ case 'PageDown':
229
+ this.scrollBy(page);
230
+ return true;
231
+ case 'Home':
232
+ this.scrollTo(0);
233
+ return true;
234
+ case 'End':
235
+ this.scrollTo(this.maxOffset);
236
+ return true;
237
+ default:
238
+ return false;
239
+ }
240
+ }
241
+ /** a finger or button went down at `y` (any one coordinate space, `time` in seconds) */
242
+ dragStart(y, time) {
243
+ this.drag?.start(y, time);
244
+ this.dragMoved = false;
245
+ }
246
+ /** the pointer moved while down; the content follows once it has travelled a few pixels */
247
+ dragMove(y, time) {
248
+ const drag = this.drag;
249
+ if (!drag?.dragging)
250
+ return;
251
+ const delta = drag.move(y, time);
252
+ if (!this.dragMoved && drag.travelled < 6)
253
+ return;
254
+ this.dragMoved = true;
255
+ this.scrollBy(delta);
256
+ }
257
+ dragEnd() {
258
+ this.drag?.end();
259
+ }
260
+ /** true once the pointer travelled far enough to count as a drag rather than a tap */
261
+ get dragged() {
262
+ return this.dragMoved;
263
+ }
264
+ /** advances touch coasting; call once a frame from the owning scene's `update` */
265
+ update(dt) {
266
+ const drag = this.drag;
267
+ if (!drag)
268
+ return;
269
+ const before = this.offset_;
270
+ this.scrollBy(drag.step(dt));
271
+ if (this.offset_ === before && drag.velocity !== 0)
272
+ drag.stop();
273
+ }
274
+ /** where the scrollbar's thumb sits and how tall it is, in the box's own space */
275
+ get thumbMetrics() {
276
+ const barWidth = 6;
277
+ const height = Math.max(barWidth, (this.height_ / Math.max(1, this.contentHeight_)) * this.height_);
278
+ const y = this.maxOffset === 0 ? 0 : (this.offset_ / this.maxOffset) * (this.height_ - height);
279
+ return { y, height };
280
+ }
281
+ /** the thumb was grabbed at `y` */
282
+ thumbDragStart(y) {
283
+ this.thumbGrab = { y, offset: this.offset_ };
284
+ }
285
+ /** the thumb moved to `y`: the offset follows in proportion to the thumb's travel */
286
+ thumbDragMove(y) {
287
+ if (!this.thumbGrab)
288
+ return;
289
+ const travel = this.height_ - this.thumbMetrics.height;
290
+ if (travel <= 0)
291
+ return;
292
+ this.scrollTo(this.thumbGrab.offset + ((y - this.thumbGrab.y) / travel) * this.maxOffset);
293
+ }
294
+ /** a click on the track at local `y` puts the thumb's centre there */
295
+ scrollToThumbCentre(y) {
296
+ const travel = this.height_ - this.thumbMetrics.height;
297
+ if (travel <= 0)
298
+ return;
299
+ this.scrollTo(((y - this.thumbMetrics.height / 2) / travel) * this.maxOffset);
300
+ }
98
301
  setOffset(offset) {
99
302
  if (offset === this.offset_) {
100
303
  this.draw();
@@ -115,8 +318,7 @@ export class ScrollBox extends Container {
115
318
  const barWidth = 6;
116
319
  const x = this.width_ - barWidth;
117
320
  this.track.roundRect(x, 0, barWidth, this.height_, barWidth / 2).fill({ color: t.color.panelFill });
118
- const thumbHeight = Math.max(barWidth, (this.height_ / this.contentHeight_) * this.height_);
119
- const thumbY = (this.offset_ / this.maxOffset) * (this.height_ - thumbHeight);
321
+ const { y: thumbY, height: thumbHeight } = this.thumbMetrics;
120
322
  this.thumb.roundRect(x, thumbY, barWidth, thumbHeight, barWidth / 2).fill({ color: t.color.textHighlight });
121
323
  }
122
324
  destroy(options) {
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollBox.js","sourceRoot":"","sources":["../../../src/two-d/ui/ScrollBox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScrollBox.js","sourceRoot":"","sources":["../../../src/two-d/ui/ScrollBox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import { Container } from 'pixi.js';
2
+ import { type LabelOptions } from './Label.ts';
3
+ import { ScrollBox } from './ScrollBox.ts';
4
+ /**
5
+ * `text` cut to fit `maxWidth`, ending in `ellipsis`, as measured by `measure` (the width of a string
6
+ * in whatever font the caller draws it with). A text that already fits comes back unchanged.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { ellipsize } from '@datamoc/mw_games/two-d/ui';
11
+ *
12
+ * const width = (text: string) => text.length * 10;
13
+ * console.log(ellipsize('3. Le Fleuve profond (verrouillé)', 150, width)); // 3. Le Fleuve…
14
+ * ```
15
+ */
16
+ export declare function ellipsize(text: string, maxWidth: number, measure: (text: string) => number, ellipsis?: string): string;
17
+ /**
18
+ * `text` wrapped at `maxWidth` and cut to `maxLines`, the last kept line ending in an ellipsis when
19
+ * something was dropped. Words are not split unless one alone is wider than a line.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { truncateLines } from '@datamoc/mw_games/two-d/ui';
24
+ *
25
+ * const width = (text: string) => text.length * 10;
26
+ * console.log(truncateLines('build a bridge across the river gorge', 120, 2, width));
27
+ * // ['build a', 'bridge acr…']
28
+ * ```
29
+ */
30
+ export declare function truncateLines(text: string, maxWidth: number, maxLines: number, measure: (text: string) => number, ellipsis?: string): string[];
31
+ /**
32
+ * How far a line of `textWidth` is shifted to scroll inside `boxWidth`, `time` seconds in: it waits
33
+ * `pause` seconds, slides to its end at `speed` px/s, waits again, then slides back, over and over.
34
+ * A text that fits never moves.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { marqueeOffset } from '@datamoc/mw_games/two-d/ui';
39
+ *
40
+ * console.log(marqueeOffset(300, 200, 0)); // 0, waiting at the start
41
+ * console.log(marqueeOffset(300, 200, 3)); // 100, at the far end
42
+ * console.log(marqueeOffset(150, 200, 3)); // 0, it fits
43
+ * ```
44
+ */
45
+ export declare function marqueeOffset(textWidth: number, boxWidth: number, time: number, speed?: number, pause?: number): number;
46
+ export interface ScrollTextOptions {
47
+ width: number;
48
+ /** the tallest the box grows before the text scrolls instead */
49
+ maxHeight: number;
50
+ text?: string;
51
+ label?: Omit<LabelOptions, 'text' | 'wrapWidth'>;
52
+ /** a finger drag scrolls the text; true when omitted */
53
+ touch?: boolean;
54
+ }
55
+ /**
56
+ * A wrapped `Label` in a `ScrollBox` that sizes itself: the box is as tall as the text up to
57
+ * `maxHeight`, and scrolls (wheel, touch, keys, scrollbar) beyond it, so a long hint, credit list or
58
+ * result message never spills over what is around it. `setText` re-measures; the caller no longer
59
+ * measures the label and feeds `setContentHeight` by hand.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * import { ScrollText } from '@datamoc/mw_games/two-d/ui';
64
+ *
65
+ * const hint = new ScrollText({ width: 220, maxHeight: 60 });
66
+ * hint.setText('Span the gorge with at most 400 of budget. Cables only pull; beams push as well.');
67
+ * console.log(hint.box.viewportHeight <= 60); // true
68
+ * ```
69
+ */
70
+ export declare class ScrollText extends Container {
71
+ readonly box: ScrollBox;
72
+ private readonly body;
73
+ constructor(options: ScrollTextOptions);
74
+ /** the text's own height, which sizes the box; its own method so a test can supply it */
75
+ protected measureHeight(): number;
76
+ private measure;
77
+ setText(text: string): void;
78
+ /** call each frame for touch coasting */
79
+ update(dt: number): void;
80
+ }
81
+ export interface MarqueeLabelOptions {
82
+ width: number;
83
+ text?: string;
84
+ label?: Omit<LabelOptions, 'text'>;
85
+ /** pixels per second; 40 when omitted */
86
+ speed?: number;
87
+ /** seconds it waits at each end; 1 when omitted */
88
+ pause?: number;
89
+ }
90
+ /**
91
+ * One line of text that stays on one line: when it is wider than `width` it slides back and forth
92
+ * inside a clipped window (`marqueeOffset`), driven by `update(dt)`. Under reduced motion it holds
93
+ * still, cut short with an ellipsis, instead of moving.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * import { MarqueeLabel } from '@datamoc/mw_games/two-d/ui';
98
+ *
99
+ * const title = new MarqueeLabel({ width: 160, text: 'A very long track title that cannot fit' });
100
+ * title.update(1 / 60); // once a frame from the scene
101
+ * ```
102
+ */
103
+ export declare class MarqueeLabel extends Container {
104
+ private readonly body;
105
+ private readonly clip;
106
+ private readonly speed;
107
+ private readonly pause;
108
+ private readonly width_;
109
+ private readonly labelOptions;
110
+ private source;
111
+ private fullWidth;
112
+ private time;
113
+ constructor(options: MarqueeLabelOptions);
114
+ /** the text's width in pixels; its own method so a test can supply it */
115
+ protected measureWidth(text: string): number;
116
+ setText(text: string): void;
117
+ private apply;
118
+ /** where the text is shifted to now (0 until it has waited out its first pause) */
119
+ get shift(): number;
120
+ update(dt: number): void;
121
+ }
122
+ //# sourceMappingURL=ScrollText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScrollText.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/ScrollText.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,202 @@
1
+ import { Container, Graphics } from 'pixi.js';
2
+ import { reducedMotion } from '../../core/Motion.js';
3
+ import { Label } from './Label.js';
4
+ import { ScrollBox } from './ScrollBox.js';
5
+ /**
6
+ * `text` cut to fit `maxWidth`, ending in `ellipsis`, as measured by `measure` (the width of a string
7
+ * in whatever font the caller draws it with). A text that already fits comes back unchanged.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { ellipsize } from '@datamoc/mw_games/two-d/ui';
12
+ *
13
+ * const width = (text: string) => text.length * 10;
14
+ * console.log(ellipsize('3. Le Fleuve profond (verrouillé)', 150, width)); // 3. Le Fleuve…
15
+ * ```
16
+ */
17
+ export function ellipsize(text, maxWidth, measure, ellipsis = '…') {
18
+ if (measure(text) <= maxWidth)
19
+ return text;
20
+ let low = 0;
21
+ let high = text.length;
22
+ while (low < high) {
23
+ const middle = Math.ceil((low + high) / 2);
24
+ if (measure(text.slice(0, middle).trimEnd() + ellipsis) <= maxWidth)
25
+ low = middle;
26
+ else
27
+ high = middle - 1;
28
+ }
29
+ return low === 0 ? ellipsis : text.slice(0, low).trimEnd() + ellipsis;
30
+ }
31
+ /**
32
+ * `text` wrapped at `maxWidth` and cut to `maxLines`, the last kept line ending in an ellipsis when
33
+ * something was dropped. Words are not split unless one alone is wider than a line.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * import { truncateLines } from '@datamoc/mw_games/two-d/ui';
38
+ *
39
+ * const width = (text: string) => text.length * 10;
40
+ * console.log(truncateLines('build a bridge across the river gorge', 120, 2, width));
41
+ * // ['build a', 'bridge acr…']
42
+ * ```
43
+ */
44
+ export function truncateLines(text, maxWidth, maxLines, measure, ellipsis = '…') {
45
+ const lines = [];
46
+ let line = '';
47
+ for (const word of text.split(/\s+/).filter(Boolean)) {
48
+ const next = line ? `${line} ${word}` : word;
49
+ if (measure(next) <= maxWidth || !line)
50
+ line = next;
51
+ else {
52
+ lines.push(line);
53
+ line = word;
54
+ }
55
+ }
56
+ if (line)
57
+ lines.push(line);
58
+ if (lines.length <= maxLines)
59
+ return lines.map((each) => ellipsize(each, maxWidth, measure, ellipsis));
60
+ const kept = lines.slice(0, maxLines);
61
+ const rest = lines.slice(maxLines - 1).join(' ');
62
+ kept[maxLines - 1] = ellipsize(rest + ellipsis, maxWidth, measure, ellipsis);
63
+ return kept;
64
+ }
65
+ /**
66
+ * How far a line of `textWidth` is shifted to scroll inside `boxWidth`, `time` seconds in: it waits
67
+ * `pause` seconds, slides to its end at `speed` px/s, waits again, then slides back, over and over.
68
+ * A text that fits never moves.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * import { marqueeOffset } from '@datamoc/mw_games/two-d/ui';
73
+ *
74
+ * console.log(marqueeOffset(300, 200, 0)); // 0, waiting at the start
75
+ * console.log(marqueeOffset(300, 200, 3)); // 100, at the far end
76
+ * console.log(marqueeOffset(150, 200, 3)); // 0, it fits
77
+ * ```
78
+ */
79
+ export function marqueeOffset(textWidth, boxWidth, time, speed = 40, pause = 1) {
80
+ const travel = textWidth - boxWidth;
81
+ if (travel <= 0)
82
+ return 0;
83
+ const slide = travel / speed;
84
+ const period = 2 * (pause + slide);
85
+ const at = ((time % period) + period) % period;
86
+ if (at < pause)
87
+ return 0;
88
+ if (at < pause + slide)
89
+ return (at - pause) * speed;
90
+ if (at < 2 * pause + slide)
91
+ return travel;
92
+ return travel - (at - 2 * pause - slide) * speed;
93
+ }
94
+ /**
95
+ * A wrapped `Label` in a `ScrollBox` that sizes itself: the box is as tall as the text up to
96
+ * `maxHeight`, and scrolls (wheel, touch, keys, scrollbar) beyond it, so a long hint, credit list or
97
+ * result message never spills over what is around it. `setText` re-measures; the caller no longer
98
+ * measures the label and feeds `setContentHeight` by hand.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * import { ScrollText } from '@datamoc/mw_games/two-d/ui';
103
+ *
104
+ * const hint = new ScrollText({ width: 220, maxHeight: 60 });
105
+ * hint.setText('Span the gorge with at most 400 of budget. Cables only pull; beams push as well.');
106
+ * console.log(hint.box.viewportHeight <= 60); // true
107
+ * ```
108
+ */
109
+ export class ScrollText extends Container {
110
+ constructor(options) {
111
+ super();
112
+ this.body = new Label({ ...options.label, text: options.text ?? '', wrapWidth: options.width - 10 });
113
+ this.box = new ScrollBox({
114
+ width: options.width,
115
+ height: options.maxHeight,
116
+ autoHeight: true,
117
+ touch: options.touch ?? true,
118
+ keyboard: true,
119
+ });
120
+ this.box.content.addChild(this.body);
121
+ this.addChild(this.box);
122
+ this.measure();
123
+ }
124
+ /** the text's own height, which sizes the box; its own method so a test can supply it */
125
+ measureHeight() {
126
+ return this.body.height;
127
+ }
128
+ measure() {
129
+ this.box.setContentHeight(this.measureHeight());
130
+ }
131
+ setText(text) {
132
+ this.body.setText(text);
133
+ this.measure();
134
+ this.box.scrollTo(0);
135
+ }
136
+ /** call each frame for touch coasting */
137
+ update(dt) {
138
+ this.box.update(dt);
139
+ }
140
+ }
141
+ /**
142
+ * One line of text that stays on one line: when it is wider than `width` it slides back and forth
143
+ * inside a clipped window (`marqueeOffset`), driven by `update(dt)`. Under reduced motion it holds
144
+ * still, cut short with an ellipsis, instead of moving.
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * import { MarqueeLabel } from '@datamoc/mw_games/two-d/ui';
149
+ *
150
+ * const title = new MarqueeLabel({ width: 160, text: 'A very long track title that cannot fit' });
151
+ * title.update(1 / 60); // once a frame from the scene
152
+ * ```
153
+ */
154
+ export class MarqueeLabel extends Container {
155
+ constructor(options) {
156
+ super();
157
+ this.clip = new Graphics();
158
+ this.source = '';
159
+ this.fullWidth = 0;
160
+ this.time = 0;
161
+ this.width_ = options.width;
162
+ this.speed = options.speed ?? 40;
163
+ this.pause = options.pause ?? 1;
164
+ this.labelOptions = options.label ?? {};
165
+ this.body = new Label({ ...this.labelOptions, text: '' });
166
+ this.clip.rect(0, 0, options.width, 4096).fill({ color: 0xffffff });
167
+ this.addChild(this.body, this.clip);
168
+ this.body.mask = this.clip;
169
+ this.setText(options.text ?? '');
170
+ }
171
+ /** the text's width in pixels; its own method so a test can supply it */
172
+ measureWidth(text) {
173
+ const probe = new Label({ ...this.labelOptions, text });
174
+ const width = probe.width;
175
+ probe.destroy();
176
+ return width;
177
+ }
178
+ setText(text) {
179
+ this.source = text;
180
+ this.fullWidth = this.measureWidth(text);
181
+ this.time = 0;
182
+ this.apply();
183
+ }
184
+ apply() {
185
+ if (reducedMotion()) {
186
+ this.body.setText(ellipsize(this.source, this.width_, (text) => this.measureWidth(text)));
187
+ this.body.x = 0;
188
+ return;
189
+ }
190
+ this.body.setText(this.source);
191
+ this.body.x = -marqueeOffset(this.fullWidth, this.width_, this.time, this.speed, this.pause);
192
+ }
193
+ /** where the text is shifted to now (0 until it has waited out its first pause) */
194
+ get shift() {
195
+ return 0 - this.body.x;
196
+ }
197
+ update(dt) {
198
+ this.time += dt;
199
+ this.apply();
200
+ }
201
+ }
202
+ //# sourceMappingURL=ScrollText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScrollText.js","sourceRoot":"","sources":["../../../src/two-d/ui/ScrollText.ts"],"names":[],"mappings":"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"}