@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
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.os.SystemClock;
|
|
4
|
+
import android.view.Choreographer;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
import java.lang.ref.WeakReference;
|
|
7
|
+
import java.util.ArrayList;
|
|
8
|
+
import org.json.JSONArray;
|
|
9
|
+
import org.json.JSONException;
|
|
10
|
+
import org.json.JSONObject;
|
|
11
|
+
|
|
12
|
+
/** Persistent native follower graph. The frame callback never enters JavaScript. */
|
|
13
|
+
public final class LiveSpring {
|
|
14
|
+
private static final ArrayList<LiveSpring> nodes = new ArrayList<>();
|
|
15
|
+
private static boolean scheduled;
|
|
16
|
+
private static long previousFrame;
|
|
17
|
+
private static final Choreographer.FrameCallback clock = new Choreographer.FrameCallback() {
|
|
18
|
+
@Override public void doFrame(long nanos) {
|
|
19
|
+
scheduled = false;
|
|
20
|
+
double now = nanos / 1e6;
|
|
21
|
+
double remaining = previousFrame == 0 ? 1.0 / 120 : Math.min(.064, Math.max(0, (nanos - previousFrame) / 1e9));
|
|
22
|
+
previousFrame = nanos;
|
|
23
|
+
// Older nodes precede their followers. Substeps bound chain phase error at 60/120Hz.
|
|
24
|
+
while (remaining > 1e-9) {
|
|
25
|
+
double dt = Math.min(remaining, 1.0 / 240);
|
|
26
|
+
remaining -= dt;
|
|
27
|
+
for (int i = 0; i < nodes.size(); i++) nodes.get(i).step(now - remaining * 1000, dt);
|
|
28
|
+
}
|
|
29
|
+
boolean active = false;
|
|
30
|
+
for (int i = 0; i < nodes.size(); i++) {
|
|
31
|
+
LiveSpring node = nodes.get(i);
|
|
32
|
+
node.apply();
|
|
33
|
+
active |= node.moving || node.layersMoving(now);
|
|
34
|
+
}
|
|
35
|
+
if (active) schedule(); else previousFrame = 0;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
private static void schedule() {
|
|
39
|
+
if (scheduled || nodes.isEmpty()) return;
|
|
40
|
+
scheduled = true;
|
|
41
|
+
Choreographer.getInstance().postFrameCallback(clock);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private final SpringState state;
|
|
45
|
+
private final double stiffness, damping, mass, restDelta, restSpeed;
|
|
46
|
+
private final ArrayList<Binding> bindings = new ArrayList<>();
|
|
47
|
+
private LiveSpring source;
|
|
48
|
+
private Mapping[] sourceMaps = new Mapping[0];
|
|
49
|
+
private SampledInput input;
|
|
50
|
+
private boolean direct = true;
|
|
51
|
+
private double targetValue;
|
|
52
|
+
private boolean moving, reduced, disposed, paused, inputHeld, sensorInput;
|
|
53
|
+
|
|
54
|
+
public LiveSpring(double initial, double stiffness, double damping, double mass,
|
|
55
|
+
double restDelta, double restSpeed, boolean reduced) {
|
|
56
|
+
state = new SpringState(initial, 0);
|
|
57
|
+
this.stiffness = stiffness; this.damping = damping; this.mass = mass;
|
|
58
|
+
this.restDelta = restDelta; this.restSpeed = restSpeed; this.reduced = reduced;
|
|
59
|
+
targetValue = initial;
|
|
60
|
+
nodes.add(this);
|
|
61
|
+
}
|
|
62
|
+
public double getPosition() { return state.position; }
|
|
63
|
+
public double getVelocity() { return state.velocity; }
|
|
64
|
+
public boolean isMoving() { return moving; }
|
|
65
|
+
public static int activeCount() { return scheduled ? 1 : 0; }
|
|
66
|
+
public static int nodeCount() { return nodes.size(); }
|
|
67
|
+
|
|
68
|
+
public void follow(LiveSpring parent, String mappings) {
|
|
69
|
+
if (disposed || parent.disposed || nodes.indexOf(parent) >= nodes.indexOf(this))
|
|
70
|
+
throw new IllegalArgumentException("A spring can only follow an existing live node");
|
|
71
|
+
sourceMaps = maps(mappings);
|
|
72
|
+
source = parent;
|
|
73
|
+
wake();
|
|
74
|
+
}
|
|
75
|
+
public void updateInput(String snapshot) {
|
|
76
|
+
if (disposed) return;
|
|
77
|
+
try { input = new SampledInput(new JSONObject(snapshot)); }
|
|
78
|
+
catch (JSONException error) { throw new IllegalArgumentException(error); }
|
|
79
|
+
sensorInput = false; direct = false;
|
|
80
|
+
wake();
|
|
81
|
+
}
|
|
82
|
+
public void setSensorInput(double value) {
|
|
83
|
+
if (disposed || !Double.isFinite(value) || (sensorInput && inputHeld && state.position == value)) return;
|
|
84
|
+
sensorInput = true; inputHeld = true; direct = true; targetValue = value; input = null;
|
|
85
|
+
state.position = value; state.velocity = 0; moving = false;
|
|
86
|
+
schedule();
|
|
87
|
+
}
|
|
88
|
+
public void setTarget(double value) {
|
|
89
|
+
if (disposed) return;
|
|
90
|
+
sensorInput = false; direct = true; targetValue = value; input = null;
|
|
91
|
+
wake();
|
|
92
|
+
}
|
|
93
|
+
public void holdInput(double value, double velocity) {
|
|
94
|
+
if (disposed) return;
|
|
95
|
+
sensorInput = false; inputHeld = true; direct = true; targetValue = value; input = null;
|
|
96
|
+
state.position = value; state.velocity = velocity; moving = true;
|
|
97
|
+
apply(); schedule();
|
|
98
|
+
}
|
|
99
|
+
public void releaseInput(double target, double velocity) {
|
|
100
|
+
if (disposed) return;
|
|
101
|
+
inputHeld = false; state.velocity = velocity; setTarget(target);
|
|
102
|
+
}
|
|
103
|
+
public void setReduced(boolean value) { reduced = value; wake(); }
|
|
104
|
+
public void setPaused(boolean value) {
|
|
105
|
+
paused = value;
|
|
106
|
+
if (value) moving = false; else wake();
|
|
107
|
+
}
|
|
108
|
+
private void wake() {
|
|
109
|
+
// Sensor inputs are held data; policy changes must not start an endless frame clock.
|
|
110
|
+
if (disposed || paused || sensorInput) return;
|
|
111
|
+
moving = true;
|
|
112
|
+
if (reduced) { step(SystemClock.uptimeMillis(), 0); apply(); }
|
|
113
|
+
schedule();
|
|
114
|
+
}
|
|
115
|
+
private void step(double now, double dt) {
|
|
116
|
+
if (disposed || paused || inputHeld) return;
|
|
117
|
+
double target = source == null ? (direct ? targetValue : input.value(now)) : map(source.state.position, sourceMaps);
|
|
118
|
+
boolean inputMoving = source == null ? !direct && input.running(now) : source.moving;
|
|
119
|
+
if (reduced) { state.position = target; state.velocity = 0; }
|
|
120
|
+
else state.advance(target, stiffness, damping, mass, dt);
|
|
121
|
+
boolean rest = Math.abs(state.position - target) <= restDelta && Math.abs(state.velocity) <= restSpeed;
|
|
122
|
+
if (rest && !inputMoving) { state.position = target; state.velocity = 0; }
|
|
123
|
+
moving = inputMoving || !rest;
|
|
124
|
+
}
|
|
125
|
+
public Binding bind(View view, String property, String mappings) {
|
|
126
|
+
if (disposed) throw new IllegalStateException("Spring disposed");
|
|
127
|
+
Binding binding = new Binding(view, property, maps(mappings));
|
|
128
|
+
bindings.add(binding);
|
|
129
|
+
binding.apply();
|
|
130
|
+
return binding;
|
|
131
|
+
}
|
|
132
|
+
private void apply() {
|
|
133
|
+
for (int i = bindings.size() - 1; i >= 0; i--) {
|
|
134
|
+
Binding binding = bindings.get(i);
|
|
135
|
+
if (binding.view.get() == null) bindings.remove(i); else binding.apply();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
private boolean layersMoving(double now) {
|
|
139
|
+
for (int i = 0; i < bindings.size(); i++)
|
|
140
|
+
for (SampledInput layer : bindings.get(i).layers)
|
|
141
|
+
if (layer.running(now)) return true;
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
public static void sync(View view) {
|
|
145
|
+
for (int i = 0; i < nodes.size(); i++) {
|
|
146
|
+
LiveSpring node = nodes.get(i);
|
|
147
|
+
for (int j = 0; j < node.bindings.size(); j++) {
|
|
148
|
+
Binding binding = node.bindings.get(j);
|
|
149
|
+
if (binding.view.get() == view) binding.apply();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
public void dispose() {
|
|
154
|
+
if (disposed) return;
|
|
155
|
+
disposed = true; moving = false;
|
|
156
|
+
bindings.clear();
|
|
157
|
+
nodes.remove(this);
|
|
158
|
+
// A retained child continues from its own state toward the parent's last value.
|
|
159
|
+
for (int i = 0; i < nodes.size(); i++) {
|
|
160
|
+
LiveSpring child = nodes.get(i);
|
|
161
|
+
if (child.source == this) {
|
|
162
|
+
child.source = null;
|
|
163
|
+
child.setTarget(map(state.position, child.sourceMaps));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
source = null;
|
|
167
|
+
if (nodes.isEmpty() && scheduled) {
|
|
168
|
+
Choreographer.getInstance().removeFrameCallback(clock);
|
|
169
|
+
scheduled = false; previousFrame = 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public final class Binding {
|
|
174
|
+
private final WeakReference<View> view;
|
|
175
|
+
private final String property;
|
|
176
|
+
private final Mapping[] mappings;
|
|
177
|
+
private final float density;
|
|
178
|
+
private boolean stopped;
|
|
179
|
+
private SampledInput[] layers = new SampledInput[0];
|
|
180
|
+
Binding(View view, String property, Mapping[] mappings) {
|
|
181
|
+
this.view = new WeakReference<>(view); this.property = property; this.mappings = mappings;
|
|
182
|
+
density = view.getResources().getDisplayMetrics().density;
|
|
183
|
+
}
|
|
184
|
+
public double getValue() { return map(state.position, mappings); }
|
|
185
|
+
public void setLayers(String inputs) {
|
|
186
|
+
try {
|
|
187
|
+
JSONArray array = new JSONArray(inputs);
|
|
188
|
+
SampledInput[] next = new SampledInput[array.length()];
|
|
189
|
+
for (int i = 0; i < next.length; i++) next[i] = new SampledInput(array.getJSONObject(i));
|
|
190
|
+
layers = next;
|
|
191
|
+
} catch (JSONException error) { throw new IllegalArgumentException(error); }
|
|
192
|
+
apply(); schedule();
|
|
193
|
+
}
|
|
194
|
+
public void cancel() { stopped = true; bindings.remove(this); }
|
|
195
|
+
private void apply() {
|
|
196
|
+
View target = view.get();
|
|
197
|
+
if (stopped || target == null || !target.isAttachedToWindow()) return;
|
|
198
|
+
double composed = getValue();
|
|
199
|
+
boolean multiply = property.equals("opacity") || property.startsWith("scale");
|
|
200
|
+
double now = SystemClock.uptimeMillis();
|
|
201
|
+
for (SampledInput layer : layers) composed = multiply ? composed * layer.value(now) : composed + layer.value(now);
|
|
202
|
+
float value = (float)composed;
|
|
203
|
+
switch (property) {
|
|
204
|
+
case "x": target.setTranslationX(value * density); break;
|
|
205
|
+
case "y": target.setTranslationY(value * density); break;
|
|
206
|
+
case "scaleX": target.setScaleX(value); break;
|
|
207
|
+
case "scaleY": target.setScaleY(value); break;
|
|
208
|
+
case "rotate": target.setRotation(value); break;
|
|
209
|
+
case "rotateX": target.setRotationX(value); break;
|
|
210
|
+
case "rotateY": target.setRotationY(value); break;
|
|
211
|
+
case "opacity": target.setAlpha(Math.max(0, Math.min(1, value))); break;
|
|
212
|
+
default: throw new IllegalArgumentException("Unsupported live property " + property);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
private static final class Mapping {
|
|
217
|
+
final double[] input, output;
|
|
218
|
+
final boolean clamp;
|
|
219
|
+
Mapping(JSONObject json) throws JSONException {
|
|
220
|
+
input = array(json.getJSONArray("input")); output = array(json.getJSONArray("output"));
|
|
221
|
+
clamp = json.getBoolean("clamp");
|
|
222
|
+
}
|
|
223
|
+
double value(double value) {
|
|
224
|
+
if (clamp && value <= input[0]) return output[0];
|
|
225
|
+
if (clamp && value >= input[input.length - 1]) return output[output.length - 1];
|
|
226
|
+
int index = 0;
|
|
227
|
+
while (index < input.length - 2 && value > input[index + 1]) index++;
|
|
228
|
+
double span = input[index + 1] - input[index];
|
|
229
|
+
double fraction = span > 0 ? (value - input[index]) / span : value < input[index] ? 0 : 1;
|
|
230
|
+
return output[index] + (output[index + 1] - output[index]) * fraction;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
private static Mapping[] maps(String json) {
|
|
234
|
+
try {
|
|
235
|
+
JSONArray array = new JSONArray(json);
|
|
236
|
+
Mapping[] result = new Mapping[array.length()];
|
|
237
|
+
for (int i = 0; i < result.length; i++) result[i] = new Mapping(array.getJSONObject(i));
|
|
238
|
+
return result;
|
|
239
|
+
} catch (JSONException error) { throw new IllegalArgumentException(error); }
|
|
240
|
+
}
|
|
241
|
+
private static double map(double value, Mapping[] maps) {
|
|
242
|
+
for (Mapping mapping : maps) value = mapping.value(value);
|
|
243
|
+
return value;
|
|
244
|
+
}
|
|
245
|
+
private static double[] array(JSONArray input) throws JSONException {
|
|
246
|
+
double[] result = new double[input.length()];
|
|
247
|
+
for (int i = 0; i < result.length; i++) result[i] = input.getDouble(i);
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
private static final class SampledInput {
|
|
251
|
+
final double value, anchor, elapsed, duration, delay, repeat, end;
|
|
252
|
+
final double[] values, times;
|
|
253
|
+
final boolean reverse, playing;
|
|
254
|
+
SampledInput(JSONObject json) throws JSONException {
|
|
255
|
+
value = json.getDouble("value");
|
|
256
|
+
anchor = SystemClock.uptimeMillis(); elapsed = json.getDouble("elapsed");
|
|
257
|
+
playing = json.getBoolean("running");
|
|
258
|
+
duration = json.getDouble("duration"); delay = json.getDouble("delay");
|
|
259
|
+
repeat = json.getDouble("repeat"); end = json.getDouble("to");
|
|
260
|
+
reverse = json.getBoolean("reverse");
|
|
261
|
+
values = array(json.getJSONArray("values")); times = array(json.getJSONArray("times"));
|
|
262
|
+
}
|
|
263
|
+
boolean running(double now) { return playing && (repeat < 0 || now - anchor + elapsed < delay + duration * (repeat + 1)); }
|
|
264
|
+
double value(double now) {
|
|
265
|
+
if (!playing || values.length < 2) return value;
|
|
266
|
+
if (!running(now)) return end;
|
|
267
|
+
double time = Math.max(0, now - anchor + elapsed - delay);
|
|
268
|
+
double iteration = Math.floor(time / Math.max(1, duration));
|
|
269
|
+
double progress = (time % Math.max(1, duration)) / Math.max(1, duration);
|
|
270
|
+
if (reverse && iteration % 2 >= 1) progress = 1 - progress;
|
|
271
|
+
int lo = 0, hi = times.length - 1;
|
|
272
|
+
while (lo + 1 < hi) { int mid = (lo + hi) / 2; if (times[mid] <= progress) lo = mid; else hi = mid; }
|
|
273
|
+
double fraction = times[hi] > times[lo] ? (progress - times[lo]) / (times[hi] - times[lo]) : 1;
|
|
274
|
+
return values[lo] + (values[hi] - values[lo]) * Math.max(0, Math.min(1, fraction));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.os.SystemClock;
|
|
4
|
+
import android.view.Choreographer;
|
|
5
|
+
import android.view.View;
|
|
6
|
+
import java.lang.ref.WeakReference;
|
|
7
|
+
import org.json.JSONArray;
|
|
8
|
+
import org.json.JSONObject;
|
|
9
|
+
import org.json.JSONException;
|
|
10
|
+
|
|
11
|
+
/** Optional development sampling. No callback crosses into JavaScript per frame. */
|
|
12
|
+
public final class MotionProbe implements Choreographer.FrameCallback {
|
|
13
|
+
private static int activeCount;
|
|
14
|
+
private final WeakReference<View> view;
|
|
15
|
+
private final double[][] rows;
|
|
16
|
+
private final double density, interval;
|
|
17
|
+
private int head, count, dropped, samples;
|
|
18
|
+
private double last = Double.NEGATIVE_INFINITY, sampleCPU, drainCPU;
|
|
19
|
+
private boolean active = true;
|
|
20
|
+
|
|
21
|
+
public static MotionProbe start(View view, int capacity, double hertz) {
|
|
22
|
+
return new MotionProbe(view, capacity, hertz);
|
|
23
|
+
}
|
|
24
|
+
public static int activeCount() { return activeCount; }
|
|
25
|
+
private MotionProbe(View target, int capacity, double hertz) {
|
|
26
|
+
view = new WeakReference<>(target);
|
|
27
|
+
rows = new double[Math.max(8, Math.min(600, capacity))][9];
|
|
28
|
+
density = target.getResources().getDisplayMetrics().density;
|
|
29
|
+
interval = 1000 / Math.max(1, Math.min(120, hertz));
|
|
30
|
+
activeCount++; Choreographer.getInstance().postFrameCallback(this);
|
|
31
|
+
}
|
|
32
|
+
@Override public void doFrame(long frameTimeNanos) {
|
|
33
|
+
if (!active) return;
|
|
34
|
+
View target = view.get();
|
|
35
|
+
if (target == null || !target.isAttachedToWindow()) { dispose(); return; }
|
|
36
|
+
long begin = System.nanoTime();
|
|
37
|
+
double now = SystemClock.uptimeMillis();
|
|
38
|
+
if (now - last >= interval - 0.5) {
|
|
39
|
+
last = now;
|
|
40
|
+
int slot;
|
|
41
|
+
if (count == rows.length) { slot = head; head = (head + 1) % rows.length; dropped++; }
|
|
42
|
+
else { slot = (head + count) % rows.length; count++; }
|
|
43
|
+
double[] r = rows[slot];
|
|
44
|
+
r[0] = now; r[1] = target.getTranslationX()/density; r[2] = target.getTranslationY()/density;
|
|
45
|
+
r[3] = target.getScaleX(); r[4] = target.getScaleY(); r[5] = target.getRotation();
|
|
46
|
+
r[6] = target.getRotationX(); r[7] = target.getRotationY(); r[8] = target.getAlpha();
|
|
47
|
+
samples++; sampleCPU += (System.nanoTime()-begin)/1e6;
|
|
48
|
+
}
|
|
49
|
+
Choreographer.getInstance().postFrameCallback(this);
|
|
50
|
+
}
|
|
51
|
+
public String drain() {
|
|
52
|
+
long begin = System.nanoTime();
|
|
53
|
+
try {
|
|
54
|
+
JSONArray out = new JSONArray();
|
|
55
|
+
for (int i=0;i<count;i++) {
|
|
56
|
+
JSONArray row = new JSONArray();
|
|
57
|
+
for(double value:rows[(head+i)%rows.length]) row.put(Double.isFinite(value)?value:JSONObject.NULL);
|
|
58
|
+
out.put(row);
|
|
59
|
+
}
|
|
60
|
+
head=0; count=0;
|
|
61
|
+
JSONObject result=new JSONObject(); result.put("rows",out); result.put("dropped",dropped);
|
|
62
|
+
result.put("samples",samples); result.put("sampleCpuMs",sampleCPU); result.put("drainCpuMs",drainCPU); result.put("active",active);
|
|
63
|
+
String json=result.toString(); drainCPU+=(System.nanoTime()-begin)/1e6; return json;
|
|
64
|
+
} catch(JSONException error) { throw new IllegalStateException(error); }
|
|
65
|
+
}
|
|
66
|
+
public void dispose() {
|
|
67
|
+
if (!active) return;
|
|
68
|
+
active=false; activeCount--; Choreographer.getInstance().removeFrameCallback(this); view.clear();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.database.ContentObserver;
|
|
4
|
+
import android.graphics.Canvas;
|
|
5
|
+
import android.graphics.ColorFilter;
|
|
6
|
+
import android.graphics.Paint;
|
|
7
|
+
import android.graphics.PixelFormat;
|
|
8
|
+
import android.graphics.drawable.Drawable;
|
|
9
|
+
import android.os.Handler;
|
|
10
|
+
import android.os.Looper;
|
|
11
|
+
import android.os.SystemClock;
|
|
12
|
+
import android.provider.Settings;
|
|
13
|
+
import android.view.Choreographer;
|
|
14
|
+
import android.view.View;
|
|
15
|
+
import android.view.ViewParent;
|
|
16
|
+
|
|
17
|
+
/** A visual-only ViewOverlay drawable: all integration, deadlines and drawing stay in Java. */
|
|
18
|
+
public final class ParticleEmitter extends Drawable implements Choreographer.FrameCallback, View.OnAttachStateChangeListener {
|
|
19
|
+
public interface Listener { void onEnd(); }
|
|
20
|
+
private static int activeCount;
|
|
21
|
+
private View target, host;
|
|
22
|
+
private final boolean overlay;
|
|
23
|
+
private final float density;
|
|
24
|
+
private final ParticleSimulation simulation;
|
|
25
|
+
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
26
|
+
private final Choreographer choreographer = Choreographer.getInstance();
|
|
27
|
+
private final Handler handler = new Handler(Looper.getMainLooper());
|
|
28
|
+
private final float[] point = new float[2];
|
|
29
|
+
private final int[] location = new int[2];
|
|
30
|
+
private final long[] intervals = new long[512];
|
|
31
|
+
private final ContentObserver scaleObserver = new ContentObserver(handler) {
|
|
32
|
+
@Override public void onChange(boolean selfChange) { if (disabled()) stop(); }
|
|
33
|
+
};
|
|
34
|
+
private Listener listener;
|
|
35
|
+
private boolean started, stopped, observing;
|
|
36
|
+
private long began, lastFrame, frames, draws, workNanos, drawNanos;
|
|
37
|
+
private float originX, originY, corner;
|
|
38
|
+
private final Runnable expire = new Runnable() { @Override public void run() { stop(); } };
|
|
39
|
+
private final long deadline;
|
|
40
|
+
|
|
41
|
+
public ParticleEmitter(View target, boolean overlay, int[] colors, int shape, int source,
|
|
42
|
+
double rate, double lifetimeMs, float size, float velocity, float velocityRange,
|
|
43
|
+
float angle, float spread, float gravity, float spin, float spinRange,
|
|
44
|
+
boolean fade, double durationMs, Listener listener) {
|
|
45
|
+
this.target = target; this.host = overlay ? target.getRootView() : target; this.overlay = overlay;
|
|
46
|
+
this.listener = listener;
|
|
47
|
+
density = target.getResources().getDisplayMetrics().density;
|
|
48
|
+
simulation = new ParticleSimulation(colors, shape, source, rate, lifetimeMs, size,
|
|
49
|
+
velocity, velocityRange, angle, spread, gravity, spin, spinRange, fade, durationMs, System.nanoTime());
|
|
50
|
+
deadline = durationMs < 0 ? -1 : (long)Math.ceil(durationMs + lifetimeMs);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private boolean disabled() {
|
|
54
|
+
return target != null && Settings.Global.getFloat(target.getContext().getContentResolver(),
|
|
55
|
+
Settings.Global.ANIMATOR_DURATION_SCALE, 1) == 0;
|
|
56
|
+
}
|
|
57
|
+
private boolean valid() {
|
|
58
|
+
return target != null && target.isAttachedToWindow() && target.getWindowVisibility() == View.VISIBLE
|
|
59
|
+
&& target.isShown() && target.getWidth() > 0 && target.getHeight() > 0
|
|
60
|
+
&& host.getWindowToken() != null && host.getWindowToken() == target.getWindowToken()
|
|
61
|
+
&& (!overlay || host == target.getRootView());
|
|
62
|
+
}
|
|
63
|
+
public void start() {
|
|
64
|
+
if (started || stopped) return;
|
|
65
|
+
if (!valid() || disabled()) { stop(); return; }
|
|
66
|
+
started = true; activeCount++;
|
|
67
|
+
began = SystemClock.uptimeMillis();
|
|
68
|
+
if (overlay) {
|
|
69
|
+
// Convert the center through transforms and parent scrolling into root-overlay coordinates.
|
|
70
|
+
point[0] = target.getWidth() * .5f; point[1] = target.getHeight() * .5f;
|
|
71
|
+
View current = target;
|
|
72
|
+
while (current != host) {
|
|
73
|
+
current.getMatrix().mapPoints(point);
|
|
74
|
+
point[0] += current.getLeft(); point[1] += current.getTop();
|
|
75
|
+
ViewParent parent = current.getParent();
|
|
76
|
+
if (!(parent instanceof View)) { stop(); return; }
|
|
77
|
+
current = (View)parent;
|
|
78
|
+
point[0] -= current.getScrollX(); point[1] -= current.getScrollY();
|
|
79
|
+
}
|
|
80
|
+
originX = point[0]; originY = point[1];
|
|
81
|
+
}
|
|
82
|
+
target.addOnAttachStateChangeListener(this);
|
|
83
|
+
target.getContext().getContentResolver().registerContentObserver(
|
|
84
|
+
Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE), false, scaleObserver);
|
|
85
|
+
observing = true;
|
|
86
|
+
setBounds(0, 0, host.getWidth(), host.getHeight());
|
|
87
|
+
host.getOverlay().add(this);
|
|
88
|
+
if (deadline >= 0) handler.postDelayed(expire, deadline);
|
|
89
|
+
choreographer.postFrameCallback(this);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Layout/identity checks at JS boundaries; moving views otherwise stay in their native overlay. */
|
|
93
|
+
public void refresh(float cornerPixels) {
|
|
94
|
+
corner = Math.max(0, cornerPixels);
|
|
95
|
+
if (!stopped && started && !valid()) stop();
|
|
96
|
+
}
|
|
97
|
+
@Override public void doFrame(long frameTimeNanos) {
|
|
98
|
+
if (stopped) return;
|
|
99
|
+
long workStart = System.nanoTime();
|
|
100
|
+
if (!valid()) { stop(); return; }
|
|
101
|
+
if (lastFrame != 0) intervals[(int)((frames - 1) % intervals.length)] = frameTimeNanos - lastFrame;
|
|
102
|
+
lastFrame = frameTimeNanos; frames++;
|
|
103
|
+
// Deliberately use monotonic wall time: UI stalls cannot extend emission/lifetime deadlines.
|
|
104
|
+
simulation.advance((SystemClock.uptimeMillis() - began) / 1000d,
|
|
105
|
+
overlay ? 0 : target.getWidth() / density, overlay ? 0 : target.getHeight() / density);
|
|
106
|
+
if (simulation.finished()) { stop(); return; }
|
|
107
|
+
if (getBounds().width() != host.getWidth() || getBounds().height() != host.getHeight())
|
|
108
|
+
setBounds(0, 0, host.getWidth(), host.getHeight());
|
|
109
|
+
invalidateSelf();
|
|
110
|
+
workNanos += System.nanoTime() - workStart;
|
|
111
|
+
choreographer.postFrameCallback(this);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Override public void draw(Canvas canvas) {
|
|
115
|
+
if (stopped) return;
|
|
116
|
+
long drawStart = System.nanoTime(); draws++;
|
|
117
|
+
int save = canvas.save();
|
|
118
|
+
// The overlay is above this host's content, bounded by the host/window viewport.
|
|
119
|
+
canvas.clipRect(getBounds());
|
|
120
|
+
if (!overlay && corner > 0) {
|
|
121
|
+
// A retained path avoids allocating rounded clips per frame.
|
|
122
|
+
clip.rewind();
|
|
123
|
+
rect.set(getBounds());
|
|
124
|
+
clip.addRoundRect(rect, corner, corner, android.graphics.Path.Direction.CW);
|
|
125
|
+
canvas.clipPath(clip);
|
|
126
|
+
}
|
|
127
|
+
if (overlay) canvas.translate(originX, originY);
|
|
128
|
+
canvas.scale(density, density);
|
|
129
|
+
float size = simulation.size, radius = size * .5f;
|
|
130
|
+
paint.setStyle(simulation.shape == 2 ? Paint.Style.STROKE : Paint.Style.FILL);
|
|
131
|
+
paint.setStrokeWidth(size * (3f / 32));
|
|
132
|
+
for (int i = 0, count = simulation.live(); i < count; i++) {
|
|
133
|
+
paint.setColor(simulation.color(i));
|
|
134
|
+
float x = simulation.x(i), y = simulation.y(i);
|
|
135
|
+
if (simulation.shape == 1) {
|
|
136
|
+
int particleSave = canvas.save();
|
|
137
|
+
canvas.rotate(simulation.rotation(i), x, y);
|
|
138
|
+
canvas.drawRect(x - radius, y - size * (9f / 32), x + radius, y + size * (9f / 32), paint);
|
|
139
|
+
canvas.restoreToCount(particleSave);
|
|
140
|
+
} else canvas.drawCircle(x, y, simulation.shape == 2 ? size * (14f / 32) : radius, paint);
|
|
141
|
+
}
|
|
142
|
+
canvas.restoreToCount(save);
|
|
143
|
+
drawNanos += System.nanoTime() - drawStart;
|
|
144
|
+
}
|
|
145
|
+
private final android.graphics.Path clip = new android.graphics.Path();
|
|
146
|
+
private final android.graphics.RectF rect = new android.graphics.RectF();
|
|
147
|
+
|
|
148
|
+
public void stop() {
|
|
149
|
+
if (stopped) return;
|
|
150
|
+
stopped = true;
|
|
151
|
+
choreographer.removeFrameCallback(this);
|
|
152
|
+
handler.removeCallbacks(expire);
|
|
153
|
+
if (observing) target.getContext().getContentResolver().unregisterContentObserver(scaleObserver);
|
|
154
|
+
observing = false;
|
|
155
|
+
if (started) { activeCount--; target.removeOnAttachStateChangeListener(this); host.getOverlay().remove(this); }
|
|
156
|
+
simulation.clear();
|
|
157
|
+
setCallback(null);
|
|
158
|
+
target = host = null;
|
|
159
|
+
Listener done = listener; listener = null;
|
|
160
|
+
if (done != null) done.onEnd();
|
|
161
|
+
}
|
|
162
|
+
@Override public void onViewAttachedToWindow(View view) { }
|
|
163
|
+
@Override public void onViewDetachedFromWindow(View view) { stop(); }
|
|
164
|
+
@Override public void setAlpha(int alpha) { }
|
|
165
|
+
@Override public void setColorFilter(ColorFilter filter) { paint.setColorFilter(filter); }
|
|
166
|
+
@Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }
|
|
167
|
+
|
|
168
|
+
// Native conformance/diagnostics. Reads allocate only when explicitly requested, never per frame.
|
|
169
|
+
public static int getActiveCount() { return activeCount; }
|
|
170
|
+
public boolean isStopped() { return stopped; }
|
|
171
|
+
public int getLiveCount() { return simulation.live(); }
|
|
172
|
+
public int getPeakCount() { return simulation.peak(); }
|
|
173
|
+
public int getCapacity() { return simulation.capacity(); }
|
|
174
|
+
public long getEmittedCount() { return simulation.emitted(); }
|
|
175
|
+
public long getSkippedCount() { return simulation.skipped(); }
|
|
176
|
+
public long getFrameCount() { return frames; }
|
|
177
|
+
public long getDrawCount() { return draws; }
|
|
178
|
+
public long getWorkNanos() { return workNanos; }
|
|
179
|
+
public long getDrawNanos() { return drawNanos; }
|
|
180
|
+
public float getDensity() { return density; }
|
|
181
|
+
public double getTimeSeconds() { return simulation.time(); }
|
|
182
|
+
public boolean isObserving() { return observing; }
|
|
183
|
+
public float[] getOriginInWindow() {
|
|
184
|
+
if (host != null) host.getLocationInWindow(location);
|
|
185
|
+
return new float[] { originX + location[0], originY + location[1] };
|
|
186
|
+
}
|
|
187
|
+
public float[] getParticle(int index) { return new float[] { simulation.x(index), simulation.y(index), simulation.rotation(index), simulation.color(index) }; }
|
|
188
|
+
public long[] getFrameIntervals() {
|
|
189
|
+
int count = (int)Math.min(Math.max(0, frames - 1), intervals.length);
|
|
190
|
+
return java.util.Arrays.copyOf(intervals, count);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
/** Bounded, allocation-free particle state. Units are DIPs, seconds and degrees.
|
|
4
|
+
* Android supplies elapsed wall time; the same engine runs in deterministic JVM tests. */
|
|
5
|
+
public final class ParticleSimulation {
|
|
6
|
+
public static final int MAX_PARTICLES = 10000;
|
|
7
|
+
public final int shape, source;
|
|
8
|
+
public final float size;
|
|
9
|
+
private final int[] palette;
|
|
10
|
+
private final double rate, lifetime, duration;
|
|
11
|
+
private final float velocity, velocityRange, angle, spread, gravity, spin, spinRange;
|
|
12
|
+
private final boolean fade;
|
|
13
|
+
private double[] births;
|
|
14
|
+
private float[] xs, ys, vxs, vys, rotations, spins;
|
|
15
|
+
private int[] colors;
|
|
16
|
+
private int live, peak;
|
|
17
|
+
private long scheduled, emitted, skipped;
|
|
18
|
+
private long random;
|
|
19
|
+
private double time;
|
|
20
|
+
|
|
21
|
+
public ParticleSimulation(int[] palette, int shape, int source, double rate,
|
|
22
|
+
double lifetimeMs, float size, float velocity, float velocityRange,
|
|
23
|
+
float angle, float spread, float gravity, float spin, float spinRange,
|
|
24
|
+
boolean fade, double durationMs, long seed) {
|
|
25
|
+
if (palette == null || palette.length == 0 || palette.length > 32 || shape < 0 || shape > 2 || source < 0 || source > 2)
|
|
26
|
+
throw new IllegalArgumentException("Invalid particle colors, shape or source");
|
|
27
|
+
if (!finite(rate) || rate <= 0 || rate > 50000 || !finite(lifetimeMs) || lifetimeMs < 1 || lifetimeMs > 60000
|
|
28
|
+
|| !finite(durationMs) || (durationMs != -1 && (durationMs < 1 || durationMs > Integer.MAX_VALUE - lifetimeMs - 50))
|
|
29
|
+
|| !finite(size) || size < 1 || size > 128 || !finite(velocity) || velocity < 0 || velocity > 10000
|
|
30
|
+
|| !finite(velocityRange) || velocityRange < 0 || velocityRange > 10000
|
|
31
|
+
|| !finite(angle) || Math.abs(angle) > 360 || !finite(spread) || spread < 0 || spread > 360
|
|
32
|
+
|| !finite(gravity) || Math.abs(gravity) > 10000 || !finite(spin) || Math.abs(spin) > 3600
|
|
33
|
+
|| !finite(spinRange) || spinRange < 0 || spinRange > 3600)
|
|
34
|
+
throw new IllegalArgumentException("Invalid particle settings");
|
|
35
|
+
this.palette = palette.clone();
|
|
36
|
+
this.shape = shape; this.source = source; this.rate = rate;
|
|
37
|
+
lifetime = lifetimeMs / 1000; duration = durationMs < 0 ? Double.POSITIVE_INFINITY : durationMs / 1000;
|
|
38
|
+
this.size = size; this.velocity = velocity; this.velocityRange = velocityRange;
|
|
39
|
+
this.angle = angle; this.spread = spread; this.gravity = gravity;
|
|
40
|
+
this.spin = spin; this.spinRange = spinRange; this.fade = fade;
|
|
41
|
+
random = seed == 0 ? 1 : seed;
|
|
42
|
+
double population = rate * Math.min(lifetime, duration);
|
|
43
|
+
if (population > MAX_PARTICLES + 0.000001) throw new IllegalArgumentException("Particle population exceeds 10000");
|
|
44
|
+
int capacity = Math.max(1, Math.min(MAX_PARTICLES, (int)Math.ceil(population)));
|
|
45
|
+
births = new double[capacity]; xs = new float[capacity]; ys = new float[capacity];
|
|
46
|
+
vxs = new float[capacity]; vys = new float[capacity]; rotations = new float[capacity];
|
|
47
|
+
spins = new float[capacity]; colors = new int[capacity];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private static boolean finite(double value) { return !Double.isNaN(value) && !Double.isInfinite(value); }
|
|
51
|
+
private float unit() {
|
|
52
|
+
// xorshift64*: deterministic internal seed, never part of the public JS contract.
|
|
53
|
+
random ^= random >>> 12; random ^= random << 25; random ^= random >>> 27;
|
|
54
|
+
return ((random * 2685821657736338717L) >>> 40) / 16777216f;
|
|
55
|
+
}
|
|
56
|
+
private float variation(float range) { return (unit() * 2 - 1) * range; }
|
|
57
|
+
|
|
58
|
+
/** Advance directly to the current time, skipping already-dead births after a stall.
|
|
59
|
+
* No backlog of expired particles and no integration steps proportional to missed frames. */
|
|
60
|
+
public void advance(double elapsedSeconds, float width, float height) {
|
|
61
|
+
if (births == null || !finite(elapsedSeconds)) return;
|
|
62
|
+
time = Math.max(time, Math.max(0, elapsedSeconds));
|
|
63
|
+
for (int i = live - 1; i >= 0; i--) {
|
|
64
|
+
if (time - births[i] >= lifetime - 0.000000001) {
|
|
65
|
+
int last = --live;
|
|
66
|
+
births[i] = births[last]; xs[i] = xs[last]; ys[i] = ys[last];
|
|
67
|
+
vxs[i] = vxs[last]; vys[i] = vys[last]; rotations[i] = rotations[last];
|
|
68
|
+
spins[i] = spins[last]; colors[i] = colors[last];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
long until = (long)Math.floor(Math.min(time, duration) * rate + 0.0000001);
|
|
72
|
+
long dead = Math.min(until, (long)Math.floor(Math.max(0, time - lifetime) * rate + 0.0000001));
|
|
73
|
+
if (dead > scheduled) { skipped += dead - scheduled; scheduled = dead; }
|
|
74
|
+
// scheduled is monotonic; at most capacity particles can be alive in this interval.
|
|
75
|
+
while (scheduled < until) {
|
|
76
|
+
long index = ++scheduled;
|
|
77
|
+
if (live >= births.length) { skipped++; continue; }
|
|
78
|
+
int i = live++;
|
|
79
|
+
births[i] = index / rate;
|
|
80
|
+
xs[i] = source == 0 ? width * .5f : unit() * width;
|
|
81
|
+
ys[i] = source == 1 ? 0 : source == 2 ? height : height * .5f;
|
|
82
|
+
double direction = Math.toRadians(angle + variation(spread * .5f));
|
|
83
|
+
float speed = velocity + variation(velocityRange);
|
|
84
|
+
vxs[i] = (float)Math.cos(direction) * speed;
|
|
85
|
+
vys[i] = (float)Math.sin(direction) * speed;
|
|
86
|
+
rotations[i] = shape == 1 ? unit() * 360 : 0;
|
|
87
|
+
spins[i] = spin + variation(spinRange);
|
|
88
|
+
colors[i] = palette[(int)((index - 1) % palette.length)];
|
|
89
|
+
emitted++;
|
|
90
|
+
}
|
|
91
|
+
peak = Math.max(peak, live);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public float x(int i) { return xs[i] + vxs[i] * (float)(time - births[i]); }
|
|
95
|
+
public float y(int i) { float age = (float)(time - births[i]); return ys[i] + vys[i] * age + gravity * age * age * .5f; }
|
|
96
|
+
public float rotation(int i) { return rotations[i] + spins[i] * (float)(time - births[i]); }
|
|
97
|
+
public int color(int i) {
|
|
98
|
+
int color = colors[i];
|
|
99
|
+
if (!fade) return color;
|
|
100
|
+
int alpha = Math.round((color >>> 24) * (float)Math.max(0, 1 - (time - births[i]) / lifetime));
|
|
101
|
+
return (color & 0x00ffffff) | (alpha << 24);
|
|
102
|
+
}
|
|
103
|
+
public boolean finished() { return time >= duration + lifetime || (time >= duration && live == 0); }
|
|
104
|
+
public int live() { return live; }
|
|
105
|
+
public int peak() { return peak; }
|
|
106
|
+
public int capacity() { return births == null ? 0 : births.length; }
|
|
107
|
+
public long emitted() { return emitted; }
|
|
108
|
+
public long skipped() { return skipped; }
|
|
109
|
+
public double time() { return time; }
|
|
110
|
+
public void clear() {
|
|
111
|
+
live = 0;
|
|
112
|
+
births = null; xs = ys = vxs = vys = rotations = spins = null; colors = null;
|
|
113
|
+
}
|
|
114
|
+
}
|