@thunderclap-engine/engine 0.0.0-stage → 1.1.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/CHANGELOG.md +390 -0
- package/LICENSE +21 -0
- package/README.md +333 -2
- package/dist/analytics/analytics.d.ts +80 -0
- package/dist/analytics/analytics.js +129 -0
- package/dist/analytics/index.d.ts +1 -0
- package/dist/analytics/index.js +1 -0
- package/dist/anim/aim.d.ts +43 -0
- package/dist/anim/aim.js +157 -0
- package/dist/anim/clip.d.ts +98 -0
- package/dist/anim/clip.js +282 -0
- package/dist/anim/compress.d.ts +65 -0
- package/dist/anim/compress.js +339 -0
- package/dist/anim/foot-ik.d.ts +74 -0
- package/dist/anim/foot-ik.js +241 -0
- package/dist/anim/graph.d.ts +153 -0
- package/dist/anim/graph.js +532 -0
- package/dist/anim/ik.d.ts +105 -0
- package/dist/anim/ik.js +435 -0
- package/dist/anim/index.d.ts +36 -0
- package/dist/anim/index.js +21 -0
- package/dist/anim/match.d.ts +66 -0
- package/dist/anim/match.js +153 -0
- package/dist/anim/mixer.d.ts +113 -0
- package/dist/anim/mixer.js +314 -0
- package/dist/anim/morph.d.ts +41 -0
- package/dist/anim/morph.js +94 -0
- package/dist/anim/pose.d.ts +74 -0
- package/dist/anim/pose.js +254 -0
- package/dist/anim/quat.d.ts +44 -0
- package/dist/anim/quat.js +187 -0
- package/dist/anim/retarget.d.ts +97 -0
- package/dist/anim/retarget.js +366 -0
- package/dist/anim/root-motion.d.ts +44 -0
- package/dist/anim/root-motion.js +224 -0
- package/dist/anim/skin-pose.d.ts +39 -0
- package/dist/anim/skin-pose.js +53 -0
- package/dist/anim/socket.d.ts +47 -0
- package/dist/anim/socket.js +84 -0
- package/dist/anim/spring-chain.d.ts +73 -0
- package/dist/anim/spring-chain.js +294 -0
- package/dist/assets/atlas.d.ts +90 -0
- package/dist/assets/atlas.js +212 -0
- package/dist/assets/baked.d.ts +33 -0
- package/dist/assets/baked.js +38 -0
- package/dist/assets/bundle.d.ts +88 -0
- package/dist/assets/bundle.js +464 -0
- package/dist/assets/cache.d.ts +56 -0
- package/dist/assets/cache.js +123 -0
- package/dist/assets/gltf-load.d.ts +252 -0
- package/dist/assets/gltf-load.js +661 -0
- package/dist/assets/gltf-skin.d.ts +36 -0
- package/dist/assets/gltf-skin.js +109 -0
- package/dist/assets/gltf.d.ts +706 -0
- package/dist/assets/gltf.js +1376 -0
- package/dist/assets/index.d.ts +20 -0
- package/dist/assets/index.js +10 -0
- package/dist/assets/ktx2.d.ts +71 -0
- package/dist/assets/ktx2.js +213 -0
- package/dist/assets/manifest.d.ts +79 -0
- package/dist/assets/manifest.js +7 -0
- package/dist/assets/meshopt.d.ts +23 -0
- package/dist/assets/meshopt.js +403 -0
- package/dist/audio/audio.d.ts +733 -0
- package/dist/audio/audio.js +2013 -0
- package/dist/audio/dsp.d.ts +61 -0
- package/dist/audio/dsp.js +159 -0
- package/dist/audio/duck.d.ts +44 -0
- package/dist/audio/duck.js +101 -0
- package/dist/audio/envelope.d.ts +53 -0
- package/dist/audio/envelope.js +106 -0
- package/dist/audio/index.d.ts +13 -0
- package/dist/audio/index.js +14 -0
- package/dist/audio/music.d.ts +113 -0
- package/dist/audio/music.js +548 -0
- package/dist/audio/occlusion.d.ts +55 -0
- package/dist/audio/occlusion.js +61 -0
- package/dist/audio/persist.d.ts +23 -0
- package/dist/audio/persist.js +27 -0
- package/dist/audio/recipes.d.ts +55 -0
- package/dist/audio/recipes.js +227 -0
- package/dist/audio/send.d.ts +41 -0
- package/dist/audio/send.js +118 -0
- package/dist/audio/sprites.d.ts +59 -0
- package/dist/audio/sprites.js +43 -0
- package/dist/audio/synth.d.ts +103 -0
- package/dist/audio/synth.js +197 -0
- package/dist/audio/variations.d.ts +25 -0
- package/dist/audio/variations.js +55 -0
- package/dist/audio/zones.d.ts +100 -0
- package/dist/audio/zones.js +167 -0
- package/dist/core/detached-surface.d.ts +44 -0
- package/dist/core/detached-surface.js +104 -0
- package/dist/core/events.d.ts +24 -0
- package/dist/core/events.js +43 -0
- package/dist/core/game.d.ts +409 -0
- package/dist/core/game.js +530 -0
- package/dist/core/hash.d.ts +24 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.js +9 -0
- package/dist/core/loop.d.ts +113 -0
- package/dist/core/loop.js +185 -0
- package/dist/core/math.d.ts +58 -0
- package/dist/core/math.js +210 -0
- package/dist/core/noise.d.ts +40 -0
- package/dist/core/noise.js +247 -0
- package/dist/core/pool.d.ts +42 -0
- package/dist/core/pool.js +85 -0
- package/dist/core/random.d.ts +61 -0
- package/dist/core/random.js +199 -0
- package/dist/core/scene.d.ts +79 -0
- package/dist/core/scene.js +195 -0
- package/dist/core/timer.d.ts +66 -0
- package/dist/core/timer.js +286 -0
- package/dist/fx/billboard-wgsl.d.ts +29 -0
- package/dist/fx/billboard-wgsl.js +158 -0
- package/dist/fx/billboard.d.ts +249 -0
- package/dist/fx/billboard.js +702 -0
- package/dist/fx/debug-draw.d.ts +127 -0
- package/dist/fx/debug-draw.js +523 -0
- package/dist/fx/debug-wgsl.d.ts +7 -0
- package/dist/fx/debug-wgsl.js +32 -0
- package/dist/fx/decals-wgsl.d.ts +15 -0
- package/dist/fx/decals-wgsl.js +173 -0
- package/dist/fx/decals.d.ts +216 -0
- package/dist/fx/decals.js +607 -0
- package/dist/fx/effect.d.ts +129 -0
- package/dist/fx/effect.js +349 -0
- package/dist/fx/effects/hit-spark.json +48 -0
- package/dist/fx/effects/index.d.ts +8 -0
- package/dist/fx/effects/index.js +9 -0
- package/dist/fx/effects/magic-aura.json +47 -0
- package/dist/fx/effects/smoke-puff.json +34 -0
- package/dist/fx/emit-surface.d.ts +40 -0
- package/dist/fx/emit-surface.js +124 -0
- package/dist/fx/flicker.d.ts +30 -0
- package/dist/fx/flicker.js +42 -0
- package/dist/fx/index.d.ts +31 -0
- package/dist/fx/index.js +20 -0
- package/dist/fx/particles-wgsl.d.ts +57 -0
- package/dist/fx/particles-wgsl.js +828 -0
- package/dist/fx/particles.d.ts +566 -0
- package/dist/fx/particles.js +1533 -0
- package/dist/fx/random.d.ts +15 -0
- package/dist/fx/random.js +20 -0
- package/dist/fx/sky-wgsl.d.ts +23 -0
- package/dist/fx/sky-wgsl.js +127 -0
- package/dist/fx/sky.d.ts +96 -0
- package/dist/fx/sky.js +175 -0
- package/dist/fx/text-atlas.d.ts +143 -0
- package/dist/fx/text-atlas.js +327 -0
- package/dist/fx/trail-wgsl.d.ts +11 -0
- package/dist/fx/trail-wgsl.js +42 -0
- package/dist/fx/trail.d.ts +194 -0
- package/dist/fx/trail.js +555 -0
- package/dist/fx/water-wgsl.d.ts +34 -0
- package/dist/fx/water-wgsl.js +197 -0
- package/dist/fx/water.d.ts +176 -0
- package/dist/fx/water.js +371 -0
- package/dist/geom/collide/bvh.d.ts +151 -0
- package/dist/geom/collide/bvh.js +493 -0
- package/dist/geom/collide/debug.d.ts +14 -0
- package/dist/geom/collide/debug.js +74 -0
- package/dist/geom/collide/grid.d.ts +26 -0
- package/dist/geom/collide/grid.js +91 -0
- package/dist/geom/collide/index.d.ts +8 -0
- package/dist/geom/collide/index.js +8 -0
- package/dist/geom/collide/queries.d.ts +70 -0
- package/dist/geom/collide/queries.js +583 -0
- package/dist/geom/collide/serialize.d.ts +14 -0
- package/dist/geom/collide/serialize.js +145 -0
- package/dist/geom/collide/shapes.d.ts +161 -0
- package/dist/geom/collide/shapes.js +686 -0
- package/dist/geom/collide/slide.d.ts +66 -0
- package/dist/geom/collide/slide.js +375 -0
- package/dist/geom/collide/tile-slide.d.ts +88 -0
- package/dist/geom/collide/tile-slide.js +255 -0
- package/dist/geom/geometry.d.ts +95 -0
- package/dist/geom/geometry.js +322 -0
- package/dist/geom/heightfield.d.ts +72 -0
- package/dist/geom/heightfield.js +295 -0
- package/dist/geom/hull.d.ts +27 -0
- package/dist/geom/hull.js +279 -0
- package/dist/geom/index.d.ts +35 -0
- package/dist/geom/index.js +23 -0
- package/dist/geom/iso.d.ts +74 -0
- package/dist/geom/iso.js +89 -0
- package/dist/geom/lod.d.ts +29 -0
- package/dist/geom/lod.js +27 -0
- package/dist/geom/ops.d.ts +47 -0
- package/dist/geom/ops.js +285 -0
- package/dist/geom/primitives.d.ts +97 -0
- package/dist/geom/primitives.js +359 -0
- package/dist/geom/shapes.d.ts +43 -0
- package/dist/geom/shapes.js +88 -0
- package/dist/geom/simplify.d.ts +38 -0
- package/dist/geom/simplify.js +519 -0
- package/dist/geom/split.d.ts +37 -0
- package/dist/geom/split.js +413 -0
- package/dist/geom/sweep.d.ts +83 -0
- package/dist/geom/sweep.js +534 -0
- package/dist/geom/tangents.d.ts +16 -0
- package/dist/geom/tangents.js +124 -0
- package/dist/geom/triangulate.d.ts +19 -0
- package/dist/geom/triangulate.js +147 -0
- package/dist/host/default.d.ts +10 -0
- package/dist/host/default.js +10 -0
- package/dist/host/index.d.ts +4 -0
- package/dist/host/index.js +3 -0
- package/dist/host/types.d.ts +144 -0
- package/dist/host/types.js +1 -0
- package/dist/host/web-links.d.ts +38 -0
- package/dist/host/web-links.js +110 -0
- package/dist/host/web.d.ts +30 -0
- package/dist/host/web.js +216 -0
- package/dist/host/xr.d.ts +24 -0
- package/dist/host/xr.js +59 -0
- package/dist/i18n/i18n.d.ts +59 -0
- package/dist/i18n/i18n.js +241 -0
- package/dist/i18n/index.d.ts +3 -0
- package/dist/i18n/index.js +3 -0
- package/dist/i18n/message.d.ts +72 -0
- package/dist/i18n/message.js +369 -0
- package/dist/i18n/negotiate.d.ts +17 -0
- package/dist/i18n/negotiate.js +58 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -0
- package/dist/input/bindings.d.ts +31 -0
- package/dist/input/bindings.js +141 -0
- package/dist/input/clock.d.ts +44 -0
- package/dist/input/clock.js +49 -0
- package/dist/input/follow.d.ts +133 -0
- package/dist/input/follow.js +218 -0
- package/dist/input/gestures.d.ts +281 -0
- package/dist/input/gestures.js +662 -0
- package/dist/input/glyphs.d.ts +35 -0
- package/dist/input/glyphs.js +216 -0
- package/dist/input/gyro.d.ts +85 -0
- package/dist/input/gyro.js +140 -0
- package/dist/input/index.d.ts +19 -0
- package/dist/input/index.js +16 -0
- package/dist/input/input.d.ts +543 -0
- package/dist/input/input.js +1492 -0
- package/dist/input/look.d.ts +327 -0
- package/dist/input/look.js +681 -0
- package/dist/input/magnify.d.ts +177 -0
- package/dist/input/magnify.js +131 -0
- package/dist/input/pointer-dispatch.d.ts +138 -0
- package/dist/input/pointer-dispatch.js +180 -0
- package/dist/input/pointer-router.d.ts +204 -0
- package/dist/input/pointer-router.js +533 -0
- package/dist/input/pointer-sources.d.ts +164 -0
- package/dist/input/pointer-sources.js +306 -0
- package/dist/input/rays.d.ts +138 -0
- package/dist/input/rays.js +615 -0
- package/dist/input/record.d.ts +209 -0
- package/dist/input/record.js +601 -0
- package/dist/input/touch-zones.d.ts +147 -0
- package/dist/input/touch-zones.js +300 -0
- package/dist/input/types.d.ts +158 -0
- package/dist/input/types.js +1 -0
- package/dist/input/xr-source.d.ts +53 -0
- package/dist/input/xr-source.js +164 -0
- package/dist/nav/astar.d.ts +45 -0
- package/dist/nav/astar.js +182 -0
- package/dist/nav/corridor.d.ts +40 -0
- package/dist/nav/corridor.js +95 -0
- package/dist/nav/crowd.d.ts +94 -0
- package/dist/nav/crowd.js +624 -0
- package/dist/nav/flow.d.ts +61 -0
- package/dist/nav/flow.js +193 -0
- package/dist/nav/grid.d.ts +108 -0
- package/dist/nav/grid.js +210 -0
- package/dist/nav/heap.d.ts +22 -0
- package/dist/nav/heap.js +92 -0
- package/dist/nav/index.d.ts +37 -0
- package/dist/nav/index.js +19 -0
- package/dist/nav/mesh/areas.d.ts +44 -0
- package/dist/nav/mesh/areas.js +98 -0
- package/dist/nav/mesh/bake-options.d.ts +33 -0
- package/dist/nav/mesh/bake-options.js +76 -0
- package/dist/nav/mesh/contour.d.ts +22 -0
- package/dist/nav/mesh/contour.js +323 -0
- package/dist/nav/mesh/flow3.d.ts +35 -0
- package/dist/nav/mesh/flow3.js +229 -0
- package/dist/nav/mesh/links.d.ts +38 -0
- package/dist/nav/mesh/links.js +72 -0
- package/dist/nav/mesh/mesh-path.d.ts +152 -0
- package/dist/nav/mesh/mesh-path.js +643 -0
- package/dist/nav/mesh/mesh-reach.d.ts +78 -0
- package/dist/nav/mesh/mesh-reach.js +450 -0
- package/dist/nav/mesh/navmesh.d.ts +117 -0
- package/dist/nav/mesh/navmesh.js +647 -0
- package/dist/nav/mesh/polymesh.d.ts +24 -0
- package/dist/nav/mesh/polymesh.js +384 -0
- package/dist/nav/mesh/regions.d.ts +12 -0
- package/dist/nav/mesh/regions.js +367 -0
- package/dist/nav/mesh/serialize.d.ts +13 -0
- package/dist/nav/mesh/serialize.js +197 -0
- package/dist/nav/mesh/voxelize.d.ts +111 -0
- package/dist/nav/mesh/voxelize.js +552 -0
- package/dist/nav/obstacles.d.ts +75 -0
- package/dist/nav/obstacles.js +294 -0
- package/dist/nav/path.d.ts +59 -0
- package/dist/nav/path.js +177 -0
- package/dist/nav/query-queue.d.ts +46 -0
- package/dist/nav/query-queue.js +308 -0
- package/dist/nav/reach.d.ts +53 -0
- package/dist/nav/reach.js +148 -0
- package/dist/nav/steer.d.ts +36 -0
- package/dist/nav/steer.js +78 -0
- package/dist/platform/boot.d.ts +28 -0
- package/dist/platform/boot.js +43 -0
- package/dist/platform/device-mode.d.ts +40 -0
- package/dist/platform/device-mode.js +104 -0
- package/dist/platform/device.d.ts +31 -0
- package/dist/platform/device.js +91 -0
- package/dist/platform/environment.d.ts +42 -0
- package/dist/platform/environment.js +82 -0
- package/dist/platform/gpu.d.ts +40 -0
- package/dist/platform/gpu.js +57 -0
- package/dist/platform/index.d.ts +18 -0
- package/dist/platform/index.js +10 -0
- package/dist/platform/letterbox.d.ts +43 -0
- package/dist/platform/letterbox.js +57 -0
- package/dist/platform/links.d.ts +20 -0
- package/dist/platform/links.js +43 -0
- package/dist/platform/screens.d.ts +36 -0
- package/dist/platform/screens.js +138 -0
- package/dist/platform/surface.d.ts +72 -0
- package/dist/platform/surface.js +157 -0
- package/dist/platform/xr-fake.d.ts +168 -0
- package/dist/platform/xr-fake.js +434 -0
- package/dist/platform/xr-surface.d.ts +120 -0
- package/dist/platform/xr-surface.js +214 -0
- package/dist/platform/xr-types.d.ts +262 -0
- package/dist/post/ao.d.ts +12 -0
- package/dist/post/ao.js +136 -0
- package/dist/post/blend.d.ts +27 -0
- package/dist/post/blend.js +129 -0
- package/dist/post/depth-pass.d.ts +43 -0
- package/dist/post/depth-pass.js +118 -0
- package/dist/post/dof.d.ts +1 -0
- package/dist/post/dof.js +66 -0
- package/dist/post/exposure.d.ts +80 -0
- package/dist/post/exposure.js +322 -0
- package/dist/post/index.d.ts +12 -0
- package/dist/post/index.js +11 -0
- package/dist/post/lens-dirt.d.ts +13 -0
- package/dist/post/lens-dirt.js +91 -0
- package/dist/post/lut.d.ts +19 -0
- package/dist/post/lut.js +50 -0
- package/dist/post/motion-blur.d.ts +9 -0
- package/dist/post/motion-blur.js +78 -0
- package/dist/post/post-stack.d.ts +302 -0
- package/dist/post/post-stack.js +1137 -0
- package/dist/post/settings.d.ts +485 -0
- package/dist/post/settings.js +416 -0
- package/dist/post/shaders.d.ts +25 -0
- package/dist/post/shaders.js +410 -0
- package/dist/post/ssr.d.ts +16 -0
- package/dist/post/ssr.js +155 -0
- package/dist/post/taa.d.ts +74 -0
- package/dist/post/taa.js +235 -0
- package/dist/post/white-balance.d.ts +25 -0
- package/dist/post/white-balance.js +98 -0
- package/dist/render/bindings.d.ts +98 -0
- package/dist/render/bindings.js +281 -0
- package/dist/render/blend.d.ts +13 -0
- package/dist/render/blend.js +26 -0
- package/dist/render/camera-2d.d.ts +72 -0
- package/dist/render/camera-2d.js +92 -0
- package/dist/render/camera.d.ts +302 -0
- package/dist/render/camera.js +671 -0
- package/dist/render/color.d.ts +16 -0
- package/dist/render/color.js +41 -0
- package/dist/render/compressed.d.ts +104 -0
- package/dist/render/compressed.js +248 -0
- package/dist/render/diagnostics.d.ts +15 -0
- package/dist/render/diagnostics.js +43 -0
- package/dist/render/dynamic-resolution.d.ts +70 -0
- package/dist/render/dynamic-resolution.js +126 -0
- package/dist/render/fake-gpu.d.ts +204 -0
- package/dist/render/fake-gpu.js +426 -0
- package/dist/render/flipbook.d.ts +56 -0
- package/dist/render/flipbook.js +87 -0
- package/dist/render/frame.d.ts +278 -0
- package/dist/render/frame.js +174 -0
- package/dist/render/fullscreen.d.ts +54 -0
- package/dist/render/fullscreen.js +91 -0
- package/dist/render/gpu-timer.d.ts +73 -0
- package/dist/render/gpu-timer.js +186 -0
- package/dist/render/index.d.ts +53 -0
- package/dist/render/index.js +29 -0
- package/dist/render/instance-list.d.ts +185 -0
- package/dist/render/instance-list.js +547 -0
- package/dist/render/lights.d.ts +181 -0
- package/dist/render/lights.js +233 -0
- package/dist/render/lod.d.ts +54 -0
- package/dist/render/lod.js +52 -0
- package/dist/render/material.d.ts +165 -0
- package/dist/render/material.js +292 -0
- package/dist/render/mesh.d.ts +284 -0
- package/dist/render/mesh.js +472 -0
- package/dist/render/mipmap.d.ts +16 -0
- package/dist/render/mipmap.js +121 -0
- package/dist/render/parallax.d.ts +50 -0
- package/dist/render/parallax.js +47 -0
- package/dist/render/pbr-wgsl.d.ts +31 -0
- package/dist/render/pbr-wgsl.js +119 -0
- package/dist/render/ping-pong.d.ts +42 -0
- package/dist/render/ping-pong.js +74 -0
- package/dist/render/renderer.d.ts +741 -0
- package/dist/render/renderer.js +2486 -0
- package/dist/render/scene-pipelines.d.ts +44 -0
- package/dist/render/scene-pipelines.js +92 -0
- package/dist/render/scene-target.d.ts +170 -0
- package/dist/render/scene-target.js +450 -0
- package/dist/render/shadow.d.ts +74 -0
- package/dist/render/shadow.js +208 -0
- package/dist/render/skin.d.ts +112 -0
- package/dist/render/skin.js +240 -0
- package/dist/render/snapshot.d.ts +36 -0
- package/dist/render/snapshot.js +34 -0
- package/dist/render/standard.d.ts +162 -0
- package/dist/render/standard.js +263 -0
- package/dist/render/texture.d.ts +142 -0
- package/dist/render/texture.js +228 -0
- package/dist/render/tile-layer.d.ts +110 -0
- package/dist/render/tile-layer.js +304 -0
- package/dist/render/transform.d.ts +115 -0
- package/dist/render/transform.js +318 -0
- package/dist/render/wgsl.d.ts +131 -0
- package/dist/render/wgsl.js +528 -0
- package/dist/save/codec.d.ts +49 -0
- package/dist/save/codec.js +169 -0
- package/dist/save/index.d.ts +8 -0
- package/dist/save/index.js +8 -0
- package/dist/save/journal.d.ts +24 -0
- package/dist/save/journal.js +102 -0
- package/dist/save/migrate.d.ts +15 -0
- package/dist/save/migrate.js +37 -0
- package/dist/save/schema.d.ts +72 -0
- package/dist/save/schema.js +154 -0
- package/dist/save/settings.d.ts +28 -0
- package/dist/save/settings.js +59 -0
- package/dist/save/slots.d.ts +56 -0
- package/dist/save/slots.js +200 -0
- package/dist/save/storage.d.ts +35 -0
- package/dist/save/storage.js +62 -0
- package/dist/save/store.d.ts +114 -0
- package/dist/save/store.js +269 -0
- package/dist/testing/fake-host.d.ts +103 -0
- package/dist/testing/fake-host.js +163 -0
- package/dist/testing/fixed-clock.d.ts +25 -0
- package/dist/testing/fixed-clock.js +30 -0
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/test-game.d.ts +76 -0
- package/dist/testing/test-game.js +92 -0
- package/dist/tween/ease.d.ts +77 -0
- package/dist/tween/ease.js +192 -0
- package/dist/tween/index.d.ts +8 -0
- package/dist/tween/index.js +7 -0
- package/dist/tween/timeline.d.ts +78 -0
- package/dist/tween/timeline.js +269 -0
- package/dist/tween/tween.d.ts +168 -0
- package/dist/tween/tween.js +320 -0
- package/dist/ui/anchor.d.ts +206 -0
- package/dist/ui/anchor.js +307 -0
- package/dist/ui/caption.d.ts +122 -0
- package/dist/ui/caption.js +286 -0
- package/dist/ui/cursor.d.ts +105 -0
- package/dist/ui/cursor.js +261 -0
- package/dist/ui/dom.d.ts +30 -0
- package/dist/ui/dom.js +92 -0
- package/dist/ui/floats.d.ts +86 -0
- package/dist/ui/floats.js +260 -0
- package/dist/ui/hud.d.ts +198 -0
- package/dist/ui/hud.js +431 -0
- package/dist/ui/index.d.ts +37 -0
- package/dist/ui/index.js +34 -0
- package/dist/ui/inventory-card.d.ts +52 -0
- package/dist/ui/inventory-card.js +173 -0
- package/dist/ui/inventory-context.d.ts +29 -0
- package/dist/ui/inventory-context.js +125 -0
- package/dist/ui/inventory-drag.d.ts +63 -0
- package/dist/ui/inventory-drag.js +394 -0
- package/dist/ui/inventory-grid.d.ts +66 -0
- package/dist/ui/inventory-grid.js +625 -0
- package/dist/ui/inventory-radial.d.ts +39 -0
- package/dist/ui/inventory-radial.js +168 -0
- package/dist/ui/inventory.d.ts +128 -0
- package/dist/ui/inventory.js +154 -0
- package/dist/ui/layout.d.ts +356 -0
- package/dist/ui/layout.js +856 -0
- package/dist/ui/link.d.ts +64 -0
- package/dist/ui/link.js +155 -0
- package/dist/ui/loading.d.ts +40 -0
- package/dist/ui/loading.js +157 -0
- package/dist/ui/loupe.d.ts +74 -0
- package/dist/ui/loupe.js +164 -0
- package/dist/ui/menu-nav.d.ts +33 -0
- package/dist/ui/menu-nav.js +28 -0
- package/dist/ui/minimap-canvas.d.ts +145 -0
- package/dist/ui/minimap-canvas.js +460 -0
- package/dist/ui/notify.d.ts +40 -0
- package/dist/ui/notify.js +141 -0
- package/dist/ui/orb.d.ts +53 -0
- package/dist/ui/orb.js +304 -0
- package/dist/ui/overlay.d.ts +213 -0
- package/dist/ui/overlay.js +394 -0
- package/dist/ui/padnav.d.ts +53 -0
- package/dist/ui/padnav.js +146 -0
- package/dist/ui/perf.d.ts +130 -0
- package/dist/ui/perf.js +329 -0
- package/dist/ui/rotate-card.d.ts +54 -0
- package/dist/ui/rotate-card.js +97 -0
- package/dist/ui/stack.d.ts +128 -0
- package/dist/ui/stack.js +312 -0
- package/dist/ui/styles.d.ts +13 -0
- package/dist/ui/styles.js +200 -0
- package/dist/ui/text-scale.d.ts +67 -0
- package/dist/ui/text-scale.js +102 -0
- package/dist/ui/theme.d.ts +70 -0
- package/dist/ui/theme.js +98 -0
- package/dist/ui/toast.d.ts +23 -0
- package/dist/ui/toast.js +46 -0
- package/dist/ui/tooltip.d.ts +89 -0
- package/dist/ui/tooltip.js +333 -0
- package/dist/ui/widgets-2.d.ts +134 -0
- package/dist/ui/widgets-2.js +399 -0
- package/dist/ui/widgets-3.d.ts +91 -0
- package/dist/ui/widgets-3.js +212 -0
- package/dist/ui/widgets.d.ts +34 -0
- package/dist/ui/widgets.js +50 -0
- package/dist/ui/world-panel/index.d.ts +5 -0
- package/dist/ui/world-panel/index.js +5 -0
- package/dist/ui/world-panel/layout.d.ts +38 -0
- package/dist/ui/world-panel/layout.js +68 -0
- package/dist/ui/world-panel/paint.d.ts +96 -0
- package/dist/ui/world-panel/paint.js +136 -0
- package/dist/ui/world-panel/panel.d.ts +235 -0
- package/dist/ui/world-panel/panel.js +762 -0
- package/dist/ui/world-panel/wgsl.d.ts +10 -0
- package/dist/ui/world-panel/wgsl.js +52 -0
- package/dist/ui/world-panel/widgets.d.ts +207 -0
- package/dist/ui/world-panel/widgets.js +569 -0
- package/dist/voxel/chunks.d.ts +77 -0
- package/dist/voxel/chunks.js +149 -0
- package/dist/voxel/grid.d.ts +84 -0
- package/dist/voxel/grid.js +223 -0
- package/dist/voxel/index.d.ts +22 -0
- package/dist/voxel/index.js +7 -0
- package/dist/voxel/mesher-worker.d.ts +14 -0
- package/dist/voxel/mesher-worker.js +47 -0
- package/dist/voxel/mesher.d.ts +73 -0
- package/dist/voxel/mesher.js +306 -0
- package/dist/voxel/ray.d.ts +32 -0
- package/dist/voxel/ray.js +73 -0
- package/dist/voxel/wgsl.d.ts +16 -0
- package/dist/voxel/wgsl.js +28 -0
- package/dist/voxel/worker-client.d.ts +79 -0
- package/dist/voxel/worker-client.js +122 -0
- package/package.json +177 -3
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { type AnchorCamera, Anchors } from './anchor.js';
|
|
2
|
+
import { CaptionCard, type CaptionOptions } from './caption.js';
|
|
3
|
+
import { type CursorOptions, type WorldCursor } from './cursor.js';
|
|
4
|
+
import { type Floats, type FloatsOptions } from './floats.js';
|
|
5
|
+
import { type Heading, type HeadingOptions, type Meter, type MeterOptions, type Reticle, type ReticleOptions, type Slots, type SlotsOptions } from './hud.js';
|
|
6
|
+
import { type Card, type CardOptions } from './inventory-card.js';
|
|
7
|
+
import { type ContextItem, type ContextList, type ContextListOptions } from './inventory-context.js';
|
|
8
|
+
import { type DragContext } from './inventory-drag.js';
|
|
9
|
+
import { type Grid, type GridOptions } from './inventory-grid.js';
|
|
10
|
+
import { type Radial, type RadialOptions } from './inventory-radial.js';
|
|
11
|
+
import { type Layout, type LayoutSpec, type Units } from './layout.js';
|
|
12
|
+
import { type LoadingOptions, type LoadingScreen } from './loading.js';
|
|
13
|
+
import { type CanvasMinimap, type CanvasMinimapOptions } from './minimap-canvas.js';
|
|
14
|
+
import { type Notification, type Notifier, type NotifyOptions } from './notify.js';
|
|
15
|
+
import { type PadOwner, PanelStack } from './stack.js';
|
|
16
|
+
import { type ThemeOverrides } from './theme.js';
|
|
17
|
+
import { Toaster } from './toast.js';
|
|
18
|
+
import { type Tooltip, type TooltipOptions, type Tooltips, type TooltipTarget } from './tooltip.js';
|
|
19
|
+
import { type Compass, type CompassOptions, type Ring, type RingOptions } from './widgets-3.js';
|
|
20
|
+
/**
|
|
21
|
+
* The attribute holding an overlay control's stable id (ws/input-12). `ButtonOptions.id` sets
|
|
22
|
+
* it; any `<button>` may carry it. It wins over the derived id (`controlId`).
|
|
23
|
+
*/
|
|
24
|
+
export declare const CONTROL_ID_ATTR = "data-tc-id";
|
|
25
|
+
/**
|
|
26
|
+
* The attribute naming the page a derived control id starts with (ws/input-12): put it on a
|
|
27
|
+
* screen's container (`data-tc-page="settings"`). Without one, a panel's accessible name (its
|
|
28
|
+
* `title` or `label`) is the page.
|
|
29
|
+
*/
|
|
30
|
+
export declare const CONTROL_PAGE_ATTR = "data-tc-page";
|
|
31
|
+
/**
|
|
32
|
+
* The stable id of an overlay control (ws/input-12): what a recording stores when it fires, so
|
|
33
|
+
* a replay finds the same control by id, never by DOM node. It is the button's
|
|
34
|
+
* `CONTROL_ID_ATTR` (`ButtonOptions.id`) when set; otherwise `page/key`, where the page is the
|
|
35
|
+
* nearest `CONTROL_PAGE_ATTR` or the panel's accessible name (omitted outside both) and the key
|
|
36
|
+
* the button's `aria-label` or text. A derived id shared by earlier buttons in `root` gets
|
|
37
|
+
* `#2`, `#3`, … in document order. Null for an element with no id and no label (it cannot be
|
|
38
|
+
* recorded).
|
|
39
|
+
*/
|
|
40
|
+
export declare function controlId(el: Element, root?: ParentNode): string | null;
|
|
41
|
+
/** A rectangle in CSS pixels relative to the overlay's parent (what platform's letterbox gives). */
|
|
42
|
+
export interface Rect {
|
|
43
|
+
x: number;
|
|
44
|
+
y: number;
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
}
|
|
48
|
+
export interface OverlayOptions {
|
|
49
|
+
/** Element to mount into. It should be `position: relative` (or fixed/absolute) and contain the canvas. */
|
|
50
|
+
parent: HTMLElement;
|
|
51
|
+
/** The frame's logical size (the canvas's design size). Default 1920×1080. */
|
|
52
|
+
designWidth?: number;
|
|
53
|
+
designHeight?: number;
|
|
54
|
+
/** Region tracks per form factor and the form-factor rule (see `Layout`). */
|
|
55
|
+
layout?: LayoutSpec;
|
|
56
|
+
/**
|
|
57
|
+
* Token overrides on top of `defaultTheme`. Sizes are design px: in `frame` units they scale
|
|
58
|
+
* with the frame, in `css` units they are taken as CSS px.
|
|
59
|
+
*/
|
|
60
|
+
theme?: ThemeOverrides;
|
|
61
|
+
caption?: CaptionOptions;
|
|
62
|
+
/** Max simultaneous toasts. Default 3. */
|
|
63
|
+
maxToasts?: number;
|
|
64
|
+
/**
|
|
65
|
+
* Where focus goes when the last panel closes and its opener can't or shouldn't get it
|
|
66
|
+
* back (typically the canvas). See `PanelStackFocusOptions.home` and `NO_RESTORE_FOCUS_ATTR`.
|
|
67
|
+
*/
|
|
68
|
+
focusHome?: () => HTMLElement | null;
|
|
69
|
+
/**
|
|
70
|
+
* The camera `anchors()` and `floats()` use when called without one (ws/api-core), read each
|
|
71
|
+
* frame. `createGame` passes `() => ctx.camera`. Without it the first `anchors` call needs one.
|
|
72
|
+
*/
|
|
73
|
+
camera?: () => AnchorCamera;
|
|
74
|
+
}
|
|
75
|
+
export interface Overlay {
|
|
76
|
+
/** `.tc-overlay`: the whole parent, in CSS px. */
|
|
77
|
+
readonly root: HTMLElement;
|
|
78
|
+
/**
|
|
79
|
+
* Layers, bottom to top, all in CSS px.
|
|
80
|
+
* - `hud` and `captions` cover the **frame** (the canvas rect; see `frame`) and clip to it:
|
|
81
|
+
* world-anchored DOM goes in `hud`, at design coordinates times `--tc-dpx`.
|
|
82
|
+
* - `layout` covers the whole overlay: the layout's regions (`layout`).
|
|
83
|
+
* - `panels` and `toasts` cover the frame in `frame` units and the whole overlay in `css`
|
|
84
|
+
* units (see `units`).
|
|
85
|
+
*/
|
|
86
|
+
readonly layers: {
|
|
87
|
+
hud: HTMLElement;
|
|
88
|
+
captions: HTMLElement;
|
|
89
|
+
layout: HTMLElement;
|
|
90
|
+
panels: HTMLElement;
|
|
91
|
+
toasts: HTMLElement;
|
|
92
|
+
};
|
|
93
|
+
readonly stack: PanelStack;
|
|
94
|
+
readonly toasts: Toaster;
|
|
95
|
+
readonly caption: CaptionCard;
|
|
96
|
+
/** Regions per form factor over the whole overlay; it also picks `units`. */
|
|
97
|
+
readonly layout: Layout;
|
|
98
|
+
/**
|
|
99
|
+
* How the base UI (theme, panels, toasts, captions) is sized in the current form factor (the
|
|
100
|
+
* layout's `FormSpec.units`, also `data-units` on the root):
|
|
101
|
+
* - `frame`: design px scaled with the frame (`--tc-dpx` CSS px each), so the UI keeps its
|
|
102
|
+
* proportions to the canvas, as a fixed 16:9 game does on desktops and tablets;
|
|
103
|
+
* - `css`: CSS px (`cssPxTheme`), so text and targets keep a readable size on a small screen.
|
|
104
|
+
*/
|
|
105
|
+
readonly units: Units;
|
|
106
|
+
/** CSS px per design px of the frame (`--tc-dpx`). */
|
|
107
|
+
readonly scale: number;
|
|
108
|
+
/** The overlay's own box, CSS px (the parent's size; x and y are 0). */
|
|
109
|
+
readonly rect: Readonly<Rect>;
|
|
110
|
+
/** The frame: the canvas rect in overlay CSS px (`--tc-frame-x/y/w/h`). */
|
|
111
|
+
readonly frame: Readonly<Rect>;
|
|
112
|
+
/** Place the frame over the canvas and re-measure the parent. Call on every resize. */
|
|
113
|
+
setFrame(frame: Rect): void;
|
|
114
|
+
/** Called after every `setFrame` (the layout follows it). Returns unsubscribe. */
|
|
115
|
+
onResize(fn: (frame: Readonly<Rect>) => void): () => void;
|
|
116
|
+
/** Apply token overrides (sizes in design px, as `OverlayOptions.theme`). */
|
|
117
|
+
setTheme(theme: ThemeOverrides): void;
|
|
118
|
+
/**
|
|
119
|
+
* Client (CSS px, viewport) → frame coordinates (design px), or null outside the frame. Uses
|
|
120
|
+
* the parent's bounding box.
|
|
121
|
+
*/
|
|
122
|
+
clientToDesign(clientX: number, clientY: number): {
|
|
123
|
+
x: number;
|
|
124
|
+
y: number;
|
|
125
|
+
} | null;
|
|
126
|
+
/**
|
|
127
|
+
* The overlay's one `Anchors` (DOM that follows world points; see `ui/anchor.ts`), built on the
|
|
128
|
+
* first call with `camera` and laid on the `hud` layer (other layers by name through
|
|
129
|
+
* `AnchorOptions.layer`). A later call with a camera switches it. Without one the first call
|
|
130
|
+
* uses `OverlayOptions.camera` (the game's camera under `createGame`) and throws when that
|
|
131
|
+
* is unset too.
|
|
132
|
+
*/
|
|
133
|
+
anchors(camera?: () => AnchorCamera): Anchors;
|
|
134
|
+
/** `anchors().update()` if `anchors` was ever called, else nothing. `createGame` calls it after every frame. */
|
|
135
|
+
updateAnchors(): void;
|
|
136
|
+
/** A reticle centred on the frame (`hud` layer), hidden while a modal is open (`ui/hud.ts`). */
|
|
137
|
+
reticle(opts?: ReticleOptions): Reticle;
|
|
138
|
+
/** A `role="meter"` bar in a layout region. */
|
|
139
|
+
meter(opts?: MeterOptions): Meter;
|
|
140
|
+
/** A strip of slots with key-hint badges and a selected highlight, in a layout region. */
|
|
141
|
+
slots(opts: SlotsOptions): Slots;
|
|
142
|
+
/** A sliding cardinal strip driven by `setYaw`, in a layout region. */
|
|
143
|
+
heading(opts?: HeadingOptions): Heading;
|
|
144
|
+
/** An item grid (`ui/inventory-grid.ts`), registered with `drag`; the game appends `element`. */
|
|
145
|
+
grid(opts: GridOptions): Grid;
|
|
146
|
+
/** An item card (tooltip) on the `hud` layer (`ui/inventory-card.ts`). */
|
|
147
|
+
card(opts: CardOptions): Card;
|
|
148
|
+
/** A radial menu on the `hud` layer, hidden under a modal (`ui/inventory-radial.ts`). */
|
|
149
|
+
radial(opts: RadialOptions): Radial;
|
|
150
|
+
/** A context list on the `toasts` layer, open until picked or cancelled (`ui/inventory-context.ts`). */
|
|
151
|
+
contextList(items: ContextItem[], opts: ContextListOptions): ContextList;
|
|
152
|
+
/** The drag context grids and `slotsTarget`s register with; made on first use (`ui/inventory-drag.ts`). */
|
|
153
|
+
readonly drag: DragContext;
|
|
154
|
+
/**
|
|
155
|
+
* A tooltip on an element (hover after `delay`, focus; leave, blur, Escape hide) or a world
|
|
156
|
+
* point (rides `anchors()`), in the overlay's one shared `role="tooltip"` element on the
|
|
157
|
+
* `toasts` layer (`ui/tooltip.ts`).
|
|
158
|
+
*/
|
|
159
|
+
tooltip(target: TooltipTarget, content: string | Node, opts?: TooltipOptions): Tooltip;
|
|
160
|
+
/** The shared tooltip element and the tooltip showing now; made on first use. */
|
|
161
|
+
readonly tooltips: Tooltips;
|
|
162
|
+
/** A pad/keyboard world cursor on the `hud` layer, yielding to modal panels (`ui/cursor.ts`). */
|
|
163
|
+
cursor(opts: CursorOptions): WorldCursor;
|
|
164
|
+
/** `stack.padOwner`: `'stack'` while a modal panel has the gamepad, else `'game'` (ws/ui-4). */
|
|
165
|
+
readonly padOwner: PadOwner;
|
|
166
|
+
/**
|
|
167
|
+
* The overlay's floating text on the `hud` layer (`ui/floats.ts`), made by the first call:
|
|
168
|
+
* `camera` goes to `anchors(camera)` (omitted: `OverlayOptions.camera`, the game's camera
|
|
169
|
+
* under `createGame`) and `opts` set the pool. Later calls return the same
|
|
170
|
+
* `Floats` (their arguments are ignored); `createFloats(ui, camera, opts)` makes another.
|
|
171
|
+
* Call `floats.update(dt)` once per update (ws/ui-6).
|
|
172
|
+
*/
|
|
173
|
+
floats(camera?: () => AnchorCamera, opts?: FloatsOptions): Floats;
|
|
174
|
+
/** A radial progress ring in a layout region (`ui/widgets-3.ts`). */
|
|
175
|
+
ring(opts?: RingOptions): Ring;
|
|
176
|
+
/** A compass strip with bearing markers in a layout region (`ui/widgets-3.ts`). */
|
|
177
|
+
compass(opts?: CompassOptions): Compass;
|
|
178
|
+
/**
|
|
179
|
+
* A canvas minimap of a bounded world in a layout region: markers by kind, the player's arrow,
|
|
180
|
+
* north- or player-up, tap to pick (`ui/minimap-canvas.ts`, ws/ui-6).
|
|
181
|
+
*/
|
|
182
|
+
minimap(opts: CanvasMinimapOptions): CanvasMinimap;
|
|
183
|
+
/** A loading screen on the `panels` layer; root `aria-busy` while shown (`ui/loading.ts`). */
|
|
184
|
+
loading(opts?: LoadingOptions): LoadingScreen;
|
|
185
|
+
/** A notification card stacked top-right on the `toasts` layer (`ui/notify.ts`). */
|
|
186
|
+
notify(opts: NotifyOptions): Notification;
|
|
187
|
+
/** The notification stack (`dismissAll`, the `menuNav` root); made on first use. */
|
|
188
|
+
readonly notifications: Notifier;
|
|
189
|
+
/**
|
|
190
|
+
* Called when a `<button>` in the overlay is clicked (a pointer, Enter or Space, a pad's A
|
|
191
|
+
* through `PadNav`, or `activate`), before its own handlers, with its stable id (`controlId`;
|
|
192
|
+
* ws/input-12). Buttons with no id are skipped. `createGame` feeds it to `ctx.input.control`,
|
|
193
|
+
* so a recording carries it. Returns unsubscribe.
|
|
194
|
+
*/
|
|
195
|
+
onControl(fn: (id: string, el: HTMLElement) => void): () => void;
|
|
196
|
+
/**
|
|
197
|
+
* Click the enabled overlay button whose `controlId` is `id` (ws/input-12): what a replay does
|
|
198
|
+
* for a recorded control. Its handlers run now, and `onControl` sees it. False when no such
|
|
199
|
+
* button is in the overlay.
|
|
200
|
+
*/
|
|
201
|
+
activate(id: string): boolean;
|
|
202
|
+
destroy(): void;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The DOM overlay: one root over the whole parent, laid out in CSS px on every form factor. The
|
|
206
|
+
* frame (the canvas rect) is exposed as CSS custom properties on the root, `--tc-frame-x/y/w/h`
|
|
207
|
+
* and `--tc-dpx` (one design px in CSS px), and the `hud` and `captions` layers sit on it, so
|
|
208
|
+
* DOM anchored to the world is placed at `logicalToClient` of its design coordinates. The
|
|
209
|
+
* layout's regions (`overlay.layout`) cover the whole overlay. The root is
|
|
210
|
+
* `pointer-events: none`; only interactive children take the pointer, so clicks on empty space
|
|
211
|
+
* fall through to the canvas.
|
|
212
|
+
*/
|
|
213
|
+
export declare function createOverlay(opts: OverlayOptions): Overlay;
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { Anchors } from './anchor.js';
|
|
2
|
+
import { CaptionCard } from './caption.js';
|
|
3
|
+
import { createCursor } from './cursor.js';
|
|
4
|
+
import { h } from './dom.js';
|
|
5
|
+
import { createFloats } from './floats.js';
|
|
6
|
+
import { createHeading, createMeter, createReticle, createSlots, } from './hud.js';
|
|
7
|
+
import { ensureInventoryStyles } from './inventory.js';
|
|
8
|
+
import { card as createCard } from './inventory-card.js';
|
|
9
|
+
import { contextList as createContextList, } from './inventory-context.js';
|
|
10
|
+
import { createDragContext } from './inventory-drag.js';
|
|
11
|
+
import { grid as createGrid } from './inventory-grid.js';
|
|
12
|
+
import { radial as createRadial } from './inventory-radial.js';
|
|
13
|
+
import { createLayout } from './layout.js';
|
|
14
|
+
import { createLoading } from './loading.js';
|
|
15
|
+
import { createCanvasMinimap, } from './minimap-canvas.js';
|
|
16
|
+
import { createNotifier } from './notify.js';
|
|
17
|
+
import { PanelStack } from './stack.js';
|
|
18
|
+
import { ensureStyles } from './styles.js';
|
|
19
|
+
import { CSS_FONT_PX, DESIGN_FONT_PX, TEXT_SCALE_VAR, textScaleTokens, toFrameUnits, } from './text-scale.js';
|
|
20
|
+
import { cssPxTheme, defaultTheme, tokenVar } from './theme.js';
|
|
21
|
+
import { Toaster } from './toast.js';
|
|
22
|
+
import { createTooltips, } from './tooltip.js';
|
|
23
|
+
import { ensureWidgets2Styles } from './widgets-2.js';
|
|
24
|
+
import { createCompass, createRing, } from './widgets-3.js';
|
|
25
|
+
/**
|
|
26
|
+
* The attribute holding an overlay control's stable id (ws/input-12). `ButtonOptions.id` sets
|
|
27
|
+
* it; any `<button>` may carry it. It wins over the derived id (`controlId`).
|
|
28
|
+
*/
|
|
29
|
+
export const CONTROL_ID_ATTR = 'data-tc-id';
|
|
30
|
+
/**
|
|
31
|
+
* The attribute naming the page a derived control id starts with (ws/input-12): put it on a
|
|
32
|
+
* screen's container (`data-tc-page="settings"`). Without one, a panel's accessible name (its
|
|
33
|
+
* `title` or `label`) is the page.
|
|
34
|
+
*/
|
|
35
|
+
export const CONTROL_PAGE_ATTR = 'data-tc-page';
|
|
36
|
+
/** The page of a control: the nearest `CONTROL_PAGE_ATTR`, else its panel's accessible name. */
|
|
37
|
+
function controlPage(el) {
|
|
38
|
+
const marked = el.closest(`[${CONTROL_PAGE_ATTR}]`);
|
|
39
|
+
if (marked)
|
|
40
|
+
return marked.getAttribute(CONTROL_PAGE_ATTR) ?? '';
|
|
41
|
+
const panel = el.closest('[role="dialog"],[role="alertdialog"]');
|
|
42
|
+
if (!panel)
|
|
43
|
+
return '';
|
|
44
|
+
const label = panel.getAttribute('aria-label');
|
|
45
|
+
if (label)
|
|
46
|
+
return label;
|
|
47
|
+
const by = panel.getAttribute('aria-labelledby');
|
|
48
|
+
const title = by ? panel.ownerDocument.getElementById(by) : null;
|
|
49
|
+
return title?.textContent?.trim() ?? '';
|
|
50
|
+
}
|
|
51
|
+
/** A control's id before the duplicate suffix: `page/key`, `key` off any page; null with no key. */
|
|
52
|
+
function baseControlId(el) {
|
|
53
|
+
const own = el.getAttribute(CONTROL_ID_ATTR);
|
|
54
|
+
if (own)
|
|
55
|
+
return own;
|
|
56
|
+
const key = el.getAttribute('aria-label') || el.textContent?.trim() || '';
|
|
57
|
+
if (!key)
|
|
58
|
+
return null;
|
|
59
|
+
const page = controlPage(el);
|
|
60
|
+
return page ? `${page}/${key}` : key;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The stable id of an overlay control (ws/input-12): what a recording stores when it fires, so
|
|
64
|
+
* a replay finds the same control by id, never by DOM node. It is the button's
|
|
65
|
+
* `CONTROL_ID_ATTR` (`ButtonOptions.id`) when set; otherwise `page/key`, where the page is the
|
|
66
|
+
* nearest `CONTROL_PAGE_ATTR` or the panel's accessible name (omitted outside both) and the key
|
|
67
|
+
* the button's `aria-label` or text. A derived id shared by earlier buttons in `root` gets
|
|
68
|
+
* `#2`, `#3`, … in document order. Null for an element with no id and no label (it cannot be
|
|
69
|
+
* recorded).
|
|
70
|
+
*/
|
|
71
|
+
export function controlId(el, root = el.ownerDocument) {
|
|
72
|
+
const base = baseControlId(el);
|
|
73
|
+
if (base === null || el.hasAttribute(CONTROL_ID_ATTR))
|
|
74
|
+
return base;
|
|
75
|
+
let n = 1;
|
|
76
|
+
for (const other of root.querySelectorAll('button')) {
|
|
77
|
+
if (other === el)
|
|
78
|
+
break;
|
|
79
|
+
if (!other.hasAttribute(CONTROL_ID_ATTR) && baseControlId(other) === base)
|
|
80
|
+
n++;
|
|
81
|
+
}
|
|
82
|
+
return n > 1 ? `${base}#${n}` : base;
|
|
83
|
+
}
|
|
84
|
+
/** The first enabled `<button>` in `root` whose `controlId` is `id`, or null. */
|
|
85
|
+
function findControl(root, id) {
|
|
86
|
+
const seen = new Map();
|
|
87
|
+
for (const el of root.querySelectorAll('button')) {
|
|
88
|
+
let cid = baseControlId(el);
|
|
89
|
+
if (cid === null)
|
|
90
|
+
continue;
|
|
91
|
+
if (!el.hasAttribute(CONTROL_ID_ATTR)) {
|
|
92
|
+
const n = (seen.get(cid) ?? 0) + 1;
|
|
93
|
+
seen.set(cid, n);
|
|
94
|
+
if (n > 1)
|
|
95
|
+
cid = `${cid}#${n}`;
|
|
96
|
+
}
|
|
97
|
+
if (cid === id && !el.disabled)
|
|
98
|
+
return el;
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The DOM overlay: one root over the whole parent, laid out in CSS px on every form factor. The
|
|
104
|
+
* frame (the canvas rect) is exposed as CSS custom properties on the root, `--tc-frame-x/y/w/h`
|
|
105
|
+
* and `--tc-dpx` (one design px in CSS px), and the `hud` and `captions` layers sit on it, so
|
|
106
|
+
* DOM anchored to the world is placed at `logicalToClient` of its design coordinates. The
|
|
107
|
+
* layout's regions (`overlay.layout`) cover the whole overlay. The root is
|
|
108
|
+
* `pointer-events: none`; only interactive children take the pointer, so clicks on empty space
|
|
109
|
+
* fall through to the canvas.
|
|
110
|
+
*/
|
|
111
|
+
export function createOverlay(opts) {
|
|
112
|
+
const doc = opts.parent.ownerDocument;
|
|
113
|
+
ensureStyles(doc);
|
|
114
|
+
ensureWidgets2Styles(doc);
|
|
115
|
+
ensureInventoryStyles(doc);
|
|
116
|
+
const dw = opts.designWidth ?? 1920;
|
|
117
|
+
const dh = opts.designHeight ?? 1080;
|
|
118
|
+
const layer = (name) => h('div', { class: 'tc-layer', dataset: { layer: name } });
|
|
119
|
+
const layers = {
|
|
120
|
+
hud: layer('hud'),
|
|
121
|
+
captions: layer('captions'),
|
|
122
|
+
layout: layer('layout'),
|
|
123
|
+
panels: layer('panels'),
|
|
124
|
+
toasts: layer('toasts'),
|
|
125
|
+
};
|
|
126
|
+
const root = h('div', { class: 'tc-overlay' }, layers.hud, layers.captions, layers.layout, layers.panels, layers.toasts);
|
|
127
|
+
opts.parent.append(root);
|
|
128
|
+
// Captions, HUD and regions go inert under a modal; toasts stay readable.
|
|
129
|
+
const stack = new PanelStack(layers.panels, [layers.hud, layers.captions, layers.layout], {
|
|
130
|
+
home: opts.focusHome,
|
|
131
|
+
});
|
|
132
|
+
const toasts = new Toaster(layers.toasts, opts.maxToasts ?? 3);
|
|
133
|
+
const caption = new CaptionCard(layers.captions, opts.caption);
|
|
134
|
+
// A modal hides the caption and pauses it, so a line is never read through (or lost under) a
|
|
135
|
+
// dialog; it picks up again when the last modal closes.
|
|
136
|
+
const unwatch = stack.onChange((s) => caption.suspend(s.hasModal));
|
|
137
|
+
const measure = () => ({
|
|
138
|
+
x: 0,
|
|
139
|
+
y: 0,
|
|
140
|
+
width: opts.parent.clientWidth,
|
|
141
|
+
height: opts.parent.clientHeight,
|
|
142
|
+
});
|
|
143
|
+
let rect = measure();
|
|
144
|
+
let frame = { ...rect };
|
|
145
|
+
let scale = 1;
|
|
146
|
+
let units = 'frame';
|
|
147
|
+
const subs = new Set();
|
|
148
|
+
// Theme: the defaults, the game's overrides (design px), then the text-scale tokens, written
|
|
149
|
+
// in the current units.
|
|
150
|
+
const overrides = { ...opts.theme };
|
|
151
|
+
const writeTheme = (tokens) => {
|
|
152
|
+
for (const [k, v] of Object.entries(tokens)) {
|
|
153
|
+
let css = units === 'frame' ? toFrameUnits(v) : v;
|
|
154
|
+
// Outlines snap down to whole pixels; a scaled ring (the old transform) was drawn
|
|
155
|
+
// antialiased at its full width. Round up so the focus ring never thins.
|
|
156
|
+
if (units === 'frame' && k === 'focusRing')
|
|
157
|
+
css = `round(up, ${css}, 1px)`;
|
|
158
|
+
root.style.setProperty(tokenVar(k), css);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
const applyUnits = (u) => {
|
|
162
|
+
units = u;
|
|
163
|
+
root.dataset.units = u;
|
|
164
|
+
writeTheme({ ...defaultTheme, ...(u === 'css' ? cssPxTheme : {}), ...overrides });
|
|
165
|
+
// A text scale already applied (`applyTextScale`) is re-derived for the new units.
|
|
166
|
+
const ts = Number.parseFloat(root.style.getPropertyValue(TEXT_SCALE_VAR));
|
|
167
|
+
if (ts > 0)
|
|
168
|
+
writeTheme(textScaleTokens(ts, u === 'css' ? CSS_FONT_PX : DESIGN_FONT_PX));
|
|
169
|
+
};
|
|
170
|
+
const place = (f) => {
|
|
171
|
+
frame = { ...f };
|
|
172
|
+
rect = measure();
|
|
173
|
+
scale = Math.min(f.width / dw, f.height / dh) || 1;
|
|
174
|
+
const s = root.style;
|
|
175
|
+
s.setProperty('--tc-frame-x', `${f.x}px`);
|
|
176
|
+
s.setProperty('--tc-frame-y', `${f.y}px`);
|
|
177
|
+
s.setProperty('--tc-frame-w', `${f.width}px`);
|
|
178
|
+
s.setProperty('--tc-frame-h', `${f.height}px`);
|
|
179
|
+
s.setProperty('--tc-dpx', `${scale}px`);
|
|
180
|
+
// The same scale as a number, for `zoom` on native controls (ui/styles.ts).
|
|
181
|
+
s.setProperty('--tc-zoom', String(scale));
|
|
182
|
+
};
|
|
183
|
+
place(frame);
|
|
184
|
+
applyUnits('frame');
|
|
185
|
+
const layout = createLayout({
|
|
186
|
+
root,
|
|
187
|
+
layers,
|
|
188
|
+
caption,
|
|
189
|
+
get rect() {
|
|
190
|
+
return rect;
|
|
191
|
+
},
|
|
192
|
+
onResize: (fn) => {
|
|
193
|
+
subs.add(fn);
|
|
194
|
+
return () => subs.delete(fn);
|
|
195
|
+
},
|
|
196
|
+
}, opts.layout);
|
|
197
|
+
applyUnits(layout.state.units);
|
|
198
|
+
const offLayout = layout.onChange((st) => {
|
|
199
|
+
if (st.units !== units)
|
|
200
|
+
applyUnits(st.units);
|
|
201
|
+
});
|
|
202
|
+
let anchors = null;
|
|
203
|
+
let drag = null;
|
|
204
|
+
let tooltips = null;
|
|
205
|
+
let notifications = null;
|
|
206
|
+
let floats = null;
|
|
207
|
+
// Overlay controls (ws/input-12): one capture listener names every button click by id.
|
|
208
|
+
const controlSubs = new Set();
|
|
209
|
+
const onClick = (e) => {
|
|
210
|
+
if (controlSubs.size === 0)
|
|
211
|
+
return;
|
|
212
|
+
const t = e.target;
|
|
213
|
+
const el = t?.closest?.('button');
|
|
214
|
+
if (!el || !root.contains(el))
|
|
215
|
+
return;
|
|
216
|
+
const id = controlId(el, root);
|
|
217
|
+
if (id === null)
|
|
218
|
+
return;
|
|
219
|
+
for (const fn of controlSubs)
|
|
220
|
+
fn(id, el);
|
|
221
|
+
};
|
|
222
|
+
root.addEventListener('click', onClick, true);
|
|
223
|
+
const overlay = {
|
|
224
|
+
root,
|
|
225
|
+
layers,
|
|
226
|
+
stack,
|
|
227
|
+
toasts,
|
|
228
|
+
caption,
|
|
229
|
+
layout,
|
|
230
|
+
get units() {
|
|
231
|
+
return units;
|
|
232
|
+
},
|
|
233
|
+
get scale() {
|
|
234
|
+
return scale;
|
|
235
|
+
},
|
|
236
|
+
get rect() {
|
|
237
|
+
return rect;
|
|
238
|
+
},
|
|
239
|
+
get frame() {
|
|
240
|
+
return frame;
|
|
241
|
+
},
|
|
242
|
+
setFrame(f) {
|
|
243
|
+
place(f);
|
|
244
|
+
for (const fn of subs)
|
|
245
|
+
fn(frame);
|
|
246
|
+
},
|
|
247
|
+
onResize(fn) {
|
|
248
|
+
subs.add(fn);
|
|
249
|
+
return () => subs.delete(fn);
|
|
250
|
+
},
|
|
251
|
+
setTheme(theme) {
|
|
252
|
+
Object.assign(overrides, theme);
|
|
253
|
+
writeTheme(theme);
|
|
254
|
+
},
|
|
255
|
+
clientToDesign(cx, cy) {
|
|
256
|
+
const pb = opts.parent.getBoundingClientRect();
|
|
257
|
+
const x = (cx - pb.left - frame.x) / scale;
|
|
258
|
+
const y = (cy - pb.top - frame.y) / scale;
|
|
259
|
+
return x >= 0 && y >= 0 && x <= dw && y <= dh ? { x, y } : null;
|
|
260
|
+
},
|
|
261
|
+
anchors(camera) {
|
|
262
|
+
if (anchors) {
|
|
263
|
+
if (camera)
|
|
264
|
+
anchors.setCamera(camera);
|
|
265
|
+
return anchors;
|
|
266
|
+
}
|
|
267
|
+
const cam = camera ?? opts.camera;
|
|
268
|
+
if (!cam)
|
|
269
|
+
throw new Error('overlay.anchors: the first call needs a camera');
|
|
270
|
+
anchors = new Anchors({
|
|
271
|
+
root: layers.hud,
|
|
272
|
+
camera: cam,
|
|
273
|
+
// The frame is the canvas rect; the design size is the logical size it shows.
|
|
274
|
+
surface: {
|
|
275
|
+
get rect() {
|
|
276
|
+
return frame;
|
|
277
|
+
},
|
|
278
|
+
logicalWidth: dw,
|
|
279
|
+
logicalHeight: dh,
|
|
280
|
+
},
|
|
281
|
+
layers,
|
|
282
|
+
// hud and captions sit on the frame; layout covers the root; panels and toasts follow units.
|
|
283
|
+
onFrame: (l) => l === 'hud' ||
|
|
284
|
+
l === 'captions' ||
|
|
285
|
+
((l === 'panels' || l === 'toasts') && units === 'frame'),
|
|
286
|
+
});
|
|
287
|
+
return anchors;
|
|
288
|
+
},
|
|
289
|
+
updateAnchors() {
|
|
290
|
+
anchors?.update();
|
|
291
|
+
tooltips?.update();
|
|
292
|
+
},
|
|
293
|
+
reticle(o) {
|
|
294
|
+
return createReticle(overlay, o);
|
|
295
|
+
},
|
|
296
|
+
meter(o) {
|
|
297
|
+
return createMeter(overlay, o);
|
|
298
|
+
},
|
|
299
|
+
slots(o) {
|
|
300
|
+
return createSlots(overlay, o);
|
|
301
|
+
},
|
|
302
|
+
heading(o) {
|
|
303
|
+
return createHeading(overlay, o);
|
|
304
|
+
},
|
|
305
|
+
grid(o) {
|
|
306
|
+
const g = createGrid(o);
|
|
307
|
+
overlay.drag.register(g);
|
|
308
|
+
return g;
|
|
309
|
+
},
|
|
310
|
+
card(o) {
|
|
311
|
+
return createCard(overlay, o);
|
|
312
|
+
},
|
|
313
|
+
radial(o) {
|
|
314
|
+
return createRadial(overlay, o);
|
|
315
|
+
},
|
|
316
|
+
contextList(items, o) {
|
|
317
|
+
return createContextList(overlay, items, o);
|
|
318
|
+
},
|
|
319
|
+
get drag() {
|
|
320
|
+
drag ??= createDragContext(overlay);
|
|
321
|
+
return drag;
|
|
322
|
+
},
|
|
323
|
+
get tooltips() {
|
|
324
|
+
tooltips ??= createTooltips(overlay);
|
|
325
|
+
return tooltips;
|
|
326
|
+
},
|
|
327
|
+
tooltip(target, content, o) {
|
|
328
|
+
return overlay.tooltips.tooltip(target, content, o);
|
|
329
|
+
},
|
|
330
|
+
cursor(o) {
|
|
331
|
+
return createCursor(overlay, o);
|
|
332
|
+
},
|
|
333
|
+
get padOwner() {
|
|
334
|
+
return stack.padOwner;
|
|
335
|
+
},
|
|
336
|
+
floats(camera, o) {
|
|
337
|
+
floats ??= createFloats(overlay, camera, o);
|
|
338
|
+
return floats;
|
|
339
|
+
},
|
|
340
|
+
ring(o) {
|
|
341
|
+
return createRing(overlay, o);
|
|
342
|
+
},
|
|
343
|
+
compass(o) {
|
|
344
|
+
return createCompass(overlay, o);
|
|
345
|
+
},
|
|
346
|
+
minimap(o) {
|
|
347
|
+
return createCanvasMinimap(overlay, o);
|
|
348
|
+
},
|
|
349
|
+
loading(o) {
|
|
350
|
+
return createLoading(overlay, o);
|
|
351
|
+
},
|
|
352
|
+
get notifications() {
|
|
353
|
+
notifications ??= createNotifier(layers.toasts);
|
|
354
|
+
return notifications;
|
|
355
|
+
},
|
|
356
|
+
notify(o) {
|
|
357
|
+
return overlay.notifications.notify(o);
|
|
358
|
+
},
|
|
359
|
+
onControl(fn) {
|
|
360
|
+
controlSubs.add(fn);
|
|
361
|
+
return () => controlSubs.delete(fn);
|
|
362
|
+
},
|
|
363
|
+
activate(id) {
|
|
364
|
+
const el = findControl(root, id);
|
|
365
|
+
if (!el)
|
|
366
|
+
return false;
|
|
367
|
+
el.click();
|
|
368
|
+
return true;
|
|
369
|
+
},
|
|
370
|
+
destroy() {
|
|
371
|
+
root.removeEventListener('click', onClick, true);
|
|
372
|
+
controlSubs.clear();
|
|
373
|
+
drag?.destroy();
|
|
374
|
+
drag = null;
|
|
375
|
+
tooltips?.dispose();
|
|
376
|
+
tooltips = null;
|
|
377
|
+
floats?.dispose();
|
|
378
|
+
floats = null;
|
|
379
|
+
notifications?.dispose();
|
|
380
|
+
notifications = null;
|
|
381
|
+
anchors?.clear();
|
|
382
|
+
anchors = null;
|
|
383
|
+
unwatch();
|
|
384
|
+
offLayout();
|
|
385
|
+
layout.destroy();
|
|
386
|
+
subs.clear();
|
|
387
|
+
stack.destroy();
|
|
388
|
+
caption.destroy();
|
|
389
|
+
toasts.clear();
|
|
390
|
+
root.remove();
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
return overlay;
|
|
394
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { PanelStack } from './stack.js';
|
|
2
|
+
/** The slice of the Gamepad API this reads (standard mapping). */
|
|
3
|
+
export interface PadLike {
|
|
4
|
+
readonly buttons: readonly {
|
|
5
|
+
readonly pressed: boolean;
|
|
6
|
+
}[];
|
|
7
|
+
readonly axes?: readonly number[];
|
|
8
|
+
}
|
|
9
|
+
export interface PadNavOptions {
|
|
10
|
+
/** Gamepad source. Default: `navigator.getGamepads()` (guarded). */
|
|
11
|
+
getGamepads?: () => readonly (PadLike | null)[];
|
|
12
|
+
/** Stick deflection that counts as a d-pad press. Default 0.6. */
|
|
13
|
+
axisThreshold?: number;
|
|
14
|
+
}
|
|
15
|
+
/** A d-pad direction. */
|
|
16
|
+
export type PadDir = 'up' | 'down' | 'left' | 'right';
|
|
17
|
+
type Dir = PadDir;
|
|
18
|
+
/** `navigator.getGamepads()`, guarded; empty where there is no navigator. */
|
|
19
|
+
export declare function defaultPads(): readonly (PadLike | null)[];
|
|
20
|
+
/**
|
|
21
|
+
* Drives the top modal panel with a gamepad, the way Tab, Enter and Esc drive it from a
|
|
22
|
+
* keyboard: the d-pad (or left stick) moves focus through the panel's controls, A activates
|
|
23
|
+
* the focused one, B dismisses the panel. On a focused range slider left/right step its value,
|
|
24
|
+
* and on a `select` they pick the previous/next option. Call `update()` once per frame. It does
|
|
25
|
+
* nothing (and reads no pad) while the stack does not own the pad (`stack.padOwner`), so the
|
|
26
|
+
* game's own input map keeps it; the latch resets on each owner transition.
|
|
27
|
+
*/
|
|
28
|
+
export declare class PadNav {
|
|
29
|
+
private readonly stack;
|
|
30
|
+
private readonly getGamepads;
|
|
31
|
+
private readonly threshold;
|
|
32
|
+
private prev;
|
|
33
|
+
private next;
|
|
34
|
+
/** True while the stack owns the pad (a modal is open); kept by `onPadOwnerChange`. */
|
|
35
|
+
private owning;
|
|
36
|
+
private readonly unwatch;
|
|
37
|
+
constructor(stack: PanelStack, opts?: PadNavOptions);
|
|
38
|
+
/** Stop following the stack; `update()` does nothing after. */
|
|
39
|
+
dispose(): void;
|
|
40
|
+
update(): void;
|
|
41
|
+
/** Left/right on a value control changes the value instead of moving focus. */
|
|
42
|
+
private adjust;
|
|
43
|
+
}
|
|
44
|
+
/** A pad control `readPad` reports: the d-pad (or stick) directions, A and B. */
|
|
45
|
+
export type PadControl = Dir | 'activate' | 'back';
|
|
46
|
+
/**
|
|
47
|
+
* The controls held on any of `pads` right now (standard mapping: 0 = A, 1 = B, 12–15 = d-pad;
|
|
48
|
+
* the left stick past `threshold` counts as the d-pad). `out` is cleared and filled when given,
|
|
49
|
+
* so a per-frame reader allocates nothing. `PadNav` and the world cursor (`ui/cursor.ts`) latch
|
|
50
|
+
* on this set: a control is fresh when it is in this frame's set and not the last one's.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readPad(pads: readonly (PadLike | null)[], threshold?: number, out?: Set<PadControl>): Set<PadControl>;
|
|
53
|
+
export {};
|