@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,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The clock gestures and look are timed on (ws/input-8). By default that is `performance.now()`
|
|
3
|
+
* (wall time). A game with a fixed step passes one `createTickClock()` to both and advances it
|
|
4
|
+
* from the step, so long-presses, double taps, look acceleration and `Look.onTap` run on game
|
|
5
|
+
* time, and a recording replays the same gestures on the same tick indices however far apart
|
|
6
|
+
* the replay's ticks are in wall time.
|
|
7
|
+
*/
|
|
8
|
+
/** `performance.now()` (or `Date.now()` where there is no `performance`): the default clock. */
|
|
9
|
+
export const wallClock = {
|
|
10
|
+
now: () => (typeof performance !== 'undefined' ? performance.now() : Date.now()),
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A game-time clock for gestures and look. Call `advance(stepMs)` from the fixed step, before
|
|
14
|
+
* `input.update()`, and pass the same clock to `createGestures({ clock })` and
|
|
15
|
+
* `createLook({ clock })` so the two share one time base. `start` is the first reading
|
|
16
|
+
* (default 0).
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const clock = createTickClock();
|
|
20
|
+
* const input = new Input(bindings, {
|
|
21
|
+
* gestures: createGestures({ clock }),
|
|
22
|
+
* look: createLook({ clock }),
|
|
23
|
+
* });
|
|
24
|
+
* // GameLoop `update(dt)`, in fixed steps of `dt` seconds:
|
|
25
|
+
* clock.advance(dt * 1000);
|
|
26
|
+
* input.update();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export function createTickClock(start = 0) {
|
|
30
|
+
let t = Number.isFinite(start) ? start : 0;
|
|
31
|
+
return {
|
|
32
|
+
now: () => t,
|
|
33
|
+
advance(ms) {
|
|
34
|
+
if (ms > 0 && Number.isFinite(ms))
|
|
35
|
+
t += ms;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The clock options gestures and look accept resolved to one clock and its bound `now`:
|
|
41
|
+
* `clock` wins over the older `now` function, and with neither it is `wallClock`.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveClock(clock, now) {
|
|
44
|
+
if (clock)
|
|
45
|
+
return { clock, now: () => clock.now() };
|
|
46
|
+
if (now)
|
|
47
|
+
return { clock: { now }, now };
|
|
48
|
+
return { clock: wallClock, now: wallClock.now };
|
|
49
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Camera } from '../render/camera.js';
|
|
2
|
+
import type { Look } from './look.js';
|
|
3
|
+
import type { Vec3 } from './rays.js';
|
|
4
|
+
/** The part of `Camera` a `Follow` drives: it only ever calls `lookAt`. */
|
|
5
|
+
export type FollowCamera = Pick<Camera, 'lookAt'>;
|
|
6
|
+
/** `'third'`: orbit behind the target. `'first'`: through its eyes, same yaw and pitch. */
|
|
7
|
+
export type FollowMode = 'first' | 'third';
|
|
8
|
+
/** What the camera follows. The game owns the object and moves it; `Follow` reads it each frame. */
|
|
9
|
+
export interface FollowSubject {
|
|
10
|
+
/** The target's feet (or centre), world units. `eyeHeight` is added for the pivot. */
|
|
11
|
+
position: ArrayLike<number>;
|
|
12
|
+
/**
|
|
13
|
+
* The target's facing, radians (same convention as `yaw`: 0 is -z, positive turns right).
|
|
14
|
+
* With `realign` set, the orbit eases back to it while nobody is looking around.
|
|
15
|
+
*/
|
|
16
|
+
yaw?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The game's line-of-sight test (the engine has no world). `from` is the pivot, `to` the camera
|
|
20
|
+
* position the orbit wants. Return true and write the first obstacle point into `outHit` to pull
|
|
21
|
+
* the camera in to `outHit` minus `margin`; return false for a clear line.
|
|
22
|
+
*/
|
|
23
|
+
export type FollowObstacle = (from: Vec3, to: Vec3, outHit: Vec3) => boolean;
|
|
24
|
+
export interface FollowOptions {
|
|
25
|
+
/** Orbit radius wanted, world units. Default 4. */
|
|
26
|
+
distance?: number;
|
|
27
|
+
/** `zoom()` floor. Default 1. */
|
|
28
|
+
minDistance?: number;
|
|
29
|
+
/** `zoom()` ceiling. Default 12. */
|
|
30
|
+
maxDistance?: number;
|
|
31
|
+
/** Over-the-shoulder offset of the pivot, camera right and up, world units. Default `[0, 0]`. */
|
|
32
|
+
shoulder?: readonly [number, number];
|
|
33
|
+
/** Pitch floor, radians (negative looks down; the orbit rises above the target). Default -1.2. */
|
|
34
|
+
pitchMin?: number;
|
|
35
|
+
/** Pitch ceiling, radians. Default 1.2. */
|
|
36
|
+
pitchMax?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Time constant, seconds, of the pivot's approach to the target and of the distance's recovery
|
|
39
|
+
* after an obstacle (it snaps in, eases out). 0 follows exactly. Default 0.12.
|
|
40
|
+
*/
|
|
41
|
+
smoothing?: number;
|
|
42
|
+
/** Height of the pivot (and the first-person eye) above `target.position`. Default 1.6. */
|
|
43
|
+
eyeHeight?: number;
|
|
44
|
+
/** World units one `zoom(1)` step changes `distance` by. Default 0.5. */
|
|
45
|
+
zoomStep?: number;
|
|
46
|
+
/** Line-of-sight test from the pivot to the wanted camera position. Default none. */
|
|
47
|
+
obstacle?: FollowObstacle;
|
|
48
|
+
/** Pull-back from an obstacle point along the line to the pivot, world units. Default 0.2. */
|
|
49
|
+
margin?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Time constant, seconds, of the orbit yaw easing back to `target.yaw` while the look input
|
|
52
|
+
* is still. 0 (default) never realigns.
|
|
53
|
+
*/
|
|
54
|
+
realign?: number;
|
|
55
|
+
/** Starting orbit yaw, radians. Default 0 (behind a target facing -z). */
|
|
56
|
+
yaw?: number;
|
|
57
|
+
/** Starting pitch, radians. Default -0.35 (a little above, looking down). */
|
|
58
|
+
pitch?: number;
|
|
59
|
+
/** Starting mode. Default `'third'`. */
|
|
60
|
+
mode?: FollowMode;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A third-person camera that follows a target, orbits from the same `look` deltas `Look` reports,
|
|
64
|
+
* swings in on obstacles the game reports, and becomes a first-person camera with one
|
|
65
|
+
* assignment (`mode = 'first'`). Each `update(dt)` reads the linked `Look` (or the yaw and pitch
|
|
66
|
+
* the game set), places the eye and calls `camera.lookAt`. Nothing allocates per frame.
|
|
67
|
+
*
|
|
68
|
+
* Conventions match `Look` and the look harness: yaw 0 looks down -z and positive yaw turns
|
|
69
|
+
* right; positive pitch looks up (so in third person the camera sinks below the pivot; negative
|
|
70
|
+
* pitch raises it). The pivot is `target.position + (0, eyeHeight, 0)` shifted by `shoulder`
|
|
71
|
+
* along the camera's right and up; the eye sits `distance` behind it along the view direction.
|
|
72
|
+
*
|
|
73
|
+
* ```ts
|
|
74
|
+
* const follow = new Follow(camera, { distance: 5, shoulder: [0.6, 0], obstacle: world.raycast });
|
|
75
|
+
* follow.target = player; // { position: Float32Array(3), yaw }
|
|
76
|
+
* follow.setLook(look);
|
|
77
|
+
* // each tick, after input.update():
|
|
78
|
+
* follow.update(dt); // the look's zoom axis (wheel, pinch, pad) steps distance
|
|
79
|
+
* if (input.pressed('view')) follow.mode = follow.mode === 'third' ? 'first' : 'third';
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare class Follow {
|
|
83
|
+
/** What to follow. Until set, the pivot is at the origin. */
|
|
84
|
+
target: FollowSubject | null;
|
|
85
|
+
/** Orbit yaw, radians (0 is -z, positive turns right). The `Look` adds to it. */
|
|
86
|
+
yaw: number;
|
|
87
|
+
/** View pitch, radians, clamped to `pitchMin..pitchMax` each update. */
|
|
88
|
+
pitch: number;
|
|
89
|
+
/** Orbit radius wanted; `currentDistance` is what an obstacle left of it. `zoom()` steps it. */
|
|
90
|
+
distance: number;
|
|
91
|
+
mode: FollowMode;
|
|
92
|
+
minDistance: number;
|
|
93
|
+
maxDistance: number;
|
|
94
|
+
pitchMin: number;
|
|
95
|
+
pitchMax: number;
|
|
96
|
+
smoothing: number;
|
|
97
|
+
eyeHeight: number;
|
|
98
|
+
zoomStep: number;
|
|
99
|
+
margin: number;
|
|
100
|
+
realign: number;
|
|
101
|
+
obstacle: FollowObstacle | null;
|
|
102
|
+
/** Shoulder offset (camera right, up). Mutate in place. */
|
|
103
|
+
readonly shoulder: [number, number];
|
|
104
|
+
/** The eye placed by the last `update`, world units. Read-only. */
|
|
105
|
+
readonly position: Vec3;
|
|
106
|
+
/** The smoothed pivot the camera orbits (and looks at) as of the last `update`. Read-only. */
|
|
107
|
+
readonly pivot: Vec3;
|
|
108
|
+
/** The unit view direction of the last `update`. Read-only. */
|
|
109
|
+
readonly forward: Vec3;
|
|
110
|
+
/** The orbit radius the last `update` used: `distance`, shortened by an obstacle. */
|
|
111
|
+
currentDistance: number;
|
|
112
|
+
private readonly camera;
|
|
113
|
+
private look;
|
|
114
|
+
private pivotSet;
|
|
115
|
+
private readonly wanted;
|
|
116
|
+
private readonly hit;
|
|
117
|
+
private readonly aim;
|
|
118
|
+
constructor(camera: FollowCamera, opts?: FollowOptions);
|
|
119
|
+
/** Read yaw and pitch deltas and the zoom axis from this `Look` each update (`null` stops reading). */
|
|
120
|
+
setLook(look: Look | null): void;
|
|
121
|
+
/**
|
|
122
|
+
* Step `distance` by `steps × zoomStep` (positive zooms out), clamped to min..max. A linked
|
|
123
|
+
* `Look` calls it through `update` with its `zoom` axis negated; games call it for extra keys.
|
|
124
|
+
*/
|
|
125
|
+
zoom(steps: number): void;
|
|
126
|
+
/** Forget the smoothed pivot so the next `update` snaps to the target (teleports, scene changes). */
|
|
127
|
+
snap(): void;
|
|
128
|
+
/**
|
|
129
|
+
* Advance one frame: apply the look deltas, clamp the pitch, follow the target, test the line
|
|
130
|
+
* of sight and aim the camera. `dt` in seconds.
|
|
131
|
+
*/
|
|
132
|
+
update(dt: number): void;
|
|
133
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/** Longest `dt` one `update` integrates over, seconds. */
|
|
2
|
+
const MAX_DT = 0.1;
|
|
3
|
+
/**
|
|
4
|
+
* A third-person camera that follows a target, orbits from the same `look` deltas `Look` reports,
|
|
5
|
+
* swings in on obstacles the game reports, and becomes a first-person camera with one
|
|
6
|
+
* assignment (`mode = 'first'`). Each `update(dt)` reads the linked `Look` (or the yaw and pitch
|
|
7
|
+
* the game set), places the eye and calls `camera.lookAt`. Nothing allocates per frame.
|
|
8
|
+
*
|
|
9
|
+
* Conventions match `Look` and the look harness: yaw 0 looks down -z and positive yaw turns
|
|
10
|
+
* right; positive pitch looks up (so in third person the camera sinks below the pivot; negative
|
|
11
|
+
* pitch raises it). The pivot is `target.position + (0, eyeHeight, 0)` shifted by `shoulder`
|
|
12
|
+
* along the camera's right and up; the eye sits `distance` behind it along the view direction.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* const follow = new Follow(camera, { distance: 5, shoulder: [0.6, 0], obstacle: world.raycast });
|
|
16
|
+
* follow.target = player; // { position: Float32Array(3), yaw }
|
|
17
|
+
* follow.setLook(look);
|
|
18
|
+
* // each tick, after input.update():
|
|
19
|
+
* follow.update(dt); // the look's zoom axis (wheel, pinch, pad) steps distance
|
|
20
|
+
* if (input.pressed('view')) follow.mode = follow.mode === 'third' ? 'first' : 'third';
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class Follow {
|
|
24
|
+
/** What to follow. Until set, the pivot is at the origin. */
|
|
25
|
+
target = null;
|
|
26
|
+
/** Orbit yaw, radians (0 is -z, positive turns right). The `Look` adds to it. */
|
|
27
|
+
yaw;
|
|
28
|
+
/** View pitch, radians, clamped to `pitchMin..pitchMax` each update. */
|
|
29
|
+
pitch;
|
|
30
|
+
/** Orbit radius wanted; `currentDistance` is what an obstacle left of it. `zoom()` steps it. */
|
|
31
|
+
distance;
|
|
32
|
+
mode;
|
|
33
|
+
minDistance;
|
|
34
|
+
maxDistance;
|
|
35
|
+
pitchMin;
|
|
36
|
+
pitchMax;
|
|
37
|
+
smoothing;
|
|
38
|
+
eyeHeight;
|
|
39
|
+
zoomStep;
|
|
40
|
+
margin;
|
|
41
|
+
realign;
|
|
42
|
+
obstacle;
|
|
43
|
+
/** Shoulder offset (camera right, up). Mutate in place. */
|
|
44
|
+
shoulder;
|
|
45
|
+
/** The eye placed by the last `update`, world units. Read-only. */
|
|
46
|
+
position = [0, 0, 0];
|
|
47
|
+
/** The smoothed pivot the camera orbits (and looks at) as of the last `update`. Read-only. */
|
|
48
|
+
pivot = [0, 0, 0];
|
|
49
|
+
/** The unit view direction of the last `update`. Read-only. */
|
|
50
|
+
forward = [0, 0, -1];
|
|
51
|
+
/** The orbit radius the last `update` used: `distance`, shortened by an obstacle. */
|
|
52
|
+
currentDistance;
|
|
53
|
+
camera;
|
|
54
|
+
look = null;
|
|
55
|
+
pivotSet = false;
|
|
56
|
+
wanted = [0, 0, 0];
|
|
57
|
+
hit = [0, 0, 0];
|
|
58
|
+
aim = [0, 0, 0];
|
|
59
|
+
constructor(camera, opts = {}) {
|
|
60
|
+
this.camera = camera;
|
|
61
|
+
this.distance = opts.distance ?? 4;
|
|
62
|
+
this.minDistance = opts.minDistance ?? 1;
|
|
63
|
+
this.maxDistance = opts.maxDistance ?? 12;
|
|
64
|
+
this.shoulder = [opts.shoulder?.[0] ?? 0, opts.shoulder?.[1] ?? 0];
|
|
65
|
+
this.pitchMin = opts.pitchMin ?? -1.2;
|
|
66
|
+
this.pitchMax = opts.pitchMax ?? 1.2;
|
|
67
|
+
this.smoothing = opts.smoothing ?? 0.12;
|
|
68
|
+
this.eyeHeight = opts.eyeHeight ?? 1.6;
|
|
69
|
+
this.zoomStep = opts.zoomStep ?? 0.5;
|
|
70
|
+
this.obstacle = opts.obstacle ?? null;
|
|
71
|
+
this.margin = opts.margin ?? 0.2;
|
|
72
|
+
this.realign = opts.realign ?? 0;
|
|
73
|
+
this.yaw = opts.yaw ?? 0;
|
|
74
|
+
this.pitch = opts.pitch ?? -0.35;
|
|
75
|
+
this.mode = opts.mode ?? 'third';
|
|
76
|
+
this.currentDistance = this.distance;
|
|
77
|
+
}
|
|
78
|
+
/** Read yaw and pitch deltas and the zoom axis from this `Look` each update (`null` stops reading). */
|
|
79
|
+
setLook(look) {
|
|
80
|
+
this.look = look;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Step `distance` by `steps × zoomStep` (positive zooms out), clamped to min..max. A linked
|
|
84
|
+
* `Look` calls it through `update` with its `zoom` axis negated; games call it for extra keys.
|
|
85
|
+
*/
|
|
86
|
+
zoom(steps) {
|
|
87
|
+
this.distance = clamp(this.distance + steps * this.zoomStep, this.minDistance, this.maxDistance);
|
|
88
|
+
}
|
|
89
|
+
/** Forget the smoothed pivot so the next `update` snaps to the target (teleports, scene changes). */
|
|
90
|
+
snap() {
|
|
91
|
+
this.pivotSet = false;
|
|
92
|
+
this.currentDistance = this.distance;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Advance one frame: apply the look deltas, clamp the pitch, follow the target, test the line
|
|
96
|
+
* of sight and aim the camera. `dt` in seconds.
|
|
97
|
+
*/
|
|
98
|
+
update(dt) {
|
|
99
|
+
const step = Math.min(MAX_DT, Math.max(0, dt));
|
|
100
|
+
const look = this.look;
|
|
101
|
+
let turned = false;
|
|
102
|
+
if (look) {
|
|
103
|
+
const dx = look.look.dx;
|
|
104
|
+
const dy = look.look.dy;
|
|
105
|
+
this.yaw += dx;
|
|
106
|
+
this.pitch += dy;
|
|
107
|
+
turned = dx !== 0 || dy !== 0;
|
|
108
|
+
// `Look.zoom` > 0 is closer; `zoom(steps)` > 0 is farther.
|
|
109
|
+
if (look.zoom !== 0)
|
|
110
|
+
this.zoom(0 - look.zoom);
|
|
111
|
+
}
|
|
112
|
+
this.pitch = clamp(this.pitch, this.pitchMin, this.pitchMax);
|
|
113
|
+
this.distance = clamp(this.distance, this.minDistance, this.maxDistance);
|
|
114
|
+
const t = this.target;
|
|
115
|
+
const tp = t?.position;
|
|
116
|
+
const tx = tp ? tp[0] : 0;
|
|
117
|
+
const ty = (tp ? tp[1] : 0) + this.eyeHeight;
|
|
118
|
+
const tz = tp ? tp[2] : 0;
|
|
119
|
+
if (this.realign > 0 && !turned && t && t.yaw !== undefined) {
|
|
120
|
+
this.yaw += angleDelta(this.yaw, t.yaw) * ease(step, this.realign);
|
|
121
|
+
}
|
|
122
|
+
const sy = Math.sin(this.yaw);
|
|
123
|
+
const cy = Math.cos(this.yaw);
|
|
124
|
+
const sp = Math.sin(this.pitch);
|
|
125
|
+
const cp = Math.cos(this.pitch);
|
|
126
|
+
const f = this.forward;
|
|
127
|
+
f[0] = sy * cp;
|
|
128
|
+
f[1] = sp;
|
|
129
|
+
f[2] = -cy * cp;
|
|
130
|
+
const eye = this.position;
|
|
131
|
+
const pivot = this.pivot;
|
|
132
|
+
const aim = this.aim;
|
|
133
|
+
if (this.mode === 'first') {
|
|
134
|
+
// Head-mounted: no lag, no shoulder; the pivot sits on the eye.
|
|
135
|
+
eye[0] = pivot[0] = tx;
|
|
136
|
+
eye[1] = pivot[1] = ty;
|
|
137
|
+
eye[2] = pivot[2] = tz;
|
|
138
|
+
this.pivotSet = true;
|
|
139
|
+
this.currentDistance = 0;
|
|
140
|
+
aim[0] = eye[0] + f[0];
|
|
141
|
+
aim[1] = eye[1] + f[1];
|
|
142
|
+
aim[2] = eye[2] + f[2];
|
|
143
|
+
this.camera.lookAt(eye, aim);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
// Camera right (yaw only) and up (perpendicular to forward in the yaw plane).
|
|
147
|
+
const rx = cy;
|
|
148
|
+
const rz = sy;
|
|
149
|
+
const ux = -sy * sp;
|
|
150
|
+
const uy = cp;
|
|
151
|
+
const uz = cy * sp;
|
|
152
|
+
const sh = this.shoulder;
|
|
153
|
+
const px = tx + rx * sh[0] + ux * sh[1];
|
|
154
|
+
const py = ty + uy * sh[1];
|
|
155
|
+
const pz = tz + rz * sh[0] + uz * sh[1];
|
|
156
|
+
if (this.pivotSet && this.smoothing > 0) {
|
|
157
|
+
const k = ease(step, this.smoothing);
|
|
158
|
+
pivot[0] += (px - pivot[0]) * k;
|
|
159
|
+
pivot[1] += (py - pivot[1]) * k;
|
|
160
|
+
pivot[2] += (pz - pivot[2]) * k;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
pivot[0] = px;
|
|
164
|
+
pivot[1] = py;
|
|
165
|
+
pivot[2] = pz;
|
|
166
|
+
this.pivotSet = true;
|
|
167
|
+
}
|
|
168
|
+
const wanted = this.wanted;
|
|
169
|
+
const d = this.distance;
|
|
170
|
+
wanted[0] = pivot[0] - f[0] * d;
|
|
171
|
+
wanted[1] = pivot[1] - f[1] * d;
|
|
172
|
+
wanted[2] = pivot[2] - f[2] * d;
|
|
173
|
+
let allowed = d;
|
|
174
|
+
const ob = this.obstacle;
|
|
175
|
+
if (ob) {
|
|
176
|
+
const hit = this.hit;
|
|
177
|
+
if (ob(pivot, wanted, hit)) {
|
|
178
|
+
const hd = Math.hypot(hit[0] - pivot[0], hit[1] - pivot[1], hit[2] - pivot[2]);
|
|
179
|
+
allowed = Math.max(0, Math.min(d, hd - this.margin));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// Snap in on an obstacle; ease back out when the line clears.
|
|
183
|
+
let cur = this.currentDistance;
|
|
184
|
+
if (allowed < cur || this.smoothing <= 0)
|
|
185
|
+
cur = allowed;
|
|
186
|
+
else
|
|
187
|
+
cur += (allowed - cur) * ease(step, this.smoothing);
|
|
188
|
+
this.currentDistance = cur;
|
|
189
|
+
eye[0] = pivot[0] - f[0] * cur;
|
|
190
|
+
eye[1] = pivot[1] - f[1] * cur;
|
|
191
|
+
eye[2] = pivot[2] - f[2] * cur;
|
|
192
|
+
if (cur > 0) {
|
|
193
|
+
this.camera.lookAt(eye, pivot);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
aim[0] = eye[0] + f[0];
|
|
197
|
+
aim[1] = eye[1] + f[1];
|
|
198
|
+
aim[2] = eye[2] + f[2];
|
|
199
|
+
this.camera.lookAt(eye, aim);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function clamp(v, lo, hi) {
|
|
204
|
+
return Math.min(hi, Math.max(lo, v));
|
|
205
|
+
}
|
|
206
|
+
/** The fraction of the gap to close this step for an exponential approach with time constant `tau`. */
|
|
207
|
+
function ease(dt, tau) {
|
|
208
|
+
return tau > 0 ? 1 - Math.exp(-dt / tau) : 1;
|
|
209
|
+
}
|
|
210
|
+
/** Shortest signed turn from `from` to `to`, radians in -π..π. */
|
|
211
|
+
function angleDelta(from, to) {
|
|
212
|
+
let d = (to - from) % (2 * Math.PI);
|
|
213
|
+
if (d > Math.PI)
|
|
214
|
+
d -= 2 * Math.PI;
|
|
215
|
+
else if (d < -Math.PI)
|
|
216
|
+
d += 2 * Math.PI;
|
|
217
|
+
return d;
|
|
218
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { type InputClock } from './clock.js';
|
|
2
|
+
import { type Aim, type MagnifyOptions } from './magnify.js';
|
|
3
|
+
import { type PointerDispatcher } from './pointer-dispatch.js';
|
|
4
|
+
import type { GestureKind, PointerTransform } from './types.js';
|
|
5
|
+
/** Device of the pointer that made a gesture. */
|
|
6
|
+
export type GestureDevice = 'mouse' | 'touch' | 'pen';
|
|
7
|
+
/** Phases of a continuous gesture (pan, drag, pinch). */
|
|
8
|
+
export type GesturePhase = 'start' | 'move' | 'end' | 'cancel';
|
|
9
|
+
/** A point in game space (through the `PointerTransform`). */
|
|
10
|
+
export interface GesturePoint {
|
|
11
|
+
/** Game space. When the transform returns `null` (letterbox bars) this holds the last inside position. */
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
/** False when the transform returned `null` for this point. */
|
|
15
|
+
inside: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** `tap`, `doubleTap` and `longPress`: one point, reported on one tick. */
|
|
18
|
+
export interface TapGesture extends GesturePoint {
|
|
19
|
+
device: GestureDevice;
|
|
20
|
+
}
|
|
21
|
+
/** `pan`: one pointer moved past the threshold. Two or more pointers pinch and never pan. */
|
|
22
|
+
export interface PanGesture extends GesturePoint {
|
|
23
|
+
phase: GesturePhase;
|
|
24
|
+
/** Movement since the previous report, game space. Every `dx` of one pan sums to its total travel from the down point. */
|
|
25
|
+
dx: number;
|
|
26
|
+
dy: number;
|
|
27
|
+
/** Pointers in the pan: always 1 (a second pointer cancels the pan and starts a pinch). */
|
|
28
|
+
pointers: 1;
|
|
29
|
+
device: GestureDevice;
|
|
30
|
+
}
|
|
31
|
+
/** `drag`: one pointer moved past the threshold. Like a one-pointer pan, with the origin. */
|
|
32
|
+
export interface DragGesture extends GesturePoint {
|
|
33
|
+
phase: GesturePhase;
|
|
34
|
+
/** Where the pointer went down, game space. */
|
|
35
|
+
origin: GesturePoint;
|
|
36
|
+
dx: number;
|
|
37
|
+
dy: number;
|
|
38
|
+
device: GestureDevice;
|
|
39
|
+
}
|
|
40
|
+
/** `pinch`: two pointers. `x`/`y` is their centre. */
|
|
41
|
+
export interface PinchGesture extends GesturePoint {
|
|
42
|
+
phase: GesturePhase;
|
|
43
|
+
/** Distance between the pointers now / at the start (1 = unchanged). */
|
|
44
|
+
scale: number;
|
|
45
|
+
/** Change since the previous report (multiply a zoom by it). */
|
|
46
|
+
delta: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* An `onGesture` listener: called once, synchronously, each time the recogniser decides something,
|
|
50
|
+
* before any tick reports it. `g` is the report that the tick fields will carry (a `TapGesture`,
|
|
51
|
+
* `PanGesture`, `DragGesture` or `PinchGesture`, narrowed by `kind`). Discrete kinds (`tap`,
|
|
52
|
+
* `doubleTap`, `longPress`) come with phase `'end'`.
|
|
53
|
+
*/
|
|
54
|
+
export type GestureListener = (kind: GestureKind, phase: GesturePhase, g: GesturePoint) => void;
|
|
55
|
+
export interface GestureOptions {
|
|
56
|
+
/**
|
|
57
|
+
* CSS px a pointer may move and still be a tap or long-press. Past it the press is a pan and a
|
|
58
|
+
* drag. Default 10.
|
|
59
|
+
*/
|
|
60
|
+
panThreshold?: number;
|
|
61
|
+
/** Ms a pointer must stay down (and within `panThreshold`) for a long-press. Default 450. */
|
|
62
|
+
longPressMs?: number;
|
|
63
|
+
/** Most ms from the end of one tap to the start of the next for a double tap. Default 300. */
|
|
64
|
+
doubleTapMs?: number;
|
|
65
|
+
/** Most CSS px between the two taps of a double tap. Default 24. */
|
|
66
|
+
doubleTapDistance?: number;
|
|
67
|
+
/** While true no gesture is reported (see `Gestures`). An `Input` that links this replaces it with its own. */
|
|
68
|
+
blocked?: () => boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Clock in ms. Default `performance.now()`. Tests pass a fake one. Attached DOM events are
|
|
71
|
+
* timed by their `timeStamp`, moved onto this clock by their age (`eventTime`); the long-press
|
|
72
|
+
* timer in `update()` reads this clock. The older spelling of `clock`; `clock` wins.
|
|
73
|
+
*/
|
|
74
|
+
now?: () => number;
|
|
75
|
+
/**
|
|
76
|
+
* The clock gestures are timed on (ws/input-8), e.g. a `createTickClock()` the game advances
|
|
77
|
+
* from its fixed step and shares with `Look`. Default `performance.now()`.
|
|
78
|
+
*/
|
|
79
|
+
clock?: InputClock;
|
|
80
|
+
/**
|
|
81
|
+
* Loupe and snap for small touch targets (see `magnify.ts`): while one touch pointer is down
|
|
82
|
+
* each tick reports `aim`, and below `below` CSS px of pitch a loupe shows the aim point.
|
|
83
|
+
*/
|
|
84
|
+
magnify?: MagnifyOptions;
|
|
85
|
+
/**
|
|
86
|
+
* `'prefer'` (ws/input-3): a pointer whose cumulative travel passes a quarter of `panThreshold`
|
|
87
|
+
* is a pan candidate and can no longer long-press, however long the next frame takes; if it
|
|
88
|
+
* lifts before crossing the threshold it is a tap (within `longPressMs`) or nothing. Default:
|
|
89
|
+
* a still-enough pointer long-presses when its time is up, even after a little travel.
|
|
90
|
+
*/
|
|
91
|
+
pan?: 'prefer';
|
|
92
|
+
/**
|
|
93
|
+
* Called once per press, synchronously, when its pointer's travel passes a quarter of
|
|
94
|
+
* `panThreshold` (in either `pan` mode), with the pointer id and the travel so far. An
|
|
95
|
+
* observer for games that want to cancel their own long-press affordance early.
|
|
96
|
+
*/
|
|
97
|
+
onPanCandidate?: (pointer: number, travel: number) => void;
|
|
98
|
+
}
|
|
99
|
+
export interface GestureAttachOptions {
|
|
100
|
+
/** Element that receives pointer events (the canvas, or the element wrapping it). */
|
|
101
|
+
pointerTarget: HTMLElement;
|
|
102
|
+
/** Set `touch-action: none` on the target so touch drags don't scroll or zoom. Default true. */
|
|
103
|
+
disableTouchScroll?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The pointer dispatcher to consume from (ws/input-4) instead of listening on the target
|
|
106
|
+
* directly. `Input.attach` passes its own; without one the gestures build a private dispatcher.
|
|
107
|
+
*/
|
|
108
|
+
dispatcher?: PointerDispatcher;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Touch and pointer gestures: tap, double tap, long-press, pan, drag and pinch. Feed it pointer
|
|
112
|
+
* events (via `attach` or the public feed methods), call `update()` once per simulation tick,
|
|
113
|
+
* then read this tick's gestures. Thresholds are CSS px; positions are game space through the
|
|
114
|
+
* same `PointerTransform` as `Input`.
|
|
115
|
+
*
|
|
116
|
+
* ```ts
|
|
117
|
+
* const gestures = new Gestures();
|
|
118
|
+
* input.setGestures(gestures); // shares blocked(), the transform, attach and update()
|
|
119
|
+
* // each tick, after input.update():
|
|
120
|
+
* if (gestures.tap) select(gestures.tap.x, gestures.tap.y);
|
|
121
|
+
* if (gestures.drag?.phase === 'move') moveBy(gestures.drag.dx, gestures.drag.dy);
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* Or bind them as actions: `{ select: [{ gesture: 'tap' }], info: [{ gesture: 'longPress' }] }`.
|
|
125
|
+
*
|
|
126
|
+
* Rules:
|
|
127
|
+
* - A tap is a down and up that stays within `panThreshold` and ends before `longPressMs`. A
|
|
128
|
+
* double tap also reports a tap for each of its two taps.
|
|
129
|
+
* - A long-press fires once, after `longPressMs` within the threshold; no tap follows it.
|
|
130
|
+
* - Moving past the threshold starts a pan and a drag (one pointer) for the rest of the press.
|
|
131
|
+
* Travel is cumulative from the down point, so a slow drag crosses it too, and the threshold
|
|
132
|
+
* is checked before the long-press timer on every move: a pointer whose travel crosses it
|
|
133
|
+
* never long-presses, however long the frame took. A long-press that already fired stays.
|
|
134
|
+
* - A second pointer cancels the pan and drag (and any tap or long-press) and starts a pinch;
|
|
135
|
+
* while two or more pointers are down, pan and drag report nothing (pinch wins). Lifting
|
|
136
|
+
* either pointer ends the pinch; nothing more is reported until every pointer is up.
|
|
137
|
+
* - Discrete gestures that arrive faster than ticks are queued, one per kind per tick. Moves in
|
|
138
|
+
* one tick are merged; `start` and `end` each get their own tick. While a pan, drag or pinch
|
|
139
|
+
* runs, every tick reports it (a `move` with no change when nothing moved).
|
|
140
|
+
* - While `blocked()` nothing is reported, the press in progress is dropped, and a pan, drag or
|
|
141
|
+
* pinch that had started gets one `cancel`, so the game can put things back.
|
|
142
|
+
*/
|
|
143
|
+
export declare class Gestures {
|
|
144
|
+
/** This tick's gestures, or `null`. */
|
|
145
|
+
tap: TapGesture | null;
|
|
146
|
+
doubleTap: TapGesture | null;
|
|
147
|
+
longPress: TapGesture | null;
|
|
148
|
+
pan: PanGesture | null;
|
|
149
|
+
drag: DragGesture | null;
|
|
150
|
+
pinch: PinchGesture | null;
|
|
151
|
+
/** This tick's aim while one touch pointer is down (with the `magnify` option), or `null`. */
|
|
152
|
+
aim: Aim | null;
|
|
153
|
+
blocked: () => boolean;
|
|
154
|
+
readonly panThreshold: number;
|
|
155
|
+
readonly longPressMs: number;
|
|
156
|
+
readonly doubleTapMs: number;
|
|
157
|
+
readonly doubleTapDistance: number;
|
|
158
|
+
/** `GestureOptions.pan`: `'prefer'` keeps a pan candidate from long-pressing. */
|
|
159
|
+
readonly panMode: 'prefer' | null;
|
|
160
|
+
/**
|
|
161
|
+
* The pointer-claim hook (ws/input-3): called on every `pointerDown` with the pointer id and
|
|
162
|
+
* device; when it returns true the pointer is not a gesture (its moves and lift are ignored
|
|
163
|
+
* too). `Input.setLook` installs one so an orbit look drag never pans; a game may install its
|
|
164
|
+
* own when nothing is linked.
|
|
165
|
+
*/
|
|
166
|
+
claim: ((id: number, device: GestureDevice) => boolean) | null;
|
|
167
|
+
/**
|
|
168
|
+
* The clock gestures are timed on (`GestureOptions.now`). Recordings stamp pointer events on
|
|
169
|
+
* it and playbacks replay them on it (ws/input-7). `clock.now`, bound.
|
|
170
|
+
*/
|
|
171
|
+
readonly now: () => number;
|
|
172
|
+
/** The clock (`GestureOptions.clock`, or one wrapping `now`, or the wall clock). */
|
|
173
|
+
readonly clock: InputClock;
|
|
174
|
+
private readonly onPanCandidate;
|
|
175
|
+
private transform;
|
|
176
|
+
private session;
|
|
177
|
+
/** Last tap, for double taps: client position and end time. */
|
|
178
|
+
private lastTap;
|
|
179
|
+
private lastInside;
|
|
180
|
+
/** Taps; `double` marks the second tap of a double tap (reported on the same tick). */
|
|
181
|
+
private readonly taps;
|
|
182
|
+
private readonly longPresses;
|
|
183
|
+
private readonly pans;
|
|
184
|
+
private readonly drags;
|
|
185
|
+
private readonly pinches;
|
|
186
|
+
/** Continuous gestures reported as started and not yet ended, with their last report. */
|
|
187
|
+
private readonly running;
|
|
188
|
+
/** The session whose long-press has been reported, while its pointer stays down. */
|
|
189
|
+
private longPressSession;
|
|
190
|
+
private detachFn;
|
|
191
|
+
private magnify;
|
|
192
|
+
private loupe;
|
|
193
|
+
/** The aim at the moment the finger lifted, reported (with `ended`) on the next tick. */
|
|
194
|
+
private endedAim;
|
|
195
|
+
/** `onGesture` listeners, called at recognition time. */
|
|
196
|
+
private readonly listeners;
|
|
197
|
+
constructor(opts?: GestureOptions);
|
|
198
|
+
/** Turn magnify on (or off with `null`) after construction. */
|
|
199
|
+
setMagnify(opts: MagnifyOptions | null): void;
|
|
200
|
+
/** The loupe element, once one has been shown (for styling and tests). */
|
|
201
|
+
get loupeElement(): HTMLElement | null;
|
|
202
|
+
/** Install the client → game-space mapping. `null` = identity (relative to the target when attached). */
|
|
203
|
+
setPointerTransform(fn: PointerTransform | null): void;
|
|
204
|
+
/**
|
|
205
|
+
* Observe the gesture stream: `listener` is called synchronously each time a gesture is
|
|
206
|
+
* recognised (a tap on lift, a long-press when its time is up, a pan's `start`, every `move`,
|
|
207
|
+
* `end` or `cancel`), not once per tick. It is an observer for tests, replays and logging; the
|
|
208
|
+
* per-tick fields (`tap`, `drag`, ...) and action bindings stay the way a game reads gestures.
|
|
209
|
+
* Returns the unsubscribe function.
|
|
210
|
+
*/
|
|
211
|
+
onGesture(listener: GestureListener): () => void;
|
|
212
|
+
private emit;
|
|
213
|
+
/**
|
|
214
|
+
* True while `kind` drives an action binding: on the tick a tap or double tap is reported;
|
|
215
|
+
* from a long-press until its pointer lifts; on a pan, drag or pinch's `start` and `move` ticks.
|
|
216
|
+
*/
|
|
217
|
+
active(kind: GestureKind): boolean;
|
|
218
|
+
/** True when `kind` was reported fresh this tick: a new tap, double tap, long-press or `start`. */
|
|
219
|
+
fired(kind: GestureKind): boolean;
|
|
220
|
+
/** Advance one tick: fire due long-presses and publish one report per kind. */
|
|
221
|
+
update(): void;
|
|
222
|
+
/**
|
|
223
|
+
* This tick's aim (the `magnify` option): one touch pointer down, not blocked, `when()`. The
|
|
224
|
+
* aim point is the finger, raised by `lift` while it drags; `snap` picks the target; the
|
|
225
|
+
* loupe shows while the pitch is below `below` and the aim is over the targets.
|
|
226
|
+
*/
|
|
227
|
+
private updateAim;
|
|
228
|
+
/** The aim of touch contact `c` (`null` for mouse and pen, or while `when()` is false). */
|
|
229
|
+
private aimOf;
|
|
230
|
+
/** The `cancel` report for a running `kind` (blocked), or `null`. */
|
|
231
|
+
private cancelled;
|
|
232
|
+
/**
|
|
233
|
+
* This tick's report for `kind`: the next queued event (consecutive moves merged), or, while
|
|
234
|
+
* the gesture runs with nothing new, the last report as a `move` with no change.
|
|
235
|
+
*/
|
|
236
|
+
private publish;
|
|
237
|
+
private clearQueues;
|
|
238
|
+
pointerDown(id: number, clientX: number, clientY: number, device?: GestureDevice, time?: number): void;
|
|
239
|
+
pointerMove(id: number, clientX: number, clientY: number, time?: number): void;
|
|
240
|
+
pointerUp(id: number, clientX?: number, clientY?: number, time?: number): void;
|
|
241
|
+
/** The browser took the pointer (system gesture, palm rejection): drop the press. */
|
|
242
|
+
pointerCancel(id: number): void;
|
|
243
|
+
/** Drop every pointer (focus loss, tab hidden). A started pan, drag or pinch is cancelled. */
|
|
244
|
+
cancelAll(): void;
|
|
245
|
+
private cancelSession;
|
|
246
|
+
private checkLongPress;
|
|
247
|
+
/** True when `c` may no longer long-press: a pan candidate under `pan: 'prefer'`. */
|
|
248
|
+
private preferPan;
|
|
249
|
+
private longPressOf;
|
|
250
|
+
private emitTap;
|
|
251
|
+
private pushMove;
|
|
252
|
+
/** Queues one pan and one drag report and tells the listeners. */
|
|
253
|
+
private pushPan;
|
|
254
|
+
private pushPinch;
|
|
255
|
+
/** Ends (or cancels) a one-pointer pan and drag, if one is running in `s`. */
|
|
256
|
+
private endOnePointer;
|
|
257
|
+
/** Two pointers: only the pinch moves. Their centre moving is not a pan (pinch wins). */
|
|
258
|
+
private moveTwo;
|
|
259
|
+
private endTwo;
|
|
260
|
+
private map;
|
|
261
|
+
/**
|
|
262
|
+
* Listen to pointer events on the target. Mouse: the primary button only. Touch and pen: up
|
|
263
|
+
* to two contacts. The target captures each pointer, so a drag off its edge keeps reporting.
|
|
264
|
+
* `Input.setGestures` calls this from `Input.attach`; call it yourself only when the gestures
|
|
265
|
+
* are used without an `Input`.
|
|
266
|
+
*/
|
|
267
|
+
attach(opts: GestureAttachOptions): void;
|
|
268
|
+
/** The private dispatcher a standalone `attach` built, or `null` (shared or detached). */
|
|
269
|
+
private ownDispatcher;
|
|
270
|
+
/**
|
|
271
|
+
* The dispatcher consumer: mouse primary button only; every touch and pen contact. Each event
|
|
272
|
+
* is timed by its `timeStamp` (`eventTime`: `now() - age`), not by when it was handled, so a
|
|
273
|
+
* tap delivered after a stalled frame is still a tap; a replayed event by its recorded time.
|
|
274
|
+
*/
|
|
275
|
+
private readonly consumer;
|
|
276
|
+
detach(): void;
|
|
277
|
+
/** Detach and remove the loupe element. */
|
|
278
|
+
destroy(): void;
|
|
279
|
+
}
|
|
280
|
+
/** `new Gestures(opts)`: gestures, on `opts.clock` when given (ws/input-8). */
|
|
281
|
+
export declare function createGestures(opts?: GestureOptions): Gestures;
|