@rafaelaugusto/jolt 0.1.0-beta.9 → 0.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -21
- package/dist/animate.d.ts +25 -4
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +67 -26
- package/dist/animate.js.map +1 -1
- package/dist/blur/index.d.ts +6 -0
- package/dist/blur/index.d.ts.map +1 -0
- package/dist/blur/index.js +196 -0
- package/dist/blur/index.js.map +1 -0
- package/dist/blur/native.d.ts +17 -0
- package/dist/blur/native.d.ts.map +1 -0
- package/dist/blur/native.js +44 -0
- package/dist/blur/native.js.map +1 -0
- package/dist/blur/types.d.ts +32 -0
- package/dist/blur/types.d.ts.map +1 -0
- package/dist/blur/types.js +2 -0
- package/dist/blur/types.js.map +1 -0
- package/dist/bottom-sheet/geometry.d.ts +18 -0
- package/dist/bottom-sheet/geometry.d.ts.map +1 -0
- package/dist/bottom-sheet/geometry.js +51 -0
- package/dist/bottom-sheet/geometry.js.map +1 -0
- package/dist/bottom-sheet/index.d.ts +56 -0
- package/dist/bottom-sheet/index.d.ts.map +1 -0
- package/dist/bottom-sheet/index.js +462 -0
- package/dist/bottom-sheet/index.js.map +1 -0
- package/dist/bottom-sheet/native.d.ts +11 -0
- package/dist/bottom-sheet/native.d.ts.map +1 -0
- package/dist/bottom-sheet/native.js +173 -0
- package/dist/bottom-sheet/native.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +40 -1
- package/dist/config.js.map +1 -1
- package/dist/decay.d.ts +1 -0
- package/dist/decay.d.ts.map +1 -1
- package/dist/decay.js +7 -0
- package/dist/decay.js.map +1 -1
- package/dist/drag-physics.d.ts +6 -1
- package/dist/drag-physics.d.ts.map +1 -1
- package/dist/drag.d.ts +17 -3
- package/dist/drag.d.ts.map +1 -1
- package/dist/drag.js +34 -11
- package/dist/drag.js.map +1 -1
- package/dist/driver/android-gradient.d.ts +5 -0
- package/dist/driver/android-gradient.d.ts.map +1 -0
- package/dist/driver/android-gradient.js +99 -0
- package/dist/driver/android-gradient.js.map +1 -0
- package/dist/driver/android-particles.d.ts +6 -0
- package/dist/driver/android-particles.d.ts.map +1 -0
- package/dist/driver/android-particles.js +93 -0
- package/dist/driver/android-particles.js.map +1 -0
- package/dist/driver/android.d.ts.map +1 -1
- package/dist/driver/android.js +27 -1
- package/dist/driver/android.js.map +1 -1
- package/dist/driver/frame.d.ts +3 -0
- package/dist/driver/frame.d.ts.map +1 -0
- package/dist/driver/frame.js +7 -0
- package/dist/driver/frame.js.map +1 -0
- package/dist/driver/index.d.ts +4 -0
- package/dist/driver/index.d.ts.map +1 -1
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/ios-gradient.d.ts +5 -0
- package/dist/driver/ios-gradient.d.ts.map +1 -0
- package/dist/driver/ios-gradient.js +131 -0
- package/dist/driver/ios-gradient.js.map +1 -0
- package/dist/driver/ios-scroll-delegate.d.ts +4 -0
- package/dist/driver/ios-scroll-delegate.d.ts.map +1 -0
- package/dist/driver/ios-scroll-delegate.js +26 -0
- package/dist/driver/ios-scroll-delegate.js.map +1 -0
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +9 -0
- package/dist/driver/ios.js.map +1 -1
- package/dist/easing.d.ts +3 -1
- package/dist/easing.d.ts.map +1 -1
- package/dist/easing.js +18 -1
- package/dist/easing.js.map +1 -1
- package/dist/engine.d.ts +31 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +194 -42
- package/dist/engine.js.map +1 -1
- package/dist/gesture-native.d.ts +28 -0
- package/dist/gesture-native.d.ts.map +1 -0
- package/dist/gesture-native.js +61 -0
- package/dist/gesture-native.js.map +1 -0
- package/dist/gestures/index.d.ts +69 -0
- package/dist/gestures/index.d.ts.map +1 -0
- package/dist/gestures/index.js +262 -0
- package/dist/gestures/index.js.map +1 -0
- package/dist/glass/index.d.ts +55 -0
- package/dist/glass/index.d.ts.map +1 -0
- package/dist/glass/index.js +205 -0
- package/dist/glass/index.js.map +1 -0
- package/dist/gradient-binding.d.ts +38 -0
- package/dist/gradient-binding.d.ts.map +1 -0
- package/dist/gradient-binding.js +128 -0
- package/dist/gradient-binding.js.map +1 -0
- package/dist/gradient.d.ts +105 -0
- package/dist/gradient.d.ts.map +1 -0
- package/dist/gradient.js +514 -0
- package/dist/gradient.js.map +1 -0
- package/dist/gravity.d.ts +13 -0
- package/dist/gravity.d.ts.map +1 -0
- package/dist/gravity.js +84 -0
- package/dist/gravity.js.map +1 -0
- package/dist/haptics.d.ts.map +1 -1
- package/dist/haptics.js +101 -28
- package/dist/haptics.js.map +1 -1
- package/dist/image-effect.d.ts +1 -0
- package/dist/image-effect.d.ts.map +1 -1
- package/dist/image-effect.js +10 -2
- package/dist/image-effect.js.map +1 -1
- package/dist/index.d.ts +19 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/inspector/index.d.ts +86 -0
- package/dist/inspector/index.d.ts.map +1 -0
- package/dist/inspector/index.js +419 -0
- package/dist/inspector/index.js.map +1 -0
- package/dist/inspector/plot.d.ts +4 -0
- package/dist/inspector/plot.d.ts.map +1 -0
- package/dist/inspector/plot.js +23 -0
- package/dist/inspector/plot.js.map +1 -0
- package/dist/inspector/probe.d.ts +19 -0
- package/dist/inspector/probe.d.ts.map +1 -0
- package/dist/inspector/probe.js +37 -0
- package/dist/inspector/probe.js.map +1 -0
- package/dist/inspector/tuning.d.ts +19 -0
- package/dist/inspector/tuning.d.ts.map +1 -0
- package/dist/inspector/tuning.js +37 -0
- package/dist/inspector/tuning.js.map +1 -0
- package/dist/interactive-navigation/index.d.ts +44 -0
- package/dist/interactive-navigation/index.d.ts.map +1 -0
- package/dist/interactive-navigation/index.js +350 -0
- package/dist/interactive-navigation/index.js.map +1 -0
- package/dist/keyboard.d.ts +24 -0
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +199 -6
- package/dist/keyboard.js.map +1 -1
- package/dist/live-spring-driver.d.ts +52 -0
- package/dist/live-spring-driver.d.ts.map +1 -0
- package/dist/live-spring-driver.js +104 -0
- package/dist/live-spring-driver.js.map +1 -0
- package/dist/mixer.d.ts +55 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixer.js +286 -0
- package/dist/mixer.js.map +1 -0
- package/dist/motion-scope.d.ts +8 -2
- package/dist/motion-scope.d.ts.map +1 -1
- package/dist/motion-scope.js +24 -3
- package/dist/motion-scope.js.map +1 -1
- package/dist/motion-states.d.ts +19 -7
- package/dist/motion-states.d.ts.map +1 -1
- package/dist/motion-states.js +116 -26
- package/dist/motion-states.js.map +1 -1
- package/dist/motion-value.d.ts +227 -0
- package/dist/motion-value.d.ts.map +1 -0
- package/dist/motion-value.js +1074 -0
- package/dist/motion-value.js.map +1 -0
- package/dist/native/index.d.ts +10 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +6 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native-properties.d.ts +28 -0
- package/dist/native-properties.d.ts.map +1 -0
- package/dist/native-properties.js +154 -0
- package/dist/native-properties.js.map +1 -0
- package/dist/native-property-driver.d.ts +19 -0
- package/dist/native-property-driver.d.ts.map +1 -0
- package/dist/native-property-driver.js +69 -0
- package/dist/native-property-driver.js.map +1 -0
- package/dist/native-property.d.ts +37 -0
- package/dist/native-property.d.ts.map +1 -0
- package/dist/native-property.js +285 -0
- package/dist/native-property.js.map +1 -0
- package/dist/particles.d.ts +5 -2
- package/dist/particles.d.ts.map +1 -1
- package/dist/particles.js +16 -10
- package/dist/particles.js.map +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +2 -2
- package/dist/path.js.map +1 -1
- package/dist/physics/index.d.ts +139 -0
- package/dist/physics/index.d.ts.map +1 -0
- package/dist/physics/index.js +316 -0
- package/dist/physics/index.js.map +1 -0
- package/dist/physics/native.d.ts +54 -0
- package/dist/physics/native.d.ts.map +1 -0
- package/dist/physics/native.js +64 -0
- package/dist/physics/native.js.map +1 -0
- package/dist/playback-group.d.ts.map +1 -1
- package/dist/playback-group.js +17 -1
- package/dist/playback-group.js.map +1 -1
- package/dist/playback.d.ts +15 -0
- package/dist/playback.d.ts.map +1 -1
- package/dist/playback.js +23 -0
- package/dist/playback.js.map +1 -1
- package/dist/predictive-back/index.d.ts +45 -0
- package/dist/predictive-back/index.d.ts.map +1 -0
- package/dist/predictive-back/index.js +220 -0
- package/dist/predictive-back/index.js.map +1 -0
- package/dist/predictive-back/presentation.d.ts +4 -0
- package/dist/predictive-back/presentation.d.ts.map +1 -0
- package/dist/predictive-back/presentation.js +3 -0
- package/dist/predictive-back/presentation.js.map +1 -0
- package/dist/press.d.ts.map +1 -1
- package/dist/press.js +11 -2
- package/dist/press.js.map +1 -1
- package/dist/reorder/handle.d.ts +6 -0
- package/dist/reorder/handle.d.ts.map +1 -0
- package/dist/reorder/handle.js +10 -0
- package/dist/reorder/handle.js.map +1 -0
- package/dist/reorder/index.d.ts +10 -0
- package/dist/reorder/index.d.ts.map +1 -0
- package/dist/reorder/index.js +233 -0
- package/dist/reorder/index.js.map +1 -0
- package/dist/reorder/list-view.d.ts +5 -0
- package/dist/reorder/list-view.d.ts.map +1 -0
- package/dist/reorder/list-view.js +238 -0
- package/dist/reorder/list-view.js.map +1 -0
- package/dist/reorder/model.d.ts +6 -0
- package/dist/reorder/model.d.ts.map +1 -0
- package/dist/reorder/model.js +30 -0
- package/dist/reorder/model.js.map +1 -0
- package/dist/reorder/surface.d.ts +6 -0
- package/dist/reorder/surface.d.ts.map +1 -0
- package/dist/reorder/surface.js +10 -0
- package/dist/reorder/surface.js.map +1 -0
- package/dist/reorder/types.d.ts +92 -0
- package/dist/reorder/types.d.ts.map +1 -0
- package/dist/reorder/types.js +2 -0
- package/dist/reorder/types.js.map +1 -0
- package/dist/sampling.d.ts +35 -0
- package/dist/sampling.d.ts.map +1 -0
- package/dist/sampling.js +123 -0
- package/dist/sampling.js.map +1 -0
- package/dist/scene-appearance.d.ts +14 -0
- package/dist/scene-appearance.d.ts.map +1 -0
- package/dist/scene-appearance.js +68 -0
- package/dist/scene-appearance.js.map +1 -0
- package/dist/scene-camera.d.ts +5 -0
- package/dist/scene-camera.d.ts.map +1 -0
- package/dist/scene-camera.js +23 -0
- package/dist/scene-camera.js.map +1 -0
- package/dist/scene-shader.d.ts +18 -0
- package/dist/scene-shader.d.ts.map +1 -0
- package/dist/scene-shader.js +76 -0
- package/dist/scene-shader.js.map +1 -0
- package/dist/scroll-header/geometry.d.ts +18 -0
- package/dist/scroll-header/geometry.d.ts.map +1 -0
- package/dist/scroll-header/geometry.js +46 -0
- package/dist/scroll-header/geometry.js.map +1 -0
- package/dist/scroll-header/index.d.ts +48 -0
- package/dist/scroll-header/index.d.ts.map +1 -0
- package/dist/scroll-header/index.js +399 -0
- package/dist/scroll-header/index.js.map +1 -0
- package/dist/scroll-header/native.d.ts +28 -0
- package/dist/scroll-header/native.d.ts.map +1 -0
- package/dist/scroll-header/native.js +43 -0
- package/dist/scroll-header/native.js.map +1 -0
- package/dist/sensors/index.d.ts +69 -0
- package/dist/sensors/index.d.ts.map +1 -0
- package/dist/sensors/index.js +149 -0
- package/dist/sensors/index.js.map +1 -0
- package/dist/sensors/native.d.ts +20 -0
- package/dist/sensors/native.d.ts.map +1 -0
- package/dist/sensors/native.js +48 -0
- package/dist/sensors/native.js.map +1 -0
- package/dist/sequence.d.ts +24 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +181 -19
- package/dist/sequence.js.map +1 -1
- package/dist/shapes/android.d.ts +3 -0
- package/dist/shapes/android.d.ts.map +1 -0
- package/dist/shapes/android.js +51 -0
- package/dist/shapes/android.js.map +1 -0
- package/dist/shapes/index.d.ts +6 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +238 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/ios.d.ts +3 -0
- package/dist/shapes/ios.d.ts.map +1 -0
- package/dist/shapes/ios.js +164 -0
- package/dist/shapes/ios.js.map +1 -0
- package/dist/shapes/native.d.ts +18 -0
- package/dist/shapes/native.d.ts.map +1 -0
- package/dist/shapes/native.js +10 -0
- package/dist/shapes/native.js.map +1 -0
- package/dist/shapes/path.d.ts +10 -0
- package/dist/shapes/path.d.ts.map +1 -0
- package/dist/shapes/path.js +106 -0
- package/dist/shapes/path.js.map +1 -0
- package/dist/shapes/types.d.ts +55 -0
- package/dist/shapes/types.d.ts.map +1 -0
- package/dist/shapes/types.js +11 -0
- package/dist/shapes/types.js.map +1 -0
- package/dist/shared-layout/index.d.ts +40 -0
- package/dist/shared-layout/index.d.ts.map +1 -0
- package/dist/shared-layout/index.js +267 -0
- package/dist/shared-layout/index.js.map +1 -0
- package/dist/shared-layout/native.d.ts +15 -0
- package/dist/shared-layout/native.d.ts.map +1 -0
- package/dist/shared-layout/native.js +79 -0
- package/dist/shared-layout/native.js.map +1 -0
- package/dist/shared-layout/timing.d.ts +9 -0
- package/dist/shared-layout/timing.d.ts.map +1 -0
- package/dist/shared-layout/timing.js +68 -0
- package/dist/shared-layout/timing.js.map +1 -0
- package/dist/shared-navigation/entry.d.ts +51 -0
- package/dist/shared-navigation/entry.d.ts.map +1 -0
- package/dist/shared-navigation/entry.js +619 -0
- package/dist/shared-navigation/entry.js.map +1 -0
- package/dist/shared-navigation/index.d.ts +58 -0
- package/dist/shared-navigation/index.d.ts.map +1 -0
- package/dist/shared-navigation/index.js +318 -0
- package/dist/shared-navigation/index.js.map +1 -0
- package/dist/shared-navigation/return-signal.d.ts +16 -0
- package/dist/shared-navigation/return-signal.d.ts.map +1 -0
- package/dist/shared-navigation/return-signal.js +35 -0
- package/dist/shared-navigation/return-signal.js.map +1 -0
- package/dist/shared-navigation/return-target.d.ts +32 -0
- package/dist/shared-navigation/return-target.d.ts.map +1 -0
- package/dist/shared-navigation/return-target.js +168 -0
- package/dist/shared-navigation/return-target.js.map +1 -0
- package/dist/shared-navigation/scope.d.ts +4 -0
- package/dist/shared-navigation/scope.d.ts.map +1 -0
- package/dist/shared-navigation/scope.js +2 -0
- package/dist/shared-navigation/scope.js.map +1 -0
- package/dist/shared-navigation/targets.d.ts +6 -0
- package/dist/shared-navigation/targets.d.ts.map +1 -0
- package/dist/shared-navigation/targets.js +36 -0
- package/dist/shared-navigation/targets.js.map +1 -0
- package/dist/size-layout.d.ts +19 -0
- package/dist/size-layout.d.ts.map +1 -0
- package/dist/size-layout.js +216 -0
- package/dist/size-layout.js.map +1 -0
- package/dist/size.d.ts +19 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/size.js +251 -0
- package/dist/size.js.map +1 -0
- package/dist/spring.d.ts +2 -0
- package/dist/spring.d.ts.map +1 -1
- package/dist/spring.js +11 -0
- package/dist/spring.js.map +1 -1
- package/dist/svg-path.d.ts +18 -0
- package/dist/svg-path.d.ts.map +1 -1
- package/dist/svg-path.js +3 -2
- package/dist/svg-path.js.map +1 -1
- package/dist/testing/clock.d.ts +40 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +116 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/handoff-recorder.d.ts +8 -0
- package/dist/testing/handoff-recorder.d.ts.map +1 -0
- package/dist/testing/handoff-recorder.js +77 -0
- package/dist/testing/handoff-recorder.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/native.d.ts +46 -0
- package/dist/testing/native.d.ts.map +1 -0
- package/dist/testing/native.js +313 -0
- package/dist/testing/native.js.map +1 -0
- package/dist/testing/presentation.d.ts +11 -0
- package/dist/testing/presentation.d.ts.map +1 -0
- package/dist/testing/presentation.js +45 -0
- package/dist/testing/presentation.js.map +1 -0
- package/dist/testing/replay.d.ts +39 -0
- package/dist/testing/replay.d.ts.map +1 -0
- package/dist/testing/replay.js +99 -0
- package/dist/testing/replay.js.map +1 -0
- package/dist/testing/scroll-handoff-native.d.ts +10 -0
- package/dist/testing/scroll-handoff-native.d.ts.map +1 -0
- package/dist/testing/scroll-handoff-native.js +151 -0
- package/dist/testing/scroll-handoff-native.js.map +1 -0
- package/dist/testing/scroll-handoff.d.ts +25 -0
- package/dist/testing/scroll-handoff.d.ts.map +1 -0
- package/dist/testing/scroll-handoff.js +127 -0
- package/dist/testing/scroll-handoff.js.map +1 -0
- package/dist/testing/sensors.d.ts +13 -0
- package/dist/testing/sensors.d.ts.map +1 -0
- package/dist/testing/sensors.js +26 -0
- package/dist/testing/sensors.js.map +1 -0
- package/dist/testing/trace.d.ts +101 -0
- package/dist/testing/trace.d.ts.map +1 -0
- package/dist/testing/trace.js +263 -0
- package/dist/testing/trace.js.map +1 -0
- package/dist/timed-animation.d.ts +38 -0
- package/dist/timed-animation.d.ts.map +1 -0
- package/dist/timed-animation.js +177 -0
- package/dist/timed-animation.js.map +1 -0
- package/dist/track.d.ts +3 -0
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +281 -40
- package/dist/track.js.map +1 -1
- package/dist/transition.d.ts +54 -2
- package/dist/transition.d.ts.map +1 -1
- package/dist/transition.js +128 -8
- package/dist/transition.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/value-observers.d.ts +22 -0
- package/dist/value-observers.d.ts.map +1 -0
- package/dist/value-observers.js +122 -0
- package/dist/value-observers.js.map +1 -0
- package/dist/value-track.d.ts +13 -0
- package/dist/value-track.d.ts.map +1 -0
- package/dist/value-track.js +59 -0
- package/dist/value-track.js.map +1 -0
- package/dist/vue/index.d.ts +33 -3
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +118 -3
- package/dist/vue/index.js.map +1 -1
- package/dist/zoomable.d.ts +1 -1
- package/dist/zoomable.d.ts.map +1 -1
- package/package.json +68 -3
- package/platforms/android/include.gradle +10 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/BlurEffect.java +89 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/CircleMath.java +158 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/CircleWorld.java +221 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GestureSession.java +227 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GestureSurface.java +54 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +224 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrame.java +53 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrameFollower.java +57 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/LiveSpring.java +277 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/MotionProbe.java +70 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/PredictiveBackSession.java +212 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderHandle.java +25 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSession.java +213 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSurface.java +27 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ScrollHeader.java +84 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SensorMath.java +28 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SensorSource.java +217 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ShapeLayer.java +120 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SharedLayoutFlight.java +287 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SharedNavigationScene.java +115 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SpringState.java +39 -0
- package/platforms/android/proguard-rules.pro +20 -0
- package/platforms/ios/build.xcconfig +1 -1
- package/platforms/ios/src/JoltBlur.h +14 -0
- package/platforms/ios/src/JoltBlur.m +86 -0
- package/platforms/ios/src/JoltCircleMath.h +191 -0
- package/platforms/ios/src/JoltCircleWorld.h +18 -0
- package/platforms/ios/src/JoltCircleWorld.m +218 -0
- package/platforms/ios/src/JoltGestureSession.h +23 -0
- package/platforms/ios/src/JoltGestureSession.m +251 -0
- package/platforms/ios/src/JoltInteractiveNavigation.h +23 -0
- package/platforms/ios/src/JoltInteractiveNavigation.m +255 -0
- package/platforms/ios/src/JoltLiveSpring.h +29 -0
- package/platforms/ios/src/JoltLiveSpring.m +243 -0
- package/platforms/ios/src/JoltMotionProbe.h +9 -0
- package/platforms/ios/src/JoltMotionProbe.m +72 -0
- package/platforms/ios/src/JoltReorderSession.h +15 -0
- package/platforms/ios/src/JoltReorderSession.m +205 -0
- package/platforms/ios/src/JoltScrollHeader.h +13 -0
- package/platforms/ios/src/JoltScrollHeader.m +101 -0
- package/platforms/ios/src/JoltSensorMath.h +39 -0
- package/platforms/ios/src/JoltSensorSource.h +13 -0
- package/platforms/ios/src/JoltSensorSource.m +201 -0
- package/platforms/ios/src/JoltSharedLayoutFlight.h +19 -0
- package/platforms/ios/src/JoltSharedLayoutFlight.m +250 -0
- package/platforms/ios/src/JoltSpringState.h +35 -0
- package/platforms/ios/src/module.modulemap +10 -0
- package/src/android-plugin.d.ts +464 -0
- package/src/animate.ts +129 -15
- package/src/blur/index.ts +195 -0
- package/src/blur/native.ts +70 -0
- package/src/blur/types.ts +32 -0
- package/src/bottom-sheet/geometry.ts +84 -0
- package/src/bottom-sheet/index.ts +536 -0
- package/src/bottom-sheet/native.ts +214 -0
- package/src/config.ts +39 -1
- package/src/decay.ts +9 -0
- package/src/drag.ts +67 -21
- package/src/driver/android-gradient.ts +116 -0
- package/src/driver/android-particles.ts +118 -0
- package/src/driver/android.ts +31 -1
- package/src/driver/frame.ts +10 -0
- package/src/driver/index.ts +4 -0
- package/src/driver/ios-gradient.ts +136 -0
- package/src/driver/ios-scroll-delegate.ts +23 -0
- package/src/driver/ios.ts +10 -0
- package/src/easing.ts +21 -1
- package/src/engine.ts +209 -60
- package/src/gesture-native.ts +139 -0
- package/src/gestures/index.ts +365 -0
- package/src/glass/index.ts +218 -0
- package/src/gradient-binding.ts +158 -0
- package/src/gradient.ts +663 -0
- package/src/gravity.ts +107 -0
- package/src/haptics.ts +106 -28
- package/src/image-effect.ts +10 -2
- package/src/index.ts +56 -7
- package/src/inspector/index.ts +523 -0
- package/src/inspector/plot.ts +27 -0
- package/src/inspector/probe.ts +50 -0
- package/src/inspector/tuning.ts +51 -0
- package/src/interactive-navigation/index.ts +427 -0
- package/src/ios-plugin.d.ts +280 -0
- package/src/keyboard.ts +231 -7
- package/src/live-spring-driver.ts +181 -0
- package/src/mixer.ts +312 -0
- package/src/motion-scope.ts +39 -6
- package/src/motion-states.ts +149 -42
- package/src/motion-value.ts +1289 -0
- package/src/native/index.ts +30 -0
- package/src/native-properties.ts +188 -0
- package/src/native-property-driver.ts +123 -0
- package/src/native-property.ts +366 -0
- package/src/particles.ts +18 -17
- package/src/path.ts +2 -1
- package/src/physics/index.ts +476 -0
- package/src/physics/native.ts +121 -0
- package/src/playback-group.ts +17 -1
- package/src/playback.ts +41 -0
- package/src/predictive-back/index.ts +280 -0
- package/src/predictive-back/presentation.ts +6 -0
- package/src/press.ts +10 -2
- package/src/reorder/handle.ts +9 -0
- package/src/reorder/index.ts +243 -0
- package/src/reorder/list-view.ts +262 -0
- package/src/reorder/model.ts +47 -0
- package/src/reorder/surface.ts +10 -0
- package/src/reorder/types.ts +87 -0
- package/src/sampling.ts +173 -0
- package/src/scene-appearance.ts +92 -0
- package/src/scene-camera.ts +30 -0
- package/src/scene-shader.ts +139 -0
- package/src/scroll-header/geometry.ts +88 -0
- package/src/scroll-header/index.ts +530 -0
- package/src/scroll-header/native.ts +89 -0
- package/src/sensors/index.ts +246 -0
- package/src/sensors/native.ts +72 -0
- package/src/sequence.ts +209 -20
- package/src/shapes/android.ts +63 -0
- package/src/shapes/index.ts +267 -0
- package/src/shapes/ios.ts +194 -0
- package/src/shapes/native.ts +27 -0
- package/src/shapes/path.ts +127 -0
- package/src/shapes/types.ts +63 -0
- package/src/shared-layout/index.ts +343 -0
- package/src/shared-layout/native.ts +138 -0
- package/src/shared-layout/timing.ts +87 -0
- package/src/shared-navigation/entry.ts +695 -0
- package/src/shared-navigation/index.ts +414 -0
- package/src/shared-navigation/return-signal.ts +41 -0
- package/src/shared-navigation/return-target.ts +197 -0
- package/src/shared-navigation/scope.ts +3 -0
- package/src/shared-navigation/targets.ts +38 -0
- package/src/size-layout.ts +237 -0
- package/src/size.ts +302 -0
- package/src/spring.ts +18 -0
- package/src/svg-path.ts +8 -3
- package/src/testing/clock.ts +128 -0
- package/src/testing/handoff-recorder.ts +98 -0
- package/src/testing/index.ts +4 -0
- package/src/testing/native.ts +386 -0
- package/src/testing/presentation.ts +46 -0
- package/src/testing/replay.ts +149 -0
- package/src/testing/scroll-handoff-native.ts +201 -0
- package/src/testing/scroll-handoff.ts +140 -0
- package/src/testing/sensors.ts +41 -0
- package/src/testing/trace.ts +340 -0
- package/src/timed-animation.ts +192 -0
- package/src/track.ts +334 -38
- package/src/transition.ts +197 -9
- package/src/types.ts +11 -1
- package/src/value-observers.ts +147 -0
- package/src/value-track.ts +71 -0
- package/src/vue/index.ts +147 -1
- package/src/zoomable.ts +1 -1
package/src/particles.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Application, Color, isIOS, type View } from '@nativescript/core'
|
|
1
|
+
import { Application, Color, isAndroid, isIOS, type View } from '@nativescript/core'
|
|
2
2
|
import { toView } from './animate.js'
|
|
3
3
|
import type { Target } from './types.js'
|
|
4
|
-
import { reducedMotion } from './config.js'
|
|
4
|
+
import { onReducedMotion, reducedMotion } from './config.js'
|
|
5
|
+
import { androidParticles } from './driver/android-particles.js'
|
|
5
6
|
|
|
6
7
|
export interface ConfettiOptions {
|
|
7
8
|
/** Approximate number of particles in the burst. Defaults to 80. */
|
|
@@ -38,7 +39,10 @@ export interface ParticleOptions {
|
|
|
38
39
|
duration?: number
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
type
|
|
42
|
+
export type ParticleSettings = Required<Omit<ParticleOptions, 'duration'>> & {
|
|
43
|
+
duration?: number
|
|
44
|
+
}
|
|
45
|
+
type Settings = ParticleSettings
|
|
42
46
|
const bursts = new WeakMap<View, () => void>()
|
|
43
47
|
const emitters = new WeakMap<View, () => void>()
|
|
44
48
|
const palette = ['#facc15', '#ef4444', '#3b82f6', '#22c55e', '#a855f7']
|
|
@@ -46,7 +50,7 @@ const textures = new Map<Settings['shape'], UIImage>()
|
|
|
46
50
|
const radians = (degrees: number) => (degrees * Math.PI) / 180
|
|
47
51
|
const BURST_DURATION = 200
|
|
48
52
|
|
|
49
|
-
/** Bursts from the target's center into its window.
|
|
53
|
+
/** Bursts from the target's center into its window. Returns immediate cleanup. */
|
|
50
54
|
export function confetti(target: Target, options: ConfettiOptions = {}): () => void {
|
|
51
55
|
const count = number('count', options.count ?? 80, 0, 10000)
|
|
52
56
|
if (!Number.isInteger(count)) throw new RangeError('Particle count must be an integer.')
|
|
@@ -70,7 +74,7 @@ export function confetti(target: Target, options: ConfettiOptions = {}): () => v
|
|
|
70
74
|
return start(target, settings, true)
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
/** Adds a native particle emitter to the target.
|
|
77
|
+
/** Adds a native particle emitter to the target. Returns immediate cleanup. */
|
|
74
78
|
export function particles(target: Target, options: ParticleOptions = {}): () => void {
|
|
75
79
|
return start(target, resolve(options), false)
|
|
76
80
|
}
|
|
@@ -79,7 +83,9 @@ function start(target: Target, settings: Settings, overlay: boolean): () => void
|
|
|
79
83
|
const view = toView(target)
|
|
80
84
|
const running = overlay ? bursts : emitters
|
|
81
85
|
running.get(view)?.()
|
|
82
|
-
if (
|
|
86
|
+
if (settings.rate === 0 || reducedMotion()) return () => {}
|
|
87
|
+
if (isAndroid) return androidParticles(view, settings, overlay, running)
|
|
88
|
+
if (!isIOS) return () => {}
|
|
83
89
|
return new Emitter(view, settings, overlay, running).stop
|
|
84
90
|
}
|
|
85
91
|
|
|
@@ -141,7 +147,7 @@ class Emitter {
|
|
|
141
147
|
private native: UIView | undefined
|
|
142
148
|
private window: UIWindow | undefined
|
|
143
149
|
private timer: ReturnType<typeof setTimeout> | undefined
|
|
144
|
-
private
|
|
150
|
+
private unwatch: (() => void) | undefined
|
|
145
151
|
|
|
146
152
|
constructor(
|
|
147
153
|
private readonly view: View,
|
|
@@ -153,6 +159,8 @@ class Emitter {
|
|
|
153
159
|
view.on('loaded', this.schedule)
|
|
154
160
|
view.on('layoutChanged', this.schedule)
|
|
155
161
|
view.on('unloaded', this.stop)
|
|
162
|
+
Application.on(Application.suspendEvent, this.stop)
|
|
163
|
+
this.unwatch = onReducedMotion(this.motionChanged)
|
|
156
164
|
this.schedule()
|
|
157
165
|
}
|
|
158
166
|
|
|
@@ -162,17 +170,14 @@ class Emitter {
|
|
|
162
170
|
this.view.off('loaded', this.schedule)
|
|
163
171
|
this.view.off('layoutChanged', this.schedule)
|
|
164
172
|
this.view.off('unloaded', this.stop)
|
|
173
|
+
Application.off(Application.suspendEvent, this.stop)
|
|
165
174
|
if (this.running.get(this.view) === this.stop) this.running.delete(this.view)
|
|
166
175
|
if (this.timer !== undefined) clearTimeout(this.timer)
|
|
167
|
-
|
|
168
|
-
Application.ios.removeNotificationObserver(
|
|
169
|
-
this.observer,
|
|
170
|
-
UIAccessibilityReduceMotionStatusDidChangeNotification,
|
|
171
|
-
)
|
|
176
|
+
this.unwatch?.()
|
|
172
177
|
this.layer?.removeAllAnimations()
|
|
173
178
|
this.layer?.removeFromSuperlayer()
|
|
174
179
|
this.layer = this.native = this.window = undefined
|
|
175
|
-
this.timer = this.
|
|
180
|
+
this.timer = this.unwatch = undefined
|
|
176
181
|
}
|
|
177
182
|
|
|
178
183
|
private schedule = () => {
|
|
@@ -232,10 +237,6 @@ class Emitter {
|
|
|
232
237
|
),
|
|
233
238
|
window,
|
|
234
239
|
)
|
|
235
|
-
this.observer = Application.ios.addNotificationObserver(
|
|
236
|
-
UIAccessibilityReduceMotionStatusDidChangeNotification,
|
|
237
|
-
this.motionChanged,
|
|
238
|
-
)
|
|
239
240
|
if (this.settings.duration !== undefined) {
|
|
240
241
|
// The render server stops emission even if JS is blocked. The timer
|
|
241
242
|
// only removes the empty layer after the last particles have expired.
|
package/src/path.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { parsePath, type MotionPath } from './svg-path.js'
|
|
|
2
2
|
import { reducedMotion, timeScale } from './config.js'
|
|
3
3
|
import { createTrack, instantTrack, type Track } from './track.js'
|
|
4
4
|
import {
|
|
5
|
+
fitTransition,
|
|
5
6
|
mergeTransitions,
|
|
6
7
|
resolveTransition,
|
|
7
8
|
type Transition,
|
|
@@ -37,7 +38,7 @@ export function preparePath(
|
|
|
37
38
|
const geometry = parsePath(keyframes.path)
|
|
38
39
|
const orient = keyframes.orient === true
|
|
39
40
|
const transition = resolveTransition(
|
|
40
|
-
overrides.path ? mergeTransitions(base, overrides.path) : base,
|
|
41
|
+
fitTransition(overrides.path ? mergeTransitions(base, overrides.path) : base, 2),
|
|
41
42
|
'opacity',
|
|
42
43
|
2,
|
|
43
44
|
)
|
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
import { Application, type View } from '@nativescript/core'
|
|
2
|
+
import { toView } from '../animate.js'
|
|
3
|
+
import { onReducedMotion, reducedMotion } from '../config.js'
|
|
4
|
+
import type { MotionScope } from '../motion-scope.js'
|
|
5
|
+
import type { Target } from '../types.js'
|
|
6
|
+
import { createCircleDriver, type CircleDriver } from './native.js'
|
|
7
|
+
|
|
8
|
+
export interface PhysicsVector {
|
|
9
|
+
x: number
|
|
10
|
+
y: number
|
|
11
|
+
}
|
|
12
|
+
export interface PhysicsAttachment {
|
|
13
|
+
/** Anchor in container-local DIPs. Scales proportionally when the board resizes. */
|
|
14
|
+
anchor: PhysicsVector
|
|
15
|
+
/** Rest length in DIPs; remains fixed on resize. Default 0. */
|
|
16
|
+
length?: number
|
|
17
|
+
/** Spring force per DIP, 1–1000; default 180. */
|
|
18
|
+
stiffness?: number
|
|
19
|
+
/** Viscous damping, 0–120; default 24. */
|
|
20
|
+
damping?: number
|
|
21
|
+
/** Optional native line, drawn from the anchor to the circle edge. */
|
|
22
|
+
line?: { color: string; width?: number }
|
|
23
|
+
}
|
|
24
|
+
export interface PhysicsSnap {
|
|
25
|
+
/** 1–8 distinct circle centers. Selected natively on release; no initial selection. */
|
|
26
|
+
points: readonly PhysicsVector[]
|
|
27
|
+
stiffness?: number
|
|
28
|
+
damping?: number
|
|
29
|
+
/** Seconds of release-velocity projection for choosing a point, 0–.3; default .12. */
|
|
30
|
+
projection?: number
|
|
31
|
+
}
|
|
32
|
+
export interface PhysicsSpringDrag {
|
|
33
|
+
type: 'spring'
|
|
34
|
+
/** Temporary pointer spring rest length in DIPs, 0–10000; default 0. */
|
|
35
|
+
length?: number
|
|
36
|
+
/** Spring force per DIP, 1–1000; default 180. */
|
|
37
|
+
stiffness?: number
|
|
38
|
+
/** Viscous damping, 0–120; default 24. */
|
|
39
|
+
damping?: number
|
|
40
|
+
/** Optional native tether, visible only during the gesture. */
|
|
41
|
+
line?: { color: string; width?: number }
|
|
42
|
+
}
|
|
43
|
+
export interface CircleBody {
|
|
44
|
+
id: string
|
|
45
|
+
/** A dedicated, square direct child of the container, sized to radius * 2. */
|
|
46
|
+
view: Target
|
|
47
|
+
radius: number
|
|
48
|
+
/** Initial center in container-local DIPs, x right, y down. */
|
|
49
|
+
x: number
|
|
50
|
+
y: number
|
|
51
|
+
mass?: number
|
|
52
|
+
/** DIPs per second; maximum speed 1200. */
|
|
53
|
+
velocity?: PhysicsVector
|
|
54
|
+
attachment?: PhysicsAttachment
|
|
55
|
+
snap?: PhysicsSnap
|
|
56
|
+
/** Direct dragging by default. A spring drag keeps the body dynamic during contact. */
|
|
57
|
+
drag?: 'direct' | PhysicsSpringDrag
|
|
58
|
+
}
|
|
59
|
+
export interface PhysicsOptions {
|
|
60
|
+
/** DIPs/s². Defaults to { x: 0, y: 750 }. */
|
|
61
|
+
gravity?: PhysicsVector
|
|
62
|
+
/** 0–1. Contacts slower than 40 DIPs/s settle without bouncing. Default .65. */
|
|
63
|
+
restitution?: number
|
|
64
|
+
/** Exponential velocity damping per second, 0–20. Default .5. */
|
|
65
|
+
damping?: number
|
|
66
|
+
reducedMotion?: 'pause' | 'continue'
|
|
67
|
+
scope?: MotionScope
|
|
68
|
+
}
|
|
69
|
+
export interface PhysicsSnapshot {
|
|
70
|
+
status: 'running' | 'sleeping' | 'paused' | 'detached' | 'invalid-bounds' | 'disposed'
|
|
71
|
+
bodies: {
|
|
72
|
+
id: string
|
|
73
|
+
x: number
|
|
74
|
+
y: number
|
|
75
|
+
vx: number
|
|
76
|
+
vy: number
|
|
77
|
+
radius: number
|
|
78
|
+
held: boolean
|
|
79
|
+
/** Temporary center target: pointer plus the initial center-to-contact offset, in local DIPs. */
|
|
80
|
+
pointer: {
|
|
81
|
+
anchor: PhysicsVector
|
|
82
|
+
length: number
|
|
83
|
+
stiffness: number
|
|
84
|
+
damping: number
|
|
85
|
+
} | null
|
|
86
|
+
/** Last native release, before snap selection or subsequent integration. */
|
|
87
|
+
release: { x: number; y: number; vx: number; vy: number } | null
|
|
88
|
+
attachment: {
|
|
89
|
+
anchor: PhysicsVector
|
|
90
|
+
length: number
|
|
91
|
+
stiffness: number
|
|
92
|
+
damping: number
|
|
93
|
+
} | null
|
|
94
|
+
snap: { index: number; point: PhysicsVector; settled: boolean } | null
|
|
95
|
+
}[]
|
|
96
|
+
frames: number
|
|
97
|
+
steps: number
|
|
98
|
+
contacts: number
|
|
99
|
+
dragStarts: number
|
|
100
|
+
dragMoves: number
|
|
101
|
+
dragEnds: number
|
|
102
|
+
dragCancels: number
|
|
103
|
+
processingMs: number
|
|
104
|
+
/** Time discarded after UI stalls; the world never catches up without a bound. */
|
|
105
|
+
droppedMs: number
|
|
106
|
+
clock: boolean
|
|
107
|
+
/** Native tether drawing resources retained by this world. */
|
|
108
|
+
guides: number
|
|
109
|
+
}
|
|
110
|
+
export interface PhysicsWorld {
|
|
111
|
+
readonly disposed: boolean
|
|
112
|
+
readonly paused: boolean
|
|
113
|
+
pause(): void
|
|
114
|
+
play(): void
|
|
115
|
+
/** Restore the initial arrangement, scaled to the current container bounds. */
|
|
116
|
+
reset(): void
|
|
117
|
+
/** Mass × DIPs/s. Ignored while paused, detached, reduced or being dragged. */
|
|
118
|
+
impulse(id: string, impulse: PhysicsVector): void
|
|
119
|
+
/** Replace/remove the anchor spring without resetting velocity. Clears the selected snap. */
|
|
120
|
+
attach(id: string, attachment: PhysicsAttachment | null): void
|
|
121
|
+
/** Choose a configured snap point, including while paused. Ignored during an active drag. */
|
|
122
|
+
snapTo(id: string, index: number): void
|
|
123
|
+
/** On-demand diagnostics; never installs a JS frame observer. */
|
|
124
|
+
snapshot(): PhysicsSnapshot
|
|
125
|
+
dispose(): void
|
|
126
|
+
}
|
|
127
|
+
const owners = new WeakSet<View>()
|
|
128
|
+
function number(value: number, name: string, min: number, max: number) {
|
|
129
|
+
if (!Number.isFinite(value) || value < min || value > max)
|
|
130
|
+
throw new RangeError(`${name} must be finite and within ${min}–${max}.`)
|
|
131
|
+
return value
|
|
132
|
+
}
|
|
133
|
+
function vector(value: PhysicsVector, name: string, limit: number): PhysicsVector {
|
|
134
|
+
if (!value || typeof value !== 'object') throw new TypeError(`Expected ${name} vector.`)
|
|
135
|
+
return {
|
|
136
|
+
x: number(value.x, `${name}.x`, -limit, limit),
|
|
137
|
+
y: number(value.y, `${name}.y`, -limit, limit),
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function point(
|
|
141
|
+
value: PhysicsVector,
|
|
142
|
+
name: string,
|
|
143
|
+
width: number,
|
|
144
|
+
height: number,
|
|
145
|
+
inset = 0,
|
|
146
|
+
) {
|
|
147
|
+
if (!value || typeof value !== 'object') throw new TypeError(`Expected ${name} point.`)
|
|
148
|
+
return {
|
|
149
|
+
x: number(value.x, `${name}.x`, inset, width - inset),
|
|
150
|
+
y: number(value.y, `${name}.y`, inset, height - inset),
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function prepareAttachment(
|
|
154
|
+
value: PhysicsAttachment | null,
|
|
155
|
+
width: number,
|
|
156
|
+
height: number,
|
|
157
|
+
) {
|
|
158
|
+
if (value === null) return null
|
|
159
|
+
if (!value || typeof value !== 'object')
|
|
160
|
+
throw new TypeError('Expected attachment options or null.')
|
|
161
|
+
const anchor = point(value.anchor, 'anchor', width, height)
|
|
162
|
+
const stiffness = number(value.stiffness ?? 180, 'attachment.stiffness', 1, 1000)
|
|
163
|
+
const damping = number(value.damping ?? 24, 'attachment.damping', 0, 120)
|
|
164
|
+
const length = number(value.length ?? 0, 'attachment.length', 0, 10000)
|
|
165
|
+
let line: { color: number; width: number } | null = null
|
|
166
|
+
if (value.line !== undefined) {
|
|
167
|
+
if (
|
|
168
|
+
!value.line ||
|
|
169
|
+
typeof value.line.color !== 'string' ||
|
|
170
|
+
!/^#[0-9a-f]{6}$/i.test(value.line.color)
|
|
171
|
+
)
|
|
172
|
+
throw new TypeError('Attachment line color must be #RRGGBB.')
|
|
173
|
+
line = {
|
|
174
|
+
color: parseInt(value.line.color.slice(1), 16),
|
|
175
|
+
width: number(value.line.width ?? 1.5, 'attachment.line.width', 0.5, 6),
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return { x: anchor.x, y: anchor.y, length, stiffness, damping, line }
|
|
179
|
+
}
|
|
180
|
+
function prepareSnap(
|
|
181
|
+
value: PhysicsSnap | undefined,
|
|
182
|
+
width: number,
|
|
183
|
+
height: number,
|
|
184
|
+
radius: number,
|
|
185
|
+
) {
|
|
186
|
+
if (value === undefined) return null
|
|
187
|
+
if (
|
|
188
|
+
!value ||
|
|
189
|
+
!Array.isArray(value.points) ||
|
|
190
|
+
value.points.length < 1 ||
|
|
191
|
+
value.points.length > 8
|
|
192
|
+
)
|
|
193
|
+
throw new RangeError('Snap needs 1–8 distinct points.')
|
|
194
|
+
const points = Array.from(value.points, (p) =>
|
|
195
|
+
point(p, 'snap point', width, height, radius),
|
|
196
|
+
)
|
|
197
|
+
if (new Set(points.map((p) => `${p.x},${p.y}`)).size !== points.length)
|
|
198
|
+
throw new RangeError('Snap points must be distinct.')
|
|
199
|
+
return {
|
|
200
|
+
points,
|
|
201
|
+
stiffness: number(value.stiffness ?? 180, 'snap.stiffness', 1, 1000),
|
|
202
|
+
damping: number(value.damping ?? 24, 'snap.damping', 0, 120),
|
|
203
|
+
projection: number(value.projection ?? 0.12, 'snap.projection', 0, 0.3),
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function prepareDrag(value: CircleBody['drag'], width: number, height: number) {
|
|
207
|
+
if (value === undefined || value === 'direct') return null
|
|
208
|
+
if (!value || typeof value !== 'object' || value.type !== 'spring')
|
|
209
|
+
throw new TypeError('Expected direct dragging or a spring drag configuration.')
|
|
210
|
+
// Share the validated spring ranges and line style; the pointer supplies the anchor natively.
|
|
211
|
+
const {
|
|
212
|
+
x: _x,
|
|
213
|
+
y: _y,
|
|
214
|
+
...spring
|
|
215
|
+
} = prepareAttachment({ ...value, anchor: { x: 0, y: 0 } }, width, height)!
|
|
216
|
+
return spring
|
|
217
|
+
}
|
|
218
|
+
function untransformed(view: View) {
|
|
219
|
+
return (
|
|
220
|
+
(view.translateX ?? 0) === 0 &&
|
|
221
|
+
(view.translateY ?? 0) === 0 &&
|
|
222
|
+
(view.rotate ?? 0) === 0 &&
|
|
223
|
+
(view.rotateX ?? 0) === 0 &&
|
|
224
|
+
(view.rotateY ?? 0) === 0 &&
|
|
225
|
+
(view.scaleX ?? 1) === 1 &&
|
|
226
|
+
(view.scaleY ?? 1) === 1
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
/** Native, circle-only physics for 1–16 dedicated views. Create after layout. */
|
|
230
|
+
export function physicsWorld(
|
|
231
|
+
target: Target,
|
|
232
|
+
bodies: readonly CircleBody[],
|
|
233
|
+
options: PhysicsOptions = {},
|
|
234
|
+
): PhysicsWorld {
|
|
235
|
+
let host: View | undefined = toView(target)
|
|
236
|
+
if (!Array.isArray(bodies) || bodies.length < 1 || bodies.length > 16)
|
|
237
|
+
throw new RangeError('Physics needs 1–16 circles.')
|
|
238
|
+
if (!options || typeof options !== 'object')
|
|
239
|
+
throw new TypeError('Expected physics options.')
|
|
240
|
+
if (options.scope?.disposed || options.scope?.suspended)
|
|
241
|
+
throw new Error('Physics scope must be active.')
|
|
242
|
+
const policy = options.reducedMotion ?? 'pause'
|
|
243
|
+
if (policy !== 'pause' && policy !== 'continue')
|
|
244
|
+
throw new TypeError('Invalid physics reduced-motion policy.')
|
|
245
|
+
const gravity = vector(options.gravity ?? { x: 0, y: 750 }, 'gravity', 2000)
|
|
246
|
+
const restitution = number(options.restitution ?? 0.65, 'restitution', 0, 1)
|
|
247
|
+
const damping = number(options.damping ?? 0.5, 'damping', 0, 20)
|
|
248
|
+
const { width, height } = host.getActualSize()
|
|
249
|
+
number(width, 'Container width', 1, 10000)
|
|
250
|
+
number(height, 'Container height', 1, 10000)
|
|
251
|
+
for (
|
|
252
|
+
let parent: View | undefined = host;
|
|
253
|
+
parent;
|
|
254
|
+
parent = parent.parent as View | undefined
|
|
255
|
+
)
|
|
256
|
+
if (!untransformed(parent))
|
|
257
|
+
throw new Error('Physics requires an untransformed container and ancestors.')
|
|
258
|
+
const ids: string[] = [],
|
|
259
|
+
unique = new Set<View>()
|
|
260
|
+
let views: View[] = []
|
|
261
|
+
const config = Array.from(bodies, (body) => {
|
|
262
|
+
if (!body || typeof body.id !== 'string' || !body.id.trim() || ids.includes(body.id))
|
|
263
|
+
throw new TypeError('Each circle needs a unique, nonempty id.')
|
|
264
|
+
ids.push(body.id)
|
|
265
|
+
const view = toView(body.view)
|
|
266
|
+
if (view.parent !== host || unique.has(view) || !untransformed(view))
|
|
267
|
+
throw new Error('Use distinct, untransformed direct children for physics circles.')
|
|
268
|
+
if (owners.has(view) || owners.has(host!))
|
|
269
|
+
throw new Error('Physics view already has an owner.')
|
|
270
|
+
if (!view.isLoaded || !view.nativeViewProtected)
|
|
271
|
+
throw new Error('Create physics after native layout.')
|
|
272
|
+
if (!view.isEnabled || view.isUserInteractionEnabled === false)
|
|
273
|
+
throw new Error('Physics circles must accept touch input.')
|
|
274
|
+
// Physics owns native input. A tap/drag/etc listener would compete with the native recognizer.
|
|
275
|
+
for (const gesture of [1, 2, 4, 8, 16, 32, 64, 128])
|
|
276
|
+
if (view.getGestureObservers?.(gesture)?.length)
|
|
277
|
+
throw new Error('Physics circles require exclusive native touch input.')
|
|
278
|
+
const radius = number(body.radius, 'radius', 12, 256),
|
|
279
|
+
mass = number(body.mass ?? 1, 'mass', 0.1, 100)
|
|
280
|
+
const size = view.getActualSize()
|
|
281
|
+
if (Math.abs(size.width - radius * 2) > 1 || Math.abs(size.height - radius * 2) > 1)
|
|
282
|
+
throw new Error('Circle views must be square and sized to twice their radius.')
|
|
283
|
+
const x = number(body.x, 'x', radius, width - radius),
|
|
284
|
+
y = number(body.y, 'y', radius, height - radius)
|
|
285
|
+
const velocity = vector(body.velocity ?? { x: 0, y: 0 }, 'velocity', 1200)
|
|
286
|
+
if (Math.hypot(velocity.x, velocity.y) > 1200)
|
|
287
|
+
throw new RangeError('Circle speed cannot exceed 1200 DIPs/s.')
|
|
288
|
+
views.push(view)
|
|
289
|
+
unique.add(view)
|
|
290
|
+
return {
|
|
291
|
+
x,
|
|
292
|
+
y,
|
|
293
|
+
radius,
|
|
294
|
+
mass,
|
|
295
|
+
vx: velocity.x,
|
|
296
|
+
vy: velocity.y,
|
|
297
|
+
attachment: prepareAttachment(body.attachment ?? null, width, height),
|
|
298
|
+
snap: prepareSnap(body.snap, width, height, radius),
|
|
299
|
+
drag: prepareDrag(body.drag, width, height),
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
if (!host.isLoaded || !host.nativeViewProtected)
|
|
303
|
+
throw new Error('Create physics after native layout.')
|
|
304
|
+
if (
|
|
305
|
+
config.reduce((area, b) => area + Math.PI * b.radius ** 2, 0) >
|
|
306
|
+
width * height * 0.4
|
|
307
|
+
)
|
|
308
|
+
throw new RangeError('Circles may occupy at most 40% of the container area.')
|
|
309
|
+
config.forEach((a, i) =>
|
|
310
|
+
config.slice(i + 1).forEach((b) => {
|
|
311
|
+
if (Math.hypot(a.x - b.x, a.y - b.y) < a.radius + b.radius)
|
|
312
|
+
throw new RangeError('Initial circles must not overlap.')
|
|
313
|
+
}),
|
|
314
|
+
)
|
|
315
|
+
let native: CircleDriver | undefined,
|
|
316
|
+
ended = false,
|
|
317
|
+
held = false,
|
|
318
|
+
background = false
|
|
319
|
+
let worldRef: PhysicsWorld | undefined
|
|
320
|
+
const originalNative = new Map([host, ...views].map((v) => [v, v.nativeViewProtected]))
|
|
321
|
+
const releases: (() => void)[] = [],
|
|
322
|
+
unloaded = new Set<View>()
|
|
323
|
+
const update = () => {
|
|
324
|
+
if (ended || !host || !native) return
|
|
325
|
+
if (
|
|
326
|
+
[host, ...views].some(
|
|
327
|
+
(v) => v.nativeViewProtected && v.nativeViewProtected !== originalNative.get(v),
|
|
328
|
+
)
|
|
329
|
+
) {
|
|
330
|
+
// A rebuilt native hierarchy needs fresh recognizers and original-state captures.
|
|
331
|
+
worldRef?.dispose()
|
|
332
|
+
return
|
|
333
|
+
}
|
|
334
|
+
native.resize(host.getActualSize().width, host.getActualSize().height)
|
|
335
|
+
native.enabled(
|
|
336
|
+
!held &&
|
|
337
|
+
!background &&
|
|
338
|
+
!unloaded.size &&
|
|
339
|
+
(policy === 'continue' || !reducedMotion()) &&
|
|
340
|
+
views.every((v) => v.parent === host && v.isLoaded && !!v.nativeViewProtected),
|
|
341
|
+
)
|
|
342
|
+
}
|
|
343
|
+
const suspend = () => {
|
|
344
|
+
background = true
|
|
345
|
+
update()
|
|
346
|
+
},
|
|
347
|
+
resume = () => {
|
|
348
|
+
background = false
|
|
349
|
+
update()
|
|
350
|
+
}
|
|
351
|
+
const cleanup = () => {
|
|
352
|
+
releases.splice(0).forEach((fn) => fn())
|
|
353
|
+
views.forEach((v) => owners.delete(v))
|
|
354
|
+
if (host) owners.delete(host)
|
|
355
|
+
views = []
|
|
356
|
+
host = undefined
|
|
357
|
+
unloaded.clear()
|
|
358
|
+
originalNative.clear()
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
native = createCircleDriver(host, views, {
|
|
362
|
+
width,
|
|
363
|
+
height,
|
|
364
|
+
gravity,
|
|
365
|
+
restitution,
|
|
366
|
+
damping,
|
|
367
|
+
bodies: config,
|
|
368
|
+
})
|
|
369
|
+
;[host, ...views].forEach((v) => {
|
|
370
|
+
owners.add(v)
|
|
371
|
+
const loaded = () => {
|
|
372
|
+
unloaded.delete(v)
|
|
373
|
+
update()
|
|
374
|
+
},
|
|
375
|
+
unload = () => {
|
|
376
|
+
unloaded.add(v)
|
|
377
|
+
update()
|
|
378
|
+
}
|
|
379
|
+
v.on('loaded', loaded)
|
|
380
|
+
v.on('unloaded', unload)
|
|
381
|
+
v.on('layoutChanged', update)
|
|
382
|
+
releases.push(() => {
|
|
383
|
+
v.off('loaded', loaded)
|
|
384
|
+
v.off('unloaded', unload)
|
|
385
|
+
v.off('layoutChanged', update)
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
Application.on(Application.suspendEvent, suspend)
|
|
389
|
+
Application.on(Application.resumeEvent, resume)
|
|
390
|
+
releases.push(() => {
|
|
391
|
+
Application.off(Application.suspendEvent, suspend)
|
|
392
|
+
Application.off(Application.resumeEvent, resume)
|
|
393
|
+
}, onReducedMotion(update))
|
|
394
|
+
const world: PhysicsWorld = {
|
|
395
|
+
get disposed() {
|
|
396
|
+
return ended
|
|
397
|
+
},
|
|
398
|
+
get paused() {
|
|
399
|
+
return held
|
|
400
|
+
},
|
|
401
|
+
pause() {
|
|
402
|
+
if (!ended) {
|
|
403
|
+
held = true
|
|
404
|
+
update()
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
play() {
|
|
408
|
+
if (!ended) {
|
|
409
|
+
held = false
|
|
410
|
+
update()
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
reset() {
|
|
414
|
+
if (!ended) native!.reset()
|
|
415
|
+
},
|
|
416
|
+
impulse(id, impulse) {
|
|
417
|
+
const index = ids.indexOf(id)
|
|
418
|
+
if (index < 0) throw new RangeError(`Unknown circle: ${id}`)
|
|
419
|
+
const v = vector(impulse, 'impulse', 120000)
|
|
420
|
+
if (!ended) native!.impulse(index, v.x, v.y)
|
|
421
|
+
},
|
|
422
|
+
attach(id, attachment) {
|
|
423
|
+
const index = ids.indexOf(id)
|
|
424
|
+
if (index < 0) throw new RangeError(`Unknown circle: ${id}`)
|
|
425
|
+
if (ended) return
|
|
426
|
+
const size = host!.getActualSize()
|
|
427
|
+
number(size.width, 'Container width', 1, 10000)
|
|
428
|
+
number(size.height, 'Container height', 1, 10000)
|
|
429
|
+
if (
|
|
430
|
+
config.some((b) => 2 * b.radius > Math.min(size.width, size.height)) ||
|
|
431
|
+
config.reduce((a, b) => a + Math.PI * b.radius ** 2, 0) >
|
|
432
|
+
size.width * size.height * 0.4
|
|
433
|
+
)
|
|
434
|
+
throw new RangeError(
|
|
435
|
+
'Resize the container to fit its circles before updating an attachment.',
|
|
436
|
+
)
|
|
437
|
+
const prepared = prepareAttachment(attachment, size.width, size.height)
|
|
438
|
+
update()
|
|
439
|
+
if (!ended) native!.attach(index, prepared)
|
|
440
|
+
},
|
|
441
|
+
snapTo(id, index) {
|
|
442
|
+
const body = ids.indexOf(id)
|
|
443
|
+
if (body < 0) throw new RangeError(`Unknown circle: ${id}`)
|
|
444
|
+
const count = config[body]!.snap?.points.length ?? 0
|
|
445
|
+
if (!Number.isInteger(index) || index < 0 || index >= count)
|
|
446
|
+
throw new RangeError('Unknown snap point.')
|
|
447
|
+
if (!ended) native!.snapTo(body, index)
|
|
448
|
+
},
|
|
449
|
+
snapshot() {
|
|
450
|
+
const result = native!.snapshot()
|
|
451
|
+
return { ...result, bodies: result.bodies.map((b, i) => ({ ...b, id: ids[i]! })) }
|
|
452
|
+
},
|
|
453
|
+
dispose() {
|
|
454
|
+
if (ended) return
|
|
455
|
+
ended = true
|
|
456
|
+
try {
|
|
457
|
+
native!.dispose()
|
|
458
|
+
} finally {
|
|
459
|
+
cleanup()
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
}
|
|
463
|
+
worldRef = world
|
|
464
|
+
options.scope?.add(world)
|
|
465
|
+
update()
|
|
466
|
+
return world
|
|
467
|
+
} catch (error) {
|
|
468
|
+
ended = true
|
|
469
|
+
try {
|
|
470
|
+
native?.dispose()
|
|
471
|
+
} finally {
|
|
472
|
+
cleanup()
|
|
473
|
+
}
|
|
474
|
+
throw error
|
|
475
|
+
}
|
|
476
|
+
}
|