@rafaelaugusto/jolt 0.1.0-beta.1 → 0.1.0-beta.10
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 +367 -18
- package/dist/animate.d.ts +19 -3
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +186 -14
- package/dist/animate.js.map +1 -1
- package/dist/color.d.ts +11 -0
- package/dist/color.d.ts.map +1 -0
- package/dist/color.js +73 -0
- package/dist/color.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/decay.d.ts +11 -0
- package/dist/decay.d.ts.map +1 -0
- package/dist/decay.js +22 -0
- package/dist/decay.js.map +1 -0
- package/dist/decoration.d.ts +18 -0
- package/dist/decoration.d.ts.map +1 -0
- package/dist/decoration.js +155 -0
- package/dist/decoration.js.map +1 -0
- package/dist/drag-input.d.ts +15 -0
- package/dist/drag-input.d.ts.map +1 -0
- package/dist/drag-input.js +66 -0
- package/dist/drag-input.js.map +1 -0
- package/dist/drag-physics.d.ts +20 -0
- package/dist/drag-physics.d.ts.map +1 -0
- package/dist/drag-physics.js +75 -0
- package/dist/drag-physics.js.map +1 -0
- package/dist/drag.d.ts +58 -0
- package/dist/drag.d.ts.map +1 -0
- package/dist/drag.js +324 -0
- package/dist/drag.js.map +1 -0
- package/dist/driver/android-color.d.ts +20 -0
- package/dist/driver/android-color.d.ts.map +1 -0
- package/dist/driver/android-color.js +136 -0
- package/dist/driver/android-color.js.map +1 -0
- package/dist/driver/android-decoration.d.ts +22 -0
- package/dist/driver/android-decoration.d.ts.map +1 -0
- package/dist/driver/android-decoration.js +139 -0
- package/dist/driver/android-decoration.js.map +1 -0
- package/dist/driver/android-playback.d.ts +13 -0
- package/dist/driver/android-playback.d.ts.map +1 -0
- package/dist/driver/android-playback.js +141 -0
- package/dist/driver/android-playback.js.map +1 -0
- package/dist/driver/android.d.ts +1 -1
- package/dist/driver/android.d.ts.map +1 -1
- package/dist/driver/android.js +165 -13
- package/dist/driver/android.js.map +1 -1
- package/dist/driver/index.d.ts +25 -2
- package/dist/driver/index.d.ts.map +1 -1
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/ios-color.d.ts +16 -0
- package/dist/driver/ios-color.d.ts.map +1 -0
- package/dist/driver/ios-color.js +392 -0
- package/dist/driver/ios-color.js.map +1 -0
- package/dist/driver/ios-decoration.d.ts +17 -0
- package/dist/driver/ios-decoration.d.ts.map +1 -0
- package/dist/driver/ios-decoration.js +271 -0
- package/dist/driver/ios-decoration.js.map +1 -0
- package/dist/driver/ios-layout.d.ts +9 -0
- package/dist/driver/ios-layout.d.ts.map +1 -0
- package/dist/driver/ios-layout.js +52 -0
- package/dist/driver/ios-layout.js.map +1 -0
- package/dist/driver/ios-playback.d.ts +10 -0
- package/dist/driver/ios-playback.d.ts.map +1 -0
- package/dist/driver/ios-playback.js +47 -0
- package/dist/driver/ios-playback.js.map +1 -0
- package/dist/driver/ios-shadow.d.ts +6 -0
- package/dist/driver/ios-shadow.d.ts.map +1 -0
- package/dist/driver/ios-shadow.js +52 -0
- package/dist/driver/ios-shadow.js.map +1 -0
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +163 -28
- package/dist/driver/ios.js.map +1 -1
- package/dist/engine.d.ts +75 -5
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +293 -23
- package/dist/engine.js.map +1 -1
- package/dist/haptics.d.ts +21 -0
- package/dist/haptics.d.ts.map +1 -0
- package/dist/haptics.js +120 -0
- package/dist/haptics.js.map +1 -0
- package/dist/image-effect-native.d.ts +26 -0
- package/dist/image-effect-native.d.ts.map +1 -0
- package/dist/image-effect-native.js +73 -0
- package/dist/image-effect-native.js.map +1 -0
- package/dist/image-effect.d.ts +50 -0
- package/dist/image-effect.d.ts.map +1 -0
- package/dist/image-effect.js +290 -0
- package/dist/image-effect.js.map +1 -0
- package/dist/image-owner.d.ts +3 -0
- package/dist/image-owner.d.ts.map +1 -0
- package/dist/image-owner.js +11 -0
- package/dist/image-owner.js.map +1 -0
- package/dist/index.d.ts +43 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/interaction-surface.d.ts +12 -0
- package/dist/interaction-surface.d.ts.map +1 -0
- package/dist/interaction-surface.js +36 -0
- package/dist/interaction-surface.js.map +1 -0
- package/dist/items.d.ts +20 -0
- package/dist/items.d.ts.map +1 -0
- package/dist/items.js +109 -0
- package/dist/items.js.map +1 -0
- package/dist/keyboard.d.ts +41 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +256 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/label.d.ts +7 -0
- package/dist/label.d.ts.map +1 -0
- package/dist/label.js +60 -0
- package/dist/label.js.map +1 -0
- package/dist/layout.d.ts +13 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +348 -0
- package/dist/layout.js.map +1 -0
- package/dist/liquid-grid.d.ts +3 -0
- package/dist/liquid-grid.d.ts.map +1 -0
- package/dist/liquid-grid.js +24 -0
- package/dist/liquid-grid.js.map +1 -0
- package/dist/liquid.d.ts +18 -0
- package/dist/liquid.d.ts.map +1 -0
- package/dist/liquid.js +234 -0
- package/dist/liquid.js.map +1 -0
- package/dist/loader.d.ts +19 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +173 -0
- package/dist/loader.js.map +1 -0
- package/dist/motion-scope.d.ts +39 -0
- package/dist/motion-scope.d.ts.map +1 -0
- package/dist/motion-scope.js +238 -0
- package/dist/motion-scope.js.map +1 -0
- package/dist/motion-states.d.ts +36 -0
- package/dist/motion-states.d.ts.map +1 -0
- package/dist/motion-states.js +165 -0
- package/dist/motion-states.js.map +1 -0
- package/dist/particles.d.ts +39 -0
- package/dist/particles.d.ts.map +1 -0
- package/dist/particles.js +265 -0
- package/dist/particles.js.map +1 -0
- package/dist/path.d.ts +12 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +90 -0
- package/dist/path.js.map +1 -0
- package/dist/playback-group.d.ts +6 -0
- package/dist/playback-group.d.ts.map +1 -0
- package/dist/playback-group.js +141 -0
- package/dist/playback-group.js.map +1 -0
- package/dist/playback.d.ts +25 -0
- package/dist/playback.d.ts.map +1 -0
- package/dist/playback.js +35 -0
- package/dist/playback.js.map +1 -0
- package/dist/press.d.ts.map +1 -1
- package/dist/press.js +23 -7
- package/dist/press.js.map +1 -1
- package/dist/properties.d.ts +6 -3
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +26 -2
- package/dist/properties.js.map +1 -1
- package/dist/reveal.d.ts +25 -0
- package/dist/reveal.d.ts.map +1 -0
- package/dist/reveal.js +294 -0
- package/dist/reveal.js.map +1 -0
- package/dist/roll-diff.d.ts +22 -0
- package/dist/roll-diff.d.ts.map +1 -0
- package/dist/roll-diff.js +36 -0
- package/dist/roll-diff.js.map +1 -0
- package/dist/roll.d.ts +29 -0
- package/dist/roll.d.ts.map +1 -0
- package/dist/roll.js +442 -0
- package/dist/roll.js.map +1 -0
- package/dist/scroll-linked.d.ts +10 -0
- package/dist/scroll-linked.d.ts.map +1 -0
- package/dist/scroll-linked.js +58 -0
- package/dist/scroll-linked.js.map +1 -0
- package/dist/sequence.d.ts +10 -5
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +208 -14
- package/dist/sequence.js.map +1 -1
- package/dist/shimmer.d.ts +12 -0
- package/dist/shimmer.d.ts.map +1 -0
- package/dist/shimmer.js +161 -0
- package/dist/shimmer.js.map +1 -0
- package/dist/svg-path.d.ts +14 -0
- package/dist/svg-path.d.ts.map +1 -0
- package/dist/svg-path.js +281 -0
- package/dist/svg-path.js.map +1 -0
- package/dist/symbol-effect.d.ts +23 -0
- package/dist/symbol-effect.d.ts.map +1 -0
- package/dist/symbol-effect.js +187 -0
- package/dist/symbol-effect.js.map +1 -0
- package/dist/text-layout.d.ts +30 -0
- package/dist/text-layout.d.ts.map +1 -0
- package/dist/text-layout.js +185 -0
- package/dist/text-layout.js.map +1 -0
- package/dist/text.d.ts +17 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +263 -0
- package/dist/text.js.map +1 -0
- package/dist/track.d.ts +3 -1
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +266 -13
- package/dist/track.js.map +1 -1
- package/dist/transition.d.ts +17 -1
- package/dist/transition.d.ts.map +1 -1
- package/dist/transition.js +41 -6
- package/dist/transition.js.map +1 -1
- package/dist/types.d.ts +48 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/vue/index.d.ts +95 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +163 -0
- package/dist/vue/index.js.map +1 -0
- package/dist/zoom-native.d.ts +30 -0
- package/dist/zoom-native.d.ts.map +1 -0
- package/dist/zoom-native.js +56 -0
- package/dist/zoom-native.js.map +1 -0
- package/dist/zoomable.d.ts +48 -0
- package/dist/zoomable.d.ts.map +1 -0
- package/dist/zoomable.js +249 -0
- package/dist/zoomable.js.map +1 -0
- package/package.json +29 -5
- package/platforms/android/include.gradle +7 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ColorTarget.java +102 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/DecorationTarget.java +154 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ImageEffect.java +288 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFollower.java +91 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/NumberRoll.java +190 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/PhotoZoom.java +250 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/TextReveal.java +180 -0
- package/platforms/android/proguard-rules.pro +19 -0
- package/platforms/ios/build.xcconfig +1 -0
- package/platforms/ios/src/JoltImageEffect.h +25 -0
- package/platforms/ios/src/JoltImageEffect.mm +242 -0
- package/platforms/ios/src/JoltInteractiveAnimation.h +18 -0
- package/platforms/ios/src/JoltInteractiveAnimation.m +123 -0
- package/platforms/ios/src/JoltPhotoZoom.h +23 -0
- package/platforms/ios/src/JoltPhotoZoom.m +229 -0
- package/platforms/ios/src/module.modulemap +6 -0
- package/src/android-plugin.d.ts +155 -0
- package/src/animate.ts +249 -36
- package/src/color.ts +101 -0
- package/src/config.ts +84 -0
- package/src/decay.ts +45 -0
- package/src/decoration.ts +180 -0
- package/src/drag-input.ts +74 -0
- package/src/drag-physics.ts +110 -0
- package/src/drag.ts +395 -0
- package/src/driver/android-color.ts +170 -0
- package/src/driver/android-decoration.ts +182 -0
- package/src/driver/android-playback.ts +157 -0
- package/src/driver/android.ts +208 -20
- package/src/driver/index.ts +37 -2
- package/src/driver/ios-color.ts +441 -0
- package/src/driver/ios-decoration.ts +332 -0
- package/src/driver/ios-layout.ts +63 -0
- package/src/driver/ios-playback.ts +51 -0
- package/src/driver/ios-shadow.ts +50 -0
- package/src/driver/ios.ts +193 -33
- package/src/engine.ts +321 -27
- package/src/haptics.ts +148 -0
- package/src/image-effect-native.ts +129 -0
- package/src/image-effect.ts +336 -0
- package/src/image-owner.ts +12 -0
- package/src/index.ts +59 -2
- package/src/interaction-surface.ts +41 -0
- package/src/ios-plugin.d.ts +81 -0
- package/src/items.ts +140 -0
- package/src/keyboard.ts +291 -0
- package/src/label.ts +76 -0
- package/src/layout.ts +408 -0
- package/src/liquid-grid.ts +28 -0
- package/src/liquid.ts +287 -0
- package/src/loader.ts +202 -0
- package/src/motion-scope.ts +279 -0
- package/src/motion-states.ts +215 -0
- package/src/particles.ts +323 -0
- package/src/path.ts +124 -0
- package/src/playback-group.ts +143 -0
- package/src/playback.ts +62 -0
- package/src/press.ts +26 -10
- package/src/properties.ts +32 -6
- package/src/reveal.ts +374 -0
- package/src/roll-diff.ts +57 -0
- package/src/roll.ts +515 -0
- package/src/scroll-linked.ts +73 -0
- package/src/sequence.ts +204 -14
- package/src/shimmer.ts +180 -0
- package/src/svg-path.ts +355 -0
- package/src/symbol-effect.ts +226 -0
- package/src/text-layout.ts +228 -0
- package/src/text.ts +279 -0
- package/src/track.ts +347 -12
- package/src/transition.ts +63 -6
- package/src/types.ts +49 -1
- package/src/vue/index.ts +231 -0
- package/src/zoom-native.ts +124 -0
- package/src/zoomable.ts +330 -0
package/dist/zoomable.js
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { Application, Image, isIOS } from '@nativescript/core';
|
|
2
|
+
import { stop, toView } from './animate.js';
|
|
3
|
+
import { reducedMotion } from './config.js';
|
|
4
|
+
import { ownImage } from './image-owner.js';
|
|
5
|
+
import { createZoomDriver } from './zoom-native.js';
|
|
6
|
+
/** Makes an Image interactive without per-frame JS. Owns its transforms until disposed. */
|
|
7
|
+
export function zoomable(target, options = {}) {
|
|
8
|
+
const image = toView(target);
|
|
9
|
+
if (!(image instanceof Image))
|
|
10
|
+
throw new TypeError('zoomable() expects a NativeScript Image.');
|
|
11
|
+
if (!options || typeof options !== 'object')
|
|
12
|
+
throw new TypeError('Zoom options must be an object.');
|
|
13
|
+
const viewport = options.viewport
|
|
14
|
+
? toView(options.viewport)
|
|
15
|
+
: image.parent;
|
|
16
|
+
if (!viewport)
|
|
17
|
+
throw new TypeError('A zoom viewport is required before the image has a parent.');
|
|
18
|
+
const scale = options.scale ?? [1, 5];
|
|
19
|
+
if (!Array.isArray(scale) ||
|
|
20
|
+
scale.length !== 2 ||
|
|
21
|
+
!scale.every(Number.isFinite) ||
|
|
22
|
+
scale[0] < 1 ||
|
|
23
|
+
scale[1] < scale[0])
|
|
24
|
+
throw new RangeError('Zoom scale must be [minimum, maximum], with 1 <= minimum <= maximum.');
|
|
25
|
+
const doubleTap = options.doubleTap ?? 2.5;
|
|
26
|
+
if (!Number.isFinite(doubleTap) || doubleTap < 1)
|
|
27
|
+
throw new RangeError('Double-tap zoom must be a finite number >= 1.');
|
|
28
|
+
if (options.dismiss !== undefined &&
|
|
29
|
+
options.dismiss !== false &&
|
|
30
|
+
options.dismiss !== 'vertical')
|
|
31
|
+
throw new TypeError("Dismiss must be 'vertical' or false.");
|
|
32
|
+
for (const callback of [options.onDismiss, options.onSettled, options.onError])
|
|
33
|
+
if (callback !== undefined && typeof callback !== 'function')
|
|
34
|
+
throw new TypeError('Zoom callbacks must be functions.');
|
|
35
|
+
const backdrop = options.backdrop ? toView(options.backdrop) : undefined;
|
|
36
|
+
const chrome = options.chrome ? toView(options.chrome) : undefined;
|
|
37
|
+
if (backdrop === image ||
|
|
38
|
+
chrome === image ||
|
|
39
|
+
backdrop === viewport ||
|
|
40
|
+
chrome === viewport)
|
|
41
|
+
throw new TypeError('Dismissal backdrop/chrome must be separate from the image and viewport.');
|
|
42
|
+
if (image.parent && image.parent !== viewport)
|
|
43
|
+
throw new TypeError('The zoom viewport must be the image’s direct parent.');
|
|
44
|
+
if (image.rotate ||
|
|
45
|
+
image.rotateX ||
|
|
46
|
+
image.rotateY ||
|
|
47
|
+
image.scaleX <= 0 ||
|
|
48
|
+
image.scaleY <= 0)
|
|
49
|
+
throw new TypeError('Zoom supports positive axis-aligned image transforms; rotate an ancestor instead.');
|
|
50
|
+
return new Photo(image, viewport, { ...options, doubleTap, scale, backdrop, chrome });
|
|
51
|
+
}
|
|
52
|
+
class Photo {
|
|
53
|
+
image;
|
|
54
|
+
viewport;
|
|
55
|
+
options;
|
|
56
|
+
failure;
|
|
57
|
+
suspended = false;
|
|
58
|
+
driver;
|
|
59
|
+
stopped = false;
|
|
60
|
+
queued = false;
|
|
61
|
+
releaseOwnership = () => { };
|
|
62
|
+
generation = 0;
|
|
63
|
+
reduceObserver;
|
|
64
|
+
latest;
|
|
65
|
+
constructor(image, viewport, options) {
|
|
66
|
+
this.image = image;
|
|
67
|
+
this.viewport = viewport;
|
|
68
|
+
this.options = options;
|
|
69
|
+
this.latest = { x: 0, y: 0, scale: options.scale[0], progress: 0, pending: false };
|
|
70
|
+
this.releaseOwnership = ownImage(image, this.dispose);
|
|
71
|
+
stop(image, ['x', 'y', 'scaleX', 'scaleY']);
|
|
72
|
+
for (const view of [image, viewport]) {
|
|
73
|
+
view.on('loaded', this.schedule);
|
|
74
|
+
view.on('layoutChanged', this.schedule);
|
|
75
|
+
view.on('unloaded', this.dispose);
|
|
76
|
+
}
|
|
77
|
+
image.on('imageSourceChange', this.sourceChanged);
|
|
78
|
+
image.on('stretchChange', this.sourceChanged);
|
|
79
|
+
Application.on(Application.suspendEvent, this.suspend);
|
|
80
|
+
Application.on(Application.resumeEvent, this.resume);
|
|
81
|
+
if (isIOS)
|
|
82
|
+
this.reduceObserver = Application.ios.addNotificationObserver(UIAccessibilityReduceMotionStatusDidChangeNotification, this.preferences);
|
|
83
|
+
this.schedule();
|
|
84
|
+
}
|
|
85
|
+
get ready() {
|
|
86
|
+
return !!this.driver;
|
|
87
|
+
}
|
|
88
|
+
get error() {
|
|
89
|
+
return this.failure;
|
|
90
|
+
}
|
|
91
|
+
get state() {
|
|
92
|
+
return { ...(this.driver?.state ?? this.latest) };
|
|
93
|
+
}
|
|
94
|
+
get nativeController() {
|
|
95
|
+
return this.driver?.native;
|
|
96
|
+
}
|
|
97
|
+
zoomTo(value, focus, animated = true) {
|
|
98
|
+
if (!Number.isFinite(value) ||
|
|
99
|
+
value < this.options.scale[0] ||
|
|
100
|
+
value > this.options.scale[1])
|
|
101
|
+
throw new RangeError('Zoom must be within the configured scale range.');
|
|
102
|
+
if (focus && (!Number.isFinite(focus.x) || !Number.isFinite(focus.y)))
|
|
103
|
+
throw new RangeError('Zoom focus must be finite.');
|
|
104
|
+
if (this.stopped)
|
|
105
|
+
return;
|
|
106
|
+
const size = this.viewport.getActualSize();
|
|
107
|
+
this.driver?.zoom(value, focus?.x ?? size.width / 2, focus?.y ?? size.height / 2, animated);
|
|
108
|
+
}
|
|
109
|
+
reset(animated = true) {
|
|
110
|
+
this.generation++;
|
|
111
|
+
this.driver?.reset(animated);
|
|
112
|
+
}
|
|
113
|
+
requestDismiss() {
|
|
114
|
+
this.driver?.requestDismiss();
|
|
115
|
+
}
|
|
116
|
+
cancelDismiss() {
|
|
117
|
+
this.reset(true);
|
|
118
|
+
}
|
|
119
|
+
dispose = () => {
|
|
120
|
+
if (this.stopped)
|
|
121
|
+
return;
|
|
122
|
+
this.stopped = true;
|
|
123
|
+
this.generation++;
|
|
124
|
+
this.latest = {
|
|
125
|
+
x: 0,
|
|
126
|
+
y: 0,
|
|
127
|
+
scale: this.options.scale[0],
|
|
128
|
+
progress: 0,
|
|
129
|
+
pending: false,
|
|
130
|
+
};
|
|
131
|
+
this.driver?.stop();
|
|
132
|
+
this.driver = undefined;
|
|
133
|
+
this.releaseOwnership();
|
|
134
|
+
for (const view of [this.image, this.viewport]) {
|
|
135
|
+
view.off('loaded', this.schedule);
|
|
136
|
+
view.off('layoutChanged', this.schedule);
|
|
137
|
+
view.off('unloaded', this.dispose);
|
|
138
|
+
}
|
|
139
|
+
this.image.off('imageSourceChange', this.sourceChanged);
|
|
140
|
+
this.image.off('stretchChange', this.sourceChanged);
|
|
141
|
+
Application.off(Application.suspendEvent, this.suspend);
|
|
142
|
+
Application.off(Application.resumeEvent, this.resume);
|
|
143
|
+
if (this.reduceObserver)
|
|
144
|
+
Application.ios.removeNotificationObserver(this.reduceObserver, UIAccessibilityReduceMotionStatusDidChangeNotification);
|
|
145
|
+
this.reduceObserver = undefined;
|
|
146
|
+
};
|
|
147
|
+
dismissed = (x, y, scale, velocity, progress) => {
|
|
148
|
+
if (this.stopped)
|
|
149
|
+
return;
|
|
150
|
+
const generation = ++this.generation;
|
|
151
|
+
const valid = () => !this.stopped && generation === this.generation;
|
|
152
|
+
const dismissal = {
|
|
153
|
+
state: { x, y, scale, progress, pending: true },
|
|
154
|
+
velocity,
|
|
155
|
+
cancel: () => {
|
|
156
|
+
if (!valid())
|
|
157
|
+
return false;
|
|
158
|
+
this.cancelDismiss();
|
|
159
|
+
return true;
|
|
160
|
+
},
|
|
161
|
+
complete: () => {
|
|
162
|
+
if (!valid())
|
|
163
|
+
return false;
|
|
164
|
+
this.dispose();
|
|
165
|
+
return true;
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
if (this.options.onDismiss)
|
|
169
|
+
this.options.onDismiss(dismissal);
|
|
170
|
+
else
|
|
171
|
+
dismissal.cancel();
|
|
172
|
+
};
|
|
173
|
+
settled = (x, y, scale) => {
|
|
174
|
+
if (this.stopped)
|
|
175
|
+
return;
|
|
176
|
+
this.generation++;
|
|
177
|
+
this.latest = { x, y, scale, progress: 0, pending: false };
|
|
178
|
+
this.options.onSettled?.({ ...this.latest });
|
|
179
|
+
};
|
|
180
|
+
sourceChanged = () => {
|
|
181
|
+
this.generation++;
|
|
182
|
+
this.driver?.stop();
|
|
183
|
+
this.driver = undefined;
|
|
184
|
+
this.schedule();
|
|
185
|
+
};
|
|
186
|
+
suspend = () => {
|
|
187
|
+
this.suspended = true;
|
|
188
|
+
this.generation++;
|
|
189
|
+
this.driver?.setActive(false);
|
|
190
|
+
};
|
|
191
|
+
resume = () => {
|
|
192
|
+
this.suspended = false;
|
|
193
|
+
this.preferences();
|
|
194
|
+
this.driver?.setActive(true);
|
|
195
|
+
this.schedule();
|
|
196
|
+
};
|
|
197
|
+
preferences = () => this.driver?.setReduced(reducedMotion());
|
|
198
|
+
schedule = () => {
|
|
199
|
+
if (this.stopped || this.queued)
|
|
200
|
+
return;
|
|
201
|
+
this.queued = true;
|
|
202
|
+
void Promise.resolve()
|
|
203
|
+
.then(() => {
|
|
204
|
+
this.queued = false;
|
|
205
|
+
if (this.stopped ||
|
|
206
|
+
this.suspended ||
|
|
207
|
+
!this.image.isLoaded ||
|
|
208
|
+
!this.viewport.isLoaded)
|
|
209
|
+
return;
|
|
210
|
+
if (this.driver) {
|
|
211
|
+
this.driver.layout();
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (this.image.parent !== this.viewport)
|
|
215
|
+
throw new TypeError('Zoom viewport must remain the direct image parent.');
|
|
216
|
+
const size = this.viewport.getActualSize();
|
|
217
|
+
const imageSize = this.image.getActualSize(), source = this.image.imageSource;
|
|
218
|
+
if (size.width <= 0 ||
|
|
219
|
+
size.height <= 0 ||
|
|
220
|
+
imageSize.width <= 0 ||
|
|
221
|
+
imageSize.height <= 0 ||
|
|
222
|
+
!source ||
|
|
223
|
+
!Number.isFinite(source.width) ||
|
|
224
|
+
!Number.isFinite(source.height) ||
|
|
225
|
+
source.width <= 0 ||
|
|
226
|
+
source.height <= 0)
|
|
227
|
+
return;
|
|
228
|
+
if (isIOS && typeof JoltPhotoZoom === 'undefined')
|
|
229
|
+
throw new Error('Rebuild the native app to install Jolt photo gestures.');
|
|
230
|
+
this.driver = createZoomDriver(this.image, this.viewport, {
|
|
231
|
+
minimum: this.options.scale[0],
|
|
232
|
+
maximum: this.options.scale[1],
|
|
233
|
+
doubleTap: this.options.doubleTap,
|
|
234
|
+
dismiss: this.options.dismiss === 'vertical',
|
|
235
|
+
reduced: reducedMotion(),
|
|
236
|
+
backdrop: this.options.backdrop,
|
|
237
|
+
chrome: this.options.chrome,
|
|
238
|
+
}, this.dismissed, this.settled);
|
|
239
|
+
})
|
|
240
|
+
.catch((error) => {
|
|
241
|
+
if (this.stopped)
|
|
242
|
+
return;
|
|
243
|
+
this.failure = error instanceof Error ? error : new Error(String(error));
|
|
244
|
+
this.dispose();
|
|
245
|
+
this.options.onError?.(this.failure);
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=zoomable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zoomable.js","sourceRoot":"","sources":["../src/zoomable.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rafaelaugusto/jolt",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.10",
|
|
4
4
|
"description": "Native animations for NativeScript: presets, springs, keyframes and stagger in one call.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nativescript",
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
"spring",
|
|
11
11
|
"keyframes",
|
|
12
12
|
"ios",
|
|
13
|
-
"android"
|
|
13
|
+
"android",
|
|
14
|
+
"vue"
|
|
14
15
|
],
|
|
15
16
|
"author": "Rafael Augusto",
|
|
16
17
|
"license": "MIT",
|
|
@@ -28,17 +29,26 @@
|
|
|
28
29
|
"types": "./dist/index.d.ts",
|
|
29
30
|
"default": "./dist/index.js"
|
|
30
31
|
},
|
|
32
|
+
"./vue": {
|
|
33
|
+
"types": "./dist/vue/index.d.ts",
|
|
34
|
+
"default": "./dist/vue/index.js"
|
|
35
|
+
},
|
|
31
36
|
"./package.json": "./package.json"
|
|
32
37
|
},
|
|
33
38
|
"files": [
|
|
34
39
|
"dist",
|
|
35
|
-
"src"
|
|
40
|
+
"src",
|
|
41
|
+
"platforms/ios",
|
|
42
|
+
"platforms/android/java",
|
|
43
|
+
"platforms/android/include.gradle",
|
|
44
|
+
"platforms/android/proguard-rules.pro"
|
|
36
45
|
],
|
|
37
46
|
"sideEffects": false,
|
|
38
47
|
"scripts": {
|
|
39
48
|
"build": "node -e \"fs.rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.build.json",
|
|
40
49
|
"dev": "tsc -p tsconfig.build.json --watch",
|
|
41
50
|
"typecheck": "tsc --noEmit",
|
|
51
|
+
"benchmark:typecheck": "tsc -p benchmarks/tsconfig.json",
|
|
42
52
|
"test": "vitest run",
|
|
43
53
|
"test:watch": "vitest",
|
|
44
54
|
"format": "prettier --write .",
|
|
@@ -46,15 +56,23 @@
|
|
|
46
56
|
"docs:dev": "vitepress dev docs",
|
|
47
57
|
"docs:build": "vitepress build docs",
|
|
48
58
|
"docs:preview": "vitepress preview docs",
|
|
49
|
-
"prepack": "npm run build"
|
|
59
|
+
"prepack": "npm run build",
|
|
60
|
+
"docs:check-media": "node scripts/check-docs-media.mjs"
|
|
50
61
|
},
|
|
51
62
|
"peerDependencies": {
|
|
52
|
-
"@nativescript/core": ">=8.9.0"
|
|
63
|
+
"@nativescript/core": ">=8.9.0",
|
|
64
|
+
"nativescript-vue": ">=3.0.0"
|
|
65
|
+
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"nativescript-vue": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
53
70
|
},
|
|
54
71
|
"devDependencies": {
|
|
55
72
|
"@nativescript/core": "^9.1.3",
|
|
56
73
|
"@nativescript/types-android": "^9.1.1",
|
|
57
74
|
"@nativescript/types-ios": "^9.1.3",
|
|
75
|
+
"nativescript-vue": "3.1.2",
|
|
58
76
|
"prettier": "^3.9.10",
|
|
59
77
|
"typescript": "^7.0.2",
|
|
60
78
|
"vitepress": "^1.6.4",
|
|
@@ -65,5 +83,11 @@
|
|
|
65
83
|
},
|
|
66
84
|
"publishConfig": {
|
|
67
85
|
"access": "public"
|
|
86
|
+
},
|
|
87
|
+
"nativescript": {
|
|
88
|
+
"platforms": {
|
|
89
|
+
"android": "8.9.0",
|
|
90
|
+
"ios": "8.9.0"
|
|
91
|
+
}
|
|
68
92
|
}
|
|
69
93
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Applied by the NativeScript app. Preserve fields used by the native color target.
|
|
2
|
+
def joltDependency = nativescriptDependencies.find { it.name == '@rafaelaugusto/jolt' }
|
|
3
|
+
if (joltDependency != null) {
|
|
4
|
+
android.buildTypes.all {
|
|
5
|
+
proguardFile new File(rootDir, "${joltDependency.directory}/platforms/android/proguard-rules.pro")
|
|
6
|
+
}
|
|
7
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.graphics.PorterDuff;
|
|
4
|
+
import android.graphics.drawable.ColorDrawable;
|
|
5
|
+
import android.graphics.drawable.Drawable;
|
|
6
|
+
import android.view.View;
|
|
7
|
+
import android.widget.TextView;
|
|
8
|
+
import java.lang.ref.WeakReference;
|
|
9
|
+
import java.lang.reflect.Field;
|
|
10
|
+
import java.lang.reflect.Method;
|
|
11
|
+
|
|
12
|
+
/** ObjectAnimator target. All frame updates stay in native code. */
|
|
13
|
+
public final class ColorTarget {
|
|
14
|
+
private static final String BORDER = "org.nativescript.widgets.BorderDrawable";
|
|
15
|
+
static final Field[] FIELDS = fields();
|
|
16
|
+
private static final String SHADOW = "org.nativescript.widgets.BoxShadowDrawable";
|
|
17
|
+
private static final Method UNWRAP = unwrapMethod();
|
|
18
|
+
private final WeakReference<View> view;
|
|
19
|
+
private final int property;
|
|
20
|
+
private int color;
|
|
21
|
+
|
|
22
|
+
// 0 = background, 1 = uniform border, 2 = text.
|
|
23
|
+
public ColorTarget(View view, int property, int initialColor) {
|
|
24
|
+
this.view = new WeakReference<>(view);
|
|
25
|
+
this.property = property;
|
|
26
|
+
this.color = initialColor;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private static Field[] fields() {
|
|
30
|
+
try {
|
|
31
|
+
Class<?> type = Class.forName(BORDER);
|
|
32
|
+
String[] names = {"backgroundColor", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor"};
|
|
33
|
+
Field[] result = new Field[names.length];
|
|
34
|
+
for (int i = 0; i < names.length; i++) {
|
|
35
|
+
result[i] = type.getDeclaredField(names[i]);
|
|
36
|
+
result[i].setAccessible(true);
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
} catch (ReflectiveOperationException | SecurityException exception) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private static Method unwrapMethod() {
|
|
45
|
+
try {
|
|
46
|
+
return Class.forName(SHADOW).getMethod("getWrappedDrawable");
|
|
47
|
+
} catch (ReflectiveOperationException exception) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static Drawable background(View nativeView) {
|
|
53
|
+
Drawable drawable = nativeView.getBackground();
|
|
54
|
+
// Avoid reflective method lookups and exceptions in the frame loop.
|
|
55
|
+
if (drawable != null && drawable.getClass().getName().equals(SHADOW) && UNWRAP != null) {
|
|
56
|
+
try {
|
|
57
|
+
return (Drawable) UNWRAP.invoke(drawable);
|
|
58
|
+
} catch (ReflectiveOperationException exception) {
|
|
59
|
+
return drawable;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return drawable;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public boolean isSupported() {
|
|
66
|
+
View nativeView = view.get();
|
|
67
|
+
if (nativeView == null) return false;
|
|
68
|
+
if (property == 2) return nativeView instanceof TextView;
|
|
69
|
+
Drawable drawable = background(nativeView);
|
|
70
|
+
if (drawable == null) return true;
|
|
71
|
+
if (drawable.getClass().getName().equals(SHADOW)) return false;
|
|
72
|
+
return !drawable.getClass().getName().equals(BORDER) || FIELDS != null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
public int getColor() { return color; }
|
|
76
|
+
|
|
77
|
+
public void setColor(int value) {
|
|
78
|
+
View nativeView = view.get();
|
|
79
|
+
if (nativeView == null) return;
|
|
80
|
+
color = value;
|
|
81
|
+
if (property == 2) {
|
|
82
|
+
((TextView) nativeView).setTextColor(value);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
// Resolve on every frame: a Core style update may replace the drawable.
|
|
86
|
+
Drawable drawable = background(nativeView);
|
|
87
|
+
if (drawable == null || drawable.getClass().getName().equals(SHADOW)) return;
|
|
88
|
+
if (drawable.getClass().getName().equals(BORDER)) {
|
|
89
|
+
if (FIELDS == null) return;
|
|
90
|
+
try {
|
|
91
|
+
if (property == 0) FIELDS[0].setInt(drawable, value);
|
|
92
|
+
else for (int i = 1; i < FIELDS.length; i++) FIELDS[i].setInt(drawable, value);
|
|
93
|
+
drawable.invalidateSelf();
|
|
94
|
+
} catch (IllegalAccessException exception) {
|
|
95
|
+
// Unsupported Core versions keep the final model color.
|
|
96
|
+
}
|
|
97
|
+
} else if (property == 0) {
|
|
98
|
+
if (drawable instanceof ColorDrawable) ((ColorDrawable) drawable).setColor(value);
|
|
99
|
+
else drawable.setColorFilter(value, PorterDuff.Mode.SRC_IN);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.animation.StateListAnimator;
|
|
4
|
+
import android.graphics.drawable.Drawable;
|
|
5
|
+
import android.graphics.drawable.ColorDrawable;
|
|
6
|
+
import android.view.View;
|
|
7
|
+
import java.lang.ref.WeakReference;
|
|
8
|
+
import java.lang.reflect.Constructor;
|
|
9
|
+
import java.lang.reflect.Field;
|
|
10
|
+
import java.util.WeakHashMap;
|
|
11
|
+
|
|
12
|
+
/** ObjectAnimator's float target. No JavaScript enters the native frame loop. */
|
|
13
|
+
public final class DecorationTarget {
|
|
14
|
+
private static final String BORDER = "org.nativescript.widgets.BorderDrawable";
|
|
15
|
+
private static final Field[][] FIELDS = fields();
|
|
16
|
+
private static final Constructor<?> CONSTRUCTOR = constructor();
|
|
17
|
+
private static final WeakHashMap<View, BackgroundLease> BACKGROUNDS = new WeakHashMap<>();
|
|
18
|
+
private static final WeakHashMap<View, Lease> LEASES = new WeakHashMap<>();
|
|
19
|
+
private final WeakReference<View> view;
|
|
20
|
+
private final int property;
|
|
21
|
+
private final int borderColor;
|
|
22
|
+
private float value;
|
|
23
|
+
private boolean acquired;
|
|
24
|
+
|
|
25
|
+
// 0 = uniform radius, 1 = uniform width, 2 = elevation, 3 = translationZ.
|
|
26
|
+
public DecorationTarget(View view, int property, float value, int borderColor) {
|
|
27
|
+
this.view = new WeakReference<>(view);
|
|
28
|
+
this.property = property;
|
|
29
|
+
this.value = value;
|
|
30
|
+
this.borderColor = borderColor;
|
|
31
|
+
}
|
|
32
|
+
private static Field[][] fields() {
|
|
33
|
+
try {
|
|
34
|
+
Class<?> type = Class.forName(BORDER);
|
|
35
|
+
String[][] names = {
|
|
36
|
+
{"borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"},
|
|
37
|
+
{"borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth"}
|
|
38
|
+
};
|
|
39
|
+
Field[][] result = new Field[2][4];
|
|
40
|
+
for (int i = 0; i < 2; i++) for (int j = 0; j < 4; j++) {
|
|
41
|
+
result[i][j] = type.getDeclaredField(names[i][j]);
|
|
42
|
+
result[i][j].setAccessible(true);
|
|
43
|
+
}
|
|
44
|
+
return result;
|
|
45
|
+
} catch (ReflectiveOperationException | SecurityException exception) { return null; }
|
|
46
|
+
}
|
|
47
|
+
private static Constructor<?> constructor() {
|
|
48
|
+
try { return Class.forName(BORDER).getConstructor(float.class); }
|
|
49
|
+
catch (ReflectiveOperationException | SecurityException exception) { return null; }
|
|
50
|
+
}
|
|
51
|
+
public boolean isSupported() {
|
|
52
|
+
View nativeView = view.get();
|
|
53
|
+
if (nativeView == null) return false;
|
|
54
|
+
if (property >= 2) return true;
|
|
55
|
+
Drawable drawable = ColorTarget.background(nativeView);
|
|
56
|
+
return FIELDS != null && ((drawable != null && drawable.getClass().getName().equals(BORDER)) ||
|
|
57
|
+
((drawable == null || drawable.getClass() == ColorDrawable.class) && CONSTRUCTOR != null && ColorTarget.FIELDS != null));
|
|
58
|
+
}
|
|
59
|
+
public float getValue() { return value; }
|
|
60
|
+
public void setValue(float next) {
|
|
61
|
+
View nativeView = view.get();
|
|
62
|
+
if (nativeView == null) return;
|
|
63
|
+
value = next;
|
|
64
|
+
if (property >= 2) suspendStateAnimator(nativeView);
|
|
65
|
+
if (property == 2) { nativeView.setElevation(next); return; }
|
|
66
|
+
if (property == 3) { nativeView.setTranslationZ(next); return; }
|
|
67
|
+
ensureBackground(nativeView);
|
|
68
|
+
Drawable drawable = ColorTarget.background(nativeView);
|
|
69
|
+
if (drawable == null || !drawable.getClass().getName().equals(BORDER) || FIELDS == null) return;
|
|
70
|
+
try {
|
|
71
|
+
// Core rebuilds the paths from these fields in draw() and getOutline().
|
|
72
|
+
// Keep its bitmap, gradient, color and all other state on the same drawable.
|
|
73
|
+
for (Field field : FIELDS[property]) field.setFloat(drawable, next);
|
|
74
|
+
drawable.invalidateSelf();
|
|
75
|
+
nativeView.invalidateOutline();
|
|
76
|
+
} catch (IllegalAccessException exception) { /* Keep Core's final model. */ }
|
|
77
|
+
}
|
|
78
|
+
public void acquire() {
|
|
79
|
+
View nativeView = view.get();
|
|
80
|
+
if (nativeView == null || acquired) return;
|
|
81
|
+
acquired = true;
|
|
82
|
+
if (property < 2) {
|
|
83
|
+
BackgroundLease lease = BACKGROUNDS.get(nativeView);
|
|
84
|
+
if (lease == null) { lease = new BackgroundLease(); BACKGROUNDS.put(nativeView, lease); }
|
|
85
|
+
lease.count++;
|
|
86
|
+
ensureBackground(nativeView);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
Lease lease = LEASES.get(nativeView);
|
|
90
|
+
if (lease == null) {
|
|
91
|
+
lease = new Lease(nativeView.getStateListAnimator());
|
|
92
|
+
LEASES.put(nativeView, lease);
|
|
93
|
+
nativeView.setStateListAnimator(null);
|
|
94
|
+
}
|
|
95
|
+
lease.count++;
|
|
96
|
+
suspendStateAnimator(nativeView);
|
|
97
|
+
}
|
|
98
|
+
public void release() {
|
|
99
|
+
View nativeView = view.get();
|
|
100
|
+
if (!acquired || nativeView == null) return;
|
|
101
|
+
acquired = false;
|
|
102
|
+
if (property < 2) {
|
|
103
|
+
BackgroundLease lease = BACKGROUNDS.get(nativeView);
|
|
104
|
+
if (lease != null && --lease.count == 0) {
|
|
105
|
+
BACKGROUNDS.remove(nativeView);
|
|
106
|
+
if (lease.drawable != null && nativeView.getBackground() == lease.drawable) nativeView.setBackground(lease.original);
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
suspendStateAnimator(nativeView);
|
|
111
|
+
Lease lease = LEASES.get(nativeView);
|
|
112
|
+
if (lease != null && --lease.count == 0) {
|
|
113
|
+
LEASES.remove(nativeView);
|
|
114
|
+
if (nativeView.getStateListAnimator() == null) {
|
|
115
|
+
float elevation = nativeView.getElevation(), z = nativeView.getTranslationZ();
|
|
116
|
+
nativeView.setStateListAnimator(lease.animator);
|
|
117
|
+
if (lease.animator != null) lease.animator.jumpToCurrentState();
|
|
118
|
+
nativeView.setElevation(elevation);
|
|
119
|
+
nativeView.setTranslationZ(z);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
private void ensureBackground(View nativeView) {
|
|
124
|
+
BackgroundLease lease = BACKGROUNDS.get(nativeView);
|
|
125
|
+
Drawable original = nativeView.getBackground();
|
|
126
|
+
if (lease == null || (original != null && original.getClass() != ColorDrawable.class) || CONSTRUCTOR == null || ColorTarget.FIELDS == null) return;
|
|
127
|
+
try {
|
|
128
|
+
Drawable drawable = (Drawable) CONSTRUCTOR.newInstance(nativeView.getResources().getDisplayMetrics().density);
|
|
129
|
+
ColorTarget.FIELDS[0].setInt(drawable, original == null ? 0 : ((ColorDrawable) original).getColor());
|
|
130
|
+
for (int i = 1; i < ColorTarget.FIELDS.length; i++) ColorTarget.FIELDS[i].setInt(drawable, borderColor);
|
|
131
|
+
lease.original = original;
|
|
132
|
+
lease.drawable = drawable;
|
|
133
|
+
nativeView.setBackground(drawable);
|
|
134
|
+
} catch (ReflectiveOperationException exception) { /* Unsupported Core. */ }
|
|
135
|
+
}
|
|
136
|
+
private static final class BackgroundLease {
|
|
137
|
+
Drawable original, drawable;
|
|
138
|
+
int count;
|
|
139
|
+
}
|
|
140
|
+
private static void suspendStateAnimator(View view) {
|
|
141
|
+
Lease lease = LEASES.get(view);
|
|
142
|
+
StateListAnimator current = view.getStateListAnimator();
|
|
143
|
+
if (lease != null && current != null) {
|
|
144
|
+
// A Core model write may have installed an updated state animator.
|
|
145
|
+
lease.animator = current;
|
|
146
|
+
view.setStateListAnimator(null);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
private static final class Lease {
|
|
150
|
+
StateListAnimator animator;
|
|
151
|
+
int count;
|
|
152
|
+
Lease(StateListAnimator animator) { this.animator = animator; }
|
|
153
|
+
}
|
|
154
|
+
}
|