@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/gradient.ts
ADDED
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
import { Application, Trace, isAndroid, isIOS, type View } from '@nativescript/core'
|
|
2
|
+
import { toView } from './animate.js'
|
|
3
|
+
import { colorMixer, parseColor, type ColorValue } from './color.js'
|
|
4
|
+
import { reducedMotion } from './config.js'
|
|
5
|
+
import { getDriver } from './driver/index.js'
|
|
6
|
+
import { androidGradient } from './driver/android-gradient.js'
|
|
7
|
+
import { iosGradient } from './driver/ios-gradient.js'
|
|
8
|
+
import type { Animation } from './engine.js'
|
|
9
|
+
import { createTrack, type Track } from './track.js'
|
|
10
|
+
import {
|
|
11
|
+
resolveTransition,
|
|
12
|
+
springs,
|
|
13
|
+
type SpringName,
|
|
14
|
+
type Transition,
|
|
15
|
+
} from './transition.js'
|
|
16
|
+
import type { Target } from './types.js'
|
|
17
|
+
import { createClock, type PlaybackClock } from './playback.js'
|
|
18
|
+
import {
|
|
19
|
+
cloneFrame,
|
|
20
|
+
gradientPatch,
|
|
21
|
+
gradientProgram,
|
|
22
|
+
put,
|
|
23
|
+
take,
|
|
24
|
+
type GradientBindings,
|
|
25
|
+
type GradientComponent,
|
|
26
|
+
type GradientPatch,
|
|
27
|
+
type GradientSource,
|
|
28
|
+
} from './gradient-binding.js'
|
|
29
|
+
export type { GradientBindings } from './gradient-binding.js'
|
|
30
|
+
|
|
31
|
+
export type GradientType = 'linear' | 'radial' | 'conic'
|
|
32
|
+
|
|
33
|
+
export interface GradientValues {
|
|
34
|
+
/** Two to eight colors. Animating keeps the count. */
|
|
35
|
+
colors?: readonly ColorValue[]
|
|
36
|
+
/** Where each color sits, from 0 to 1. Evenly spaced by default. */
|
|
37
|
+
stops?: readonly number[]
|
|
38
|
+
/** Degrees, like CSS: `linear` points this way (180 runs top to bottom), `conic` starts here (0 is up). */
|
|
39
|
+
angle?: number
|
|
40
|
+
/** `radial` and `conic`: the center, in fractions of the view's width and height. */
|
|
41
|
+
center?: { readonly x: number; readonly y: number }
|
|
42
|
+
/** `radial`: the radius, in fractions of the view's shorter side. */
|
|
43
|
+
radius?: number
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface GradientOptions extends GradientBindings {
|
|
47
|
+
type: GradientType
|
|
48
|
+
colors: NonNullable<GradientBindings['colors']>
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface Gradient {
|
|
52
|
+
readonly type: GradientType
|
|
53
|
+
/** Animates to new values from the ones on screen. Colors and stops keep their count. */
|
|
54
|
+
animate(values: GradientValues, transition?: Transition | SpringName): Animation
|
|
55
|
+
/** Applies values at once, stopping the animation in progress. */
|
|
56
|
+
set(values: GradientValues): void
|
|
57
|
+
/** Holds the current frame and detaches all gradient bindings; sources keep running. */
|
|
58
|
+
stop(): void
|
|
59
|
+
/** Attach mixed static/value components. Cleanup holds their current values; newer owners survive. */
|
|
60
|
+
bind(values: GradientBindings): () => void
|
|
61
|
+
/** Whether this gradient is explicitly suspended (independent of app/view lifecycle). */
|
|
62
|
+
readonly suspended: boolean
|
|
63
|
+
/** Hold and detach source subscriptions until resume; source playback is not paused. */
|
|
64
|
+
suspend(): void
|
|
65
|
+
/** Catch up to current source positions and reattach once. */
|
|
66
|
+
resume(): void
|
|
67
|
+
/** Takes the gradient off the view. */
|
|
68
|
+
remove(): void
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Everything the platform needs to paint one frame. */
|
|
72
|
+
export interface GradientFrame {
|
|
73
|
+
colors: number[]
|
|
74
|
+
stops: number[]
|
|
75
|
+
angle: number
|
|
76
|
+
x: number
|
|
77
|
+
y: number
|
|
78
|
+
radius: number
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface GradientTiming {
|
|
82
|
+
duration: number
|
|
83
|
+
delay: number
|
|
84
|
+
repeat: number
|
|
85
|
+
reverse: boolean
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface GradientPainter {
|
|
89
|
+
paint(frame: GradientFrame): void
|
|
90
|
+
/** Plays sampled frames natively; `onEnd(false)` when cancelled. */
|
|
91
|
+
play(
|
|
92
|
+
frames: readonly GradientFrame[],
|
|
93
|
+
times: readonly number[],
|
|
94
|
+
timing: GradientTiming,
|
|
95
|
+
onEnd: (finished: boolean) => void,
|
|
96
|
+
): { cancel(): void; control?(elapsed: number, paused: boolean): void }
|
|
97
|
+
remove(): void
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
type PainterFactory = (view: View, type: GradientType) => GradientPainter | undefined
|
|
101
|
+
|
|
102
|
+
let factory: PainterFactory | undefined
|
|
103
|
+
|
|
104
|
+
/** Test seam, like `setDriver`. */
|
|
105
|
+
export function setGradientPainter(next: PainterFactory | undefined) {
|
|
106
|
+
factory = next
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function platformPainter(view: View, type: GradientType) {
|
|
110
|
+
if (isIOS) return iosGradient(view, type)
|
|
111
|
+
if (isAndroid) return androidGradient(view, type)
|
|
112
|
+
return undefined
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const types: readonly GradientType[] = ['linear', 'radial', 'conic']
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Paints a native gradient behind a layout's children and animates it.
|
|
119
|
+
*
|
|
120
|
+
* ```ts
|
|
121
|
+
* const glow = gradient(halo, { type: 'radial', colors: ['#FF0080', '#7928CA00'], radius: 0.8 })
|
|
122
|
+
* glow.animate({ center: { x: 0.8, y: 0.2 }, radius: 1.2 }, { duration: 2000 })
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export function gradient(target: Target, options: GradientOptions): Gradient {
|
|
126
|
+
const view = toView(target)
|
|
127
|
+
const { frame, patch } = prepareGradient(options)
|
|
128
|
+
return new GradientController(view, options.type, frame, patch)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Validate declarative replacements before removing their current native layer. */
|
|
132
|
+
export function prepareGradient(options: GradientOptions) {
|
|
133
|
+
if (!options || !types.includes(options.type))
|
|
134
|
+
throw new TypeError(`Gradient type must be 'linear', 'radial' or 'conic'.`)
|
|
135
|
+
if (!options.colors)
|
|
136
|
+
throw new RangeError('A gradient needs between two and eight colors.')
|
|
137
|
+
const base: GradientFrame = {
|
|
138
|
+
colors: [],
|
|
139
|
+
stops: [],
|
|
140
|
+
angle: 180,
|
|
141
|
+
x: 0.5,
|
|
142
|
+
y: 0.5,
|
|
143
|
+
radius: 0.5,
|
|
144
|
+
}
|
|
145
|
+
const patch = gradientPatch(options, 0)
|
|
146
|
+
const prepared = gradientProgram(
|
|
147
|
+
{ at: () => base, remaining: 0, elapsed: () => 0 },
|
|
148
|
+
patch,
|
|
149
|
+
)
|
|
150
|
+
return { frame: prepared.current, patch }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface GradientRun {
|
|
154
|
+
from: GradientFrame
|
|
155
|
+
to: GradientFrame
|
|
156
|
+
track: Track
|
|
157
|
+
keys: Set<GradientComponent>
|
|
158
|
+
masked: Set<GradientComponent>
|
|
159
|
+
clock: PlaybackClock
|
|
160
|
+
cancelEnd?: () => void
|
|
161
|
+
settle(finished: boolean): void
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
class GradientController implements Gradient {
|
|
165
|
+
private painter: GradientPainter | undefined
|
|
166
|
+
private player: ReturnType<GradientPainter['play']> | undefined
|
|
167
|
+
private program: ReturnType<typeof gradientProgram> | undefined
|
|
168
|
+
private model: GradientFrame
|
|
169
|
+
private removed = false
|
|
170
|
+
private _suspended = false
|
|
171
|
+
private background = false
|
|
172
|
+
private unloadedView = false
|
|
173
|
+
private running: GradientRun | undefined
|
|
174
|
+
private bindings = new Map<
|
|
175
|
+
GradientComponent,
|
|
176
|
+
{ source: GradientSource; owner: object }
|
|
177
|
+
>()
|
|
178
|
+
private releases: (() => void)[] = []
|
|
179
|
+
private cancelWindow?: () => void
|
|
180
|
+
private generation = 0
|
|
181
|
+
|
|
182
|
+
constructor(
|
|
183
|
+
private readonly view: View,
|
|
184
|
+
readonly type: GradientType,
|
|
185
|
+
frame: GradientFrame,
|
|
186
|
+
patch: GradientPatch,
|
|
187
|
+
) {
|
|
188
|
+
this.model = frame
|
|
189
|
+
const owner = {}
|
|
190
|
+
for (const [key, source] of patch)
|
|
191
|
+
if (typeof source !== 'number') this.bindings.set(key, { source, owner })
|
|
192
|
+
this.painter = (factory ?? platformPainter)(view, type)
|
|
193
|
+
view.on('unloaded', this.unloaded)
|
|
194
|
+
view.on('loaded', this.loaded)
|
|
195
|
+
view.on('layoutChanged', this.resized)
|
|
196
|
+
Application.on(Application.suspendEvent, this.appSuspended)
|
|
197
|
+
Application.on(Application.resumeEvent, this.appResumed)
|
|
198
|
+
this.subscribe()
|
|
199
|
+
this.render()
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private get inactive() {
|
|
203
|
+
return this.removed || this._suspended || this.background || this.unloadedView
|
|
204
|
+
}
|
|
205
|
+
private patch() {
|
|
206
|
+
return new Map([...this.bindings].map(([key, entry]) => [key, entry.source]))
|
|
207
|
+
}
|
|
208
|
+
private base() {
|
|
209
|
+
const run = this.running
|
|
210
|
+
const elapsed = run?.clock.time() ?? 0
|
|
211
|
+
const model = cloneFrame(this.model)
|
|
212
|
+
return {
|
|
213
|
+
remaining: run ? Math.max(0, run.track.end - elapsed) : 0,
|
|
214
|
+
elapsed: () => (run ? Math.max(0, run.clock.time() - elapsed) : 0),
|
|
215
|
+
at: (delta: number) => {
|
|
216
|
+
const frame = cloneFrame(model)
|
|
217
|
+
if (run) {
|
|
218
|
+
const sample = mix(
|
|
219
|
+
run.from,
|
|
220
|
+
run.to,
|
|
221
|
+
run.track.valueAt(elapsed + delta),
|
|
222
|
+
reducedMotion(),
|
|
223
|
+
)
|
|
224
|
+
for (const key of run.keys)
|
|
225
|
+
if (!run.masked.has(key)) put(frame, key, take(sample, key))
|
|
226
|
+
}
|
|
227
|
+
return frame
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
private presented(): GradientFrame {
|
|
232
|
+
if (this.inactive) return cloneFrame(this.model)
|
|
233
|
+
try {
|
|
234
|
+
return gradientProgram(this.base(), this.patch()).current
|
|
235
|
+
} catch {
|
|
236
|
+
return (
|
|
237
|
+
this.program?.at(Math.min(this.program.duration, this.program.elapsed())) ??
|
|
238
|
+
cloneFrame(this.model)
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
private clearPlayer() {
|
|
243
|
+
this.generation++
|
|
244
|
+
this.cancelWindow?.()
|
|
245
|
+
this.cancelWindow = undefined
|
|
246
|
+
const player = this.player
|
|
247
|
+
this.player = undefined
|
|
248
|
+
player?.cancel()
|
|
249
|
+
}
|
|
250
|
+
private unsubscribe() {
|
|
251
|
+
for (const release of this.releases) release()
|
|
252
|
+
this.releases = []
|
|
253
|
+
}
|
|
254
|
+
private subscribe() {
|
|
255
|
+
this.unsubscribe()
|
|
256
|
+
if (this.inactive) return
|
|
257
|
+
const sources = new Map<object, GradientSource>()
|
|
258
|
+
for (const { source } of this.bindings.values()) sources.set(source.identity, source)
|
|
259
|
+
this.releases = [...sources.values()].map((source) => source.subscribe(this.changed))
|
|
260
|
+
}
|
|
261
|
+
private changed = () => {
|
|
262
|
+
if (this.inactive) return
|
|
263
|
+
try {
|
|
264
|
+
this.render()
|
|
265
|
+
} catch (error) {
|
|
266
|
+
// A later invalid source must not throw through its other consumers or leave
|
|
267
|
+
// half of a compound frame painted. Hold the last compiled frame and detach.
|
|
268
|
+
this.stop()
|
|
269
|
+
Trace.write(
|
|
270
|
+
`Jolt gradient binding stopped: ${String(error)}`,
|
|
271
|
+
Trace.categories.Error,
|
|
272
|
+
Trace.messageType.error,
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
private render() {
|
|
277
|
+
if (this.inactive) return
|
|
278
|
+
const prepared = gradientProgram(this.base(), this.patch())
|
|
279
|
+
this.clearPlayer()
|
|
280
|
+
this.program = prepared
|
|
281
|
+
const painter = this.painter
|
|
282
|
+
if (!painter) return
|
|
283
|
+
const run = this.running
|
|
284
|
+
if (run && !this.bindings.size && !run.masked.size) {
|
|
285
|
+
const generation = this.generation
|
|
286
|
+
this.player = painter.play(
|
|
287
|
+
run.track.values.map((p) => mix(run.from, run.to, p, reducedMotion())),
|
|
288
|
+
run.track.times,
|
|
289
|
+
{
|
|
290
|
+
duration: run.track.duration,
|
|
291
|
+
delay: run.track.delay,
|
|
292
|
+
repeat: run.track.repeat,
|
|
293
|
+
reverse: run.track.reverse,
|
|
294
|
+
},
|
|
295
|
+
(completed) => {
|
|
296
|
+
if (generation === this.generation && this.running === run)
|
|
297
|
+
this.finish(run, completed)
|
|
298
|
+
},
|
|
299
|
+
)
|
|
300
|
+
// Concrete playback retains its existing API; bindings always use native control.
|
|
301
|
+
if (run.clock.time() > 1) this.player.control?.(run.clock.time(), false)
|
|
302
|
+
return
|
|
303
|
+
}
|
|
304
|
+
if (prepared.duration <= 0) {
|
|
305
|
+
painter.paint(prepared.current)
|
|
306
|
+
return
|
|
307
|
+
}
|
|
308
|
+
const generation = this.generation
|
|
309
|
+
this.player = painter.play(
|
|
310
|
+
prepared.frames,
|
|
311
|
+
prepared.times,
|
|
312
|
+
{ duration: prepared.duration, delay: 0, repeat: 0, reverse: false },
|
|
313
|
+
() => {},
|
|
314
|
+
)
|
|
315
|
+
this.player.control?.(prepared.elapsed(), false)
|
|
316
|
+
// Only long compound windows need a boundary callback; each source sends its
|
|
317
|
+
// own completion/control notifications. There is no observer frame subscription.
|
|
318
|
+
if (prepared.remaining > prepared.duration)
|
|
319
|
+
this.cancelWindow = getDriver().after(
|
|
320
|
+
Math.max(1, prepared.duration - prepared.elapsed()),
|
|
321
|
+
() => {
|
|
322
|
+
if (generation === this.generation) this.changed()
|
|
323
|
+
},
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
animate(values: GradientValues, transition?: Transition | SpringName): Animation {
|
|
328
|
+
this.assertActive()
|
|
329
|
+
const from = this.presented()
|
|
330
|
+
const to = resolve(from, values, true)
|
|
331
|
+
const patch = gradientPatch(values, from.colors.length)
|
|
332
|
+
const resolved =
|
|
333
|
+
typeof transition === 'string' ? springOf(transition) : (transition ?? {})
|
|
334
|
+
const track = createTrack(
|
|
335
|
+
'opacity',
|
|
336
|
+
[0, 1],
|
|
337
|
+
resolveTransition(resolved, 'opacity', 2),
|
|
338
|
+
0,
|
|
339
|
+
)
|
|
340
|
+
this.cancelRunning()
|
|
341
|
+
this.model = from
|
|
342
|
+
for (const key of patch.keys()) this.bindings.delete(key)
|
|
343
|
+
this.subscribe()
|
|
344
|
+
let settle!: (finished: boolean) => void
|
|
345
|
+
const finished = new Promise<boolean>((resolve) => {
|
|
346
|
+
settle = resolve
|
|
347
|
+
})
|
|
348
|
+
const driver = getDriver()
|
|
349
|
+
const run: GradientRun = {
|
|
350
|
+
from,
|
|
351
|
+
to,
|
|
352
|
+
track,
|
|
353
|
+
keys: new Set(patch.keys()),
|
|
354
|
+
masked: new Set(),
|
|
355
|
+
clock: driver.clock?.(track.end) ?? createClock(() => driver.now()),
|
|
356
|
+
settle,
|
|
357
|
+
}
|
|
358
|
+
const animation: Animation = {
|
|
359
|
+
finished,
|
|
360
|
+
stop: () => {
|
|
361
|
+
if (this.running !== run) return
|
|
362
|
+
this.model = this.presented()
|
|
363
|
+
this.cancelRunning()
|
|
364
|
+
this.render()
|
|
365
|
+
},
|
|
366
|
+
then: (onfulfilled, onrejected) => finished.then(onfulfilled, onrejected),
|
|
367
|
+
}
|
|
368
|
+
this.running = run
|
|
369
|
+
if (track.end === 0 || !this.painter) this.finish(run, true)
|
|
370
|
+
else {
|
|
371
|
+
this.render()
|
|
372
|
+
if (Number.isFinite(track.end))
|
|
373
|
+
run.cancelEnd = driver.after(Math.max(1, track.end - run.clock.time()), () =>
|
|
374
|
+
this.finish(run, true),
|
|
375
|
+
)
|
|
376
|
+
}
|
|
377
|
+
return animation
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
private finish(run: GradientRun, completed: boolean) {
|
|
381
|
+
if (this.running !== run) return
|
|
382
|
+
const frame = completed
|
|
383
|
+
? mix(run.from, run.to, run.track.to, reducedMotion())
|
|
384
|
+
: this.presented()
|
|
385
|
+
for (const key of run.keys)
|
|
386
|
+
if (!run.masked.has(key)) put(this.model, key, take(frame, key))
|
|
387
|
+
this.running = undefined
|
|
388
|
+
run.cancelEnd?.()
|
|
389
|
+
run.clock.cancel()
|
|
390
|
+
this.clearPlayer()
|
|
391
|
+
run.settle(completed)
|
|
392
|
+
this.render()
|
|
393
|
+
}
|
|
394
|
+
private cancelRunning() {
|
|
395
|
+
const run = this.running
|
|
396
|
+
this.running = undefined
|
|
397
|
+
run?.cancelEnd?.()
|
|
398
|
+
run?.clock.cancel()
|
|
399
|
+
this.clearPlayer()
|
|
400
|
+
run?.settle(false)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
bind(values: GradientBindings): () => void {
|
|
404
|
+
this.assertActive()
|
|
405
|
+
const held = this.presented()
|
|
406
|
+
const patch = gradientPatch(values, held.colors.length)
|
|
407
|
+
const candidate: GradientPatch = this.patch()
|
|
408
|
+
const count = values.colors?.length ?? held.colors.length
|
|
409
|
+
const structural = count !== held.colors.length
|
|
410
|
+
if (structural) {
|
|
411
|
+
held.colors.length = held.stops.length = count
|
|
412
|
+
for (const key of candidate.keys())
|
|
413
|
+
if (key.startsWith('color:') || key.startsWith('stop:')) candidate.delete(key)
|
|
414
|
+
}
|
|
415
|
+
for (const [key, value] of patch) candidate.set(key, value)
|
|
416
|
+
const prepared = gradientProgram(
|
|
417
|
+
{ at: () => held, remaining: 0, elapsed: () => 0 },
|
|
418
|
+
candidate,
|
|
419
|
+
)
|
|
420
|
+
// Validation/sampling above is transactional. Only now may ownership change.
|
|
421
|
+
const owner = {}
|
|
422
|
+
if (structural) {
|
|
423
|
+
for (const key of this.bindings.keys())
|
|
424
|
+
if (key.startsWith('color:') || key.startsWith('stop:')) this.bindings.delete(key)
|
|
425
|
+
for (const key of this.running?.keys ?? [])
|
|
426
|
+
if (key.startsWith('color:') || key.startsWith('stop:'))
|
|
427
|
+
this.running!.masked.add(key)
|
|
428
|
+
}
|
|
429
|
+
this.model = prepared.current
|
|
430
|
+
for (const [key, source] of patch) {
|
|
431
|
+
this.running?.masked.add(key)
|
|
432
|
+
if (typeof source === 'number') this.bindings.delete(key)
|
|
433
|
+
else this.bindings.set(key, { source, owner })
|
|
434
|
+
}
|
|
435
|
+
this.subscribe()
|
|
436
|
+
this.render()
|
|
437
|
+
return () => {
|
|
438
|
+
if (this.removed) return
|
|
439
|
+
const keys = [...this.bindings]
|
|
440
|
+
.filter(([, entry]) => entry.owner === owner)
|
|
441
|
+
.map(([key]) => key)
|
|
442
|
+
if (!keys.length) return
|
|
443
|
+
const current = this.presented()
|
|
444
|
+
for (const key of keys) {
|
|
445
|
+
put(this.model, key, take(current, key))
|
|
446
|
+
this.bindings.delete(key)
|
|
447
|
+
}
|
|
448
|
+
this.subscribe()
|
|
449
|
+
this.render()
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
set(values: GradientValues) {
|
|
454
|
+
this.assertActive()
|
|
455
|
+
const from = this.presented()
|
|
456
|
+
resolve(from, values, false)
|
|
457
|
+
gradientPatch(values, from.colors.length)
|
|
458
|
+
this.cancelRunning()
|
|
459
|
+
this.model = from
|
|
460
|
+
this.bind(values)
|
|
461
|
+
}
|
|
462
|
+
stop() {
|
|
463
|
+
if (this.removed) return
|
|
464
|
+
const frame = this.presented()
|
|
465
|
+
this.bindings.clear()
|
|
466
|
+
this.unsubscribe()
|
|
467
|
+
this.cancelRunning()
|
|
468
|
+
this.model = frame
|
|
469
|
+
this.program = undefined
|
|
470
|
+
this.painter?.paint(frame)
|
|
471
|
+
}
|
|
472
|
+
private hold() {
|
|
473
|
+
this.model = this.presented()
|
|
474
|
+
this.cancelRunning()
|
|
475
|
+
this.unsubscribe()
|
|
476
|
+
this.painter?.paint(this.model)
|
|
477
|
+
}
|
|
478
|
+
get suspended() {
|
|
479
|
+
return this._suspended
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
suspend() {
|
|
483
|
+
if (!this._suspended && !this.removed) {
|
|
484
|
+
this.hold()
|
|
485
|
+
this._suspended = true
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
resume() {
|
|
489
|
+
if (this._suspended && !this.removed) {
|
|
490
|
+
this._suspended = false
|
|
491
|
+
this.subscribe()
|
|
492
|
+
this.changed()
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
private unloaded = () => {
|
|
496
|
+
if (this.removed) return
|
|
497
|
+
this.hold()
|
|
498
|
+
this.unloadedView = true
|
|
499
|
+
this.painter?.remove()
|
|
500
|
+
this.painter = undefined
|
|
501
|
+
}
|
|
502
|
+
private loaded = () => {
|
|
503
|
+
if (this.removed) return
|
|
504
|
+
this.unloadedView = false
|
|
505
|
+
this.painter ??= (factory ?? platformPainter)(this.view, this.type)
|
|
506
|
+
this.subscribe()
|
|
507
|
+
this.changed()
|
|
508
|
+
}
|
|
509
|
+
private resized = () => {
|
|
510
|
+
if (this.bindings.size || this.running) this.changed()
|
|
511
|
+
}
|
|
512
|
+
private appSuspended = () => {
|
|
513
|
+
if (!this.background && !this.removed) {
|
|
514
|
+
this.hold()
|
|
515
|
+
this.background = true
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
private appResumed = () => {
|
|
519
|
+
if (this.background && !this.removed) {
|
|
520
|
+
this.background = false
|
|
521
|
+
this.subscribe()
|
|
522
|
+
this.changed()
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
remove() {
|
|
526
|
+
if (this.removed) return
|
|
527
|
+
this.unsubscribe()
|
|
528
|
+
this.cancelRunning()
|
|
529
|
+
this.bindings.clear()
|
|
530
|
+
this.removed = true
|
|
531
|
+
this.view.off('unloaded', this.unloaded)
|
|
532
|
+
this.view.off('loaded', this.loaded)
|
|
533
|
+
this.view.off('layoutChanged', this.resized)
|
|
534
|
+
Application.off(Application.suspendEvent, this.appSuspended)
|
|
535
|
+
Application.off(Application.resumeEvent, this.appResumed)
|
|
536
|
+
this.painter?.remove()
|
|
537
|
+
this.painter = undefined
|
|
538
|
+
}
|
|
539
|
+
private assertActive() {
|
|
540
|
+
if (this.removed) throw new Error('This gradient was removed.')
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
function springOf(name: SpringName): Transition {
|
|
545
|
+
const spring = springs[name]
|
|
546
|
+
if (!spring || !Object.hasOwn(springs, name))
|
|
547
|
+
throw new Error(`Unknown spring "${name}".`)
|
|
548
|
+
return spring
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/** Validates values and fills in what they leave out from `base`. */
|
|
552
|
+
function resolve(
|
|
553
|
+
base: GradientFrame,
|
|
554
|
+
values: GradientValues,
|
|
555
|
+
sameCount: boolean,
|
|
556
|
+
): GradientFrame {
|
|
557
|
+
if (!values || typeof values !== 'object')
|
|
558
|
+
throw new TypeError('Gradient values must be an object.')
|
|
559
|
+
const colors = values.colors ? values.colors.map(parseColor) : base.colors
|
|
560
|
+
if (colors.length < 2 || colors.length > 8)
|
|
561
|
+
throw new RangeError('A gradient needs between two and eight colors.')
|
|
562
|
+
if (sameCount && values.colors && colors.length !== base.colors.length)
|
|
563
|
+
throw new RangeError(
|
|
564
|
+
`Animating a gradient keeps its ${base.colors.length} colors; use set() to change the count.`,
|
|
565
|
+
)
|
|
566
|
+
const stops = values.stops
|
|
567
|
+
? [...values.stops]
|
|
568
|
+
: values.colors || base.stops.length !== colors.length
|
|
569
|
+
? colors.map((_, i) => i / (colors.length - 1))
|
|
570
|
+
: base.stops
|
|
571
|
+
if (
|
|
572
|
+
stops.length !== colors.length ||
|
|
573
|
+
stops.some(
|
|
574
|
+
(stop, i) =>
|
|
575
|
+
!Number.isFinite(stop) || stop < 0 || stop > 1 || stop < (stops[i - 1] ?? 0),
|
|
576
|
+
)
|
|
577
|
+
)
|
|
578
|
+
throw new RangeError(
|
|
579
|
+
'Gradient stops need one value per color, from 0 to 1, without going back.',
|
|
580
|
+
)
|
|
581
|
+
const angle = values.angle ?? base.angle
|
|
582
|
+
const x = values.center?.x ?? base.x
|
|
583
|
+
const y = values.center?.y ?? base.y
|
|
584
|
+
const radius = values.radius ?? base.radius
|
|
585
|
+
for (const [name, value] of [
|
|
586
|
+
['angle', angle],
|
|
587
|
+
['center', x],
|
|
588
|
+
['center', y],
|
|
589
|
+
['radius', radius],
|
|
590
|
+
] as const)
|
|
591
|
+
if (!Number.isFinite(value))
|
|
592
|
+
throw new RangeError(`Invalid gradient ${name}: ${value}.`)
|
|
593
|
+
if (radius < 0)
|
|
594
|
+
throw new RangeError(`Gradient radius must not be negative, got ${radius}.`)
|
|
595
|
+
return { colors, stops, angle, x, y, radius }
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/** One frame between two states. Geometry follows the curve, overshoot included; colors and stops stay between their ends. */
|
|
599
|
+
export function mix(
|
|
600
|
+
from: GradientFrame,
|
|
601
|
+
to: GradientFrame,
|
|
602
|
+
progress: number,
|
|
603
|
+
reduced = false,
|
|
604
|
+
): GradientFrame {
|
|
605
|
+
const p = Math.min(Math.max(progress, 0), 1)
|
|
606
|
+
const g = reduced ? 1 : progress
|
|
607
|
+
const lerp = (a: number, b: number, t: number) => a + (b - a) * t
|
|
608
|
+
return {
|
|
609
|
+
colors: to.colors.map((color, i) => colorMixer(from.colors[i] ?? color, color)(p)),
|
|
610
|
+
stops: to.stops.map((stop, i) => lerp(from.stops[i] ?? stop, stop, p)),
|
|
611
|
+
angle: lerp(from.angle, to.angle, g),
|
|
612
|
+
x: lerp(from.x, to.x, g),
|
|
613
|
+
y: lerp(from.y, to.y, g),
|
|
614
|
+
radius: Math.max(0, lerp(from.radius, to.radius, g)),
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* The points a platform gradient needs, in unit coordinates of a `width` × `height` box.
|
|
620
|
+
* Linear follows CSS: the line runs through the center at `angle` and is long enough
|
|
621
|
+
* for the corners to get the first and last colors.
|
|
622
|
+
*/
|
|
623
|
+
export function gradientPoints(
|
|
624
|
+
type: GradientType,
|
|
625
|
+
frame: GradientFrame,
|
|
626
|
+
width: number,
|
|
627
|
+
height: number,
|
|
628
|
+
) {
|
|
629
|
+
const radians = (frame.angle * Math.PI) / 180
|
|
630
|
+
const sin = Math.sin(radians)
|
|
631
|
+
const cos = Math.cos(radians)
|
|
632
|
+
if (type === 'linear') {
|
|
633
|
+
// Core Animation keeps an axial gradient's bands square to its line in unit space, so
|
|
634
|
+
// on a box that isn't square the line leans to keep them square to `angle` on screen.
|
|
635
|
+
const ux = height > 0 ? sin / height : 0
|
|
636
|
+
const uy = width > 0 ? -cos / width : 0
|
|
637
|
+
const squared = ux * ux + uy * uy
|
|
638
|
+
const reach = squared > 0 ? (Math.abs(ux) + Math.abs(uy)) / (2 * squared) : 0
|
|
639
|
+
return {
|
|
640
|
+
start: { x: 0.5 - ux * reach, y: 0.5 - uy * reach },
|
|
641
|
+
end: { x: 0.5 + ux * reach, y: 0.5 + uy * reach },
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
const center = { x: frame.x, y: frame.y }
|
|
645
|
+
const shorter = Math.min(width, height)
|
|
646
|
+
if (type === 'radial') {
|
|
647
|
+
const r = frame.radius * shorter
|
|
648
|
+
return {
|
|
649
|
+
start: center,
|
|
650
|
+
end: {
|
|
651
|
+
x: center.x + (width > 0 ? r / width : 0),
|
|
652
|
+
y: center.y + (height > 0 ? r / height : 0),
|
|
653
|
+
},
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return {
|
|
657
|
+
start: center,
|
|
658
|
+
end: {
|
|
659
|
+
x: center.x + (width > 0 ? (sin * shorter) / (2 * width) : 0),
|
|
660
|
+
y: center.y + (height > 0 ? (-cos * shorter) / (2 * height) : 0),
|
|
661
|
+
},
|
|
662
|
+
}
|
|
663
|
+
}
|