@pibbl/core 0.0.2 → 0.0.3-alpha.109.1
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/THIRD_PARTY_NOTICES.txt +81 -0
- package/dist/features/physics/2d-testing.d.ts +1 -1
- package/dist/features/physics/2d-testing.js +2 -2
- package/dist/features/physics/2d-testing.js.map +2 -2
- package/dist/features/physics/lib/2d/canvas/components.js +25 -21
- package/dist/features/physics/lib/2d/canvas/components.js.map +2 -2
- package/dist/features/physics/lib/2d/canvas/presentation.js +1 -2
- package/dist/features/physics/lib/2d/canvas/presentation.js.map +2 -2
- package/dist/features/physics/lib/2d/collision/casts.js +4 -2
- package/dist/features/physics/lib/2d/collision/casts.js.map +2 -2
- package/dist/features/physics/lib/2d/runtime/controller.js +1 -1
- package/dist/features/physics/lib/2d/runtime/controller.js.map +2 -2
- package/dist/features/physics/lib/2d/runtime/obstacles.js +9 -11
- package/dist/features/physics/lib/2d/runtime/obstacles.js.map +2 -2
- package/dist/features/physics/lib/2d/shapes.js +8 -9
- package/dist/features/physics/lib/2d/shapes.js.map +2 -2
- package/dist/features/physics/lib/2d/world/rapier.js +22 -26
- package/dist/features/physics/lib/2d/world/rapier.js.map +2 -2
- package/dist/features/sprites/loader.js +6 -3
- package/dist/features/sprites/loader.js.map +2 -2
- package/dist/features/textures/index.d.ts +12 -2
- package/dist/features/textures/index.js +33 -1
- package/dist/features/textures/index.js.map +2 -2
- package/dist/features/textures/lib/chemical-field.d.ts +56 -0
- package/dist/features/textures/lib/chemical-field.js +154 -0
- package/dist/features/textures/lib/chemical-field.js.map +7 -0
- package/dist/features/textures/lib/chemical-recipes.d.ts +119 -0
- package/dist/features/textures/lib/chemical-recipes.js +275 -0
- package/dist/features/textures/lib/chemical-recipes.js.map +7 -0
- package/dist/features/textures/lib/definitions.d.ts +3 -18
- package/dist/features/textures/lib/definitions.js +17 -24
- package/dist/features/textures/lib/definitions.js.map +2 -2
- package/dist/features/textures/lib/geometric-patterns.d.ts +149 -0
- package/dist/features/textures/lib/geometric-patterns.js +305 -0
- package/dist/features/textures/lib/geometric-patterns.js.map +7 -0
- package/dist/features/textures/lib/gray-scott.d.ts +55 -0
- package/dist/features/textures/lib/gray-scott.js +37 -0
- package/dist/features/textures/lib/gray-scott.js.map +7 -0
- package/dist/features/textures/lib/palette.js +1 -3
- package/dist/features/textures/lib/palette.js.map +2 -2
- package/dist/features/textures/lib/patterns.d.ts +123 -0
- package/dist/features/textures/lib/patterns.js +344 -0
- package/dist/features/textures/lib/patterns.js.map +7 -0
- package/dist/features/textures/lib/rain-drops.js +2 -1
- package/dist/features/textures/lib/rain-drops.js.map +2 -2
- package/dist/features/textures/lib/reaction-diffusion.d.ts +3 -2
- package/dist/features/textures/lib/reaction-diffusion.js +9 -20
- package/dist/features/textures/lib/reaction-diffusion.js.map +2 -2
- package/dist/features/textures/lib/simulation.d.ts +10 -4
- package/dist/features/textures/lib/simulation.js +23 -13
- package/dist/features/textures/lib/simulation.js.map +2 -2
- package/dist/features/textures/lib/wasm/electric.js +8 -1
- package/dist/features/textures/lib/wasm/electric.js.map +2 -2
- package/dist/features/textures/lib/water-surface.js +1 -3
- package/dist/features/textures/lib/water-surface.js.map +2 -2
- package/dist/features/viz/index.d.ts +68 -6
- package/dist/features/viz/index.js +164 -2
- package/dist/features/viz/index.js.map +2 -2
- package/dist/features/viz/inspection/bar.d.ts +79 -0
- package/dist/features/viz/inspection/bar.js +49 -0
- package/dist/features/viz/inspection/bar.js.map +7 -0
- package/dist/features/viz/inspection/candle.d.ts +156 -0
- package/dist/features/viz/inspection/candle.js +120 -0
- package/dist/features/viz/inspection/candle.js.map +7 -0
- package/dist/features/viz/inspection/capture-types.d.ts +65 -0
- package/dist/features/viz/inspection/capture.d.ts +16 -0
- package/dist/features/viz/inspection/capture.js +49 -0
- package/dist/features/viz/inspection/capture.js.map +7 -0
- package/dist/features/viz/inspection/handler.d.ts +36 -0
- package/dist/features/viz/inspection/handler.js +91 -0
- package/dist/features/viz/inspection/handler.js.map +7 -0
- package/dist/features/viz/inspection/ohlc-bar.d.ts +132 -0
- package/dist/features/viz/inspection/ohlc-bar.js +118 -0
- package/dist/features/viz/inspection/ohlc-bar.js.map +7 -0
- package/dist/features/viz/inspection/owned-ref.d.ts +16 -0
- package/dist/features/viz/inspection/owned-ref.js +99 -0
- package/dist/features/viz/inspection/owned-ref.js.map +7 -0
- package/dist/features/viz/inspection/painted-point.d.ts +22 -0
- package/dist/features/viz/inspection/painted-point.js +29 -0
- package/dist/features/viz/inspection/painted-point.js.map +7 -0
- package/dist/features/viz/inspection/queries.d.ts +100 -0
- package/dist/features/viz/inspection/queries.js +192 -0
- package/dist/features/viz/inspection/queries.js.map +7 -0
- package/dist/features/viz/inspection/query-types.d.ts +177 -0
- package/dist/features/viz/inspection/volume.d.ts +104 -0
- package/dist/features/viz/inspection/volume.js +95 -0
- package/dist/features/viz/inspection/volume.js.map +7 -0
- package/dist/features/viz/inspection.d.ts +19 -0
- package/dist/features/viz/inspection.js +54 -0
- package/dist/features/viz/inspection.js.map +7 -0
- package/dist/features/viz/inspection.mjs +1 -0
- package/dist/features/viz/lib/area-series.d.ts +62 -0
- package/dist/features/viz/lib/area-series.js +120 -0
- package/dist/features/viz/lib/area-series.js.map +7 -0
- package/dist/features/viz/lib/axis-title.js +2 -1
- package/dist/features/viz/lib/axis-title.js.map +2 -2
- package/dist/features/viz/lib/axis.js +1 -1
- package/dist/features/viz/lib/axis.js.map +2 -2
- package/dist/features/viz/lib/bar-series.d.ts +3 -1
- package/dist/features/viz/lib/bar-series.js +16 -1
- package/dist/features/viz/lib/bar-series.js.map +2 -2
- package/dist/features/viz/lib/baseline-series.d.ts +55 -0
- package/dist/features/viz/lib/baseline-series.js +136 -0
- package/dist/features/viz/lib/baseline-series.js.map +7 -0
- package/dist/features/viz/lib/candlestick-series.d.ts +62 -0
- package/dist/features/viz/lib/candlestick-series.js +150 -0
- package/dist/features/viz/lib/candlestick-series.js.map +7 -0
- package/dist/features/viz/lib/censored-point-series.d.ts +71 -0
- package/dist/features/viz/lib/censored-point-series.js +129 -0
- package/dist/features/viz/lib/censored-point-series.js.map +7 -0
- package/dist/features/viz/lib/color-context.d.ts +4 -0
- package/dist/features/viz/lib/color-context.js +41 -0
- package/dist/features/viz/lib/color-context.js.map +7 -0
- package/dist/features/viz/lib/color-math.d.ts +4 -0
- package/dist/features/viz/lib/color-math.js +31 -0
- package/dist/features/viz/lib/color-math.js.map +7 -0
- package/dist/features/viz/lib/color-types.d.ts +53 -0
- package/dist/features/viz/lib/curve-definition.d.ts +49 -0
- package/dist/features/viz/lib/curve-definition.js +142 -0
- package/dist/features/viz/lib/curve-definition.js.map +7 -0
- package/dist/features/viz/lib/diverging-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/diverging-color-scale.js +51 -0
- package/dist/features/viz/lib/diverging-color-scale.js.map +7 -0
- package/dist/features/viz/lib/domain-navigation.d.ts +40 -0
- package/dist/features/viz/lib/domain-navigation.js +77 -0
- package/dist/features/viz/lib/domain-navigation.js.map +7 -0
- package/dist/features/viz/lib/editable-chart-elements.d.ts +178 -0
- package/dist/features/viz/lib/editable-chart-elements.js +733 -0
- package/dist/features/viz/lib/editable-chart-elements.js.map +7 -0
- package/dist/features/viz/lib/financial-aggregation.d.ts +127 -0
- package/dist/features/viz/lib/financial-aggregation.js +116 -0
- package/dist/features/viz/lib/financial-aggregation.js.map +7 -0
- package/dist/features/viz/lib/financial-autoscale.d.ts +64 -0
- package/dist/features/viz/lib/financial-autoscale.js +61 -0
- package/dist/features/viz/lib/financial-autoscale.js.map +7 -0
- package/dist/features/viz/lib/financial-comparison.d.ts +62 -0
- package/dist/features/viz/lib/financial-comparison.js +98 -0
- package/dist/features/viz/lib/financial-comparison.js.map +7 -0
- package/dist/features/viz/lib/financial-geometry.d.ts +77 -0
- package/dist/features/viz/lib/financial-geometry.js +67 -0
- package/dist/features/viz/lib/financial-geometry.js.map +7 -0
- package/dist/features/viz/lib/financial-indicators.d.ts +114 -0
- package/dist/features/viz/lib/financial-indicators.js +135 -0
- package/dist/features/viz/lib/financial-indicators.js.map +7 -0
- package/dist/features/viz/lib/financial-oscillators.d.ts +171 -0
- package/dist/features/viz/lib/financial-oscillators.js +265 -0
- package/dist/features/viz/lib/financial-oscillators.js.map +7 -0
- package/dist/features/viz/lib/graph/bipartite.d.ts +14 -0
- package/dist/features/viz/lib/graph/bipartite.js +250 -0
- package/dist/features/viz/lib/graph/bipartite.js.map +7 -0
- package/dist/features/viz/lib/graph/chord.d.ts +44 -0
- package/dist/features/viz/lib/graph/chord.js +348 -0
- package/dist/features/viz/lib/graph/chord.js.map +7 -0
- package/dist/features/viz/lib/graph/dependency.d.ts +26 -0
- package/dist/features/viz/lib/graph/dependency.js +140 -0
- package/dist/features/viz/lib/graph/dependency.js.map +7 -0
- package/dist/features/viz/lib/graph/force.d.ts +28 -0
- package/dist/features/viz/lib/graph/force.js +580 -0
- package/dist/features/viz/lib/graph/force.js.map +7 -0
- package/dist/features/viz/lib/graph/hierarchy.d.ts +21 -0
- package/dist/features/viz/lib/graph/hierarchy.js +112 -0
- package/dist/features/viz/lib/graph/hierarchy.js.map +7 -0
- package/dist/features/viz/lib/graph/icicle.d.ts +16 -0
- package/dist/features/viz/lib/graph/icicle.js +153 -0
- package/dist/features/viz/lib/graph/icicle.js.map +7 -0
- package/dist/features/viz/lib/graph/matrix.d.ts +30 -0
- package/dist/features/viz/lib/graph/matrix.js +243 -0
- package/dist/features/viz/lib/graph/matrix.js.map +7 -0
- package/dist/features/viz/lib/graph/neighborhood.d.ts +11 -0
- package/dist/features/viz/lib/graph/neighborhood.js +281 -0
- package/dist/features/viz/lib/graph/neighborhood.js.map +7 -0
- package/dist/features/viz/lib/graph/routes.d.ts +35 -0
- package/dist/features/viz/lib/graph/routes.js +101 -0
- package/dist/features/viz/lib/graph/routes.js.map +7 -0
- package/dist/features/viz/lib/graph/sankey.d.ts +44 -0
- package/dist/features/viz/lib/graph/sankey.js +341 -0
- package/dist/features/viz/lib/graph/sankey.js.map +7 -0
- package/dist/features/viz/lib/graph/shared.d.ts +59 -0
- package/dist/features/viz/lib/graph/shared.js +301 -0
- package/dist/features/viz/lib/graph/shared.js.map +7 -0
- package/dist/features/viz/lib/graph/tree.d.ts +11 -0
- package/dist/features/viz/lib/graph/tree.js +232 -0
- package/dist/features/viz/lib/graph/tree.js.map +7 -0
- package/dist/features/viz/lib/graph/treemap.d.ts +20 -0
- package/dist/features/viz/lib/graph/treemap.js +227 -0
- package/dist/features/viz/lib/graph/treemap.js.map +7 -0
- package/dist/features/viz/lib/graph/types.d.ts +1097 -0
- package/dist/features/viz/lib/hover-card.js +8 -9
- package/dist/features/viz/lib/hover-card.js.map +2 -2
- package/dist/features/viz/lib/hover-data.d.ts +1 -1
- package/dist/features/viz/lib/hover-data.js +5 -2
- package/dist/features/viz/lib/hover-data.js.map +2 -2
- package/dist/features/viz/lib/interval-band-series.d.ts +49 -0
- package/dist/features/viz/lib/interval-band-series.js +136 -0
- package/dist/features/viz/lib/interval-band-series.js.map +7 -0
- package/dist/features/viz/lib/interval-diamond-series.d.ts +43 -0
- package/dist/features/viz/lib/interval-diamond-series.js +122 -0
- package/dist/features/viz/lib/interval-diamond-series.js.map +7 -0
- package/dist/features/viz/lib/interval-series.d.ts +79 -0
- package/dist/features/viz/lib/interval-series.js +158 -0
- package/dist/features/viz/lib/interval-series.js.map +7 -0
- package/dist/features/viz/lib/layout-pie.js +9 -13
- package/dist/features/viz/lib/layout-pie.js.map +2 -2
- package/dist/features/viz/lib/line-series.d.ts +1 -1
- package/dist/features/viz/lib/line-series.js +47 -28
- package/dist/features/viz/lib/line-series.js.map +2 -2
- package/dist/features/viz/lib/linear-scale.js +1 -1
- package/dist/features/viz/lib/linear-scale.js.map +2 -2
- package/dist/features/viz/lib/monotone-curve.d.ts +11 -0
- package/dist/features/viz/lib/monotone-curve.js +63 -0
- package/dist/features/viz/lib/monotone-curve.js.map +7 -0
- package/dist/features/viz/lib/numeric-range-interpolation.d.ts +15 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js +36 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js.map +7 -0
- package/dist/features/viz/lib/ohlc-bar-series.d.ts +55 -0
- package/dist/features/viz/lib/ohlc-bar-series.js +168 -0
- package/dist/features/viz/lib/ohlc-bar-series.js.map +7 -0
- package/dist/features/viz/lib/paired-series.d.ts +44 -0
- package/dist/features/viz/lib/paired-series.js +93 -0
- package/dist/features/viz/lib/paired-series.js.map +7 -0
- package/dist/features/viz/lib/pie-layout.js +2 -1
- package/dist/features/viz/lib/pie-layout.js.map +2 -2
- package/dist/features/viz/lib/plot-series.js +11 -6
- package/dist/features/viz/lib/plot-series.js.map +2 -2
- package/dist/features/viz/lib/plot-types.d.ts +4 -3
- package/dist/features/viz/lib/point-series.d.ts +1 -1
- package/dist/features/viz/lib/point-series.js +36 -9
- package/dist/features/viz/lib/point-series.js.map +2 -2
- package/dist/features/viz/lib/point-types.d.ts +5 -2
- package/dist/features/viz/lib/reference-band.js +4 -1
- package/dist/features/viz/lib/reference-band.js.map +2 -2
- package/dist/features/viz/lib/scale-context.d.ts +1 -1
- package/dist/features/viz/lib/scale-ticks.js +21 -6
- package/dist/features/viz/lib/scale-ticks.js.map +2 -2
- package/dist/features/viz/lib/sequential-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/sequential-color-scale.js +49 -0
- package/dist/features/viz/lib/sequential-color-scale.js.map +7 -0
- package/dist/features/viz/lib/series-position.d.ts +12 -0
- package/dist/features/viz/lib/series-position.js +44 -0
- package/dist/features/viz/lib/series-position.js.map +7 -0
- package/dist/features/viz/lib/step-curves.d.ts +19 -0
- package/dist/features/viz/lib/step-curves.js +53 -0
- package/dist/features/viz/lib/step-curves.js.map +7 -0
- package/dist/features/viz/lib/threshold-color-scale.d.ts +43 -0
- package/dist/features/viz/lib/threshold-color-scale.js +59 -0
- package/dist/features/viz/lib/threshold-color-scale.js.map +7 -0
- package/dist/features/viz/lib/trading-time-mapping.d.ts +32 -0
- package/dist/features/viz/lib/trading-time-mapping.js +89 -0
- package/dist/features/viz/lib/trading-time-mapping.js.map +7 -0
- package/dist/features/viz/lib/trading-time-scale.d.ts +83 -0
- package/dist/features/viz/lib/trading-time-scale.js +96 -0
- package/dist/features/viz/lib/trading-time-scale.js.map +7 -0
- package/dist/features/viz/lib/trajectory-series.d.ts +71 -0
- package/dist/features/viz/lib/trajectory-series.js +111 -0
- package/dist/features/viz/lib/trajectory-series.js.map +7 -0
- package/dist/features/viz/lib/types.d.ts +20 -4
- package/dist/features/viz/lib/use-continuous-scale.js +6 -1
- package/dist/features/viz/lib/use-continuous-scale.js.map +2 -2
- package/dist/features/viz/lib/utc-scale.js +11 -10
- package/dist/features/viz/lib/utc-scale.js.map +2 -2
- package/dist/features/viz/lib/volume-series.d.ts +59 -0
- package/dist/features/viz/lib/volume-series.js +117 -0
- package/dist/features/viz/lib/volume-series.js.map +7 -0
- package/dist/features/viz/lib/weighted-point-series.d.ts +71 -0
- package/dist/features/viz/lib/weighted-point-series.js +169 -0
- package/dist/features/viz/lib/weighted-point-series.js.map +7 -0
- package/dist/filters/backdrop-contrast-gpu.d.ts +5 -0
- package/dist/filters/backdrop-contrast-gpu.js +33 -0
- package/dist/filters/backdrop-contrast-gpu.js.map +7 -0
- package/dist/filters/backdrop-contrast.d.ts +21 -0
- package/dist/filters/backdrop-contrast.js +61 -0
- package/dist/filters/backdrop-contrast.js.map +7 -0
- package/dist/filters/displacement.js +1 -1
- package/dist/filters/displacement.js.map +2 -2
- package/dist/filters/emboss-gpu.d.ts +4 -0
- package/dist/filters/emboss-gpu.js +39 -0
- package/dist/filters/emboss-gpu.js.map +7 -0
- package/dist/filters/emboss.d.ts +32 -0
- package/dist/filters/emboss.js +104 -0
- package/dist/filters/emboss.js.map +7 -0
- package/dist/filters/filter-executor.d.ts +11 -4
- package/dist/filters/filter-executor.js +104 -49
- package/dist/filters/filter-executor.js.map +2 -2
- package/dist/filters/reflected-light.js +1 -1
- package/dist/filters/reflected-light.js.map +2 -2
- package/dist/filters/reflection-gpu.d.ts +3 -1
- package/dist/filters/reflection-gpu.js +5 -2
- package/dist/filters/reflection-gpu.js.map +2 -2
- package/dist/filters/render-backdrop-contrast-boundary.d.ts +31 -0
- package/dist/filters/render-backdrop-contrast-boundary.js +116 -0
- package/dist/filters/render-backdrop-contrast-boundary.js.map +7 -0
- package/dist/filters/render-emboss-boundary.d.ts +13 -0
- package/dist/filters/render-emboss-boundary.js +131 -0
- package/dist/filters/render-emboss-boundary.js.map +7 -0
- package/dist/filters.d.ts +9 -5
- package/dist/filters.js +4 -0
- package/dist/filters.js.map +2 -2
- package/dist/index.d.ts +9 -5
- package/dist/index.js +18 -2
- package/dist/index.js.map +2 -2
- package/dist/internal.d.ts +4 -0
- package/dist/internal.js +6 -0
- package/dist/internal.js.map +2 -2
- package/dist/layout-kernel.d.ts +12 -0
- package/dist/layout-kernel.js +11 -0
- package/dist/layout-kernel.js.map +7 -0
- package/dist/layout-kernel.mjs +1 -0
- package/dist/lib/backend/types.d.ts +13 -1
- package/dist/lib/backend/types.js.map +2 -2
- package/dist/lib/components/arc-geometry.js +2 -1
- package/dist/lib/components/arc-geometry.js.map +2 -2
- package/dist/lib/components/g.js +2 -0
- package/dist/lib/components/g.js.map +2 -2
- package/dist/lib/components/html-box.js +2 -1
- package/dist/lib/components/html-box.js.map +2 -2
- package/dist/lib/components/img.js +3 -3
- package/dist/lib/components/img.js.map +2 -2
- package/dist/lib/components/layer.js +98 -16
- package/dist/lib/components/layer.js.map +3 -3
- package/dist/lib/components/text.d.ts +16 -0
- package/dist/lib/components/text.js +131 -24
- package/dist/lib/components/text.js.map +2 -2
- package/dist/lib/define-primitive.d.ts +4 -2
- package/dist/lib/define-primitive.js +3 -1
- package/dist/lib/define-primitive.js.map +2 -2
- package/dist/lib/element/metadata.d.ts +9 -0
- package/dist/lib/element/metadata.js +19 -0
- package/dist/lib/element/metadata.js.map +2 -2
- package/dist/lib/element/resolve-primitive-inputs.d.ts +2 -0
- package/dist/lib/element/resolve-primitive-inputs.js +17 -4
- package/dist/lib/element/resolve-primitive-inputs.js.map +2 -2
- package/dist/lib/events/event-facade.d.ts +18 -0
- package/dist/lib/events/event-facade.js +28 -2
- package/dist/lib/events/event-facade.js.map +2 -2
- package/dist/lib/events/hit-test.js +2 -1
- package/dist/lib/events/hit-test.js.map +2 -2
- package/dist/lib/events/propagation.d.ts +2 -1
- package/dist/lib/events/propagation.js +22 -16
- package/dist/lib/events/propagation.js.map +2 -2
- package/dist/lib/events/registrations.d.ts +10 -0
- package/dist/lib/events/registrations.js +160 -5
- package/dist/lib/events/registrations.js.map +2 -2
- package/dist/lib/execute-render.js +25 -1
- package/dist/lib/execute-render.js.map +2 -2
- package/dist/lib/filter/filter-region.js +3 -10
- package/dist/lib/filter/filter-region.js.map +2 -2
- package/dist/lib/focus/focus-manager.d.ts +8 -1
- package/dist/lib/focus/focus-manager.js +87 -43
- package/dist/lib/focus/focus-manager.js.map +2 -2
- package/dist/lib/focus/geometry.d.ts +2 -0
- package/dist/lib/focus/geometry.js +6 -0
- package/dist/lib/focus/geometry.js.map +2 -2
- package/dist/lib/geometry/path-bend-guide.js +1 -1
- package/dist/lib/geometry/path-bend-guide.js.map +2 -2
- package/dist/lib/geometry/path-geometry.js +12 -11
- package/dist/lib/geometry/path-geometry.js.map +2 -2
- package/dist/lib/geometry/path-transforms.js +17 -21
- package/dist/lib/geometry/path-transforms.js.map +2 -2
- package/dist/lib/geometry/path-warp-bezier.js +3 -1
- package/dist/lib/geometry/path-warp-bezier.js.map +2 -2
- package/dist/lib/geometry/path-warp.js +1 -1
- package/dist/lib/geometry/path-warp.js.map +2 -2
- package/dist/lib/global-state.js +2 -0
- package/dist/lib/global-state.js.map +2 -2
- package/dist/lib/html/html-events.d.ts +32 -0
- package/dist/lib/html/html-events.js +179 -0
- package/dist/lib/html/html-events.js.map +7 -0
- package/dist/lib/html/html-service.d.ts +8 -2
- package/dist/lib/html/html-service.js +198 -65
- package/dist/lib/html/html-service.js.map +2 -2
- package/dist/lib/html/overlay-config.js +7 -6
- package/dist/lib/html/overlay-config.js.map +2 -2
- package/dist/lib/html/types.d.ts +29 -2
- package/dist/lib/layout/absolute.d.ts +11 -5
- package/dist/lib/layout/absolute.js +329 -55
- package/dist/lib/layout/absolute.js.map +3 -3
- package/dist/lib/layout/allocation-checkpoint-owner.d.ts +11 -0
- package/dist/lib/layout/allocation-checkpoint-owner.js +86 -0
- package/dist/lib/layout/allocation-checkpoint-owner.js.map +7 -0
- package/dist/lib/layout/allocation-checkpoint.d.ts +53 -0
- package/dist/lib/layout/allocation-checkpoint.js +463 -0
- package/dist/lib/layout/allocation-checkpoint.js.map +7 -0
- package/dist/lib/layout/allocation-dependencies.d.ts +30 -0
- package/dist/lib/layout/allocation-dependencies.js +90 -0
- package/dist/lib/layout/allocation-dependencies.js.map +7 -0
- package/dist/lib/layout/allocation-revision.d.ts +13 -0
- package/dist/lib/layout/allocation-revision.js +67 -0
- package/dist/lib/layout/allocation-revision.js.map +7 -0
- package/dist/lib/layout/box-insets.d.ts +17 -0
- package/dist/lib/layout/box-insets.js +138 -0
- package/dist/lib/layout/box-insets.js.map +7 -0
- package/dist/lib/layout/box-sizing.d.ts +16 -0
- package/dist/lib/layout/box-sizing.js +77 -0
- package/dist/lib/layout/box-sizing.js.map +7 -0
- package/dist/lib/layout/box.js +42 -12
- package/dist/lib/layout/box.js.map +2 -2
- package/dist/lib/layout/canvas-measurement.d.ts +13 -0
- package/dist/lib/layout/canvas-measurement.js +57 -0
- package/dist/lib/layout/canvas-measurement.js.map +7 -0
- package/dist/lib/layout/context.d.ts +35 -6
- package/dist/lib/layout/context.js +72 -3
- package/dist/lib/layout/context.js.map +2 -2
- package/dist/lib/layout/define-layout-component.d.ts +23 -0
- package/dist/lib/layout/define-layout-component.js +84 -0
- package/dist/lib/layout/define-layout-component.js.map +7 -0
- package/dist/lib/layout/flex-allocation-cache.d.ts +42 -0
- package/dist/lib/layout/flex-baseline-mode.d.ts +2 -0
- package/dist/lib/layout/flex-baseline-mode.js +7 -0
- package/dist/lib/layout/flex-baseline-mode.js.map +7 -0
- package/dist/lib/layout/flex.d.ts +50 -15
- package/dist/lib/layout/flex.js +2124 -195
- package/dist/lib/layout/flex.js.map +3 -3
- package/dist/lib/layout/flow.js +225 -49
- package/dist/lib/layout/flow.js.map +2 -2
- package/dist/lib/layout/geometry-publication.d.ts +53 -0
- package/dist/lib/layout/geometry-publication.js +244 -0
- package/dist/lib/layout/geometry-publication.js.map +7 -0
- package/dist/lib/layout/grid-kernel.d.ts +63 -0
- package/dist/lib/layout/grid-kernel.js +168 -0
- package/dist/lib/layout/grid-kernel.js.map +7 -0
- package/dist/lib/layout/grid.d.ts +63 -4
- package/dist/lib/layout/grid.js +767 -171
- package/dist/lib/layout/grid.js.map +3 -3
- package/dist/lib/layout/measure.d.ts +55 -3
- package/dist/lib/layout/measure.js +448 -15
- package/dist/lib/layout/measure.js.map +2 -2
- package/dist/lib/layout/overlay.js +81 -23
- package/dist/lib/layout/overlay.js.map +2 -2
- package/dist/lib/layout/participation.d.ts +27 -0
- package/dist/lib/layout/participation.js +188 -0
- package/dist/lib/layout/participation.js.map +7 -0
- package/dist/lib/layout/place-child.js +1 -1
- package/dist/lib/layout/place-child.js.map +2 -2
- package/dist/lib/layout/positioning-diagnostics.d.ts +1 -1
- package/dist/lib/layout/positioning-diagnostics.js +13 -2
- package/dist/lib/layout/positioning-diagnostics.js.map +2 -2
- package/dist/lib/layout/prepared-root.d.ts +121 -0
- package/dist/lib/layout/prepared-root.js +360 -0
- package/dist/lib/layout/prepared-root.js.map +7 -0
- package/dist/lib/layout/standalone-kernel.d.ts +60 -0
- package/dist/lib/layout/standalone-kernel.js +722 -0
- package/dist/lib/layout/standalone-kernel.js.map +7 -0
- package/dist/lib/layout/topology.d.ts +21 -0
- package/dist/lib/layout/topology.js +113 -0
- package/dist/lib/layout/topology.js.map +7 -0
- package/dist/lib/layout/types.d.ts +5 -0
- package/dist/lib/layout/wasm/artifact.d.ts +1 -0
- package/dist/lib/layout/wasm/artifact.js +5 -0
- package/dist/lib/layout/wasm/artifact.js.map +7 -0
- package/dist/lib/layout/wasm/bytes.d.ts +1 -0
- package/dist/lib/layout/wasm/bytes.js +5 -0
- package/dist/lib/layout/wasm/bytes.js.map +7 -0
- package/dist/lib/layout/wasm/embedded.d.ts +2 -0
- package/dist/lib/layout/wasm/embedded.js +12 -0
- package/dist/lib/layout/wasm/embedded.js.map +7 -0
- package/dist/lib/layout/wasm/layout.wasm +0 -0
- package/dist/lib/layout/wasm/module.d.ts +8 -0
- package/dist/lib/layout/wasm/module.js +70 -0
- package/dist/lib/layout/wasm/module.js.map +7 -0
- package/dist/lib/layout/wasm/region.d.ts +267 -0
- package/dist/lib/layout/wasm/region.js +1018 -0
- package/dist/lib/layout/wasm/region.js.map +7 -0
- package/dist/lib/manipulation/controller.js +4 -7
- package/dist/lib/manipulation/controller.js.map +2 -2
- package/dist/lib/manipulation/frame.js +1 -1
- package/dist/lib/manipulation/frame.js.map +2 -2
- package/dist/lib/manipulation/handles.js +32 -33
- package/dist/lib/manipulation/handles.js.map +2 -2
- package/dist/lib/manipulation/solve.js +12 -10
- package/dist/lib/manipulation/solve.js.map +2 -2
- package/dist/lib/mount-pibbl.js +1 -0
- package/dist/lib/mount-pibbl.js.map +2 -2
- package/dist/lib/mount-prepared-pibbl.d.ts +5 -0
- package/dist/lib/mount-prepared-pibbl.js +29 -0
- package/dist/lib/mount-prepared-pibbl.js.map +7 -0
- package/dist/lib/mount-request.d.ts +8 -0
- package/dist/lib/mount-request.js +41 -0
- package/dist/lib/mount-request.js.map +7 -0
- package/dist/lib/pibbl.d.ts +21 -13
- package/dist/lib/pibbl.js +18 -16
- package/dist/lib/pibbl.js.map +2 -2
- package/dist/lib/recording/recording.d.ts +43 -0
- package/dist/lib/recording/recording.js +555 -0
- package/dist/lib/recording/recording.js.map +7 -0
- package/dist/lib/recording/types.d.ts +118 -0
- package/dist/lib/recording/wasm-bytes.d.ts +1 -0
- package/dist/lib/recording/wasm-bytes.js +5 -0
- package/dist/lib/recording/wasm-bytes.js.map +7 -0
- package/dist/lib/recording/worker-source.d.ts +1 -0
- package/dist/lib/recording/worker-source.js +5 -0
- package/dist/lib/recording/worker-source.js.map +7 -0
- package/dist/lib/render-layer/controller.d.ts +9 -3
- package/dist/lib/render-layer/controller.js +259 -110
- package/dist/lib/render-layer/controller.js.map +2 -2
- package/dist/lib/render-transaction.d.ts +12 -2
- package/dist/lib/render-transaction.js +69 -1
- package/dist/lib/render-transaction.js.map +2 -2
- package/dist/lib/render.js +32 -8
- package/dist/lib/render.js.map +2 -2
- package/dist/lib/scheduler/realm-scheduler.d.ts +2 -0
- package/dist/lib/scheduler/realm-scheduler.js +55 -26
- package/dist/lib/scheduler/realm-scheduler.js.map +2 -2
- package/dist/lib/scheduler/renderer-participant.js +1 -0
- package/dist/lib/scheduler/renderer-participant.js.map +2 -2
- package/dist/lib/series-inspection-frame.d.ts +18 -0
- package/dist/lib/series-inspection-frame.js +70 -0
- package/dist/lib/series-inspection-frame.js.map +7 -0
- package/dist/lib/signals/edge.d.ts +7 -4
- package/dist/lib/signals/edge.js +25 -3
- package/dist/lib/signals/edge.js.map +2 -2
- package/dist/lib/signals/graph.d.ts +16 -2
- package/dist/lib/signals/graph.js +54 -12
- package/dist/lib/signals/graph.js.map +2 -2
- package/dist/lib/signals/input-provision.d.ts +15 -0
- package/dist/lib/signals/input-provision.js +53 -3
- package/dist/lib/signals/input-provision.js.map +2 -2
- package/dist/lib/signals/render-consumer.d.ts +3 -0
- package/dist/lib/signals/render-consumer.js +22 -14
- package/dist/lib/signals/render-consumer.js.map +2 -2
- package/dist/lib/style/positioning.d.ts +50 -2
- package/dist/lib/style/positioning.js +28 -4
- package/dist/lib/style/positioning.js.map +2 -2
- package/dist/lib/style/resolve-built-in.d.ts +4 -3
- package/dist/lib/style/resolve-built-in.js +17 -3
- package/dist/lib/style/resolve-built-in.js.map +2 -2
- package/dist/lib/style/resolve-dispatch.d.ts +3 -0
- package/dist/lib/style/resolve-dispatch.js +77 -4
- package/dist/lib/style/resolve-dispatch.js.map +2 -2
- package/dist/lib/style/resolve-length.d.ts +2 -0
- package/dist/lib/style/resolve-length.js +13 -9
- package/dist/lib/style/resolve-length.js.map +2 -2
- package/dist/lib/style/sizing-length.d.ts +51 -0
- package/dist/lib/style/sizing-length.js +77 -0
- package/dist/lib/style/sizing-length.js.map +7 -0
- package/dist/lib/style/types.d.ts +63 -25
- package/dist/lib/surface/root-surface.js +10 -6
- package/dist/lib/surface/root-surface.js.map +2 -2
- package/dist/lib/textures/texture.js +10 -8
- package/dist/lib/textures/texture.js.map +2 -2
- package/dist/lib/transitions/capture.js +4 -1
- package/dist/lib/transitions/capture.js.map +2 -2
- package/dist/lib/transitions/embers-physics.js +17 -10
- package/dist/lib/transitions/embers-physics.js.map +2 -2
- package/dist/lib/types.d.ts +110 -1
- package/dist/sync.d.ts +16 -0
- package/dist/sync.js +13 -0
- package/dist/sync.js.map +7 -0
- package/dist/sync.mjs +1 -0
- package/package.json +26 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/features/textures/lib/rain-drops.ts"],
|
|
4
|
-
"sourcesContent": ["import { defineTexture, type TextureContext, type TextureRecipe } from \"@pibbl/core\";\nimport { validateSeed } from \"./palette.js\";\n\n/**\n * Rain rate, gravity, initial drops, condensation, trail, and outline controls for a raindrop texture.\n *\n * @see {@link rainDrops}\n */\nexport interface RainDropsOptions {\n /**\n * Seed used for deterministic sampling or simulation initialization. See\n * {@link RainDropsOptions}.\n */\n readonly seed?: number;\n /** New beads per second, from 0 through 120. */\n readonly rainRate?: number;\n /** Downward acceleration multiplier, from 0 through 10. */\n readonly gravity?: number;\n /** Number of drops seeded before continuous rain starts. See {@link RainDropsOptions}. */\n readonly initialDrops?: number;\n /** Whether simulation or playback advancement is suspended. See {@link RainDropsOptions}. */\n readonly paused?: boolean;\n /** Fine droplet film coverage, from 0 (clear) through 1 (mist). */\n readonly condensation?: number;\n /** Seconds controlling trail drying and condensation recovery, from 0 through 60. */\n readonly trailPersistence?: number;\n /** Residual water left behind a moving drop, from 0 through 1. */\n readonly trailStrength?: number;\n /** Outline and path variation, from 0 (smooth) through 1. */\n readonly irregularity?: number;\n}\n\n/**\n * Pause, reset, finger-wipe, release, and localized nudge commands for a raindrop texture.\n *\n * @see {@link rainDrops}\n */\nexport type RainDropsMessage =\n | {\n /** The literal \"pause\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"pause\";\n /** Whether simulation or playback advancement is suspended. See {@link RainDropsMessage}. */\n readonly paused: boolean;\n }\n | {\n /** The literal \"reset\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"reset\";\n }\n /** Begin or move one finger contact; successive positions wipe a continuous path. */\n | {\n /** The literal \"finger\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"finger\";\n /**\n * Horizontal coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly x: number;\n /**\n * Vertical coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly y: number;\n /** Radius in the coordinate system of this geometry or effect. See {@link RainDropsMessage}. */\n readonly radius?: number;\n }\n | {\n /** The literal \"release\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"release\";\n }\n /** Center and movement use normalized width/height; radius uses the shorter side. */\n | {\n /** The literal \"nudge\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"nudge\";\n /**\n * Horizontal coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly x: number;\n /**\n * Vertical coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly y: number;\n /** Horizontal displacement applied by the interaction. See {@link RainDropsMessage}. */\n readonly dx: number;\n /** Vertical displacement applied by the interaction. See {@link RainDropsMessage}. */\n readonly dy: number;\n /** Radius in the coordinate system of this geometry or effect. See {@link RainDropsMessage}. */\n readonly radius?: number;\n };\n\ninterface Drop { x: number; y: number; radius: number; vx: number; vy: number; phase: number }\ninterface Config { seed: number; rainRate: number; gravity: number; initialDrops: number; paused: boolean; condensation: number; trailPersistence: number; trailStrength: number; irregularity: number }\ninterface State {\n finger?: { x: number; y: number; radius: number; drop?: Drop };\n config: Config;\n drops: Drop[];\n random: number;\n births: number;\n paused: boolean;\n fresh: boolean;\n image: ImageData;\n film: Float32Array;\n trails: Float32Array;\n surface: Float32Array;\n grain: Float32Array;\n fieldActive: boolean;\n}\nconst MAX_DROPS = 256;\n\nfunction bounded(value: number, name: string, maximum: number): number {\n if (!Number.isFinite(value) || value < 0 || value > maximum) throw new RangeError(`Rain ${name} must be finite and within [0, ${maximum}].`);\n return value;\n}\nfunction options(input: RainDropsOptions): Config {\n const initialDrops = bounded(input.initialDrops ?? 100, \"initialDrops\", MAX_DROPS);\n if (!Number.isInteger(initialDrops)) throw new RangeError(\"Rain initialDrops must be an integer.\");\n return { seed: validateSeed(input.seed ?? 7), rainRate: bounded(input.rainRate ?? 24, \"rainRate\", 120), gravity: bounded(input.gravity ?? 1, \"gravity\", 10), initialDrops, paused: input.paused ?? false,\n condensation: bounded(input.condensation ?? 0, \"condensation\", 1),\n trailPersistence: bounded(input.trailPersistence ?? 8, \"trailPersistence\", 60),\n trailStrength: bounded(input.trailStrength ?? 0.65, \"trailStrength\", 1),\n irregularity: bounded(input.irregularity ?? 0.8, \"irregularity\", 1) };\n}\nfunction assertMap(context: TextureContext): void {\n if (context.palette !== undefined) throw new TypeError(\"rainDrops is a numeric displacement map and does not accept a palette.\");\n}\nfunction random(state: State): number {\n state.random = (Math.imul(state.random, 1664525) + 1013904223) >>> 0;\n return state.random / 4294967296;\n}\nfunction spawn(state: State, context: TextureContext): void {\n if (state.drops.length >= MAX_DROPS) return;\n const side = Math.min(context.canvas.width, context.canvas.height);\n state.drops.push({ x: random(state) * context.canvas.width / side, y: random(state) * context.canvas.height / side, radius: 0.005 + random(state) ** 2 * 0.015, vx: 0, vy: 0, phase: random(state) * Math.PI * 2 });\n}\nfunction reset(state: State, context: TextureContext): void {\n state.finger = undefined;\n state.random = state.config.seed; state.drops = []; state.births = 0; state.fresh = true;\n state.film.fill(1); state.trails.fill(0); state.fieldActive = false;\n for (let i = 0; i < state.grain.length; i++) {\n let value = Math.imul(i + 1, 0x45d9f3b) ^ state.config.seed;\n value = Math.imul(value ^ (value >>> 16), 0x45d9f3b);\n state.grain[i] = ((value ^ (value >>> 16)) >>> 0) / 4294967296;\n }\n for (let i = 0; i < state.config.initialDrops; i++) spawn(state, context);\n}\n/** Coalescence conserves volume and volume-weighted position/momentum. */\nfunction merge(drops: Drop[]): void {\n for (let i = 0; i < drops.length; i++) {\n const a = drops[i];\n for (let j = i + 1; j < drops.length; j++) {\n const b = drops[j];\n if (Math.hypot(a.x - b.x, a.y - b.y) >= a.radius + b.radius) continue;\n const av = a.radius ** 3, bv = b.radius ** 3, volume = av + bv;\n a.x = (a.x * av + b.x * bv) / volume; a.y = (a.y * av + b.y * bv) / volume;\n a.vx = (a.vx * av + b.vx * bv) / volume; a.vy = (a.vy * av + b.vy * bv) / volume;\n a.radius = Math.cbrt(volume);\n drops.splice(j--, 1);\n }\n }\n}\nfunction active(state: State): boolean {\n return state.fieldActive || state.config.rainRate > 0 || state.drops.some(d => (state.config.gravity > 0 && d.radius > 0.012) || Math.abs(d.vx) + Math.abs(d.vy) > 0.0001);\n}\nfunction schedule(state: State, context: TextureContext): void {\n if (!state.paused && active(state)) context.requestFrame();\n}\n\n/** Sweep the actual drop footprint, collecting film and leaving a beaded residual trail. */\nfunction sweep(state: State, drop: Drop, oldX: number, oldY: number, context: TextureContext): void {\n const { width, height } = context.canvas, side = Math.min(width, height);\n const ax = oldX * side, ay = oldY * side, bx = drop.x * side, by = drop.y * side;\n const dx = bx - ax, dy = by - ay, length2 = dx * dx + dy * dy;\n if (length2 < 0.000001) return;\n const radius = Math.max(1, drop.radius * side * 1.1);\n let collected = 0;\n for (let y = Math.max(0, Math.floor(Math.min(ay, by) - radius)); y < Math.min(height, Math.ceil(Math.max(ay, by) + radius)); y++) {\n for (let x = Math.max(0, Math.floor(Math.min(ax, bx) - radius)); x < Math.min(width, Math.ceil(Math.max(ax, bx) + radius)); x++) {\n const t = Math.max(0, Math.min(1, ((x + 0.5 - ax) * dx + (y + 0.5 - ay) * dy) / length2));\n const distance = Math.hypot(x + 0.5 - ax - t * dx, y + 0.5 - ay - t * dy) / radius;\n if (distance >= 1) continue;\n const i = y * width + x;\n const remaining = Math.max(0, Math.min(1, (distance - 0.7) / 0.3));\n const removed = Math.max(0, state.film[i] - remaining);\n collected += removed;\n state.film[i] = Math.min(state.film[i], remaining);\n // Spatially stable necks and beads avoid frame-rate-dependent trail stamping.\n const neck = 0.18 + 0.12 * Math.sin(y * 0.7 + drop.phase);\n const bead = Math.pow(state.grain[i], 7);\n const residual = Math.max(0, 1 - distance / (neck + bead * 0.6));\n state.trails[i] = Math.max(state.trails[i], residual * (0.00045 + bead * 0.0018) * state.config.trailStrength);\n }\n }\n // Film volume is swept area times a small effective thickness.\n drop.radius = Math.cbrt(drop.radius ** 3 + collected / (side * side) * state.config.condensation * 0.0002);\n state.fieldActive = true;\n}\n\n/** At capacity, coalesce the closest free beads before releasing newly gathered water. */\nfunction makeReleaseRoom(drops: Drop[]): void {\n if (drops.length < MAX_DROPS) return;\n let first = 0, second = 1, nearest = Infinity;\n for (let i = 0; i < drops.length; i++) for (let j = i + 1; j < drops.length; j++) {\n const distance = Math.hypot(drops[i].x - drops[j].x, drops[i].y - drops[j].y);\n if (distance < nearest) { nearest = distance; first = i; second = j; }\n }\n const a = drops[first], b = drops[second], av = a.radius ** 3, bv = b.radius ** 3, volume = av + bv;\n a.x = (a.x * av + b.x * bv) / volume; a.y = (a.y * av + b.y * bv) / volume;\n a.vx = (a.vx * av + b.vx * bv) / volume; a.vy = (a.vy * av + b.vy * bv) / volume;\n a.radius = Math.cbrt(volume); drops.splice(second, 1);\n}\n\n/** A finger removes film and residual water, and carries intersected beads without inertia. */\nfunction wipeFinger(state: State, oldX: number, oldY: number, context: TextureContext): void {\n const finger = state.finger;\n if (!finger) return;\n const { width, height } = context.canvas, side = Math.min(width, height);\n const dx = finger.x - oldX, dy = finger.y - oldY, length2 = dx * dx + dy * dy;\n const distance = (x: number, y: number): number => {\n const t = length2 === 0 ? 0 : Math.max(0, Math.min(1, ((x - oldX) * dx + (y - oldY) * dy) / length2));\n return Math.hypot(x - oldX - t * dx, y - oldY - t * dy);\n };\n let volume = finger.drop ? finger.drop.radius ** 3 : 0;\n for (let i = state.drops.length - 1; i >= 0; i--) {\n const drop = state.drops[i];\n if (distance(drop.x, drop.y) > finger.radius + drop.radius * 1.3) continue;\n volume += drop.radius ** 3;\n state.drops.splice(i, 1);\n }\n for (let y = Math.max(0, Math.floor((Math.min(oldY, finger.y) - finger.radius) * side)); y < Math.min(height, Math.ceil((Math.max(oldY, finger.y) + finger.radius) * side)); y++) {\n for (let x = Math.max(0, Math.floor((Math.min(oldX, finger.x) - finger.radius) * side)); x < Math.min(width, Math.ceil((Math.max(oldX, finger.x) + finger.radius) * side)); x++) {\n const coverage = Math.max(0, Math.min(1, (1 - distance((x + 0.5) / side, (y + 0.5) / side) / finger.radius) / 0.15));\n if (coverage === 0) continue;\n const i = y * width + x, remaining = 1 - coverage;\n const removedFilm = Math.max(0, state.film[i] - remaining);\n const removedTrail = state.trails[i] * coverage;\n volume += (removedFilm * state.config.condensation * 0.0002 + removedTrail) / (side * side);\n state.film[i] = Math.min(state.film[i], remaining);\n state.trails[i] -= removedTrail;\n }\n }\n if (volume > 0) {\n finger.drop ??= { x: finger.x, y: finger.y, radius: 0, vx: 0, vy: 0, phase: 0 };\n finger.drop.x = finger.x; finger.drop.y = finger.y; finger.drop.radius = Math.cbrt(volume);\n }\n state.fieldActive = true;\n}\n\nfunction recoverFilm(state: State, elapsed: number): void {\n if (!state.fieldActive) return;\n const retention = state.config.trailPersistence === 0 ? 0 : Math.exp(-elapsed / state.config.trailPersistence);\n let active = false;\n for (let i = 0; i < state.film.length; i++) {\n const missing = (1 - state.film[i]) * retention;\n state.film[i] = missing < 0.002 ? 1 : 1 - missing;\n const trail = state.trails[i] * retention;\n state.trails[i] = trail < 0.000005 ? 0 : trail;\n active ||= state.film[i] < 1 || state.trails[i] > 0;\n }\n state.fieldActive = active;\n}\n\nconst recipe = defineTexture<RainDropsOptions, State, RainDropsMessage>({\n create(context, input) {\n assertMap(context);\n const config = options(input);\n const cells = context.canvas.width * context.canvas.height;\n const state: State = { film: new Float32Array(cells), trails: new Float32Array(cells), surface: new Float32Array(cells), grain: new Float32Array(cells), fieldActive: false, config, drops: [], random: config.seed, births: 0, paused: config.paused, fresh: true, image: context.canvas.getContext(\"2d\")!.createImageData(context.canvas.width, context.canvas.height) };\n reset(state, context); schedule(state, context); return state;\n },\n update(state, input, context) {\n assertMap(context);\n const next = options(input), previous = state.config;\n state.config = next;\n if (next.condensation !== previous.condensation || next.irregularity !== previous.irregularity || next.trailStrength !== previous.trailStrength) context.invalidate();\n if (next.paused !== previous.paused) { state.paused = next.paused; state.fresh = true; }\n if (next.rainRate !== previous.rainRate || next.gravity !== previous.gravity) state.fresh = true;\n if (next.seed !== previous.seed || next.initialDrops !== previous.initialDrops) { reset(state, context); context.invalidate(); }\n schedule(state, context);\n },\n receive(state, message, context) {\n if (message.type === \"pause\") { state.paused = message.paused; state.fresh = true; }\n else if (message.type === \"reset\") { reset(state, context); context.invalidate(); }\n else if (message.type === \"finger\") {\n const x = bounded(message.x, \"finger x\", 1), y = bounded(message.y, \"finger y\", 1);\n const radius = bounded(message.radius ?? 0.045, \"finger radius\", 2);\n if (radius === 0) throw new RangeError(\"Rain finger radius must be positive.\");\n const side = Math.min(context.canvas.width, context.canvas.height);\n const nextX = x * context.canvas.width / side, nextY = y * context.canvas.height / side;\n const oldX = state.finger?.x ?? nextX, oldY = state.finger?.y ?? nextY;\n state.finger ??= { x: nextX, y: nextY, radius };\n state.finger.x = nextX; state.finger.y = nextY; state.finger.radius = radius;\n wipeFinger(state, oldX, oldY, context); context.invalidate();\n }\n else if (message.type === \"release\") {\n if (state.finger?.drop) { makeReleaseRoom(state.drops); state.drops.push(state.finger.drop); }\n state.finger = undefined; context.invalidate();\n }\n else if (message.type === \"nudge\") {\n const x = bounded(message.x, \"nudge x\", 1), y = bounded(message.y, \"nudge y\", 1);\n const radius = bounded(message.radius ?? 0.12, \"nudge radius\", 2);\n if (radius === 0) throw new RangeError(\"Rain nudge radius must be positive.\");\n for (const delta of [message.dx, message.dy]) if (!Number.isFinite(delta) || Math.abs(delta) > 1) throw new RangeError(\"Rain nudge movement must be finite and within [-1, 1].\");\n if (message.dx === 0 && message.dy === 0) return;\n const side = Math.min(context.canvas.width, context.canvas.height);\n const width = context.canvas.width / side, height = context.canvas.height / side;\n for (const drop of state.drops) {\n const distance = Math.hypot(drop.x - x * width, drop.y - y * height);\n const weight = Math.max(0, 1 - distance / radius) ** 2;\n const oldX = drop.x, oldY = drop.y;\n drop.x = Math.max(0, Math.min(width, drop.x + message.dx * width * weight));\n drop.y = Math.max(0, Math.min(height, drop.y + message.dy * height * weight));\n sweep(state, drop, oldX, oldY, context);\n drop.vx += message.dx * width * weight * 3; drop.vy += message.dy * height * weight * 3;\n }\n merge(state.drops); context.invalidate();\n } else throw new TypeError(\"Unknown rain drop message.\");\n schedule(state, context);\n },\n advance(state, frame, context) {\n if (state.paused) return;\n if (state.fresh) state.fresh = false;\n else {\n // Bounded substeps prevent tab suspension from creating a rainfall burst.\n const elapsed = Math.min(frame.delta / 1000, 0.05);\n recoverFilm(state, elapsed);\n const steps = Math.max(1, Math.ceil(elapsed * 120)), dt = elapsed / steps;\n const side = Math.min(context.canvas.width, context.canvas.height);\n for (let step = 0; step < steps; step++) {\n state.births += state.config.rainRate * dt;\n while (state.births >= 1) { spawn(state, context); state.births--; }\n for (const drop of state.drops) {\n const slide = Math.max(0, drop.radius / 0.012 - 1);\n const oldX = drop.x, oldY = drop.y;\n drop.vx += Math.sin(drop.y * 85 + drop.phase) * slide * state.config.gravity * state.config.irregularity * 0.09 * dt;\n drop.vy += state.config.gravity * slide * 0.3 * dt;\n drop.vx *= Math.exp(-7 * dt); drop.vy *= Math.exp(-3 * dt);\n if (Math.abs(drop.vx) < 0.00005) drop.vx = 0;\n if (Math.abs(drop.vy) < 0.00005) drop.vy = 0;\n drop.x += drop.vx * dt; drop.y += drop.vy * dt;\n sweep(state, drop, oldX, oldY, context);\n }\n merge(state.drops);\n state.drops = state.drops.filter(d => d.y - d.radius < context.canvas.height / side && d.y + d.radius > 0 && d.x + d.radius > 0 && d.x - d.radius < context.canvas.width / side);\n }\n if (state.finger) wipeFinger(state, state.finger.x, state.finger.y, context);\n context.invalidate();\n }\n schedule(state, context);\n },\n rasterize(state, context) {\n const { width, height } = context.canvas, side = Math.min(width, height);\n const data = state.image.data, surface = state.surface;\n for (let i = 0; i < surface.length; i++) {\n surface[i] = state.trails[i] + state.grain[i] * 0.00018 * state.config.condensation * state.film[i];\n }\n const visibleDrops = state.finger?.drop ? [...state.drops, state.finger.drop] : state.drops;\n for (const drop of visibleDrops) {\n const stretch = 1 + Math.min(1.3, Math.abs(drop.vy) * 3);\n const rx = drop.radius * side / Math.sqrt(stretch), ry = drop.radius * side * stretch;\n const cx = drop.x * side, cy = drop.y * side;\n const extent = 1.3;\n for (let y = Math.max(0, Math.floor(cy - ry * extent)); y < Math.min(height, Math.ceil(cy + ry * extent)); y++) {\n for (let x = Math.max(0, Math.floor(cx - rx * extent)); x < Math.min(width, Math.ceil(cx + rx * extent)); x++) {\n const ny = (y + 0.5 - cy) / ry;\n const nx = (x + 0.5 - cx) / rx - state.config.irregularity * 0.09 * Math.sin(ny * 3 + drop.phase);\n const angle = Math.atan2(ny, nx);\n const edge = 1 + state.config.irregularity * (0.12 * Math.sin(angle * 3 + drop.phase) + 0.07 * Math.sin(angle * 5 - drop.phase));\n const r2 = (nx * nx + ny * ny) / (edge * edge);\n if (r2 >= 1) continue;\n const i = y * width + x;\n surface[i] = Math.max(surface[i], drop.radius * Math.sqrt(1 - r2));\n }\n }\n }\n for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {\n const i = y * width + x, index = i * 4;\n const dx = (surface[y * width + Math.min(width - 1, x + 1)] - surface[y * width + Math.max(0, x - 1)]) * side * 0.5;\n const dy = (surface[Math.min(height - 1, y + 1) * width + x] - surface[Math.max(0, y - 1) * width + x]) * side * 0.5;\n data[index] = Math.round(128 + Math.max(-1, Math.min(1, dx)) * 110);\n data[index + 1] = Math.round(128 + Math.max(-1, Math.min(1, dy)) * 110);\n const droplet = Math.min(1, Math.max(0, (surface[i] - 0.001) * 1500));\n data[index + 2] = Math.round(255 * state.config.condensation * state.film[i] * (0.8 + state.grain[i] * 0.2) * (1 - droplet));\n data[index + 3] = state.config.condensation > 0 ? 255 : Math.round(Math.min(1, surface[i] * side * 2) * 255);\n }\n context.canvas.getContext(\"2d\")!.putImageData(state.image, 0, 0);\n },\n});\n\n/**\n * A seeded rain-on-glass displacement map, advanced by Pibbl's scheduler.\n *\n * @param options - Raindrop simulation and appearance settings. See {@link RainDropsOptions}.\n * @returns A raindrop texture recipe accepting raindrop messages. See {@link TextureRecipe} ,\n * {@link RainDropsMessage} .\n *\n * @see {@link RainDropsOptions}\n * @see {@link TextureRecipe}\n * @see {@link RainDropsMessage}\n */\nexport function rainDrops(options: RainDropsOptions = {}): TextureRecipe<RainDropsMessage> { return recipe(options); }\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { defineTexture, type TextureContext, type TextureRecipe } from \"@pibbl/core\";\nimport { validateSeed } from \"./palette.js\";\n\n/**\n * Rain rate, gravity, initial drops, condensation, trail, and outline controls for a raindrop texture.\n *\n * @see {@link rainDrops}\n */\nexport interface RainDropsOptions {\n /**\n * Seed used for deterministic sampling or simulation initialization. See\n * {@link RainDropsOptions}.\n */\n readonly seed?: number;\n /** New beads per second, from 0 through 120. */\n readonly rainRate?: number;\n /** Downward acceleration multiplier, from 0 through 10. */\n readonly gravity?: number;\n /** Number of drops seeded before continuous rain starts. See {@link RainDropsOptions}. */\n readonly initialDrops?: number;\n /** Whether simulation or playback advancement is suspended. See {@link RainDropsOptions}. */\n readonly paused?: boolean;\n /** Fine droplet film coverage, from 0 (clear) through 1 (mist). */\n readonly condensation?: number;\n /** Seconds controlling trail drying and condensation recovery, from 0 through 60. */\n readonly trailPersistence?: number;\n /** Residual water left behind a moving drop, from 0 through 1. */\n readonly trailStrength?: number;\n /** Outline and path variation, from 0 (smooth) through 1. */\n readonly irregularity?: number;\n}\n\n/**\n * Pause, reset, finger-wipe, release, and localized nudge commands for a raindrop texture.\n *\n * @see {@link rainDrops}\n */\nexport type RainDropsMessage =\n | {\n /** The literal \"pause\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"pause\";\n /** Whether simulation or playback advancement is suspended. See {@link RainDropsMessage}. */\n readonly paused: boolean;\n }\n | {\n /** The literal \"reset\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"reset\";\n }\n /** Begin or move one finger contact; successive positions wipe a continuous path. */\n | {\n /** The literal \"finger\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"finger\";\n /**\n * Horizontal coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly x: number;\n /**\n * Vertical coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly y: number;\n /** Radius in the coordinate system of this geometry or effect. See {@link RainDropsMessage}. */\n readonly radius?: number;\n }\n | {\n /** The literal \"release\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"release\";\n }\n /** Center and movement use normalized width/height; radius uses the shorter side. */\n | {\n /** The literal \"nudge\" identifying this variant. See {@link RainDropsMessage}. */\n readonly type: \"nudge\";\n /**\n * Horizontal coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly x: number;\n /**\n * Vertical coordinate or displacement in the containing coordinate system. See\n * {@link RainDropsMessage}.\n */\n readonly y: number;\n /** Horizontal displacement applied by the interaction. See {@link RainDropsMessage}. */\n readonly dx: number;\n /** Vertical displacement applied by the interaction. See {@link RainDropsMessage}. */\n readonly dy: number;\n /** Radius in the coordinate system of this geometry or effect. See {@link RainDropsMessage}. */\n readonly radius?: number;\n };\n\ninterface Drop { x: number; y: number; radius: number; vx: number; vy: number; phase: number }\ninterface Config { seed: number; rainRate: number; gravity: number; initialDrops: number; paused: boolean; condensation: number; trailPersistence: number; trailStrength: number; irregularity: number }\ninterface State {\n finger?: { x: number; y: number; radius: number; drop?: Drop };\n config: Config;\n drops: Drop[];\n random: number;\n births: number;\n paused: boolean;\n fresh: boolean;\n image: ImageData;\n film: Float32Array;\n trails: Float32Array;\n surface: Float32Array;\n grain: Float32Array;\n fieldActive: boolean;\n}\nconst MAX_DROPS = 256;\n\nfunction bounded(value: number, name: string, maximum: number): number {\n if (!Number.isFinite(value) || value < 0 || value > maximum) throw new RangeError(`Rain ${name} must be finite and within [0, ${maximum}].`);\n return value;\n}\nfunction options(input: RainDropsOptions): Config {\n const initialDrops = bounded(input.initialDrops ?? 100, \"initialDrops\", MAX_DROPS);\n if (!Number.isInteger(initialDrops)) throw new RangeError(\"Rain initialDrops must be an integer.\");\n return { seed: validateSeed(input.seed ?? 7), rainRate: bounded(input.rainRate ?? 24, \"rainRate\", 120), gravity: bounded(input.gravity ?? 1, \"gravity\", 10), initialDrops, paused: input.paused ?? false,\n condensation: bounded(input.condensation ?? 0, \"condensation\", 1),\n trailPersistence: bounded(input.trailPersistence ?? 8, \"trailPersistence\", 60),\n trailStrength: bounded(input.trailStrength ?? 0.65, \"trailStrength\", 1),\n irregularity: bounded(input.irregularity ?? 0.8, \"irregularity\", 1) };\n}\nfunction assertMap(context: TextureContext): void {\n if (context.palette !== undefined) throw new TypeError(\"rainDrops is a numeric displacement map and does not accept a palette.\");\n}\nfunction random(state: State): number {\n state.random = (Math.imul(state.random, 1664525) + 1013904223) >>> 0;\n return state.random / 4294967296;\n}\nfunction spawn(state: State, context: TextureContext): void {\n if (state.drops.length >= MAX_DROPS) return;\n const side = Math.min(context.canvas.width, context.canvas.height);\n state.drops.push({ x: random(state) * context.canvas.width / side, y: random(state) * context.canvas.height / side, radius: 0.005 + random(state) ** 2 * 0.015, vx: 0, vy: 0, phase: random(state) * Math.PI * 2 });\n}\nfunction reset(state: State, context: TextureContext): void {\n state.finger = undefined;\n state.random = state.config.seed; state.drops = []; state.births = 0; state.fresh = true;\n state.film.fill(1); state.trails.fill(0); state.fieldActive = false;\n for (let i = 0; i < state.grain.length; i++) {\n let value = Math.imul(i + 1, 0x45d9f3b) ^ state.config.seed;\n value = Math.imul(value ^ (value >>> 16), 0x45d9f3b);\n state.grain[i] = ((value ^ (value >>> 16)) >>> 0) / 4294967296;\n }\n for (let i = 0; i < state.config.initialDrops; i++) spawn(state, context);\n}\n/** Coalescence conserves volume and volume-weighted position/momentum. */\nfunction merge(drops: Drop[]): void {\n for (let i = 0; i < drops.length; i++) {\n const a = drops[i];\n for (let j = i + 1; j < drops.length; j++) {\n const b = drops[j];\n if (Math.hypot(a.x - b.x, a.y - b.y) >= a.radius + b.radius) continue;\n const av = a.radius ** 3, bv = b.radius ** 3, volume = av + bv;\n a.x = (a.x * av + b.x * bv) / volume; a.y = (a.y * av + b.y * bv) / volume;\n a.vx = (a.vx * av + b.vx * bv) / volume; a.vy = (a.vy * av + b.vy * bv) / volume;\n a.radius = Math.cbrt(volume);\n drops.splice(j--, 1);\n }\n }\n}\nfunction active(state: State): boolean {\n return state.fieldActive || state.config.rainRate > 0 || state.drops.some(d => (state.config.gravity > 0 && d.radius > 0.012) || Math.abs(d.vx) + Math.abs(d.vy) > 0.0001);\n}\nfunction schedule(state: State, context: TextureContext): void {\n if (!state.paused && active(state)) context.requestFrame();\n}\n\n/** Sweep the actual drop footprint, collecting film and leaving a beaded residual trail. */\nfunction sweep(state: State, drop: Drop, oldX: number, oldY: number, context: TextureContext): void {\n const { width, height } = context.canvas, side = Math.min(width, height);\n const ax = oldX * side, ay = oldY * side, bx = drop.x * side, by = drop.y * side;\n const dx = bx - ax, dy = by - ay, length2 = dx * dx + dy * dy;\n if (length2 < 0.000001) return;\n const radius = Math.max(1, drop.radius * side * 1.1);\n let collected = 0;\n for (let y = Math.max(0, Math.floor(Math.min(ay, by) - radius)); y < Math.min(height, Math.ceil(Math.max(ay, by) + radius)); y++) {\n for (let x = Math.max(0, Math.floor(Math.min(ax, bx) - radius)); x < Math.min(width, Math.ceil(Math.max(ax, bx) + radius)); x++) {\n const t = Math.max(0, Math.min(1, ((x + 0.5 - ax) * dx + (y + 0.5 - ay) * dy) / length2));\n const distance = Math.hypot(x + 0.5 - ax - t * dx, y + 0.5 - ay - t * dy) / radius;\n if (distance >= 1) continue;\n const i = y * width + x;\n const remaining = Math.max(0, Math.min(1, (distance - 0.7) / 0.3));\n const removed = Math.max(0, state.film[i] - remaining);\n collected += removed;\n state.film[i] = Math.min(state.film[i], remaining);\n // Spatially stable necks and beads avoid frame-rate-dependent trail stamping.\n const neck = 0.18 + 0.12 * Math.sin(y * 0.7 + drop.phase);\n const bead = Math.pow(state.grain[i], 7);\n const residual = Math.max(0, 1 - distance / (neck + bead * 0.6));\n state.trails[i] = Math.max(state.trails[i], residual * (0.00045 + bead * 0.0018) * state.config.trailStrength);\n }\n }\n // Film volume is swept area times a small effective thickness.\n drop.radius = Math.cbrt(drop.radius ** 3 + collected / (side * side) * state.config.condensation * 0.0002);\n state.fieldActive = true;\n}\n\n/** At capacity, coalesce the closest free beads before releasing newly gathered water. */\nfunction makeReleaseRoom(drops: Drop[]): void {\n if (drops.length < MAX_DROPS) return;\n let first = 0, second = 1, nearest = Infinity;\n for (let i = 0; i < drops.length; i++) for (let j = i + 1; j < drops.length; j++) {\n const distance = Math.hypot(drops[i].x - drops[j].x, drops[i].y - drops[j].y);\n if (distance < nearest) { nearest = distance; first = i; second = j; }\n }\n const a = drops[first], b = drops[second], av = a.radius ** 3, bv = b.radius ** 3, volume = av + bv;\n a.x = (a.x * av + b.x * bv) / volume; a.y = (a.y * av + b.y * bv) / volume;\n a.vx = (a.vx * av + b.vx * bv) / volume; a.vy = (a.vy * av + b.vy * bv) / volume;\n a.radius = Math.cbrt(volume); drops.splice(second, 1);\n}\n\n/** A finger removes film and residual water, and carries intersected beads without inertia. */\nfunction wipeFinger(state: State, oldX: number, oldY: number, context: TextureContext): void {\n const finger = state.finger;\n if (!finger) return;\n const { width, height } = context.canvas, side = Math.min(width, height);\n const dx = finger.x - oldX, dy = finger.y - oldY, length2 = dx * dx + dy * dy;\n const distance = (x: number, y: number): number => {\n const t = length2 === 0 ? 0 : Math.max(0, Math.min(1, ((x - oldX) * dx + (y - oldY) * dy) / length2));\n return Math.hypot(x - oldX - t * dx, y - oldY - t * dy);\n };\n let volume = finger.drop ? finger.drop.radius ** 3 : 0;\n for (let i = state.drops.length - 1; i >= 0; i--) {\n const drop = state.drops[i];\n if (distance(drop.x, drop.y) > finger.radius + drop.radius * 1.3) continue;\n volume += drop.radius ** 3;\n state.drops.splice(i, 1);\n }\n for (let y = Math.max(0, Math.floor((Math.min(oldY, finger.y) - finger.radius) * side)); y < Math.min(height, Math.ceil((Math.max(oldY, finger.y) + finger.radius) * side)); y++) {\n for (let x = Math.max(0, Math.floor((Math.min(oldX, finger.x) - finger.radius) * side)); x < Math.min(width, Math.ceil((Math.max(oldX, finger.x) + finger.radius) * side)); x++) {\n const coverage = Math.max(0, Math.min(1, (1 - distance((x + 0.5) / side, (y + 0.5) / side) / finger.radius) / 0.15));\n if (coverage === 0) continue;\n const i = y * width + x, remaining = 1 - coverage;\n const removedFilm = Math.max(0, state.film[i] - remaining);\n const removedTrail = state.trails[i] * coverage;\n volume += (removedFilm * state.config.condensation * 0.0002 + removedTrail) / (side * side);\n state.film[i] = Math.min(state.film[i], remaining);\n state.trails[i] -= removedTrail;\n }\n }\n if (volume > 0) {\n finger.drop ??= { x: finger.x, y: finger.y, radius: 0, vx: 0, vy: 0, phase: 0 };\n finger.drop.x = finger.x; finger.drop.y = finger.y; finger.drop.radius = Math.cbrt(volume);\n }\n state.fieldActive = true;\n}\n\nfunction recoverFilm(state: State, elapsed: number): void {\n if (!state.fieldActive) return;\n const retention = state.config.trailPersistence === 0 ? 0 : Math.exp(-elapsed / state.config.trailPersistence);\n let active = false;\n for (let i = 0; i < state.film.length; i++) {\n const missing = (1 - state.film[i]) * retention;\n state.film[i] = missing < 0.002 ? 1 : 1 - missing;\n const trail = state.trails[i] * retention;\n state.trails[i] = trail < 0.000005 ? 0 : trail;\n active ||= state.film[i] < 1 || state.trails[i] > 0;\n }\n state.fieldActive = active;\n}\n\nconst recipe = defineTexture<RainDropsOptions, State, RainDropsMessage>({\n create(context, input) {\n assertMap(context);\n const config = options(input);\n const cells = context.canvas.width * context.canvas.height;\n const state: State = { film: new Float32Array(cells), trails: new Float32Array(cells), surface: new Float32Array(cells), grain: new Float32Array(cells), fieldActive: false, config, drops: [], random: config.seed, births: 0, paused: config.paused, fresh: true, image: context.canvas.getContext(\"2d\")!.createImageData(context.canvas.width, context.canvas.height) };\n reset(state, context); schedule(state, context); return state;\n },\n update(state, input, context) {\n assertMap(context);\n const next = options(input), previous = state.config;\n state.config = next;\n if (next.condensation !== previous.condensation || next.irregularity !== previous.irregularity || next.trailStrength !== previous.trailStrength) context.invalidate();\n if (next.paused !== previous.paused) { state.paused = next.paused; state.fresh = true; }\n if (next.rainRate !== previous.rainRate || next.gravity !== previous.gravity) state.fresh = true;\n if (next.seed !== previous.seed || next.initialDrops !== previous.initialDrops) { reset(state, context); context.invalidate(); }\n schedule(state, context);\n },\n receive(state, message, context) {\n if (message.type === \"pause\") { state.paused = message.paused; state.fresh = true; }\n else if (message.type === \"reset\") { reset(state, context); context.invalidate(); }\n else if (message.type === \"finger\") {\n const x = bounded(message.x, \"finger x\", 1), y = bounded(message.y, \"finger y\", 1);\n const radius = bounded(message.radius ?? 0.045, \"finger radius\", 2);\n if (radius === 0) throw new RangeError(\"Rain finger radius must be positive.\");\n const side = Math.min(context.canvas.width, context.canvas.height);\n const nextX = x * context.canvas.width / side, nextY = y * context.canvas.height / side;\n const oldX = state.finger?.x ?? nextX, oldY = state.finger?.y ?? nextY;\n state.finger ??= { x: nextX, y: nextY, radius };\n state.finger.x = nextX; state.finger.y = nextY; state.finger.radius = radius;\n wipeFinger(state, oldX, oldY, context); context.invalidate();\n }\n else if (message.type === \"release\") {\n if (state.finger?.drop) { makeReleaseRoom(state.drops); state.drops.push(state.finger.drop); }\n state.finger = undefined; context.invalidate();\n }\n else if (message.type === \"nudge\") {\n const x = bounded(message.x, \"nudge x\", 1), y = bounded(message.y, \"nudge y\", 1);\n const radius = bounded(message.radius ?? 0.12, \"nudge radius\", 2);\n if (radius === 0) throw new RangeError(\"Rain nudge radius must be positive.\");\n if (\n !Number.isFinite(message.dx) ||\n Math.abs(message.dx) > 1 ||\n !Number.isFinite(message.dy) ||\n Math.abs(message.dy) > 1\n )\n throw new RangeError(\"Rain nudge movement must be finite and within [-1, 1].\");\n if (message.dx === 0 && message.dy === 0) return;\n const side = Math.min(context.canvas.width, context.canvas.height);\n const width = context.canvas.width / side, height = context.canvas.height / side;\n for (const drop of state.drops) {\n const distance = Math.hypot(drop.x - x * width, drop.y - y * height);\n const weight = Math.max(0, 1 - distance / radius) ** 2;\n const oldX = drop.x, oldY = drop.y;\n drop.x = Math.max(0, Math.min(width, drop.x + message.dx * width * weight));\n drop.y = Math.max(0, Math.min(height, drop.y + message.dy * height * weight));\n sweep(state, drop, oldX, oldY, context);\n drop.vx += message.dx * width * weight * 3; drop.vy += message.dy * height * weight * 3;\n }\n merge(state.drops); context.invalidate();\n } else throw new TypeError(\"Unknown rain drop message.\");\n schedule(state, context);\n },\n advance(state, frame, context) {\n if (state.paused) return;\n if (state.fresh) state.fresh = false;\n else {\n // Bounded substeps prevent tab suspension from creating a rainfall burst.\n const elapsed = Math.min(frame.delta / 1000, 0.05);\n recoverFilm(state, elapsed);\n const steps = Math.max(1, Math.ceil(elapsed * 120)), dt = elapsed / steps;\n const side = Math.min(context.canvas.width, context.canvas.height);\n for (let step = 0; step < steps; step++) {\n state.births += state.config.rainRate * dt;\n while (state.births >= 1) { spawn(state, context); state.births--; }\n for (const drop of state.drops) {\n const slide = Math.max(0, drop.radius / 0.012 - 1);\n const oldX = drop.x, oldY = drop.y;\n drop.vx += Math.sin(drop.y * 85 + drop.phase) * slide * state.config.gravity * state.config.irregularity * 0.09 * dt;\n drop.vy += state.config.gravity * slide * 0.3 * dt;\n drop.vx *= Math.exp(-7 * dt); drop.vy *= Math.exp(-3 * dt);\n if (Math.abs(drop.vx) < 0.00005) drop.vx = 0;\n if (Math.abs(drop.vy) < 0.00005) drop.vy = 0;\n drop.x += drop.vx * dt; drop.y += drop.vy * dt;\n sweep(state, drop, oldX, oldY, context);\n }\n merge(state.drops);\n state.drops = state.drops.filter(d => d.y - d.radius < context.canvas.height / side && d.y + d.radius > 0 && d.x + d.radius > 0 && d.x - d.radius < context.canvas.width / side);\n }\n if (state.finger) wipeFinger(state, state.finger.x, state.finger.y, context);\n context.invalidate();\n }\n schedule(state, context);\n },\n rasterize(state, context) {\n const { width, height } = context.canvas, side = Math.min(width, height);\n const data = state.image.data, surface = state.surface;\n for (let i = 0; i < surface.length; i++) {\n surface[i] = state.trails[i] + state.grain[i] * 0.00018 * state.config.condensation * state.film[i];\n }\n const visibleDrops = state.finger?.drop ? [...state.drops, state.finger.drop] : state.drops;\n for (const drop of visibleDrops) {\n const stretch = 1 + Math.min(1.3, Math.abs(drop.vy) * 3);\n const rx = drop.radius * side / Math.sqrt(stretch), ry = drop.radius * side * stretch;\n const cx = drop.x * side, cy = drop.y * side;\n const extent = 1.3;\n for (let y = Math.max(0, Math.floor(cy - ry * extent)); y < Math.min(height, Math.ceil(cy + ry * extent)); y++) {\n for (let x = Math.max(0, Math.floor(cx - rx * extent)); x < Math.min(width, Math.ceil(cx + rx * extent)); x++) {\n const ny = (y + 0.5 - cy) / ry;\n const nx = (x + 0.5 - cx) / rx - state.config.irregularity * 0.09 * Math.sin(ny * 3 + drop.phase);\n const angle = Math.atan2(ny, nx);\n const edge = 1 + state.config.irregularity * (0.12 * Math.sin(angle * 3 + drop.phase) + 0.07 * Math.sin(angle * 5 - drop.phase));\n const r2 = (nx * nx + ny * ny) / (edge * edge);\n if (r2 >= 1) continue;\n const i = y * width + x;\n surface[i] = Math.max(surface[i], drop.radius * Math.sqrt(1 - r2));\n }\n }\n }\n for (let y = 0; y < height; y++) for (let x = 0; x < width; x++) {\n const i = y * width + x, index = i * 4;\n const dx = (surface[y * width + Math.min(width - 1, x + 1)] - surface[y * width + Math.max(0, x - 1)]) * side * 0.5;\n const dy = (surface[Math.min(height - 1, y + 1) * width + x] - surface[Math.max(0, y - 1) * width + x]) * side * 0.5;\n data[index] = Math.round(128 + Math.max(-1, Math.min(1, dx)) * 110);\n data[index + 1] = Math.round(128 + Math.max(-1, Math.min(1, dy)) * 110);\n const droplet = Math.min(1, Math.max(0, (surface[i] - 0.001) * 1500));\n data[index + 2] = Math.round(255 * state.config.condensation * state.film[i] * (0.8 + state.grain[i] * 0.2) * (1 - droplet));\n data[index + 3] = state.config.condensation > 0 ? 255 : Math.round(Math.min(1, surface[i] * side * 2) * 255);\n }\n context.canvas.getContext(\"2d\")!.putImageData(state.image, 0, 0);\n },\n});\n\n/**\n * A seeded rain-on-glass displacement map, advanced by Pibbl's scheduler.\n *\n * @param options - Raindrop simulation and appearance settings. See {@link RainDropsOptions}.\n * @returns A raindrop texture recipe accepting raindrop messages. See {@link TextureRecipe} ,\n * {@link RainDropsMessage} .\n *\n * @see {@link RainDropsOptions}\n * @see {@link TextureRecipe}\n * @see {@link RainDropsMessage}\n */\nexport function rainDrops(options: RainDropsOptions = {}): TextureRecipe<RainDropsMessage> { return recipe(options); }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["active", "options"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactionDiffusionOptions, type ReactionDiffusionPreset } from "./gray-scott.js";
|
|
1
2
|
import { type TextureRenderer } from "./presentation.js";
|
|
2
3
|
import { type TexturePalette, type TextureResolution } from "./palette.js";
|
|
3
4
|
/**
|
|
@@ -20,7 +21,7 @@ export interface TextureBrush {
|
|
|
20
21
|
* @see {@link TextureBrush}
|
|
21
22
|
* @see {@link ReactionDiffusion}
|
|
22
23
|
*/
|
|
23
|
-
export interface ReactionDiffusionProps {
|
|
24
|
+
export interface ReactionDiffusionProps extends ReactionDiffusionOptions {
|
|
24
25
|
/**
|
|
25
26
|
* Renders the current data or resources using the supplied context. See {@link TextureRenderer}
|
|
26
27
|
* .
|
|
@@ -37,7 +38,7 @@ export interface ReactionDiffusionProps {
|
|
|
37
38
|
* Named pattern configuration used to initialize the simulation. See
|
|
38
39
|
* {@link ReactionDiffusionProps}.
|
|
39
40
|
*/
|
|
40
|
-
readonly preset?:
|
|
41
|
+
readonly preset?: ReactionDiffusionPreset;
|
|
41
42
|
/** Ordered colors used to present texture intensity. See {@link TexturePalette}. */
|
|
42
43
|
readonly palette?: TexturePalette;
|
|
43
44
|
/**
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
grayScottConfig
|
|
3
|
+
} from "./gray-scott.js";
|
|
1
4
|
import { defineRenderLayer } from "@pibbl/core";
|
|
2
5
|
import { TextureRaster } from "./presentation.js";
|
|
3
6
|
import { InkSimulation } from "./simulation.js";
|
|
4
7
|
import {
|
|
5
8
|
paletteLut,
|
|
6
9
|
texturePalettes,
|
|
7
|
-
validateResolution
|
|
8
|
-
validateSeed
|
|
10
|
+
validateResolution
|
|
9
11
|
} from "./palette.js";
|
|
10
12
|
function options(props) {
|
|
11
|
-
const
|
|
12
|
-
if (preset !== "spots" && preset !== "stripes")
|
|
13
|
-
throw new TypeError("Unknown reaction-diffusion preset.");
|
|
13
|
+
const chemistry = grayScottConfig(props);
|
|
14
14
|
const brush = props.brush ?? { radius: 6, strength: 0.8 };
|
|
15
15
|
if (brush && (!Number.isFinite(brush.radius) || brush.radius <= 0 || brush.radius > 128 || !Number.isFinite(brush.strength) || brush.strength < 0 || brush.strength > 1))
|
|
16
16
|
throw new RangeError(
|
|
@@ -20,8 +20,7 @@ function options(props) {
|
|
|
20
20
|
throw new RangeError("resetRevision must be a safe integer.");
|
|
21
21
|
return {
|
|
22
22
|
resolution: validateResolution(props.resolution),
|
|
23
|
-
|
|
24
|
-
preset,
|
|
23
|
+
...chemistry,
|
|
25
24
|
palette: [...props.palette ?? texturePalettes.lagoon],
|
|
26
25
|
paused: props.paused ?? false,
|
|
27
26
|
resetRevision: props.resetRevision ?? 0,
|
|
@@ -30,12 +29,7 @@ function options(props) {
|
|
|
30
29
|
}
|
|
31
30
|
function reset(r, config) {
|
|
32
31
|
const { width, height } = config.resolution;
|
|
33
|
-
const simulation = new InkSimulation(
|
|
34
|
-
width,
|
|
35
|
-
height,
|
|
36
|
-
config.seed,
|
|
37
|
-
config.preset
|
|
38
|
-
);
|
|
32
|
+
const simulation = new InkSimulation({ width, height, ...config });
|
|
39
33
|
let raster;
|
|
40
34
|
try {
|
|
41
35
|
raster = new TextureRaster(width, height);
|
|
@@ -109,12 +103,7 @@ const ReactionDiffusion = /* @__PURE__ */ defineRenderLayer({
|
|
|
109
103
|
raster,
|
|
110
104
|
output,
|
|
111
105
|
render: props.render,
|
|
112
|
-
simulation: new InkSimulation(
|
|
113
|
-
width,
|
|
114
|
-
height,
|
|
115
|
-
config.seed,
|
|
116
|
-
config.preset
|
|
117
|
-
),
|
|
106
|
+
simulation: new InkSimulation({ width, height, ...config }),
|
|
118
107
|
elapsed: 0,
|
|
119
108
|
fresh: true,
|
|
120
109
|
dirty: true,
|
|
@@ -134,7 +123,7 @@ const ReactionDiffusion = /* @__PURE__ */ defineRenderLayer({
|
|
|
134
123
|
r.lut = paletteLut(next.palette);
|
|
135
124
|
r.dirty = true;
|
|
136
125
|
}
|
|
137
|
-
if (next.seed !== old.seed || next.preset !== old.preset || next.resetRevision !== old.resetRevision || next.resolution.width !== old.resolution.width || next.resolution.height !== old.resolution.height)
|
|
126
|
+
if (next.seed !== old.seed || next.preset !== old.preset || next.feed !== old.feed || next.kill !== old.kill || next.warmupSteps !== old.warmupSteps || next.resetRevision !== old.resetRevision || next.resolution.width !== old.resolution.width || next.resolution.height !== old.resolution.height)
|
|
138
127
|
reset(r, next);
|
|
139
128
|
if (next.paused !== old.paused) {
|
|
140
129
|
r.elapsed = 0;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/features/textures/lib/reaction-diffusion.ts"],
|
|
4
|
-
"sourcesContent": ["import { defineRenderLayer, type PibblRenderLayerInput } from \"@pibbl/core\";\nimport { TextureRaster, type TextureRenderer } from \"./presentation.js\";\nimport { InkSimulation } from \"./simulation.js\";\nimport {\n paletteLut,\n texturePalettes,\n validateResolution,\n validateSeed,\n type TexturePalette,\n type TextureResolution,\n} from \"./palette.js\";\n\n/**\n * Radius and strength of a reaction-diffusion brush stroke.\n *\n * @see {@link ReactionDiffusionProps}\n */\nexport interface TextureBrush {\n /** Radius in the coordinate system of this geometry or effect. See {@link TextureBrush}. */\n readonly radius: number;\n /** Magnitude of the displacement or brush effect. See {@link TextureBrush}. */\n readonly strength: number;\n}\n/**\n * Authored inputs for ReactionDiffusion, including the declared data and presentation options.\n *\n * @see {@link TextureRenderer}\n * @see {@link TextureResolution}\n * @see {@link TexturePalette}\n * @see {@link TextureBrush}\n * @see {@link ReactionDiffusion}\n */\nexport interface ReactionDiffusionProps {\n /**\n * Renders the current data or resources using the supplied context. See {@link TextureRenderer}\n * .\n */\n readonly render?: TextureRenderer;\n /** Dimensions of the simulation or raster grid. See {@link TextureResolution}. */\n readonly resolution?: TextureResolution;\n /**\n * Seed used for deterministic sampling or simulation initialization. See\n * {@link ReactionDiffusionProps}.\n */\n readonly seed?: number;\n /**\n * Named pattern configuration used to initialize the simulation. See\n * {@link ReactionDiffusionProps}.\n */\n readonly preset?: \"spots\" | \"stripes\";\n /** Ordered colors used to present texture intensity. See {@link TexturePalette}. */\n readonly palette?: TexturePalette;\n /**\n * Whether simulation or playback advancement is suspended. See {@link ReactionDiffusionProps}.\n */\n readonly paused?: boolean;\n /**\n * Changing this revision requests a fresh simulation initialization. See\n * {@link ReactionDiffusionProps}.\n */\n readonly resetRevision?: number;\n /**\n * Brush configuration for interactive reaction-diffusion input, or false to disable it. See\n * {@link TextureBrush}.\n */\n readonly brush?: TextureBrush | false;\n}\ninterface Options {\n resolution: TextureResolution;\n seed: number;\n preset: \"spots\" | \"stripes\";\n palette: TexturePalette;\n paused: boolean;\n resetRevision: number;\n brush: TextureBrush | false;\n}\nfunction options(props: ReactionDiffusionProps): Options {\n const preset = props.preset ?? \"spots\";\n if (preset !== \"spots\" && preset !== \"stripes\")\n throw new TypeError(\"Unknown reaction-diffusion preset.\");\n const brush = props.brush ?? { radius: 6, strength: 0.8 };\n if (\n brush &&\n (!Number.isFinite(brush.radius) ||\n brush.radius <= 0 ||\n brush.radius > 128 ||\n !Number.isFinite(brush.strength) ||\n brush.strength < 0 ||\n brush.strength > 1)\n )\n throw new RangeError(\n \"Brush radius must be in (0,128] and strength in [0,1].\",\n );\n if (!Number.isSafeInteger(props.resetRevision ?? 0))\n throw new RangeError(\"resetRevision must be a safe integer.\");\n return {\n resolution: validateResolution(props.resolution),\n seed: validateSeed(props.seed),\n preset,\n palette: [...(props.palette ?? texturePalettes.lagoon)],\n paused: props.paused ?? false,\n resetRevision: props.resetRevision ?? 0,\n brush: brush && { ...brush },\n };\n}\ninterface Stroke {\n x: number;\n y: number;\n radius: number;\n strength: number;\n}\ninterface Resources {\n render?: TextureRenderer;\n config: Options;\n simulation: InkSimulation;\n raster: TextureRaster;\n output: OffscreenCanvasRenderingContext2D;\n lut: Uint8ClampedArray;\n elapsed: number;\n fresh: boolean;\n dirty: boolean;\n disposed: boolean;\n target: object;\n strokes: Stroke[];\n pointer?: { id: number; x: number; y: number; release: () => void };\n invalidate: () => void;\n}\nfunction reset(r: Resources, config: Options) {\n const { width, height } = config.resolution;\n const simulation = new InkSimulation(\n width,\n height,\n config.seed,\n config.preset,\n );\n let raster: TextureRaster;\n try {\n raster = new TextureRaster(width, height);\n } catch (error) {\n simulation.dispose();\n throw error;\n }\n r.simulation.dispose();\n r.simulation = simulation;\n r.raster.dispose();\n r.raster = raster;\n r.strokes.length = 0;\n r.pointer?.release();\n r.pointer = undefined;\n r.elapsed = 0;\n r.fresh = true;\n r.dirty = true;\n}\nfunction input(\n r: Resources,\n event: Readonly<PibblRenderLayerInput<object>>,\n width: number,\n height: number,\n) {\n if (r.disposed) return;\n const original = event.originalEvent as PointerEvent;\n if (event.type === \"pointerup\" || event.type === \"pointercancel\") {\n if (r.pointer?.id === original.pointerId) {\n r.pointer.release();\n r.pointer = undefined;\n }\n return;\n }\n const brush = r.config.brush;\n if (!brush || width <= 0 || height <= 0) return;\n const x = (event.point.x / width) * r.simulation.width;\n const y = (event.point.y / height) * r.simulation.height;\n if (event.type === \"pointerdown\") {\n if (r.pointer || original.button !== 0 || original.isPrimary === false)\n return;\n event.setPointerCapture(original.pointerId);\n r.pointer = {\n id: original.pointerId,\n x,\n y,\n release: () => event.releasePointerCapture(original.pointerId),\n };\n } else if (\n event.type !== \"pointermove\" ||\n r.pointer?.id !== original.pointerId\n )\n return;\n const previous = r.pointer!;\n const distance = Math.hypot(x - previous.x, y - previous.y);\n // Bound work for off-surface capture. Stamps outside the field are ignored, never clamped to its edge.\n const count = Math.min(\n 4096,\n Math.max(1, Math.ceil(distance / Math.max(0.5, brush.radius * 0.3))),\n );\n for (let i = 1; i <= count; i++) {\n const px = previous.x + ((x - previous.x) * i) / count,\n py = previous.y + ((y - previous.y) * i) / count;\n if (\n px >= 0 &&\n py >= 0 &&\n px < r.simulation.width &&\n py < r.simulation.height &&\n r.strokes.length < 8192\n )\n r.strokes.push({ x: px, y: py, ...brush });\n }\n previous.x = x;\n previous.y = y;\n r.invalidate();\n}\n\n/**\n * An independently sized, persistent Gray\u2013Scott surface, advanced by Pibbl's scheduler.\n *\n * @param props - Authored component inputs, supplied through JSX or createElement. See the linked\n * props and style types.\n * @throws When called directly; Pibbl mounts this component through JSX or createElement.\n *\n * @see {@link ReactionDiffusionProps}\n */\nexport const ReactionDiffusion = /* @__PURE__ */ defineRenderLayer<\n ReactionDiffusionProps,\n Resources\n>({\n create(context, props) {\n const config = options(props),\n lut = paletteLut(config.palette);\n const output = context.canvas.getContext(\"2d\");\n if (!output) throw new Error(\"ReactionDiffusion requires Canvas 2D.\");\n const { width, height } = config.resolution;\n const raster = new TextureRaster(width, height);\n try {\n return {\n config,\n lut,\n raster,\n output,\n render: props.render,\n simulation: new InkSimulation(\n width,\n height,\n config.seed,\n config.preset,\n ),\n elapsed: 0,\n fresh: true,\n dirty: true,\n disposed: false,\n target: {},\n strokes: [],\n invalidate: context.invalidate,\n };\n } catch (error) {\n raster.dispose();\n throw error;\n }\n },\n update(r, props) {\n const next = options(props),\n old = r.config;\n if (next.palette.join() !== old.palette.join()) {\n r.lut = paletteLut(next.palette);\n r.dirty = true;\n }\n if (\n next.seed !== old.seed ||\n next.preset !== old.preset ||\n next.resetRevision !== old.resetRevision ||\n next.resolution.width !== old.resolution.width ||\n next.resolution.height !== old.resolution.height\n )\n reset(r, next);\n if (next.paused !== old.paused) {\n r.elapsed = 0;\n r.fresh = true;\n }\n if (!next.brush) {\n r.pointer?.release();\n r.pointer = undefined;\n }\n r.config = next;\n r.render = props.render;\n },\n render(r, frame, context) {\n // The frame invalidator does not gate the committed input snapshot between brush samples.\n r.invalidate = frame.invalidate;\n for (const stroke of r.strokes)\n r.simulation.paint(stroke.x, stroke.y, stroke.radius, stroke.strength);\n if (r.strokes.length) r.dirty = true;\n r.strokes.length = 0;\n if (!r.config.paused && !r.fresh) {\n r.elapsed += Math.max(0, Math.min(50, frame.delta));\n const steps = Math.min(24, Math.floor(r.elapsed * 0.48 + 1e-9));\n r.elapsed -= steps / 0.48;\n if (steps) {\n r.simulation.advance(steps);\n r.dirty = true;\n }\n }\n r.fresh = false;\n if (r.dirty) {\n r.raster.update(r.simulation.b, r.lut, 650 / 255);\n r.dirty = false;\n }\n r.raster.draw(\n r.output,\n context.size.width,\n context.size.height,\n context.size.backingWidth,\n context.size.backingHeight,\n r.render,\n );\n if (!r.config.paused) frame.invalidate();\n },\n interaction: {\n settle(r, _props, size) {\n return {\n targets: [\n {\n target: r.target,\n cursor: r.config.brush ? \"crosshair\" : \"default\",\n },\n ],\n hitTest: () => ({ kind: \"target\", target: r.target }),\n onInput: (event) => input(r, event, size.width, size.height),\n };\n },\n },\n dispose(r) {\n if (r.disposed) return;\n r.disposed = true;\n r.pointer?.release();\n r.pointer = undefined;\n r.strokes.length = 0;\n r.invalidate = () => {};\n r.simulation.dispose();\n r.raster.dispose();\n r.render = undefined;\n },\n});\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,yBAAqD;AAC9D,SAAS,qBAA2C;AACpD,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n grayScottConfig,\n type ReactionDiffusionOptions,\n type ReactionDiffusionPreset,\n} from \"./gray-scott.js\";\nimport { defineRenderLayer, type PibblRenderLayerInput } from \"@pibbl/core\";\nimport { TextureRaster, type TextureRenderer } from \"./presentation.js\";\nimport { InkSimulation } from \"./simulation.js\";\nimport {\n paletteLut,\n texturePalettes,\n validateResolution,\n type TexturePalette,\n type TextureResolution,\n} from \"./palette.js\";\n\n/**\n * Radius and strength of a reaction-diffusion brush stroke.\n *\n * @see {@link ReactionDiffusionProps}\n */\nexport interface TextureBrush {\n /** Radius in the coordinate system of this geometry or effect. See {@link TextureBrush}. */\n readonly radius: number;\n /** Magnitude of the displacement or brush effect. See {@link TextureBrush}. */\n readonly strength: number;\n}\n/**\n * Authored inputs for ReactionDiffusion, including the declared data and presentation options.\n *\n * @see {@link TextureRenderer}\n * @see {@link TextureResolution}\n * @see {@link TexturePalette}\n * @see {@link TextureBrush}\n * @see {@link ReactionDiffusion}\n */\nexport interface ReactionDiffusionProps extends ReactionDiffusionOptions {\n /**\n * Renders the current data or resources using the supplied context. See {@link TextureRenderer}\n * .\n */\n readonly render?: TextureRenderer;\n /** Dimensions of the simulation or raster grid. See {@link TextureResolution}. */\n readonly resolution?: TextureResolution;\n /**\n * Seed used for deterministic sampling or simulation initialization. See\n * {@link ReactionDiffusionProps}.\n */\n readonly seed?: number;\n /**\n * Named pattern configuration used to initialize the simulation. See\n * {@link ReactionDiffusionProps}.\n */\n readonly preset?: ReactionDiffusionPreset;\n /** Ordered colors used to present texture intensity. See {@link TexturePalette}. */\n readonly palette?: TexturePalette;\n /**\n * Whether simulation or playback advancement is suspended. See {@link ReactionDiffusionProps}.\n */\n readonly paused?: boolean;\n /**\n * Changing this revision requests a fresh simulation initialization. See\n * {@link ReactionDiffusionProps}.\n */\n readonly resetRevision?: number;\n /**\n * Brush configuration for interactive reaction-diffusion input, or false to disable it. See\n * {@link TextureBrush}.\n */\n readonly brush?: TextureBrush | false;\n}\ninterface Options {\n resolution: TextureResolution;\n seed: number;\n preset: ReactionDiffusionPreset;\n feed: number;\n kill: number;\n warmupSteps: number;\n palette: TexturePalette;\n paused: boolean;\n resetRevision: number;\n brush: TextureBrush | false;\n}\nfunction options(props: ReactionDiffusionProps): Options {\n const chemistry = grayScottConfig(props);\n const brush = props.brush ?? { radius: 6, strength: 0.8 };\n if (\n brush &&\n (!Number.isFinite(brush.radius) ||\n brush.radius <= 0 ||\n brush.radius > 128 ||\n !Number.isFinite(brush.strength) ||\n brush.strength < 0 ||\n brush.strength > 1)\n )\n throw new RangeError(\n \"Brush radius must be in (0,128] and strength in [0,1].\",\n );\n if (!Number.isSafeInteger(props.resetRevision ?? 0))\n throw new RangeError(\"resetRevision must be a safe integer.\");\n return {\n resolution: validateResolution(props.resolution),\n ...chemistry,\n palette: [...(props.palette ?? texturePalettes.lagoon)],\n paused: props.paused ?? false,\n resetRevision: props.resetRevision ?? 0,\n brush: brush && { ...brush },\n };\n}\ninterface Stroke {\n x: number;\n y: number;\n radius: number;\n strength: number;\n}\ninterface Resources {\n render?: TextureRenderer;\n config: Options;\n simulation: InkSimulation;\n raster: TextureRaster;\n output: OffscreenCanvasRenderingContext2D;\n lut: Uint8ClampedArray;\n elapsed: number;\n fresh: boolean;\n dirty: boolean;\n disposed: boolean;\n target: object;\n strokes: Stroke[];\n pointer?: { id: number; x: number; y: number; release: () => void };\n invalidate: () => void;\n}\nfunction reset(r: Resources, config: Options) {\n const { width, height } = config.resolution;\n const simulation = new InkSimulation({ width, height, ...config });\n let raster: TextureRaster;\n try {\n raster = new TextureRaster(width, height);\n } catch (error) {\n simulation.dispose();\n throw error;\n }\n r.simulation.dispose();\n r.simulation = simulation;\n r.raster.dispose();\n r.raster = raster;\n r.strokes.length = 0;\n r.pointer?.release();\n r.pointer = undefined;\n r.elapsed = 0;\n r.fresh = true;\n r.dirty = true;\n}\nfunction input(\n r: Resources,\n event: Readonly<PibblRenderLayerInput<object>>,\n width: number,\n height: number,\n) {\n if (r.disposed) return;\n const original = event.originalEvent as PointerEvent;\n if (event.type === \"pointerup\" || event.type === \"pointercancel\") {\n if (r.pointer?.id === original.pointerId) {\n r.pointer.release();\n r.pointer = undefined;\n }\n return;\n }\n const brush = r.config.brush;\n if (!brush || width <= 0 || height <= 0) return;\n const x = (event.point.x / width) * r.simulation.width;\n const y = (event.point.y / height) * r.simulation.height;\n if (event.type === \"pointerdown\") {\n if (r.pointer || original.button !== 0 || original.isPrimary === false)\n return;\n event.setPointerCapture(original.pointerId);\n r.pointer = {\n id: original.pointerId,\n x,\n y,\n release: () => event.releasePointerCapture(original.pointerId),\n };\n } else if (\n event.type !== \"pointermove\" ||\n r.pointer?.id !== original.pointerId\n )\n return;\n const previous = r.pointer!;\n const distance = Math.hypot(x - previous.x, y - previous.y);\n // Bound work for off-surface capture. Stamps outside the field are ignored, never clamped to its edge.\n const count = Math.min(\n 4096,\n Math.max(1, Math.ceil(distance / Math.max(0.5, brush.radius * 0.3))),\n );\n for (let i = 1; i <= count; i++) {\n const px = previous.x + ((x - previous.x) * i) / count,\n py = previous.y + ((y - previous.y) * i) / count;\n if (\n px >= 0 &&\n py >= 0 &&\n px < r.simulation.width &&\n py < r.simulation.height &&\n r.strokes.length < 8192\n )\n r.strokes.push({ x: px, y: py, ...brush });\n }\n previous.x = x;\n previous.y = y;\n r.invalidate();\n}\n\n/**\n * An independently sized, persistent Gray\u2013Scott surface, advanced by Pibbl's scheduler.\n *\n * @param props - Authored component inputs, supplied through JSX or createElement. See the linked\n * props and style types.\n * @throws When called directly; Pibbl mounts this component through JSX or createElement.\n *\n * @see {@link ReactionDiffusionProps}\n */\nexport const ReactionDiffusion = /* @__PURE__ */ defineRenderLayer<\n ReactionDiffusionProps,\n Resources\n>({\n create(context, props) {\n const config = options(props),\n lut = paletteLut(config.palette);\n const output = context.canvas.getContext(\"2d\");\n if (!output) throw new Error(\"ReactionDiffusion requires Canvas 2D.\");\n const { width, height } = config.resolution;\n const raster = new TextureRaster(width, height);\n try {\n return {\n config,\n lut,\n raster,\n output,\n render: props.render,\n simulation: new InkSimulation({ width, height, ...config }),\n elapsed: 0,\n fresh: true,\n dirty: true,\n disposed: false,\n target: {},\n strokes: [],\n invalidate: context.invalidate,\n };\n } catch (error) {\n raster.dispose();\n throw error;\n }\n },\n update(r, props) {\n const next = options(props),\n old = r.config;\n if (next.palette.join() !== old.palette.join()) {\n r.lut = paletteLut(next.palette);\n r.dirty = true;\n }\n if (\n next.seed !== old.seed ||\n next.preset !== old.preset ||\n next.feed !== old.feed ||\n next.kill !== old.kill ||\n next.warmupSteps !== old.warmupSteps ||\n next.resetRevision !== old.resetRevision ||\n next.resolution.width !== old.resolution.width ||\n next.resolution.height !== old.resolution.height\n )\n reset(r, next);\n if (next.paused !== old.paused) {\n r.elapsed = 0;\n r.fresh = true;\n }\n if (!next.brush) {\n r.pointer?.release();\n r.pointer = undefined;\n }\n r.config = next;\n r.render = props.render;\n },\n render(r, frame, context) {\n // The frame invalidator does not gate the committed input snapshot between brush samples.\n r.invalidate = frame.invalidate;\n for (const stroke of r.strokes)\n r.simulation.paint(stroke.x, stroke.y, stroke.radius, stroke.strength);\n if (r.strokes.length) r.dirty = true;\n r.strokes.length = 0;\n if (!r.config.paused && !r.fresh) {\n r.elapsed += Math.max(0, Math.min(50, frame.delta));\n const steps = Math.min(24, Math.floor(r.elapsed * 0.48 + 1e-9));\n r.elapsed -= steps / 0.48;\n if (steps) {\n r.simulation.advance(steps);\n r.dirty = true;\n }\n }\n r.fresh = false;\n if (r.dirty) {\n r.raster.update(r.simulation.b, r.lut, 650 / 255);\n r.dirty = false;\n }\n r.raster.draw(\n r.output,\n context.size.width,\n context.size.height,\n context.size.backingWidth,\n context.size.backingHeight,\n r.render,\n );\n if (!r.config.paused) frame.invalidate();\n },\n interaction: {\n settle(r, _props, size) {\n return {\n targets: [\n {\n target: r.target,\n cursor: r.config.brush ? \"crosshair\" : \"default\",\n },\n ],\n hitTest: () => ({ kind: \"target\", target: r.target }),\n onInput: (event) => input(r, event, size.width, size.height),\n };\n },\n },\n dispose(r) {\n if (r.disposed) return;\n r.disposed = true;\n r.pointer?.release();\n r.pointer = undefined;\n r.strokes.length = 0;\n r.invalidate = () => {};\n r.simulation.dispose();\n r.raster.dispose();\n r.render = undefined;\n },\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import { grayScottConfig, type ReactionDiffusionOptions } from "./gray-scott.js";
|
|
1
2
|
/** Private WASM Gray–Scott state. Pibbl owns the clock and resource lifetime. */
|
|
2
3
|
export declare class InkSimulation {
|
|
3
|
-
readonly width: number;
|
|
4
|
-
readonly height: number;
|
|
5
|
-
readonly preset: "spots" | "stripes";
|
|
6
4
|
a: Float32Array;
|
|
7
5
|
b: Float32Array;
|
|
8
6
|
private owner?;
|
|
9
7
|
private parity;
|
|
10
8
|
steps: number;
|
|
11
|
-
|
|
9
|
+
readonly width: number;
|
|
10
|
+
readonly height: number;
|
|
11
|
+
readonly preset: ReturnType<typeof grayScottConfig>["preset"];
|
|
12
|
+
private readonly feed;
|
|
13
|
+
private readonly kill;
|
|
14
|
+
constructor(options: ReactionDiffusionOptions & {
|
|
15
|
+
width: number;
|
|
16
|
+
height: number;
|
|
17
|
+
});
|
|
12
18
|
paint(x: number, y: number, radius: number, strength: number): void;
|
|
13
19
|
stir(x: number, y: number, dx: number, dy: number, radius: number): void;
|
|
14
20
|
advance(count: number): void;
|
|
@@ -1,11 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
grayScottConfig
|
|
3
|
+
} from "./gray-scott.js";
|
|
1
4
|
import { FieldMemory, lazyKernel } from "./wasm/memory.js";
|
|
2
5
|
import { bytes } from "./wasm/ink-bytes.js";
|
|
3
6
|
const module = /* @__PURE__ */ lazyKernel(bytes);
|
|
4
7
|
class InkSimulation {
|
|
5
|
-
|
|
8
|
+
a;
|
|
9
|
+
b;
|
|
10
|
+
owner;
|
|
11
|
+
parity = 0;
|
|
12
|
+
steps = 0;
|
|
13
|
+
width;
|
|
14
|
+
height;
|
|
15
|
+
preset;
|
|
16
|
+
feed;
|
|
17
|
+
kill;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
const { width, height } = options;
|
|
20
|
+
const config = grayScottConfig(options);
|
|
6
21
|
this.width = width;
|
|
7
22
|
this.height = height;
|
|
8
|
-
this.preset = preset;
|
|
23
|
+
this.preset = config.preset;
|
|
24
|
+
this.feed = config.feed;
|
|
25
|
+
this.kill = config.kill;
|
|
9
26
|
const owner = this.owner = new FieldMemory(module(), width, height, 4);
|
|
10
27
|
[this.a, this.b] = owner.fields;
|
|
11
28
|
owner.kernel.initialize(
|
|
@@ -13,17 +30,10 @@ class InkSimulation {
|
|
|
13
30
|
this.b.byteOffset,
|
|
14
31
|
width,
|
|
15
32
|
height,
|
|
16
|
-
seed
|
|
33
|
+
config.seed
|
|
17
34
|
);
|
|
35
|
+
if (config.warmupSteps) this.advance(config.warmupSteps);
|
|
18
36
|
}
|
|
19
|
-
width;
|
|
20
|
-
height;
|
|
21
|
-
preset;
|
|
22
|
-
a;
|
|
23
|
-
b;
|
|
24
|
-
owner;
|
|
25
|
-
parity = 0;
|
|
26
|
-
steps = 0;
|
|
27
37
|
paint(x, y, radius, strength) {
|
|
28
38
|
const owner = this.owner;
|
|
29
39
|
owner.stamps[0] = x;
|
|
@@ -65,8 +75,8 @@ class InkSimulation {
|
|
|
65
75
|
this.width,
|
|
66
76
|
this.height,
|
|
67
77
|
count,
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
78
|
+
this.feed,
|
|
79
|
+
this.kill
|
|
70
80
|
);
|
|
71
81
|
if (count % 2) this.parity = next;
|
|
72
82
|
this.a = owner.fields[this.parity];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/features/textures/lib/simulation.ts"],
|
|
4
|
-
"sourcesContent": ["import { FieldMemory, lazyKernel } from \"./wasm/memory.js\";\nimport { bytes } from \"./wasm/ink-bytes.js\";\nconst module = /* @__PURE__ */ lazyKernel(bytes);\n/** Private WASM Gray\u2013Scott state. Pibbl owns the clock and resource lifetime. */\nexport class InkSimulation {\n a: Float32Array;\n b: Float32Array;\n private owner?: FieldMemory;\n private parity = 0;\n steps = 0;\n
|
|
5
|
-
"mappings": "AAAA,SAAS,aAAa,kBAAkB;AACxC,SAAS,aAAa;AACtB,MAAM,SAAyB,2BAAW,KAAK;AAExC,MAAM,cAAc;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n grayScottConfig,\n type ReactionDiffusionOptions,\n} from \"./gray-scott.js\";\nimport { FieldMemory, lazyKernel } from \"./wasm/memory.js\";\nimport { bytes } from \"./wasm/ink-bytes.js\";\nconst module = /* @__PURE__ */ lazyKernel(bytes);\n/** Private WASM Gray\u2013Scott state. Pibbl owns the clock and resource lifetime. */\nexport class InkSimulation {\n a: Float32Array;\n b: Float32Array;\n private owner?: FieldMemory;\n private parity = 0;\n steps = 0;\n readonly width: number;\n readonly height: number;\n readonly preset: ReturnType<typeof grayScottConfig>[\"preset\"];\n private readonly feed: number;\n private readonly kill: number;\n constructor(\n options: ReactionDiffusionOptions & { width: number; height: number },\n ) {\n const { width, height } = options;\n const config = grayScottConfig(options);\n this.width = width;\n this.height = height;\n this.preset = config.preset;\n this.feed = config.feed;\n this.kill = config.kill;\n const owner = (this.owner = new FieldMemory(module(), width, height, 4));\n [this.a, this.b] = owner.fields;\n owner.kernel.initialize(\n this.a.byteOffset,\n this.b.byteOffset,\n width,\n height,\n config.seed,\n );\n if (config.warmupSteps) this.advance(config.warmupSteps);\n }\n paint(x: number, y: number, radius: number, strength: number) {\n const owner = this.owner!;\n owner.stamps[0] = x;\n owner.stamps[1] = y;\n owner.stamps[2] = radius;\n owner.stamps[3] = strength;\n owner.kernel.paintBatch(\n this.a.byteOffset,\n this.b.byteOffset,\n this.width,\n this.height,\n owner.stamps.byteOffset,\n 1,\n );\n }\n stir(x: number, y: number, dx: number, dy: number, radius: number) {\n const owner = this.owner!,\n next = 2 - this.parity;\n owner.kernel.stir(\n this.a.byteOffset,\n this.b.byteOffset,\n owner.fields[next].byteOffset,\n owner.fields[next + 1].byteOffset,\n this.width,\n this.height,\n x,\n y,\n dx,\n dy,\n radius,\n );\n }\n advance(count: number) {\n const owner = this.owner!,\n next = 2 - this.parity;\n owner.kernel.advance(\n this.a.byteOffset,\n this.b.byteOffset,\n owner.fields[next].byteOffset,\n owner.fields[next + 1].byteOffset,\n this.width,\n this.height,\n count,\n this.feed,\n this.kill,\n );\n if (count % 2) this.parity = next;\n this.a = owner.fields[this.parity];\n this.b = owner.fields[this.parity + 1];\n this.steps += count;\n }\n dispose() {\n this.owner?.dispose();\n this.owner = undefined;\n this.a = this.b = new Float32Array(0);\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EACE;AAAA,OAEK;AACP,SAAS,aAAa,kBAAkB;AACxC,SAAS,aAAa;AACtB,MAAM,SAAyB,2BAAW,KAAK;AAExC,MAAM,cAAc;AAAA,EACzB;AAAA,EACA;AAAA,EACQ;AAAA,EACA,SAAS;AAAA,EACjB,QAAQ;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EACjB,YACE,SACA;AACA,UAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,UAAM,SAAS,gBAAgB,OAAO;AACtC,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,SAAK,SAAS,OAAO;AACrB,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO;AACnB,UAAM,QAAS,KAAK,QAAQ,IAAI,YAAY,OAAO,GAAG,OAAO,QAAQ,CAAC;AACtE,KAAC,KAAK,GAAG,KAAK,CAAC,IAAI,MAAM;AACzB,UAAM,OAAO;AAAA,MACX,KAAK,EAAE;AAAA,MACP,KAAK,EAAE;AAAA,MACP;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT;AACA,QAAI,OAAO,YAAa,MAAK,QAAQ,OAAO,WAAW;AAAA,EACzD;AAAA,EACA,MAAM,GAAW,GAAW,QAAgB,UAAkB;AAC5D,UAAM,QAAQ,KAAK;AACnB,UAAM,OAAO,CAAC,IAAI;AAClB,UAAM,OAAO,CAAC,IAAI;AAClB,UAAM,OAAO,CAAC,IAAI;AAClB,UAAM,OAAO,CAAC,IAAI;AAClB,UAAM,OAAO;AAAA,MACX,KAAK,EAAE;AAAA,MACP,KAAK,EAAE;AAAA,MACP,KAAK;AAAA,MACL,KAAK;AAAA,MACL,MAAM,OAAO;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EACA,KAAK,GAAW,GAAW,IAAY,IAAY,QAAgB;AACjE,UAAM,QAAQ,KAAK,OACjB,OAAO,IAAI,KAAK;AAClB,UAAM,OAAO;AAAA,MACX,KAAK,EAAE;AAAA,MACP,KAAK,EAAE;AAAA,MACP,MAAM,OAAO,IAAI,EAAE;AAAA,MACnB,MAAM,OAAO,OAAO,CAAC,EAAE;AAAA,MACvB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EACA,QAAQ,OAAe;AACrB,UAAM,QAAQ,KAAK,OACjB,OAAO,IAAI,KAAK;AAClB,UAAM,OAAO;AAAA,MACX,KAAK,EAAE;AAAA,MACP,KAAK,EAAE;AAAA,MACP,MAAM,OAAO,IAAI,EAAE;AAAA,MACnB,MAAM,OAAO,OAAO,CAAC,EAAE;AAAA,MACvB,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,QAAI,QAAQ,EAAG,MAAK,SAAS;AAC7B,SAAK,IAAI,MAAM,OAAO,KAAK,MAAM;AACjC,SAAK,IAAI,MAAM,OAAO,KAAK,SAAS,CAAC;AACrC,SAAK,SAAS;AAAA,EAChB;AAAA,EACA,UAAU;AACR,SAAK,OAAO,QAAQ;AACpB,SAAK,QAAQ;AACb,SAAK,IAAI,KAAK,IAAI,IAAI,aAAa,CAAC;AAAA,EACtC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -182,11 +182,18 @@ class ElectricMemory {
|
|
|
182
182
|
);
|
|
183
183
|
this.tokens.clear();
|
|
184
184
|
this.ids = [void 0];
|
|
185
|
-
for (const
|
|
185
|
+
for (const site of this.ordered) {
|
|
186
|
+
if (!this.tokens.has(site.id)) {
|
|
187
|
+
this.tokens.set(site.id, this.ids.length);
|
|
188
|
+
this.ids.push(site.id);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
for (const id of old) {
|
|
186
192
|
if (id !== void 0 && !this.tokens.has(id)) {
|
|
187
193
|
this.tokens.set(id, this.ids.length);
|
|
188
194
|
this.ids.push(id);
|
|
189
195
|
}
|
|
196
|
+
}
|
|
190
197
|
for (let i = 0; i < 32; i++)
|
|
191
198
|
this.data[T + i * 14] = old[i] === void 0 ? 0 : this.tokens.get(old[i]);
|
|
192
199
|
this.data[0] = this.ordered.length;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/features/textures/lib/wasm/electric.ts"],
|
|
4
|
-
"sourcesContent": ["import type { TextureContext } from \"@pibbl/core\";\nimport { drawCore, type ElectricPoint } from \"../electric-shared.js\";\nimport type { SourceSite } from \"../electric-sources.js\";\nconst S = 64,\n T = 2624,\n P = 3072,\n L = 3584,\n O = 3784;\ntype Exports = Record<string, (...args: number[]) => number>;\nclass PointView implements ElectricPoint {\n constructor(\n private owner: ElectricMemory,\n private offset: number,\n ) {}\n get x() {\n return this.owner.data[this.offset];\n }\n get y() {\n return this.owner.data[this.offset + 1];\n }\n}\nexport class ElectricThread {\n private readonly p: PointView;\n private readonly trajectoryPoint: PointView;\n private readonly source: PointView;\n constructor(\n private owner: ElectricMemory,\n private offset: number,\n ) {\n this.p = new PointView(owner, offset + 1);\n this.trajectoryPoint = new PointView(owner, offset + 6);\n this.source = new PointView(owner, offset + 8);\n }\n get sourceId() {\n return this.owner.ids[this.owner.data[this.offset]];\n }\n set sourceId(id: string | undefined) {\n this.owner.data[this.offset] =\n id === undefined ? 0 : this.owner.tokens.get(id)!;\n }\n get point() {\n return this.p;\n }\n set point(p: ElectricPoint) {\n this.owner.data[this.offset + 1] = p.x;\n this.owner.data[this.offset + 2] = p.y;\n }\n get trajectory() {\n return this.trajectoryPoint;\n }\n set trajectory(p: ElectricPoint) {\n this.owner.data[this.offset + 6] = p.x;\n this.owner.data[this.offset + 7] = p.y;\n }\n get sourcePoint() {\n return this.source;\n }\n set sourcePoint(p: ElectricPoint) {\n this.owner.data[this.offset + 8] = p.x;\n this.owner.data[this.offset + 9] = p.y;\n }\n get strength() {\n return this.owner.data[this.offset + 3];\n }\n set strength(v: number) {\n this.owner.data[this.offset + 3] = v;\n }\n get age() {\n return this.owner.data[this.offset + 4];\n }\n set age(v: number) {\n this.owner.data[this.offset + 4] = v;\n }\n get generation() {\n return this.owner.data[this.offset + 5];\n }\n set generation(v: number) {\n this.owner.data[this.offset + 5] = v;\n }\n get releasedAge() {\n const n = this.owner.data[this.offset + 10];\n return n < 0 ? undefined : n;\n }\n set releasedAge(v: number | undefined) {\n this.owner.data[this.offset + 10] = v ?? -1;\n }\n get visible() {\n return this.owner.data[this.offset + 11] !== 0;\n }\n set visible(v: boolean) {\n this.owner.data[this.offset + 11] = +v;\n }\n get born() {\n return this.owner.data[this.offset + 12] !== 0;\n }\n set born(v: boolean) {\n this.owner.data[this.offset + 12] = +v;\n }\n}\nexport class ElectricConnection {\n private readonly a: PointView;\n private readonly b: PointView;\n readonly offset: number;\n constructor(\n private owner: ElectricMemory,\n readonly index: number,\n ) {\n this.offset = L + index * 8;\n this.a = new PointView(owner, this.offset);\n this.b = new PointView(owner, this.offset + 2);\n }\n get positive() {\n return this.a;\n }\n set positive(p: ElectricPoint) {\n this.owner.data[this.offset] = p.x;\n this.owner.data[this.offset + 1] = p.y;\n }\n get negative() {\n return this.b;\n }\n set negative(p: ElectricPoint) {\n this.owner.data[this.offset + 2] = p.x;\n this.owner.data[this.offset + 3] = p.y;\n }\n get strength() {\n return this.owner.data[this.offset + 4];\n }\n set strength(v: number) {\n this.owner.data[this.offset + 4] = v;\n }\n get salt() {\n return this.owner.data[this.offset + 5];\n }\n set salt(v: number) {\n this.owner.data[this.offset + 5] = v;\n }\n get active() {\n return this.owner.data[this.offset + 6] > 0;\n }\n set active(v: boolean) {\n this.owner.data[this.offset + 6] = v ? 1 : -1;\n }\n release() {\n this.owner.data[this.offset + 6] = 0;\n }\n}\n/** One fixed heap per mounted electric resource; all numeric views borrow it. */\nexport class ElectricMemory {\n data: Float64Array<ArrayBuffer>;\n private kernel?: Exports;\n private outline?: readonly ElectricPoint[];\n readonly tokens = new Map<string, number>();\n ids: (string | undefined)[] = [undefined];\n private ordered: SourceSite[] = [];\n constructor(module: WebAssembly.Module) {\n const memory = new WebAssembly.Memory({ initial: 3, maximum: 3 });\n this.data = new Float64Array(memory.buffer, 65536);\n this.kernel = new WebAssembly.Instance(module, {\n env: {\n memory,\n abort() {\n throw new Error(\"Electric texture WASM aborted.\");\n },\n },\n }).exports as Exports;\n }\n thread(index: number) {\n return new ElectricThread(this, T + index * 14);\n }\n connection() {\n for (let i = 1; i < 25; i++)\n if (this.data[L + i * 8 + 6] === 0)\n return new ElectricConnection(this, i);\n throw new RangeError(\"At most 24 lightning connections may be active.\");\n }\n clearConnections() {\n this.data.fill(0, L, L + 25 * 8);\n }\n setSources(sites: readonly SourceSite[]) {\n // Preserve live bindings while compacting IDs, so removed source history\n // cannot accumulate in the JS control map across repeated edits.\n const old = Array.from(\n { length: 32 },\n (_, i) => this.ids[this.data[T + i * 14]],\n );\n this.ordered = [...sites].sort((a, b) =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0,\n );\n this.tokens.clear();\n this.ids = [undefined];\n for (const id of [...this.ordered.map((s) => s.id), ...old])\n if (id !== undefined && !this.tokens.has(id)) {\n this.tokens.set(id, this.ids.length);\n this.ids.push(id);\n }\n for (let i = 0; i < 32; i++)\n this.data[T + i * 14] =\n old[i] === undefined ? 0 : this.tokens.get(old[i]!)!;\n this.data[0] = this.ordered.length;\n this.ordered.forEach((site, i) => {\n const p = S + i * 5;\n this.data[p] = this.tokens.get(site.id)!;\n this.data[p + 1] = site.point.x;\n this.data[p + 2] = site.point.y;\n this.data[p + 3] = site.weight;\n this.data[p + 4] = site.hash;\n });\n }\n choose(seed: number, ticket: number) {\n return this.ordered[this.kernel!.choose(seed, ticket)];\n }\n boundary(points: readonly ElectricPoint[] | undefined) {\n if (this.outline === points) return;\n this.outline = points;\n this.data[1] = points?.length ?? 0;\n points?.forEach((p, i) => {\n this.data[P + i * 2] = p.x;\n this.data[P + i * 2 + 1] = p.y;\n });\n }\n advanceTendrils(count: number, seed: number, dt: number, rise: number) {\n this.kernel!.advance(count, seed, dt, rise);\n }\n advanceLightning(dt: number) {\n this.kernel!.advance(dt);\n }\n tendrils(\n c: {\n seed: number;\n center: ElectricPoint;\n rise: number;\n crackle: number;\n frequency: number;\n branching: number;\n },\n time: number,\n count: number,\n ) {\n this.kernel!.generate(\n count,\n c.seed,\n time,\n c.center.x,\n c.center.y,\n c.rise,\n c.crackle,\n c.frequency,\n c.branching,\n );\n }\n lightning(\n c: {\n seed: number;\n frequency: number;\n branching: number;\n active: boolean;\n edge?: string;\n positive: ElectricPoint;\n negative: ElectricPoint;\n contactCore: boolean;\n },\n time: number,\n connections: Iterable<ElectricConnection>,\n ) {\n let n = 0;\n for (const connection of connections) this.data[3 + n++] = connection.index;\n this.data[2] = n;\n this.kernel!.generate(\n c.seed,\n time,\n c.frequency,\n c.branching,\n +c.active,\n [\"\", \"top\", \"right\", \"bottom\", \"left\"].indexOf(c.edge ?? \"\"),\n c.positive.x,\n c.positive.y,\n c.negative.x,\n c.negative.y,\n +c.contactCore,\n );\n }\n draw(context: TextureContext, glow: number) {\n const ctx = context.canvas.getContext(\"2d\")!,\n w = context.canvas.width,\n h = context.canvas.height,\n scale = Math.min(w, h),\n d = this.data;\n ctx.globalCompositeOperation = \"lighter\";\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n for (let pass = 0; pass < 4; pass++) {\n if (pass < 2 && glow === 0) continue;\n let p = O + 3;\n for (let line = 0; line < d[O]; line++) {\n const count = d[p],\n intensity = d[p + 1],\n hue = d[p + 2],\n width = d[p + 3];\n p += 4;\n if (intensity >= 0.005) {\n ctx.beginPath();\n ctx.moveTo(d[p] * w, d[p + 1] * h);\n for (let i = 1; i < count; i++)\n ctx.lineTo(d[p + i * 2] * w, d[p + i * 2 + 1] * h);\n const alpha = Math.min(\n 1,\n intensity *\n (pass === 0\n ? 0.055 * glow\n : pass === 1\n ? 0.16 * glow\n : pass === 2\n ? 0.65\n : 0.95),\n );\n ctx.strokeStyle =\n pass === 3\n ? `rgba(245,239,255,${alpha})`\n : `hsla(${hue},100%,${pass === 2 ? 72 : 58}%,${alpha})`;\n ctx.lineWidth = Math.max(\n 0.45,\n scale *\n width *\n (pass === 0\n ? 16 * glow\n : pass === 1\n ? 6 * glow\n : pass === 2\n ? 2\n : 0.65),\n );\n ctx.stroke();\n }\n p += count * 2;\n }\n }\n let p = d[O + 1];\n for (let i = 0; i < d[O + 2]; i++, p += 4)\n drawCore(context, { x: d[p], y: d[p + 1] }, d[p + 2], glow, d[p + 3]);\n }\n dispose() {\n this.kernel = undefined;\n this.data = new Float64Array(0);\n this.tokens.clear();\n this.ids = [];\n this.ordered = [];\n this.outline = undefined;\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import type { TextureContext } from \"@pibbl/core\";\nimport { drawCore, type ElectricPoint } from \"../electric-shared.js\";\nimport type { SourceSite } from \"../electric-sources.js\";\nconst S = 64,\n T = 2624,\n P = 3072,\n L = 3584,\n O = 3784;\ntype Exports = Record<string, (...args: number[]) => number>;\nclass PointView implements ElectricPoint {\n constructor(\n private owner: ElectricMemory,\n private offset: number,\n ) {}\n get x() {\n return this.owner.data[this.offset];\n }\n get y() {\n return this.owner.data[this.offset + 1];\n }\n}\nexport class ElectricThread {\n private readonly p: PointView;\n private readonly trajectoryPoint: PointView;\n private readonly source: PointView;\n constructor(\n private owner: ElectricMemory,\n private offset: number,\n ) {\n this.p = new PointView(owner, offset + 1);\n this.trajectoryPoint = new PointView(owner, offset + 6);\n this.source = new PointView(owner, offset + 8);\n }\n get sourceId() {\n return this.owner.ids[this.owner.data[this.offset]];\n }\n set sourceId(id: string | undefined) {\n this.owner.data[this.offset] =\n id === undefined ? 0 : this.owner.tokens.get(id)!;\n }\n get point() {\n return this.p;\n }\n set point(p: ElectricPoint) {\n this.owner.data[this.offset + 1] = p.x;\n this.owner.data[this.offset + 2] = p.y;\n }\n get trajectory() {\n return this.trajectoryPoint;\n }\n set trajectory(p: ElectricPoint) {\n this.owner.data[this.offset + 6] = p.x;\n this.owner.data[this.offset + 7] = p.y;\n }\n get sourcePoint() {\n return this.source;\n }\n set sourcePoint(p: ElectricPoint) {\n this.owner.data[this.offset + 8] = p.x;\n this.owner.data[this.offset + 9] = p.y;\n }\n get strength() {\n return this.owner.data[this.offset + 3];\n }\n set strength(v: number) {\n this.owner.data[this.offset + 3] = v;\n }\n get age() {\n return this.owner.data[this.offset + 4];\n }\n set age(v: number) {\n this.owner.data[this.offset + 4] = v;\n }\n get generation() {\n return this.owner.data[this.offset + 5];\n }\n set generation(v: number) {\n this.owner.data[this.offset + 5] = v;\n }\n get releasedAge() {\n const n = this.owner.data[this.offset + 10];\n return n < 0 ? undefined : n;\n }\n set releasedAge(v: number | undefined) {\n this.owner.data[this.offset + 10] = v ?? -1;\n }\n get visible() {\n return this.owner.data[this.offset + 11] !== 0;\n }\n set visible(v: boolean) {\n this.owner.data[this.offset + 11] = +v;\n }\n get born() {\n return this.owner.data[this.offset + 12] !== 0;\n }\n set born(v: boolean) {\n this.owner.data[this.offset + 12] = +v;\n }\n}\nexport class ElectricConnection {\n private readonly a: PointView;\n private readonly b: PointView;\n readonly offset: number;\n constructor(\n private owner: ElectricMemory,\n readonly index: number,\n ) {\n this.offset = L + index * 8;\n this.a = new PointView(owner, this.offset);\n this.b = new PointView(owner, this.offset + 2);\n }\n get positive() {\n return this.a;\n }\n set positive(p: ElectricPoint) {\n this.owner.data[this.offset] = p.x;\n this.owner.data[this.offset + 1] = p.y;\n }\n get negative() {\n return this.b;\n }\n set negative(p: ElectricPoint) {\n this.owner.data[this.offset + 2] = p.x;\n this.owner.data[this.offset + 3] = p.y;\n }\n get strength() {\n return this.owner.data[this.offset + 4];\n }\n set strength(v: number) {\n this.owner.data[this.offset + 4] = v;\n }\n get salt() {\n return this.owner.data[this.offset + 5];\n }\n set salt(v: number) {\n this.owner.data[this.offset + 5] = v;\n }\n get active() {\n return this.owner.data[this.offset + 6] > 0;\n }\n set active(v: boolean) {\n this.owner.data[this.offset + 6] = v ? 1 : -1;\n }\n release() {\n this.owner.data[this.offset + 6] = 0;\n }\n}\n/** One fixed heap per mounted electric resource; all numeric views borrow it. */\nexport class ElectricMemory {\n data: Float64Array<ArrayBuffer>;\n private kernel?: Exports;\n private outline?: readonly ElectricPoint[];\n readonly tokens = new Map<string, number>();\n ids: (string | undefined)[] = [undefined];\n private ordered: SourceSite[] = [];\n constructor(module: WebAssembly.Module) {\n const memory = new WebAssembly.Memory({ initial: 3, maximum: 3 });\n this.data = new Float64Array(memory.buffer, 65536);\n this.kernel = new WebAssembly.Instance(module, {\n env: {\n memory,\n abort() {\n throw new Error(\"Electric texture WASM aborted.\");\n },\n },\n }).exports as Exports;\n }\n thread(index: number) {\n return new ElectricThread(this, T + index * 14);\n }\n connection() {\n for (let i = 1; i < 25; i++)\n if (this.data[L + i * 8 + 6] === 0)\n return new ElectricConnection(this, i);\n throw new RangeError(\"At most 24 lightning connections may be active.\");\n }\n clearConnections() {\n this.data.fill(0, L, L + 25 * 8);\n }\n setSources(sites: readonly SourceSite[]) {\n // Preserve live bindings while compacting IDs, so removed source history\n // cannot accumulate in the JS control map across repeated edits.\n const old = Array.from(\n { length: 32 },\n (_, i) => this.ids[this.data[T + i * 14]],\n );\n this.ordered = [...sites].sort((a, b) =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0,\n );\n this.tokens.clear();\n this.ids = [undefined];\n for (const site of this.ordered) {\n if (!this.tokens.has(site.id)) {\n this.tokens.set(site.id, this.ids.length);\n this.ids.push(site.id);\n }\n }\n for (const id of old) {\n if (id !== undefined && !this.tokens.has(id)) {\n this.tokens.set(id, this.ids.length);\n this.ids.push(id);\n }\n }\n for (let i = 0; i < 32; i++)\n this.data[T + i * 14] =\n old[i] === undefined ? 0 : this.tokens.get(old[i]!)!;\n this.data[0] = this.ordered.length;\n this.ordered.forEach((site, i) => {\n const p = S + i * 5;\n this.data[p] = this.tokens.get(site.id)!;\n this.data[p + 1] = site.point.x;\n this.data[p + 2] = site.point.y;\n this.data[p + 3] = site.weight;\n this.data[p + 4] = site.hash;\n });\n }\n choose(seed: number, ticket: number) {\n return this.ordered[this.kernel!.choose(seed, ticket)];\n }\n boundary(points: readonly ElectricPoint[] | undefined) {\n if (this.outline === points) return;\n this.outline = points;\n this.data[1] = points?.length ?? 0;\n points?.forEach((p, i) => {\n this.data[P + i * 2] = p.x;\n this.data[P + i * 2 + 1] = p.y;\n });\n }\n advanceTendrils(count: number, seed: number, dt: number, rise: number) {\n this.kernel!.advance(count, seed, dt, rise);\n }\n advanceLightning(dt: number) {\n this.kernel!.advance(dt);\n }\n tendrils(\n c: {\n seed: number;\n center: ElectricPoint;\n rise: number;\n crackle: number;\n frequency: number;\n branching: number;\n },\n time: number,\n count: number,\n ) {\n this.kernel!.generate(\n count,\n c.seed,\n time,\n c.center.x,\n c.center.y,\n c.rise,\n c.crackle,\n c.frequency,\n c.branching,\n );\n }\n lightning(\n c: {\n seed: number;\n frequency: number;\n branching: number;\n active: boolean;\n edge?: string;\n positive: ElectricPoint;\n negative: ElectricPoint;\n contactCore: boolean;\n },\n time: number,\n connections: Iterable<ElectricConnection>,\n ) {\n let n = 0;\n for (const connection of connections) this.data[3 + n++] = connection.index;\n this.data[2] = n;\n this.kernel!.generate(\n c.seed,\n time,\n c.frequency,\n c.branching,\n +c.active,\n [\"\", \"top\", \"right\", \"bottom\", \"left\"].indexOf(c.edge ?? \"\"),\n c.positive.x,\n c.positive.y,\n c.negative.x,\n c.negative.y,\n +c.contactCore,\n );\n }\n draw(context: TextureContext, glow: number) {\n const ctx = context.canvas.getContext(\"2d\")!,\n w = context.canvas.width,\n h = context.canvas.height,\n scale = Math.min(w, h),\n d = this.data;\n ctx.globalCompositeOperation = \"lighter\";\n ctx.lineJoin = \"round\";\n ctx.lineCap = \"round\";\n for (let pass = 0; pass < 4; pass++) {\n if (pass < 2 && glow === 0) continue;\n let p = O + 3;\n for (let line = 0; line < d[O]; line++) {\n const count = d[p],\n intensity = d[p + 1],\n hue = d[p + 2],\n width = d[p + 3];\n p += 4;\n if (intensity >= 0.005) {\n ctx.beginPath();\n ctx.moveTo(d[p] * w, d[p + 1] * h);\n for (let i = 1; i < count; i++)\n ctx.lineTo(d[p + i * 2] * w, d[p + i * 2 + 1] * h);\n const alpha = Math.min(\n 1,\n intensity *\n (pass === 0\n ? 0.055 * glow\n : pass === 1\n ? 0.16 * glow\n : pass === 2\n ? 0.65\n : 0.95),\n );\n ctx.strokeStyle =\n pass === 3\n ? `rgba(245,239,255,${alpha})`\n : `hsla(${hue},100%,${pass === 2 ? 72 : 58}%,${alpha})`;\n ctx.lineWidth = Math.max(\n 0.45,\n scale *\n width *\n (pass === 0\n ? 16 * glow\n : pass === 1\n ? 6 * glow\n : pass === 2\n ? 2\n : 0.65),\n );\n ctx.stroke();\n }\n p += count * 2;\n }\n }\n let p = d[O + 1];\n for (let i = 0; i < d[O + 2]; i++, p += 4)\n drawCore(context, { x: d[p], y: d[p + 1] }, d[p + 2], glow, d[p + 3]);\n }\n dispose() {\n this.kernel = undefined;\n this.data = new Float64Array(0);\n this.tokens.clear();\n this.ids = [];\n this.ordered = [];\n this.outline = undefined;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["p"]
|
|
7
7
|
}
|
|
@@ -213,9 +213,7 @@ function options(input) {
|
|
|
213
213
|
);
|
|
214
214
|
const obstacles = Object.freeze(
|
|
215
215
|
(input.obstacles ?? []).map((obstacle) => {
|
|
216
|
-
if (!
|
|
217
|
-
Number.isFinite
|
|
218
|
-
) || obstacle.x < 0 || obstacle.y < 0 || obstacle.width < 0 || obstacle.height < 0 || obstacle.x + obstacle.width > 1 || obstacle.y + obstacle.height > 1)
|
|
216
|
+
if (!(Number.isFinite(obstacle.x) && Number.isFinite(obstacle.y) && Number.isFinite(obstacle.width) && Number.isFinite(obstacle.height)) || obstacle.x < 0 || obstacle.y < 0 || obstacle.width < 0 || obstacle.height < 0 || obstacle.x + obstacle.width > 1 || obstacle.y + obstacle.height > 1)
|
|
219
217
|
throw new RangeError(
|
|
220
218
|
"Water surface obstacles must be finite normalized rectangles within [0, 1]."
|
|
221
219
|
);
|