@datamoc/mw_games 0.42.0 → 0.44.2
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/CHANGELOG.md +126 -0
- package/README.md +84 -1
- package/REFERENCE.md +134 -6
- package/api-surface.json +1814 -116
- package/data/microgm-essential.PROVENANCE.md +13 -0
- package/data/microgm-essential.sf2 +0 -0
- package/data/soundfont-catalog.json +8 -0
- package/dist/actors/Resource.d.ts.map +1 -1
- package/dist/actors/Resource.js +2 -3
- package/dist/actors/Resource.js.map +1 -1
- package/dist/audio/AdaptiveMusic.d.ts +85 -0
- package/dist/audio/AdaptiveMusic.d.ts.map +1 -0
- package/dist/audio/AdaptiveMusic.js +230 -0
- package/dist/audio/AdaptiveMusic.js.map +1 -0
- package/dist/audio/AudioLoader.d.ts +33 -0
- package/dist/audio/AudioLoader.d.ts.map +1 -0
- package/dist/audio/AudioLoader.js +58 -0
- package/dist/audio/AudioLoader.js.map +1 -0
- package/dist/audio/AudioViews.d.ts +70 -0
- package/dist/audio/AudioViews.d.ts.map +1 -0
- package/dist/audio/AudioViews.js +119 -0
- package/dist/audio/AudioViews.js.map +1 -0
- package/dist/audio/BusBudget.d.ts +89 -0
- package/dist/audio/BusBudget.d.ts.map +1 -0
- package/dist/audio/BusBudget.js +120 -0
- package/dist/audio/BusBudget.js.map +1 -0
- package/dist/audio/Channels.d.ts +66 -1
- package/dist/audio/Channels.d.ts.map +1 -1
- package/dist/audio/Channels.js +119 -31
- package/dist/audio/Channels.js.map +1 -1
- package/dist/audio/CoreHost.d.ts +114 -0
- package/dist/audio/CoreHost.d.ts.map +1 -0
- package/dist/audio/CoreHost.js +335 -0
- package/dist/audio/CoreHost.js.map +1 -0
- package/dist/audio/DecoderGuard.d.ts +139 -0
- package/dist/audio/DecoderGuard.d.ts.map +1 -0
- package/dist/audio/DecoderGuard.js +208 -0
- package/dist/audio/DecoderGuard.js.map +1 -0
- package/dist/audio/Fft.d.ts +3 -0
- package/dist/audio/Fft.d.ts.map +1 -0
- package/dist/audio/Fft.js +45 -0
- package/dist/audio/Fft.js.map +1 -0
- package/dist/audio/LoopTags.d.ts +18 -0
- package/dist/audio/LoopTags.d.ts.map +1 -1
- package/dist/audio/LoopTags.js +20 -0
- package/dist/audio/LoopTags.js.map +1 -1
- package/dist/audio/Midi.d.ts +35 -0
- package/dist/audio/Midi.d.ts.map +1 -1
- package/dist/audio/Midi.js +71 -1
- package/dist/audio/Midi.js.map +1 -1
- package/dist/audio/MidiRender.d.ts +47 -0
- package/dist/audio/MidiRender.d.ts.map +1 -1
- package/dist/audio/MidiRender.js +100 -2
- package/dist/audio/MidiRender.js.map +1 -1
- package/dist/audio/MidiSynth.d.ts +147 -0
- package/dist/audio/MidiSynth.d.ts.map +1 -0
- package/dist/audio/MidiSynth.js +205 -0
- package/dist/audio/MidiSynth.js.map +1 -0
- package/dist/audio/MusicPlayer.d.ts +80 -0
- package/dist/audio/MusicPlayer.d.ts.map +1 -0
- package/dist/audio/MusicPlayer.js +147 -0
- package/dist/audio/MusicPlayer.js.map +1 -0
- package/dist/audio/Playable.d.ts +7 -0
- package/dist/audio/Playable.d.ts.map +1 -1
- package/dist/audio/Playable.js.map +1 -1
- package/dist/audio/Positional.d.ts +12 -4
- package/dist/audio/Positional.d.ts.map +1 -1
- package/dist/audio/Positional.js +5 -2
- package/dist/audio/Positional.js.map +1 -1
- package/dist/audio/Resample.d.ts +61 -0
- package/dist/audio/Resample.d.ts.map +1 -0
- package/dist/audio/Resample.js +97 -0
- package/dist/audio/Resample.js.map +1 -0
- package/dist/audio/SampleDecoder.d.ts +16 -2
- package/dist/audio/SampleDecoder.d.ts.map +1 -1
- package/dist/audio/SampleDecoder.js +10 -6
- package/dist/audio/SampleDecoder.js.map +1 -1
- package/dist/audio/Settings.d.ts +99 -0
- package/dist/audio/Settings.d.ts.map +1 -0
- package/dist/audio/Settings.js +134 -0
- package/dist/audio/Settings.js.map +1 -0
- package/dist/audio/Sfx.d.ts +148 -0
- package/dist/audio/Sfx.d.ts.map +1 -0
- package/dist/audio/Sfx.js +213 -0
- package/dist/audio/Sfx.js.map +1 -0
- package/dist/audio/Sound.d.ts +2 -0
- package/dist/audio/Sound.d.ts.map +1 -1
- package/dist/audio/Sound.js +3 -0
- package/dist/audio/Sound.js.map +1 -1
- package/dist/audio/SoundFont.d.ts +5 -3
- package/dist/audio/SoundFont.d.ts.map +1 -1
- package/dist/audio/SoundFont.js +10 -8
- package/dist/audio/SoundFont.js.map +1 -1
- package/dist/audio/SpectralDistance.d.ts +34 -0
- package/dist/audio/SpectralDistance.d.ts.map +1 -0
- package/dist/audio/SpectralDistance.js +64 -0
- package/dist/audio/SpectralDistance.js.map +1 -0
- package/dist/audio/StreamChannel.d.ts +150 -0
- package/dist/audio/StreamChannel.d.ts.map +1 -0
- package/dist/audio/StreamChannel.js +390 -0
- package/dist/audio/StreamChannel.js.map +1 -0
- package/dist/audio/StreamPlayable.d.ts +73 -0
- package/dist/audio/StreamPlayable.d.ts.map +1 -0
- package/dist/audio/StreamPlayable.js +130 -0
- package/dist/audio/StreamPlayable.js.map +1 -0
- package/dist/audio/Synth.d.ts +1 -1
- package/dist/audio/Synth.d.ts.map +1 -1
- package/dist/audio/Synth.js +4 -0
- package/dist/audio/Synth.js.map +1 -1
- package/dist/audio/SyxBank.d.ts +73 -0
- package/dist/audio/SyxBank.d.ts.map +1 -0
- package/dist/audio/SyxBank.js +130 -0
- package/dist/audio/SyxBank.js.map +1 -0
- package/dist/audio/Underrun.d.ts +25 -0
- package/dist/audio/Underrun.d.ts.map +1 -0
- package/dist/audio/Underrun.js +18 -0
- package/dist/audio/Underrun.js.map +1 -0
- package/dist/audio/Wav.d.ts +56 -0
- package/dist/audio/Wav.d.ts.map +1 -0
- package/dist/audio/Wav.js +164 -0
- package/dist/audio/Wav.js.map +1 -0
- package/dist/audio/WebMidi.d.ts +58 -0
- package/dist/audio/WebMidi.d.ts.map +1 -0
- package/dist/audio/WebMidi.js +79 -0
- package/dist/audio/WebMidi.js.map +1 -0
- package/dist/audio/humanize/Onsets.d.ts.map +1 -1
- package/dist/audio/humanize/Onsets.js +1 -44
- package/dist/audio/humanize/Onsets.js.map +1 -1
- package/dist/audio/index.d.ts +43 -7
- package/dist/audio/index.d.ts.map +1 -1
- package/dist/audio/index.js +21 -3
- package/dist/audio/index.js.map +1 -1
- package/dist/battle/AttackPreview.d.ts.map +1 -1
- package/dist/battle/AttackPreview.js +8 -8
- package/dist/battle/AttackPreview.js.map +1 -1
- package/dist/battle/StatStages.d.ts.map +1 -1
- package/dist/battle/StatStages.js +2 -1
- package/dist/battle/StatStages.js.map +1 -1
- package/dist/board/Engine.d.ts +2 -0
- package/dist/board/Engine.d.ts.map +1 -1
- package/dist/board/Engine.js +1 -1
- package/dist/board/Engine.js.map +1 -1
- package/dist/board/HexSkirmish.d.ts.map +1 -1
- package/dist/board/HexSkirmish.js +11 -72
- package/dist/board/HexSkirmish.js.map +1 -1
- package/dist/board/Tactics.d.ts.map +1 -1
- package/dist/board/Tactics.js +3 -5
- package/dist/board/Tactics.js.map +1 -1
- package/dist/board/tourney.d.ts.map +1 -1
- package/dist/board/tourney.js +2 -19
- package/dist/board/tourney.js.map +1 -1
- package/dist/core/Handles.js +7 -7
- package/dist/core/Handles.js.map +1 -1
- package/dist/mw_games.global.js +25 -22
- package/dist/mwl/conditions.d.ts +12 -0
- package/dist/mwl/conditions.d.ts.map +1 -1
- package/dist/mwl/conditions.js +49 -8
- package/dist/mwl/conditions.js.map +1 -1
- package/dist/mwl/index.d.ts +13 -0
- package/dist/mwl/index.d.ts.map +1 -1
- package/dist/mwl/index.js +7 -0
- package/dist/mwl/index.js.map +1 -1
- package/dist/mwl/objects.d.ts +31 -0
- package/dist/mwl/objects.d.ts.map +1 -0
- package/dist/mwl/objects.js +83 -0
- package/dist/mwl/objects.js.map +1 -0
- package/dist/mwl/package-container.d.ts +185 -0
- package/dist/mwl/package-container.d.ts.map +1 -0
- package/dist/mwl/package-container.js +446 -0
- package/dist/mwl/package-container.js.map +1 -0
- package/dist/mwl/package-document.d.ts +217 -0
- package/dist/mwl/package-document.d.ts.map +1 -0
- package/dist/mwl/package-document.js +639 -0
- package/dist/mwl/package-document.js.map +1 -0
- package/dist/mwl/package-rom.d.ts +37 -0
- package/dist/mwl/package-rom.d.ts.map +1 -0
- package/dist/mwl/package-rom.js +96 -0
- package/dist/mwl/package-rom.js.map +1 -0
- package/dist/mwl/package-verify.d.ts +34 -0
- package/dist/mwl/package-verify.d.ts.map +1 -0
- package/dist/mwl/package-verify.js +111 -0
- package/dist/mwl/package-verify.js.map +1 -0
- package/dist/mwl/package.d.ts +184 -0
- package/dist/mwl/package.d.ts.map +1 -0
- package/dist/mwl/package.js +382 -0
- package/dist/mwl/package.js.map +1 -0
- package/dist/mwl/schema.d.ts +1 -1
- package/dist/mwl/schema.d.ts.map +1 -1
- package/dist/mwl/tables.d.ts +2 -0
- package/dist/mwl/tables.d.ts.map +1 -1
- package/dist/mwl/tables.js +13 -0
- package/dist/mwl/tables.js.map +1 -1
- package/dist/physics/PhysicsWorld.d.ts.map +1 -1
- package/dist/physics/PhysicsWorld.js +4 -3
- package/dist/physics/PhysicsWorld.js.map +1 -1
- package/dist/physics/XpbdWorld.d.ts +23 -5
- package/dist/physics/XpbdWorld.d.ts.map +1 -1
- package/dist/physics/XpbdWorld.js +91 -6
- package/dist/physics/XpbdWorld.js.map +1 -1
- package/dist/testing/FakeAudio.d.ts +149 -0
- package/dist/testing/FakeAudio.d.ts.map +1 -0
- package/dist/testing/FakeAudio.js +219 -0
- package/dist/testing/FakeAudio.js.map +1 -0
- package/dist/testing/index.d.ts +18 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +22 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/threads/index.d.ts +2 -2
- package/dist/threads/index.d.ts.map +1 -1
- package/dist/threads/index.js +1 -1
- package/dist/threads/index.js.map +1 -1
- package/dist/threads/spawn.d.ts +32 -0
- package/dist/threads/spawn.d.ts.map +1 -1
- package/dist/threads/spawn.js +35 -11
- package/dist/threads/spawn.js.map +1 -1
- package/dist/three-d/Collision3D.d.ts +46 -2
- package/dist/three-d/Collision3D.d.ts.map +1 -1
- package/dist/three-d/Collision3D.js +46 -2
- package/dist/three-d/Collision3D.js.map +1 -1
- package/dist/three-d/Grid.d.ts +12 -1
- package/dist/three-d/Grid.d.ts.map +1 -1
- package/dist/three-d/Grid.js +12 -1
- package/dist/three-d/Grid.js.map +1 -1
- package/dist/three-d/Vox.d.ts +13 -1
- package/dist/three-d/Vox.d.ts.map +1 -1
- package/dist/three-d/Vox.js +13 -1
- package/dist/three-d/Vox.js.map +1 -1
- package/dist/two-d/Game.d.ts +32 -1
- package/dist/two-d/Game.d.ts.map +1 -1
- package/dist/two-d/Game.js +105 -14
- package/dist/two-d/Game.js.map +1 -1
- package/dist/two-d/Scene2D.d.ts +24 -0
- package/dist/two-d/Scene2D.d.ts.map +1 -1
- package/dist/two-d/Scene2D.js +30 -0
- package/dist/two-d/Scene2D.js.map +1 -1
- package/dist/two-d/render/HazeLayer.d.ts.map +1 -1
- package/dist/two-d/render/HazeLayer.js +2 -1
- package/dist/two-d/render/HazeLayer.js.map +1 -1
- package/dist/two-d/render/ImageModifiers.d.ts +4 -2
- package/dist/two-d/render/ImageModifiers.d.ts.map +1 -1
- package/dist/two-d/render/ImageModifiers.js +13 -8
- package/dist/two-d/render/ImageModifiers.js.map +1 -1
- package/dist/two-d/render/NeonGlow.d.ts.map +1 -1
- package/dist/two-d/render/NeonGlow.js +2 -1
- package/dist/two-d/render/NeonGlow.js.map +1 -1
- package/dist/two-d/render/Particles.d.ts.map +1 -1
- package/dist/two-d/render/Particles.js +2 -1
- package/dist/two-d/render/Particles.js.map +1 -1
- package/dist/two-d/render/SceneTransition.d.ts +301 -0
- package/dist/two-d/render/SceneTransition.d.ts.map +1 -0
- package/dist/two-d/render/SceneTransition.js +458 -0
- package/dist/two-d/render/SceneTransition.js.map +1 -0
- package/dist/two-d/render/ScreenEffects.d.ts.map +1 -1
- package/dist/two-d/render/ScreenEffects.js +2 -1
- package/dist/two-d/render/ScreenEffects.js.map +1 -1
- package/dist/two-d/render/SkeletalSprite.d.ts.map +1 -1
- package/dist/two-d/render/SkeletalSprite.js +2 -1
- package/dist/two-d/render/SkeletalSprite.js.map +1 -1
- package/dist/two-d/render/Types2D.d.ts +2 -2
- package/dist/two-d/render/Types2D.d.ts.map +1 -1
- package/dist/two-d/render/Types2D.js +2 -2
- package/dist/two-d/render/Types2D.js.map +1 -1
- package/dist/two-d/render/index.d.ts +2 -0
- package/dist/two-d/render/index.d.ts.map +1 -1
- package/dist/two-d/render/index.js +1 -0
- package/dist/two-d/render/index.js.map +1 -1
- package/dist/two-d/ui/Bar.d.ts.map +1 -1
- package/dist/two-d/ui/Bar.js +3 -5
- package/dist/two-d/ui/Bar.js.map +1 -1
- package/dist/two-d/ui/Button.d.ts +23 -0
- package/dist/two-d/ui/Button.d.ts.map +1 -1
- package/dist/two-d/ui/Button.js +37 -0
- package/dist/two-d/ui/Button.js.map +1 -1
- package/dist/two-d/ui/Dropdown.d.ts +5 -1
- package/dist/two-d/ui/Dropdown.d.ts.map +1 -1
- package/dist/two-d/ui/Dropdown.js +8 -1
- package/dist/two-d/ui/Dropdown.js.map +1 -1
- package/dist/two-d/ui/DropdownView.d.ts +63 -3
- package/dist/two-d/ui/DropdownView.d.ts.map +1 -1
- package/dist/two-d/ui/DropdownView.js +168 -9
- package/dist/two-d/ui/DropdownView.js.map +1 -1
- package/dist/two-d/ui/FloatingText.d.ts.map +1 -1
- package/dist/two-d/ui/FloatingText.js +2 -1
- package/dist/two-d/ui/FloatingText.js.map +1 -1
- package/dist/two-d/ui/IconGrid.d.ts.map +1 -1
- package/dist/two-d/ui/IconGrid.js +2 -1
- package/dist/two-d/ui/IconGrid.js.map +1 -1
- package/dist/two-d/ui/ListView.d.ts.map +1 -1
- package/dist/two-d/ui/ListView.js +2 -1
- package/dist/two-d/ui/ListView.js.map +1 -1
- package/dist/two-d/ui/ScrollBox.d.ts +96 -0
- package/dist/two-d/ui/ScrollBox.d.ts.map +1 -1
- package/dist/two-d/ui/ScrollBox.js +218 -5
- package/dist/two-d/ui/ScrollBox.js.map +1 -1
- package/dist/two-d/ui/ScrollText.d.ts +131 -0
- package/dist/two-d/ui/ScrollText.d.ts.map +1 -0
- package/dist/two-d/ui/ScrollText.js +218 -0
- package/dist/two-d/ui/ScrollText.js.map +1 -0
- package/dist/two-d/ui/Slider.d.ts.map +1 -1
- package/dist/two-d/ui/Slider.js +4 -4
- package/dist/two-d/ui/Slider.js.map +1 -1
- package/dist/two-d/ui/Tooltip.d.ts +70 -1
- package/dist/two-d/ui/Tooltip.d.ts.map +1 -1
- package/dist/two-d/ui/Tooltip.js +115 -3
- package/dist/two-d/ui/Tooltip.js.map +1 -1
- package/dist/two-d/ui/Window.d.ts +35 -2
- package/dist/two-d/ui/Window.d.ts.map +1 -1
- package/dist/two-d/ui/Window.js +58 -3
- package/dist/two-d/ui/Window.js.map +1 -1
- package/dist/two-d/ui/index.d.ts +7 -5
- package/dist/two-d/ui/index.d.ts.map +1 -1
- package/dist/two-d/ui/index.js +3 -2
- package/dist/two-d/ui/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +14 -3
- package/sbom.cdx.json +19 -260
- package/tools/audio.d.mts +75 -0
- package/tools/audio.mjs +437 -0
- package/tools/browser-driver.mjs +3 -3
- package/tools/browser-smoke.mjs +19 -2
- package/tools/build-tablebases.mjs +7 -3
- package/tools/compile-openings.mjs +7 -3
- package/tools/compile-resources.d.mts +2 -0
- package/tools/compile-resources.mjs +13 -1
- package/tools/emit-page.d.mts +6 -0
- package/tools/emit-page.mjs +43 -3
- package/tools/find-chrome.mjs +4 -2
- package/tools/init.mjs +11 -3
- package/tools/mwl.mjs +144 -2
- package/tools/play-uci.mjs +9 -5
- package/tools/vite.mjs +9 -1
- package/tools.md +2 -1
|
@@ -0,0 +1,218 @@
|
|
|
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 and `resize(width)`
|
|
98
|
+
* re-wraps in place; the caller no longer 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.width_ = options.width;
|
|
113
|
+
this.maxHeight = options.maxHeight;
|
|
114
|
+
this.body = new Label({ ...options.label, text: options.text ?? '', wrapWidth: options.width - 10 });
|
|
115
|
+
this.box = new ScrollBox({
|
|
116
|
+
width: options.width,
|
|
117
|
+
height: options.maxHeight,
|
|
118
|
+
autoHeight: true,
|
|
119
|
+
touch: options.touch ?? true,
|
|
120
|
+
keyboard: true,
|
|
121
|
+
});
|
|
122
|
+
this.box.content.addChild(this.body);
|
|
123
|
+
this.addChild(this.box);
|
|
124
|
+
this.measure();
|
|
125
|
+
}
|
|
126
|
+
/** the text's own height, which sizes the box; its own method so a test can supply it */
|
|
127
|
+
measureHeight() {
|
|
128
|
+
return this.body.height;
|
|
129
|
+
}
|
|
130
|
+
measure() {
|
|
131
|
+
this.box.setContentHeight(this.measureHeight());
|
|
132
|
+
}
|
|
133
|
+
/** the current width, what `resize` last set it to */
|
|
134
|
+
get viewWidth() {
|
|
135
|
+
return this.width_;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Sets the width in place: the text re-wraps at the new width and the box resizes and
|
|
139
|
+
* re-measures, so a layout change does not rebuild the widget.
|
|
140
|
+
*/
|
|
141
|
+
resize(width) {
|
|
142
|
+
this.width_ = width;
|
|
143
|
+
this.body.setWrapWidth(width - 10);
|
|
144
|
+
this.box.resize(width, this.maxHeight);
|
|
145
|
+
this.measure();
|
|
146
|
+
}
|
|
147
|
+
setText(text) {
|
|
148
|
+
this.body.setText(text);
|
|
149
|
+
this.measure();
|
|
150
|
+
this.box.scrollTo(0);
|
|
151
|
+
}
|
|
152
|
+
/** call each frame for touch coasting */
|
|
153
|
+
update(dt) {
|
|
154
|
+
this.box.update(dt);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* One line of text that stays on one line: when it is wider than `width` it slides back and forth
|
|
159
|
+
* inside a clipped window (`marqueeOffset`), driven by `update(dt)`. Under reduced motion it holds
|
|
160
|
+
* still, cut short with an ellipsis, instead of moving.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* import { MarqueeLabel } from '@datamoc/mw_games/two-d/ui';
|
|
165
|
+
*
|
|
166
|
+
* const title = new MarqueeLabel({ width: 160, text: 'A very long track title that cannot fit' });
|
|
167
|
+
* title.update(1 / 60); // once a frame from the scene
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export class MarqueeLabel extends Container {
|
|
171
|
+
constructor(options) {
|
|
172
|
+
super();
|
|
173
|
+
this.clip = new Graphics();
|
|
174
|
+
this.source = '';
|
|
175
|
+
this.fullWidth = 0;
|
|
176
|
+
this.time = 0;
|
|
177
|
+
this.width_ = options.width;
|
|
178
|
+
this.speed = options.speed ?? 40;
|
|
179
|
+
this.pause = options.pause ?? 1;
|
|
180
|
+
this.labelOptions = options.label ?? {};
|
|
181
|
+
this.body = new Label({ ...this.labelOptions, text: '' });
|
|
182
|
+
this.clip.rect(0, 0, options.width, 4096).fill({ color: 0xffffff });
|
|
183
|
+
this.addChild(this.body, this.clip);
|
|
184
|
+
this.body.mask = this.clip;
|
|
185
|
+
this.setText(options.text ?? '');
|
|
186
|
+
}
|
|
187
|
+
/** the text's width in pixels; its own method so a test can supply it */
|
|
188
|
+
measureWidth(text) {
|
|
189
|
+
const probe = new Label({ ...this.labelOptions, text });
|
|
190
|
+
const width = probe.width;
|
|
191
|
+
probe.destroy();
|
|
192
|
+
return width;
|
|
193
|
+
}
|
|
194
|
+
setText(text) {
|
|
195
|
+
this.source = text;
|
|
196
|
+
this.fullWidth = this.measureWidth(text);
|
|
197
|
+
this.time = 0;
|
|
198
|
+
this.apply();
|
|
199
|
+
}
|
|
200
|
+
apply() {
|
|
201
|
+
if (reducedMotion()) {
|
|
202
|
+
this.body.setText(ellipsize(this.source, this.width_, (text) => this.measureWidth(text)));
|
|
203
|
+
this.body.x = 0;
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
this.body.setText(this.source);
|
|
207
|
+
this.body.x = -marqueeOffset(this.fullWidth, this.width_, this.time, this.speed, this.pause);
|
|
208
|
+
}
|
|
209
|
+
/** where the text is shifted to now (0 until it has waited out its first pause) */
|
|
210
|
+
get shift() {
|
|
211
|
+
return 0 - this.body.x;
|
|
212
|
+
}
|
|
213
|
+
update(dt) {
|
|
214
|
+
this.time += dt;
|
|
215
|
+
this.apply();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=ScrollText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollText.js","sourceRoot":"","sources":["../../../src/two-d/ui/ScrollText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAqB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,QAAgB,EAAE,OAAiC,EAAE,QAAQ,GAAG,GAAG;IAC1G,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC;IACvB,OAAO,GAAG,GAAG,IAAI,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,QAAQ;YAAE,GAAG,GAAG,MAAM,CAAC;;YAC7E,IAAI,GAAG,MAAM,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAC5B,IAAY,EACZ,QAAgB,EAChB,QAAgB,EAChB,OAAiC,EACjC,QAAQ,GAAG,GAAG;IAEd,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI;YAAE,IAAI,GAAG,IAAI,CAAC;aAC/C,CAAC;YACL,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,IAAI,GAAG,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvG,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACjD,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,GAAG,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,SAAiB,EAAE,QAAgB,EAAE,IAAY,EAAE,KAAK,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;IACrG,MAAM,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1B,MAAM,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC;IAC/C,IAAI,EAAE,GAAG,KAAK;QAAE,OAAO,CAAC,CAAC;IACzB,IAAI,EAAE,GAAG,KAAK,GAAG,KAAK;QAAE,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;IACpD,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1C,OAAO,MAAM,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAClD,CAAC;AAYD;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,UAAW,SAAQ,SAAS;IAMxC,YAAY,OAA0B;QACrC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,GAAG,EAAE,EAAE,CAAC,CAAC;QACrG,IAAI,CAAC,GAAG,GAAG,IAAI,SAAS,CAAC;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,SAAS;YACzB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI;YAC5B,QAAQ,EAAE,IAAI;SACd,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,yFAAyF;IAC/E,aAAa;QACtB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IACzB,CAAC;IAEO,OAAO;QACd,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,sDAAsD;IACtD,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,KAAa;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,IAAY;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IAED,yCAAyC;IACzC,MAAM,CAAC,EAAU;QAChB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACrB,CAAC;CACD;AAYD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,YAAa,SAAQ,SAAS;IAW1C,YAAY,OAA4B;QACvC,KAAK,EAAE,CAAC;QAVQ,SAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QAK/B,WAAM,GAAG,EAAE,CAAC;QACZ,cAAS,GAAG,CAAC,CAAC;QACd,SAAI,GAAG,CAAC,CAAC;QAIhB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;IAED,yEAAyE;IAC/D,YAAY,CAAC,IAAY;QAClC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1B,KAAK,CAAC,OAAO,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,CAAC,IAAY;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,KAAK,EAAE,CAAC;IACd,CAAC;IAEO,KAAK;QACZ,IAAI,aAAa,EAAE,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC1F,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9F,CAAC;IAED,mFAAmF;IACnF,IAAI,KAAK;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,CAAC,EAAU;QAChB,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAChB,IAAI,CAAC,KAAK,EAAE,CAAC;IACd,CAAC;CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Slider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Slider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAG9C,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAI,EAAE,GAAG,SAAI,GAAG,MAAM,CAGtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAI,EAAE,GAAG,SAAI,EAAE,IAAI,SAAI,GAAG,MAAM,CAMlF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,MAAO,SAAQ,SAAS;IACpC,QAAQ,CAAC,QAAQ,iBAAwB;IAEzC,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,IAAI,CAAkB;IAE9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAU;IAE3B,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IAEnD,YAAY,OAAO,EAAE,aAAa,EAyBjC;IAED,yCAAyC;IACzC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,kCAAkC;IAClC,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,WAAW,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAInC;IAED,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAS5B;IAED,6EAA6E;IAC7E,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAElC;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAI1C;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAIzB;IAEF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAGzB;IAEF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAEvB;IAEF,OAAO,CAAC,IAAI;IAyBH,OAAO,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAGpE;CACD"}
|
package/dist/two-d/ui/Slider.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Container, Graphics } from 'pixi.js';
|
|
2
|
+
import { clamp } from '../../core/Math.js';
|
|
2
3
|
import { Signal } from '../../core/Signal.js';
|
|
3
4
|
import { theme, themeChanged } from './theme.js';
|
|
4
5
|
/**
|
|
@@ -15,7 +16,7 @@ import { theme, themeChanged } from './theme.js';
|
|
|
15
16
|
export function sliderFraction(value, min = 0, max = 1) {
|
|
16
17
|
if (!(max > min))
|
|
17
18
|
return 0;
|
|
18
|
-
return
|
|
19
|
+
return clamp((value - min) / (max - min), 0, 1);
|
|
19
20
|
}
|
|
20
21
|
/**
|
|
21
22
|
* The value at a 0-to-1 position on the track, snapped to `step` and clamped to `[min, max]`.
|
|
@@ -30,8 +31,7 @@ export function sliderFraction(value, min = 0, max = 1) {
|
|
|
30
31
|
* ```
|
|
31
32
|
*/
|
|
32
33
|
export function sliderValueAt(fraction, min = 0, max = 1, step = 0) {
|
|
33
|
-
const
|
|
34
|
-
const raw = min + clamped * (max - min);
|
|
34
|
+
const raw = min + clamp(fraction, 0, 1) * (max - min);
|
|
35
35
|
if (!(step > 0))
|
|
36
36
|
return raw;
|
|
37
37
|
const decimals = (String(step).split('.')[1] ?? '').length;
|
|
@@ -139,7 +139,7 @@ export class Slider extends Container {
|
|
|
139
139
|
return sliderValueAt(sliderFraction(value, this.min, this.max), this.min, this.max, this.step);
|
|
140
140
|
}
|
|
141
141
|
fractionAt(localX) {
|
|
142
|
-
return this.trackLength > 0 ?
|
|
142
|
+
return this.trackLength > 0 ? clamp((localX - this.knobSize / 2) / this.trackLength, 0, 1) : 0;
|
|
143
143
|
}
|
|
144
144
|
draw() {
|
|
145
145
|
const t = theme();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../../src/two-d/ui/Slider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkBjD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC;IAC7D,IAAI,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAC3B,OAAO,
|
|
1
|
+
{"version":3,"file":"Slider.js","sourceRoot":"","sources":["../../../src/two-d/ui/Slider.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Container } from 'pixi.js';
|
|
2
|
+
import type { PointerTracker } from '../../core/Input.ts';
|
|
3
|
+
import { Button } from './Button.ts';
|
|
2
4
|
export interface TooltipOptions {
|
|
3
5
|
/** seconds the pointer must rest before the tooltip appears; defaults to 0.4 */
|
|
4
6
|
delay?: number;
|
|
@@ -68,11 +70,13 @@ export declare class Tooltip extends Container {
|
|
|
68
70
|
/**
|
|
69
71
|
* The pointer is resting on something with `text` to explain, at `x`/`y`.
|
|
70
72
|
*
|
|
73
|
+
* `delay` replaces the tooltip's own wait for this one call (a touch long-press waits longer than a hover).
|
|
74
|
+
*
|
|
71
75
|
* Safe to call every frame with the same arguments: the delay keeps counting rather than
|
|
72
76
|
* restarting. Calling it with *different* text restarts the wait, so sweeping across a row
|
|
73
77
|
* of icons shows the one the pointer settles on rather than the first one it crossed.
|
|
74
78
|
*/
|
|
75
|
-
hover(text: string, x: number, y: number): void;
|
|
79
|
+
hover(text: string, x: number, y: number, delay?: number): void;
|
|
76
80
|
/** the pointer left: cancels a pending tooltip and hides a shown one */
|
|
77
81
|
leave(): void;
|
|
78
82
|
get isShowing(): boolean;
|
|
@@ -105,4 +109,69 @@ export declare class Tooltip extends Container {
|
|
|
105
109
|
/** offsets from the anchor, then pulls back inside the viewport if that would overflow it */
|
|
106
110
|
private place;
|
|
107
111
|
}
|
|
112
|
+
/** a rectangle on screen that has something to explain, in the same space as the pointer positions fed to the host */
|
|
113
|
+
export interface TooltipTarget {
|
|
114
|
+
bounds(): {
|
|
115
|
+
x: number;
|
|
116
|
+
y: number;
|
|
117
|
+
width: number;
|
|
118
|
+
height: number;
|
|
119
|
+
};
|
|
120
|
+
/** what to say now, or undefined for nothing */
|
|
121
|
+
text(): string | undefined;
|
|
122
|
+
/** false while the target is hidden; a hidden one explains nothing. True when omitted */
|
|
123
|
+
active?(): boolean;
|
|
124
|
+
}
|
|
125
|
+
export interface TooltipHostOptions {
|
|
126
|
+
/** the tooltip to drive; a default one when omitted */
|
|
127
|
+
tooltip?: Tooltip;
|
|
128
|
+
/** seconds a finger or button must rest before the tooltip shows on a press; 0.5 when omitted */
|
|
129
|
+
longPress?: number;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Drives one `Tooltip` from rectangles instead of from each widget's own pointer events, which is
|
|
133
|
+
* what makes it work in the two places hover cannot reach: on a touch screen (a press that rests
|
|
134
|
+
* for `longPress` seconds shows the text, and releasing hides it) and over a disabled `Button`,
|
|
135
|
+
* which has no pointer events to receive (the host tests the button's bounds itself, and a greyed-out
|
|
136
|
+
* button is exactly the one worth explaining).
|
|
137
|
+
*
|
|
138
|
+
* Feed it pointer positions with `pointerMove`, `pointerDown` and `pointerUp` (or `attach` a
|
|
139
|
+
* `PointerTracker`), and call `update(dt)` each frame. The later a target was added, the higher it
|
|
140
|
+
* counts when targets overlap.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```ts
|
|
144
|
+
* import { Button, TooltipHost } from '@datamoc/mw_games/two-d/ui';
|
|
145
|
+
*
|
|
146
|
+
* const host = new TooltipHost({ longPress: 0.4 });
|
|
147
|
+
* host.tooltip.setViewport(800, 600);
|
|
148
|
+
*
|
|
149
|
+
* const test = new Button({ width: 80, height: 28, text: 'Test', disabled: true,
|
|
150
|
+
* tooltip: () => 'Build a road across the gap first' });
|
|
151
|
+
* host.addButton(test);
|
|
152
|
+
*
|
|
153
|
+
* host.pointerMove(10, 10); // over the disabled button: the text still shows after the hover delay
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export declare class TooltipHost extends Container {
|
|
157
|
+
readonly tooltip: Tooltip;
|
|
158
|
+
private readonly longPress;
|
|
159
|
+
private readonly targets;
|
|
160
|
+
constructor(options?: TooltipHostOptions);
|
|
161
|
+
/** @returns a function that removes the target again */
|
|
162
|
+
add(target: TooltipTarget): () => void;
|
|
163
|
+
/** a button's own bounds and `tooltip`, whether or not the button is disabled */
|
|
164
|
+
addButton(button: Button): () => void;
|
|
165
|
+
private targetAt;
|
|
166
|
+
/** a pointer with no button down moved: the usual hover */
|
|
167
|
+
pointerMove(x: number, y: number): void;
|
|
168
|
+
/** a finger or button went down: the tooltip shows once it has rested for `longPress` */
|
|
169
|
+
pointerDown(x: number, y: number): void;
|
|
170
|
+
/** the finger or button came up */
|
|
171
|
+
pointerUp(): void;
|
|
172
|
+
/** wires a `PointerTracker` (`Input.attachPointer`) to the host; returns the function that unwires it */
|
|
173
|
+
attach(pointer: PointerTracker): () => void;
|
|
174
|
+
/** @returns true on the frame the tooltip appears, as `Tooltip.update` does */
|
|
175
|
+
update(dt: number): boolean;
|
|
176
|
+
}
|
|
108
177
|
//# sourceMappingURL=Tooltip.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../src/two-d/ui/Tooltip.ts"],"names":[],"mappings":"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"}
|
package/dist/two-d/ui/Tooltip.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Container } from 'pixi.js';
|
|
2
|
+
import { Button } from './Button.js';
|
|
2
3
|
import { Label } from './Label.js';
|
|
3
4
|
import { Window } from './Window.js';
|
|
4
5
|
import { theme } from './theme.js';
|
|
@@ -68,11 +69,13 @@ export class Tooltip extends Container {
|
|
|
68
69
|
/**
|
|
69
70
|
* The pointer is resting on something with `text` to explain, at `x`/`y`.
|
|
70
71
|
*
|
|
72
|
+
* `delay` replaces the tooltip's own wait for this one call (a touch long-press waits longer than a hover).
|
|
73
|
+
*
|
|
71
74
|
* Safe to call every frame with the same arguments: the delay keeps counting rather than
|
|
72
75
|
* restarting. Calling it with *different* text restarts the wait, so sweeping across a row
|
|
73
76
|
* of icons shows the one the pointer settles on rather than the first one it crossed.
|
|
74
77
|
*/
|
|
75
|
-
hover(text, x, y) {
|
|
78
|
+
hover(text, x, y, delay = this.delay) {
|
|
76
79
|
if (this.pending && this.pending.text === text) {
|
|
77
80
|
this.pending.x = x;
|
|
78
81
|
this.pending.y = y;
|
|
@@ -80,7 +83,7 @@ export class Tooltip extends Container {
|
|
|
80
83
|
this.place();
|
|
81
84
|
return;
|
|
82
85
|
}
|
|
83
|
-
this.pending = { text, x, y };
|
|
86
|
+
this.pending = { text, x, y, delay };
|
|
84
87
|
this.waited = 0;
|
|
85
88
|
this.visible = false;
|
|
86
89
|
}
|
|
@@ -109,7 +112,7 @@ export class Tooltip extends Container {
|
|
|
109
112
|
if (!this.pending || this.visible)
|
|
110
113
|
return false;
|
|
111
114
|
this.waited += dt;
|
|
112
|
-
if (this.waited < this.delay)
|
|
115
|
+
if (this.waited < this.pending.delay)
|
|
113
116
|
return false;
|
|
114
117
|
this.body.setText(this.pending.text);
|
|
115
118
|
const t = theme();
|
|
@@ -160,4 +163,113 @@ export class Tooltip extends Container {
|
|
|
160
163
|
this.panel.y = y;
|
|
161
164
|
}
|
|
162
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Drives one `Tooltip` from rectangles instead of from each widget's own pointer events, which is
|
|
168
|
+
* what makes it work in the two places hover cannot reach: on a touch screen (a press that rests
|
|
169
|
+
* for `longPress` seconds shows the text, and releasing hides it) and over a disabled `Button`,
|
|
170
|
+
* which has no pointer events to receive (the host tests the button's bounds itself, and a greyed-out
|
|
171
|
+
* button is exactly the one worth explaining).
|
|
172
|
+
*
|
|
173
|
+
* Feed it pointer positions with `pointerMove`, `pointerDown` and `pointerUp` (or `attach` a
|
|
174
|
+
* `PointerTracker`), and call `update(dt)` each frame. The later a target was added, the higher it
|
|
175
|
+
* counts when targets overlap.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* import { Button, TooltipHost } from '@datamoc/mw_games/two-d/ui';
|
|
180
|
+
*
|
|
181
|
+
* const host = new TooltipHost({ longPress: 0.4 });
|
|
182
|
+
* host.tooltip.setViewport(800, 600);
|
|
183
|
+
*
|
|
184
|
+
* const test = new Button({ width: 80, height: 28, text: 'Test', disabled: true,
|
|
185
|
+
* tooltip: () => 'Build a road across the gap first' });
|
|
186
|
+
* host.addButton(test);
|
|
187
|
+
*
|
|
188
|
+
* host.pointerMove(10, 10); // over the disabled button: the text still shows after the hover delay
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
export class TooltipHost extends Container {
|
|
192
|
+
constructor(options = {}) {
|
|
193
|
+
super();
|
|
194
|
+
this.targets = [];
|
|
195
|
+
this.tooltip = options.tooltip ?? new Tooltip();
|
|
196
|
+
this.longPress = options.longPress ?? 0.5;
|
|
197
|
+
this.addChild(this.tooltip);
|
|
198
|
+
}
|
|
199
|
+
/** @returns a function that removes the target again */
|
|
200
|
+
add(target) {
|
|
201
|
+
this.targets.push(target);
|
|
202
|
+
return () => {
|
|
203
|
+
const at = this.targets.indexOf(target);
|
|
204
|
+
if (at >= 0)
|
|
205
|
+
this.targets.splice(at, 1);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/** a button's own bounds and `tooltip`, whether or not the button is disabled */
|
|
209
|
+
addButton(button) {
|
|
210
|
+
return this.add({
|
|
211
|
+
bounds: () => {
|
|
212
|
+
const rect = button.getBounds();
|
|
213
|
+
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
|
|
214
|
+
},
|
|
215
|
+
text: () => button.tooltip,
|
|
216
|
+
active: () => {
|
|
217
|
+
for (let node = button; node; node = node.parent)
|
|
218
|
+
if (!node.visible)
|
|
219
|
+
return false;
|
|
220
|
+
return true;
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
targetAt(x, y) {
|
|
225
|
+
for (let index = this.targets.length - 1; index >= 0; index--) {
|
|
226
|
+
const target = this.targets[index];
|
|
227
|
+
if (target.active && !target.active())
|
|
228
|
+
continue;
|
|
229
|
+
const rect = target.bounds();
|
|
230
|
+
if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
|
|
231
|
+
return target.text() === undefined ? null : target;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
/** a pointer with no button down moved: the usual hover */
|
|
237
|
+
pointerMove(x, y) {
|
|
238
|
+
const text = this.targetAt(x, y)?.text();
|
|
239
|
+
if (text)
|
|
240
|
+
this.tooltip.hover(text, x, y);
|
|
241
|
+
else
|
|
242
|
+
this.tooltip.leave();
|
|
243
|
+
}
|
|
244
|
+
/** a finger or button went down: the tooltip shows once it has rested for `longPress` */
|
|
245
|
+
pointerDown(x, y) {
|
|
246
|
+
const text = this.targetAt(x, y)?.text();
|
|
247
|
+
if (text)
|
|
248
|
+
this.tooltip.hover(text, x, y, this.longPress);
|
|
249
|
+
else
|
|
250
|
+
this.tooltip.leave();
|
|
251
|
+
}
|
|
252
|
+
/** the finger or button came up */
|
|
253
|
+
pointerUp() {
|
|
254
|
+
this.tooltip.leave();
|
|
255
|
+
}
|
|
256
|
+
/** wires a `PointerTracker` (`Input.attachPointer`) to the host; returns the function that unwires it */
|
|
257
|
+
attach(pointer) {
|
|
258
|
+
const onMove = (p) => this.pointerMove(p.x, p.y);
|
|
259
|
+
const onDown = (p) => this.pointerDown(p.x, p.y);
|
|
260
|
+
const onUp = () => this.pointerUp();
|
|
261
|
+
pointer.move.add(onMove);
|
|
262
|
+
pointer.down.add(onDown);
|
|
263
|
+
pointer.up.add(onUp);
|
|
264
|
+
return () => {
|
|
265
|
+
pointer.move.remove(onMove);
|
|
266
|
+
pointer.down.remove(onDown);
|
|
267
|
+
pointer.up.remove(onUp);
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/** @returns true on the frame the tooltip appears, as `Tooltip.update` does */
|
|
271
|
+
update(dt) {
|
|
272
|
+
return this.tooltip.update(dt);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
163
275
|
//# sourceMappingURL=Tooltip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/two-d/ui/Tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../src/two-d/ui/Tooltip.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
import { Container } from 'pixi.js';
|
|
2
2
|
import { Signal } from '../../core/Signal.ts';
|
|
3
|
+
import { type OpenAnimationKind } from '../render/SceneTransition.ts';
|
|
3
4
|
import type { Action } from '../../core/Input.ts';
|
|
4
5
|
export interface WindowColors {
|
|
5
6
|
background?: number;
|
|
6
7
|
border?: number;
|
|
7
8
|
title?: number;
|
|
8
9
|
}
|
|
10
|
+
/** how a window opens or closes: `pop` (springs out), `grow`, `slide` (up from below) or `fade` */
|
|
11
|
+
export interface WindowAnimation {
|
|
12
|
+
animation: OpenAnimationKind;
|
|
13
|
+
/** where `pop` and `grow` come from and go back to, in the window's parent space; the window's centre when omitted */
|
|
14
|
+
from?: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
/** seconds; 0.25 when omitted */
|
|
19
|
+
duration?: number;
|
|
20
|
+
}
|
|
9
21
|
export interface WindowOptions {
|
|
10
22
|
width: number;
|
|
11
23
|
height: number;
|
|
@@ -86,6 +98,7 @@ export declare class Window extends Container {
|
|
|
86
98
|
private blocker;
|
|
87
99
|
private readonly themeListener;
|
|
88
100
|
private isClosed;
|
|
101
|
+
private motion;
|
|
89
102
|
private colors;
|
|
90
103
|
constructor(options: WindowOptions);
|
|
91
104
|
/** reapplies the current theme to the frame and title, without changing size or content */
|
|
@@ -121,13 +134,33 @@ export declare class Window extends Container {
|
|
|
121
134
|
*/
|
|
122
135
|
get closed(): boolean;
|
|
123
136
|
/** called each frame while this window is the top of the stack */
|
|
124
|
-
update(
|
|
137
|
+
update(dt: number): void;
|
|
138
|
+
/** puts the window at `progress` of its animation: scaled about the origin, faded, pushed down by a slide */
|
|
139
|
+
private applyMotion;
|
|
140
|
+
/**
|
|
141
|
+
* Plays the opening animation from the window's current position. The stack calls `update(dt)`
|
|
142
|
+
* on its top window, which drives it. Under reduced motion the window simply appears.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```ts
|
|
146
|
+
* import { Window } from '@datamoc/mw_games/two-d/ui';
|
|
147
|
+
*
|
|
148
|
+
* const window = new Window({ width: 240, height: 120, title: 'Result' });
|
|
149
|
+
* window.open({ animation: 'pop' });
|
|
150
|
+
* window.update(0.25); // normally the WindowStack's update does this
|
|
151
|
+
* console.log(window.scale.x); // 1
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
open(animation?: WindowAnimation): void;
|
|
125
155
|
/**
|
|
126
156
|
* Announces the close and frees this window and its contents. Idempotent, so a second
|
|
127
157
|
* `close()` (a `pop()` racing a `cancel`, a `closeAll()` after a manual close) is a no-op
|
|
128
158
|
* rather than a second `destroy`. The instance is spent afterwards; see `closed`.
|
|
159
|
+
*
|
|
160
|
+
* With `animation` it plays the opening backwards first and closes when it ends (driven by
|
|
161
|
+
* `update(dt)`), unless reduced motion is on, when it closes at once.
|
|
129
162
|
*/
|
|
130
|
-
close(): void;
|
|
163
|
+
close(animation?: WindowAnimation): void;
|
|
131
164
|
/** positions the window in a viewport of the given size, per its anchor */
|
|
132
165
|
place(viewportWidth: number, viewportHeight: number): void;
|
|
133
166
|
/**
|