@rafaelaugusto/jolt 0.1.0-beta.10 → 0.1.0-beta.12
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 +55 -6
- package/dist/animate.d.ts +14 -4
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +50 -34
- package/dist/animate.js.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 +89 -0
- package/dist/driver/android-gradient.js.map +1 -0
- 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 +109 -0
- package/dist/driver/ios-gradient.js.map +1 -0
- package/dist/easing.d.ts +1 -1
- package/dist/easing.d.ts.map +1 -1
- package/dist/easing.js +11 -0
- package/dist/easing.js.map +1 -1
- package/dist/engine.d.ts +18 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +143 -36
- package/dist/engine.js.map +1 -1
- package/dist/gradient.d.ts +90 -0
- package/dist/gradient.d.ts.map +1 -0
- package/dist/gradient.js +253 -0
- package/dist/gradient.js.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +63 -10
- package/dist/keyboard.js.map +1 -1
- package/dist/mixer.d.ts +49 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixer.js +238 -0
- package/dist/mixer.js.map +1 -0
- package/dist/motion-scope.d.ts +4 -1
- package/dist/motion-scope.d.ts.map +1 -1
- package/dist/motion-scope.js +8 -3
- package/dist/motion-scope.js.map +1 -1
- package/dist/motion-states.d.ts +18 -6
- package/dist/motion-states.d.ts.map +1 -1
- package/dist/motion-states.js +114 -26
- package/dist/motion-states.js.map +1 -1
- package/dist/motion-value.d.ts +115 -0
- package/dist/motion-value.d.ts.map +1 -0
- package/dist/motion-value.js +437 -0
- package/dist/motion-value.js.map +1 -0
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +2 -2
- package/dist/path.js.map +1 -1
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +31 -12
- package/dist/track.js.map +1 -1
- package/dist/transition.d.ts +30 -4
- package/dist/transition.d.ts.map +1 -1
- package/dist/transition.js +63 -7
- package/dist/transition.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vue/index.d.ts +28 -2
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +78 -2
- package/dist/vue/index.js.map +1 -1
- package/package.json +1 -1
- package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +195 -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/proguard-rules.pro +2 -0
- package/src/android-plugin.d.ts +56 -0
- package/src/animate.ts +99 -16
- package/src/drag.ts +67 -21
- package/src/driver/android-gradient.ts +109 -0
- package/src/driver/ios-gradient.ts +114 -0
- package/src/easing.ts +14 -0
- package/src/engine.ts +158 -53
- package/src/gradient.ts +378 -0
- package/src/index.ts +34 -3
- package/src/keyboard.ts +83 -18
- package/src/mixer.ts +264 -0
- package/src/motion-scope.ts +14 -6
- package/src/motion-states.ts +145 -41
- package/src/motion-value.ts +563 -0
- package/src/path.ts +2 -1
- package/src/track.ts +37 -12
- package/src/transition.ts +99 -10
- package/src/types.ts +5 -0
- package/src/vue/index.ts +98 -1
package/dist/vue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,eAAe,EACf,CAAC,EACD,WAAW,EACX,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,eAAe,EACf,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/vue/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.animation.Animator;
|
|
4
|
+
import android.animation.AnimatorListenerAdapter;
|
|
5
|
+
import android.animation.ValueAnimator;
|
|
6
|
+
import android.graphics.Canvas;
|
|
7
|
+
import android.graphics.ColorFilter;
|
|
8
|
+
import android.graphics.LinearGradient;
|
|
9
|
+
import android.graphics.Matrix;
|
|
10
|
+
import android.graphics.Paint;
|
|
11
|
+
import android.graphics.PixelFormat;
|
|
12
|
+
import android.graphics.RadialGradient;
|
|
13
|
+
import android.graphics.Rect;
|
|
14
|
+
import android.graphics.RectF;
|
|
15
|
+
import android.graphics.Shader;
|
|
16
|
+
import android.graphics.SweepGradient;
|
|
17
|
+
import android.view.animation.LinearInterpolator;
|
|
18
|
+
|
|
19
|
+
/** Paints a linear, radial or conic gradient and plays sampled frames. All frame updates stay in native code. */
|
|
20
|
+
public final class GradientLayer extends android.graphics.drawable.Drawable {
|
|
21
|
+
public interface Listener {
|
|
22
|
+
void onEnd(boolean finished);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 0 = linear, 1 = radial, 2 = conic.
|
|
26
|
+
private final int type;
|
|
27
|
+
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
28
|
+
private final RectF area = new RectF();
|
|
29
|
+
private final Matrix matrix = new Matrix();
|
|
30
|
+
private int[] colors = new int[0];
|
|
31
|
+
private float[] stops = new float[0];
|
|
32
|
+
// angle, x, y, radius
|
|
33
|
+
private final float[] geometry = new float[4];
|
|
34
|
+
private float corner;
|
|
35
|
+
private ValueAnimator animator;
|
|
36
|
+
private Listener listener;
|
|
37
|
+
|
|
38
|
+
private float[] times;
|
|
39
|
+
private int[] frameColors;
|
|
40
|
+
private float[] frameStops;
|
|
41
|
+
private float[] frameGeometry;
|
|
42
|
+
|
|
43
|
+
public GradientLayer(int type) {
|
|
44
|
+
this.type = type;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public void setCorner(float radius) {
|
|
48
|
+
corner = radius;
|
|
49
|
+
invalidateSelf();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public void paint(int[] colors, float[] stops, float angle, float x, float y, float radius) {
|
|
53
|
+
cancel();
|
|
54
|
+
this.colors = colors;
|
|
55
|
+
this.stops = stops;
|
|
56
|
+
geometry[0] = angle;
|
|
57
|
+
geometry[1] = x;
|
|
58
|
+
geometry[2] = y;
|
|
59
|
+
geometry[3] = radius;
|
|
60
|
+
invalidateSelf();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Frames are flattened: `colors.length / times.length` colors and stops per frame, four geometry values per frame. */
|
|
64
|
+
public void play(float[] times, int[] colors, float[] stops, float[] geometry, long duration, long delay, int repeat, boolean reverse, Listener listener) {
|
|
65
|
+
cancel();
|
|
66
|
+
this.times = times;
|
|
67
|
+
frameColors = colors;
|
|
68
|
+
frameStops = stops;
|
|
69
|
+
frameGeometry = geometry;
|
|
70
|
+
this.listener = listener;
|
|
71
|
+
int count = colors.length / times.length;
|
|
72
|
+
this.colors = new int[count];
|
|
73
|
+
this.stops = new float[count];
|
|
74
|
+
apply(0);
|
|
75
|
+
final ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
|
|
76
|
+
animation.setDuration(Math.max(duration, 1));
|
|
77
|
+
animation.setStartDelay(delay);
|
|
78
|
+
animation.setInterpolator(new LinearInterpolator());
|
|
79
|
+
if (repeat != 0) {
|
|
80
|
+
animation.setRepeatCount(repeat < 0 ? ValueAnimator.INFINITE : repeat);
|
|
81
|
+
animation.setRepeatMode(reverse ? ValueAnimator.REVERSE : ValueAnimator.RESTART);
|
|
82
|
+
}
|
|
83
|
+
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
|
84
|
+
@Override
|
|
85
|
+
public void onAnimationUpdate(ValueAnimator updated) {
|
|
86
|
+
apply(updated.getAnimatedFraction());
|
|
87
|
+
invalidateSelf();
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
animation.addListener(new AnimatorListenerAdapter() {
|
|
91
|
+
private boolean cancelled;
|
|
92
|
+
|
|
93
|
+
@Override
|
|
94
|
+
public void onAnimationCancel(Animator ended) {
|
|
95
|
+
cancelled = true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Override
|
|
99
|
+
public void onAnimationEnd(Animator ended) {
|
|
100
|
+
if (animator != animation) return;
|
|
101
|
+
animator = null;
|
|
102
|
+
Listener done = GradientLayer.this.listener;
|
|
103
|
+
GradientLayer.this.listener = null;
|
|
104
|
+
if (done != null) done.onEnd(!cancelled);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
animator = animation;
|
|
108
|
+
animation.start();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
public void cancel() {
|
|
112
|
+
ValueAnimator running = animator;
|
|
113
|
+
animator = null;
|
|
114
|
+
listener = null;
|
|
115
|
+
if (running != null) running.cancel();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private void apply(float fraction) {
|
|
119
|
+
int frames = times.length;
|
|
120
|
+
int count = colors.length;
|
|
121
|
+
int i = 0;
|
|
122
|
+
while (i < frames - 2 && fraction > times[i + 1]) i++;
|
|
123
|
+
float span = times[i + 1] - times[i];
|
|
124
|
+
float t = span > 0 ? Math.max(0f, Math.min(1f, (fraction - times[i]) / span)) : 1f;
|
|
125
|
+
for (int c = 0; c < count; c++) {
|
|
126
|
+
colors[c] = lerpColor(frameColors[i * count + c], frameColors[(i + 1) * count + c], t);
|
|
127
|
+
stops[c] = lerp(frameStops[i * count + c], frameStops[(i + 1) * count + c], t);
|
|
128
|
+
}
|
|
129
|
+
for (int g = 0; g < 4; g++) geometry[g] = lerp(frameGeometry[i * 4 + g], frameGeometry[(i + 1) * 4 + g], t);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private static float lerp(float a, float b, float t) {
|
|
133
|
+
return a + (b - a) * t;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private static int lerpColor(int a, int b, float t) {
|
|
137
|
+
int alpha = Math.round(lerp((a >>> 24) & 0xff, (b >>> 24) & 0xff, t));
|
|
138
|
+
int red = Math.round(lerp((a >> 16) & 0xff, (b >> 16) & 0xff, t));
|
|
139
|
+
int green = Math.round(lerp((a >> 8) & 0xff, (b >> 8) & 0xff, t));
|
|
140
|
+
int blue = Math.round(lerp(a & 0xff, b & 0xff, t));
|
|
141
|
+
return (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
@Override
|
|
145
|
+
public void draw(Canvas canvas) {
|
|
146
|
+
Rect bounds = getBounds();
|
|
147
|
+
float width = bounds.width();
|
|
148
|
+
float height = bounds.height();
|
|
149
|
+
if (width <= 0 || height <= 0 || colors.length < 2) return;
|
|
150
|
+
double radians = Math.toRadians(geometry[0]);
|
|
151
|
+
float sin = (float) Math.sin(radians);
|
|
152
|
+
float cos = (float) Math.cos(radians);
|
|
153
|
+
float left = bounds.left;
|
|
154
|
+
float top = bounds.top;
|
|
155
|
+
Shader shader;
|
|
156
|
+
if (type == 0) {
|
|
157
|
+
float half = (Math.abs(width * sin) + Math.abs(height * cos)) / 2f;
|
|
158
|
+
float cx = left + width / 2f;
|
|
159
|
+
float cy = top + height / 2f;
|
|
160
|
+
shader = new LinearGradient(cx - sin * half, cy + cos * half, cx + sin * half, cy - cos * half, colors, stops, Shader.TileMode.CLAMP);
|
|
161
|
+
} else if (type == 1) {
|
|
162
|
+
float radius = Math.max(geometry[3] * Math.min(width, height), 0.01f);
|
|
163
|
+
shader = new RadialGradient(left + geometry[1] * width, top + geometry[2] * height, radius, colors, stops, Shader.TileMode.CLAMP);
|
|
164
|
+
} else {
|
|
165
|
+
float cx = left + geometry[1] * width;
|
|
166
|
+
float cy = top + geometry[2] * height;
|
|
167
|
+
SweepGradient sweep = new SweepGradient(cx, cy, colors, stops);
|
|
168
|
+
// Turned so the first color starts at 12 o'clock and sweeps clockwise, as on iOS and in CSS.
|
|
169
|
+
matrix.setRotate(geometry[0] + 90f, cx, cy);
|
|
170
|
+
sweep.setLocalMatrix(matrix);
|
|
171
|
+
shader = sweep;
|
|
172
|
+
}
|
|
173
|
+
paint.setShader(shader);
|
|
174
|
+
area.set(bounds);
|
|
175
|
+
if (corner > 0) canvas.drawRoundRect(area, corner, corner, paint);
|
|
176
|
+
else canvas.drawRect(area, paint);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
@Override
|
|
180
|
+
public void setAlpha(int alpha) {
|
|
181
|
+
paint.setAlpha(alpha);
|
|
182
|
+
invalidateSelf();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
@Override
|
|
186
|
+
public void setColorFilter(ColorFilter filter) {
|
|
187
|
+
paint.setColorFilter(filter);
|
|
188
|
+
invalidateSelf();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
@Override
|
|
192
|
+
public int getOpacity() {
|
|
193
|
+
return PixelFormat.TRANSLUCENT;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.graphics.Rect;
|
|
4
|
+
import android.view.View;
|
|
5
|
+
import android.view.ViewTreeObserver;
|
|
6
|
+
import android.view.WindowInsets;
|
|
7
|
+
|
|
8
|
+
/** Before Android 11: how much of the window the keyboard covers, read from the visible frame on each layout. */
|
|
9
|
+
public final class KeyboardFrame implements ViewTreeObserver.OnGlobalLayoutListener {
|
|
10
|
+
public interface Listener {
|
|
11
|
+
void onChange(int height);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private final View root;
|
|
15
|
+
private final Listener listener;
|
|
16
|
+
private int height;
|
|
17
|
+
|
|
18
|
+
public KeyboardFrame(View root, Listener listener) {
|
|
19
|
+
this.root = root;
|
|
20
|
+
this.listener = listener;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public void attach() {
|
|
24
|
+
height = covered(root);
|
|
25
|
+
root.getViewTreeObserver().addOnGlobalLayoutListener(this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void detach() {
|
|
29
|
+
root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public int height() {
|
|
33
|
+
return height;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Pixels of the window below the visible frame, when that is more than the navigation bar. */
|
|
37
|
+
static int covered(View root) {
|
|
38
|
+
Rect frame = new Rect();
|
|
39
|
+
root.getWindowVisibleDisplayFrame(frame);
|
|
40
|
+
int below = root.getHeight() - frame.bottom;
|
|
41
|
+
WindowInsets insets = root.getRootWindowInsets();
|
|
42
|
+
int bars = insets == null ? 0 : insets.getStableInsetBottom();
|
|
43
|
+
return below > bars ? below : 0;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@Override
|
|
47
|
+
public void onGlobalLayout() {
|
|
48
|
+
int next = covered(root);
|
|
49
|
+
if (next == height) return;
|
|
50
|
+
height = next;
|
|
51
|
+
listener.onChange(next);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
package org.rafaelaugusto.jolt;
|
|
2
|
+
|
|
3
|
+
import android.view.View;
|
|
4
|
+
import android.view.ViewTreeObserver;
|
|
5
|
+
|
|
6
|
+
/** Before Android 11: catches the view where it was when a keyboard layout moves it, and says where it should end up. */
|
|
7
|
+
public final class KeyboardFrameFollower implements ViewTreeObserver.OnGlobalLayoutListener {
|
|
8
|
+
public interface Listener {
|
|
9
|
+
void onMove(float from, float to, int keyboard);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
private final View view;
|
|
13
|
+
private final float offset;
|
|
14
|
+
private final Listener listener;
|
|
15
|
+
private int keyboard;
|
|
16
|
+
private float visualBottom;
|
|
17
|
+
|
|
18
|
+
public KeyboardFrameFollower(View view, float offset, Listener listener) {
|
|
19
|
+
this.view = view;
|
|
20
|
+
this.offset = offset;
|
|
21
|
+
this.listener = listener;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public void attach() {
|
|
25
|
+
keyboard = KeyboardFrame.covered(view.getRootView());
|
|
26
|
+
visualBottom = bottom();
|
|
27
|
+
view.getViewTreeObserver().addOnGlobalLayoutListener(this);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public void detach() {
|
|
31
|
+
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private float bottom() {
|
|
35
|
+
int[] location = new int[2];
|
|
36
|
+
view.getLocationInWindow(location);
|
|
37
|
+
return location[1] + view.getHeight();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@Override
|
|
41
|
+
public void onGlobalLayout() {
|
|
42
|
+
int next = KeyboardFrame.covered(view.getRootView());
|
|
43
|
+
if (next == keyboard) {
|
|
44
|
+
visualBottom = bottom();
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
keyboard = next;
|
|
48
|
+
// The layout for the keyboard is done; the view may already have jumped with it.
|
|
49
|
+
float untranslated = bottom() - view.getTranslationY();
|
|
50
|
+
float top = view.getRootView().getHeight() - next;
|
|
51
|
+
float to = next > 0 ? -Math.max(0, untranslated + offset - top) : 0;
|
|
52
|
+
float from = visualBottom - untranslated;
|
|
53
|
+
view.setTranslationY(from);
|
|
54
|
+
visualBottom = untranslated + to;
|
|
55
|
+
listener.onMove(from, to, next);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -17,3 +17,5 @@
|
|
|
17
17
|
-keep class org.rafaelaugusto.jolt.ImageEffect$* { *; }
|
|
18
18
|
-keep class org.rafaelaugusto.jolt.PhotoZoom { *; }
|
|
19
19
|
-keep class org.rafaelaugusto.jolt.PhotoZoom$* { *; }
|
|
20
|
+
-keep class org.rafaelaugusto.jolt.GradientLayer { *; }
|
|
21
|
+
-keep class org.rafaelaugusto.jolt.GradientLayer$* { *; }
|
package/src/android-plugin.d.ts
CHANGED
|
@@ -94,6 +94,35 @@ declare namespace org.rafaelaugusto.jolt {
|
|
|
94
94
|
})
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
class GradientLayer extends android.graphics.drawable.Drawable {
|
|
98
|
+
constructor(type: number)
|
|
99
|
+
setCorner(radius: number): void
|
|
100
|
+
paint(
|
|
101
|
+
colors: native.Array<number>,
|
|
102
|
+
stops: native.Array<number>,
|
|
103
|
+
angle: number,
|
|
104
|
+
x: number,
|
|
105
|
+
y: number,
|
|
106
|
+
radius: number,
|
|
107
|
+
): void
|
|
108
|
+
play(
|
|
109
|
+
times: native.Array<number>,
|
|
110
|
+
colors: native.Array<number>,
|
|
111
|
+
stops: native.Array<number>,
|
|
112
|
+
geometry: native.Array<number>,
|
|
113
|
+
duration: number,
|
|
114
|
+
delay: number,
|
|
115
|
+
repeat: number,
|
|
116
|
+
reverse: boolean,
|
|
117
|
+
listener: GradientLayer.Listener,
|
|
118
|
+
): void
|
|
119
|
+
cancel(): void
|
|
120
|
+
}
|
|
121
|
+
namespace GradientLayer {
|
|
122
|
+
class Listener {
|
|
123
|
+
constructor(implementation: { onEnd(finished: boolean): void })
|
|
124
|
+
}
|
|
125
|
+
}
|
|
97
126
|
class KeyboardObserver {
|
|
98
127
|
constructor(root: android.view.View, listener: KeyboardObserver.Listener)
|
|
99
128
|
attach(): void
|
|
@@ -107,6 +136,33 @@ declare namespace org.rafaelaugusto.jolt {
|
|
|
107
136
|
})
|
|
108
137
|
}
|
|
109
138
|
}
|
|
139
|
+
class KeyboardFrame {
|
|
140
|
+
constructor(root: android.view.View, listener: KeyboardFrame.Listener)
|
|
141
|
+
attach(): void
|
|
142
|
+
detach(): void
|
|
143
|
+
height(): number
|
|
144
|
+
}
|
|
145
|
+
namespace KeyboardFrame {
|
|
146
|
+
class Listener {
|
|
147
|
+
constructor(implementation: { onChange(height: number): void })
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
class KeyboardFrameFollower {
|
|
151
|
+
constructor(
|
|
152
|
+
view: android.view.View,
|
|
153
|
+
offset: number,
|
|
154
|
+
listener: KeyboardFrameFollower.Listener,
|
|
155
|
+
)
|
|
156
|
+
attach(): void
|
|
157
|
+
detach(): void
|
|
158
|
+
}
|
|
159
|
+
namespace KeyboardFrameFollower {
|
|
160
|
+
class Listener {
|
|
161
|
+
constructor(implementation: {
|
|
162
|
+
onMove(from: number, to: number, keyboard: number): void
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
}
|
|
110
166
|
class TextReveal {
|
|
111
167
|
constructor(
|
|
112
168
|
view: android.widget.TextView,
|
package/src/animate.ts
CHANGED
|
@@ -17,16 +17,25 @@ import { DEFAULT_FRICTION, solveDecay } from './decay.js'
|
|
|
17
17
|
import {
|
|
18
18
|
arrivalOf,
|
|
19
19
|
setArrival,
|
|
20
|
+
stopLayer,
|
|
20
21
|
stopView,
|
|
21
22
|
ViewAnimation,
|
|
22
23
|
type Animation,
|
|
23
24
|
type Plan,
|
|
24
25
|
} from './engine.js'
|
|
25
26
|
import { getPreset, type PresetName } from './presets.js'
|
|
27
|
+
import {
|
|
28
|
+
asRoot,
|
|
29
|
+
detachBindings,
|
|
30
|
+
isMotionValue,
|
|
31
|
+
type MotionValue,
|
|
32
|
+
} from './motion-value.js'
|
|
26
33
|
import { resolveHaptic, type Haptic } from './haptics.js'
|
|
34
|
+
import { layerable } from './mixer.js'
|
|
27
35
|
import { isProperty, precision, type Property } from './properties.js'
|
|
28
36
|
import {
|
|
29
37
|
hasCurve,
|
|
38
|
+
fitTransition,
|
|
30
39
|
mergeTransitions,
|
|
31
40
|
resolveTransition,
|
|
32
41
|
springs,
|
|
@@ -51,24 +60,45 @@ interface Options {
|
|
|
51
60
|
stagger: number | Stagger | undefined
|
|
52
61
|
relative: boolean | undefined
|
|
53
62
|
haptic: Haptic | undefined
|
|
63
|
+
layer?: string
|
|
54
64
|
}
|
|
55
65
|
|
|
56
66
|
/**
|
|
57
67
|
* Animates one view, or several. Takes keyframes or the name of a preset,
|
|
58
|
-
* and a transition or the name of a spring.
|
|
68
|
+
* and a transition or the name of a spring. A motion value animates to a number.
|
|
59
69
|
*
|
|
60
70
|
* ```ts
|
|
61
71
|
* animate(card, 'fadeInUp')
|
|
62
72
|
* animate(card, { scale: 1.1, rotate: [0, 90] }, 'bouncy')
|
|
63
73
|
* animate(rows, 'fadeInUp', { stagger: 40 })
|
|
74
|
+
* animate(progress, 1, 'snappy')
|
|
64
75
|
* ```
|
|
65
76
|
*/
|
|
77
|
+
export function animate(
|
|
78
|
+
value: MotionValue,
|
|
79
|
+
to: number | readonly (number | null)[],
|
|
80
|
+
transition?: Transition | SpringName,
|
|
81
|
+
): Animation
|
|
66
82
|
export function animate(
|
|
67
83
|
target: Target | readonly Target[],
|
|
68
84
|
animation: Keyframes | PresetName,
|
|
69
85
|
options?: AnimateOptions | SpringName,
|
|
70
|
-
): PlaybackAnimation
|
|
71
|
-
|
|
86
|
+
): PlaybackAnimation
|
|
87
|
+
export function animate(
|
|
88
|
+
target: Target | readonly Target[] | MotionValue,
|
|
89
|
+
animation: Keyframes | PresetName | number | readonly (number | null)[],
|
|
90
|
+
options?: AnimateOptions | SpringName,
|
|
91
|
+
): PlaybackAnimation | Animation {
|
|
92
|
+
if (isMotionValue(target))
|
|
93
|
+
return asRoot(target).animate(
|
|
94
|
+
animation as number | readonly (number | null)[],
|
|
95
|
+
options as Transition | SpringName | undefined,
|
|
96
|
+
)
|
|
97
|
+
return prepareAnimation(
|
|
98
|
+
target as Target | readonly Target[],
|
|
99
|
+
animation as Keyframes | PresetName,
|
|
100
|
+
options,
|
|
101
|
+
)()
|
|
72
102
|
}
|
|
73
103
|
|
|
74
104
|
/** Validate and snapshot a complete animation before changing any view ownership. */
|
|
@@ -77,7 +107,7 @@ export function prepareAnimation(
|
|
|
77
107
|
animation: Keyframes | PresetName,
|
|
78
108
|
options?: AnimateOptions | SpringName,
|
|
79
109
|
): () => PlaybackAnimation {
|
|
80
|
-
const { keyframes, base, overrides, stagger, relative, haptic, path } = prepare(
|
|
110
|
+
const { keyframes, base, overrides, stagger, relative, haptic, path, layer } = prepare(
|
|
81
111
|
animation,
|
|
82
112
|
options,
|
|
83
113
|
)
|
|
@@ -88,8 +118,15 @@ export function prepareAnimation(
|
|
|
88
118
|
for (const property of Object.keys(keyframes))
|
|
89
119
|
if (isColorProperty(property)) validateColorTarget(view, property)
|
|
90
120
|
else if (isDecorationProperty(property)) validateDecorationTarget(view, property)
|
|
91
|
-
const plans = plan(keyframes, base, overrides, 0, relative, path)
|
|
92
|
-
return () =>
|
|
121
|
+
const plans = plan(keyframes, base, overrides, 0, relative, path, layer)
|
|
122
|
+
return () => {
|
|
123
|
+
if (layer === undefined)
|
|
124
|
+
detachBindings(
|
|
125
|
+
view,
|
|
126
|
+
plans.map(({ property }) => property),
|
|
127
|
+
)
|
|
128
|
+
return new ViewAnimation(view, plans, feedback)
|
|
129
|
+
}
|
|
93
130
|
}
|
|
94
131
|
|
|
95
132
|
const views = target.map(toView)
|
|
@@ -97,6 +134,7 @@ export function prepareAnimation(
|
|
|
97
134
|
for (const property of Object.keys(keyframes))
|
|
98
135
|
if (isColorProperty(property)) validateColorTarget(view, property)
|
|
99
136
|
else if (isDecorationProperty(property)) validateDecorationTarget(view, property)
|
|
137
|
+
const seed = Math.random()
|
|
100
138
|
const plans = views.map((_, index) =>
|
|
101
139
|
plan(
|
|
102
140
|
keyframes,
|
|
@@ -105,11 +143,20 @@ export function prepareAnimation(
|
|
|
105
143
|
staggerDelay(stagger, index, views.length),
|
|
106
144
|
relative,
|
|
107
145
|
path,
|
|
146
|
+
layer,
|
|
147
|
+
seed,
|
|
108
148
|
),
|
|
109
149
|
)
|
|
110
150
|
return () =>
|
|
111
151
|
playbackGroup(
|
|
112
|
-
views.map((view, index) =>
|
|
152
|
+
views.map((view, index) => {
|
|
153
|
+
if (layer === undefined)
|
|
154
|
+
detachBindings(
|
|
155
|
+
view,
|
|
156
|
+
plans[index]!.map(({ property }) => property),
|
|
157
|
+
)
|
|
158
|
+
return new ViewAnimation(view, plans[index]!, feedback, true)
|
|
159
|
+
}),
|
|
113
160
|
)
|
|
114
161
|
}
|
|
115
162
|
|
|
@@ -186,15 +233,28 @@ export function decay(
|
|
|
186
233
|
)
|
|
187
234
|
}
|
|
188
235
|
|
|
189
|
-
/**
|
|
236
|
+
/**
|
|
237
|
+
* Stops all or selected properties at their current values. `scale` stops both axes.
|
|
238
|
+
* A motion value stops where it is, and so do the views bound to it.
|
|
239
|
+
*/
|
|
240
|
+
export function stop(value: MotionValue): void
|
|
190
241
|
export function stop(
|
|
191
242
|
target: Target | readonly Target[],
|
|
192
243
|
properties?: readonly KeyframeProperty[],
|
|
244
|
+
options?: { layer?: string },
|
|
245
|
+
): void
|
|
246
|
+
export function stop(
|
|
247
|
+
target: Target | readonly Target[] | MotionValue,
|
|
248
|
+
properties?: readonly KeyframeProperty[],
|
|
249
|
+
options?: { layer?: string },
|
|
193
250
|
) {
|
|
251
|
+
if (isMotionValue(target)) return asRoot(target).stop()
|
|
194
252
|
const expanded = properties?.flatMap<Property>((property) =>
|
|
195
253
|
property === 'scale' ? ['scaleX', 'scaleY'] : [property],
|
|
196
254
|
)
|
|
197
|
-
for (const view of toViews(target
|
|
255
|
+
for (const view of toViews(target as Target | readonly Target[]))
|
|
256
|
+
if (options?.layer !== undefined) stopLayer(view, options.layer, expanded)
|
|
257
|
+
else stopView(view, expanded)
|
|
198
258
|
}
|
|
199
259
|
|
|
200
260
|
/**
|
|
@@ -205,7 +265,13 @@ export function stop(
|
|
|
205
265
|
* set(logo, { opacity: 1, scale: 1, y: 0 })
|
|
206
266
|
* ```
|
|
207
267
|
*/
|
|
208
|
-
export function set(
|
|
268
|
+
export function set(value: MotionValue, to: number): void
|
|
269
|
+
export function set(target: Target | readonly Target[], values: Values): void
|
|
270
|
+
export function set(
|
|
271
|
+
target: Target | readonly Target[] | MotionValue,
|
|
272
|
+
values: Values | number,
|
|
273
|
+
) {
|
|
274
|
+
if (isMotionValue(target)) return asRoot(target).set(values as number)
|
|
209
275
|
if (values === null || typeof values !== 'object' || Array.isArray(values))
|
|
210
276
|
throw new TypeError('set() takes an object of values.')
|
|
211
277
|
const keyframes: Record<string, unknown> = {}
|
|
@@ -218,7 +284,7 @@ export function set(target: Target | readonly Target[], values: Values): void {
|
|
|
218
284
|
)
|
|
219
285
|
keyframes[key] = [value, value]
|
|
220
286
|
}
|
|
221
|
-
animate(target, keyframes as Keyframes, { duration: 0 })
|
|
287
|
+
animate(target as Target | readonly Target[], keyframes as Keyframes, { duration: 0 })
|
|
222
288
|
}
|
|
223
289
|
|
|
224
290
|
/** Plays several animations as one: finished once they all are, and stopped together. */
|
|
@@ -281,6 +347,7 @@ function resolveAnimation(
|
|
|
281
347
|
stagger: user.stagger ?? own.stagger,
|
|
282
348
|
relative: user.relative ?? own.relative,
|
|
283
349
|
haptic: user.haptic ?? own.haptic,
|
|
350
|
+
layer: user.layer,
|
|
284
351
|
}
|
|
285
352
|
}
|
|
286
353
|
|
|
@@ -307,16 +374,21 @@ function normalize(options: AnimateOptions | SpringName | undefined): Options {
|
|
|
307
374
|
let stagger: Options['stagger']
|
|
308
375
|
let relative: Options['relative']
|
|
309
376
|
let haptic: Options['haptic']
|
|
377
|
+
let layer: Options['layer']
|
|
310
378
|
for (const [key, value] of Object.entries(options)) {
|
|
311
379
|
if (value === undefined) continue
|
|
312
|
-
if (key === '
|
|
380
|
+
if (key === 'layer') {
|
|
381
|
+
if (typeof value !== 'string' || !value)
|
|
382
|
+
throw new TypeError('A layer is named by a nonempty string.')
|
|
383
|
+
layer = value
|
|
384
|
+
} else if (key === 'stagger') stagger = value as Options['stagger']
|
|
313
385
|
else if (key === 'relative') relative = value as Options['relative']
|
|
314
386
|
else if (key === 'haptic') haptic = value as Options['haptic']
|
|
315
387
|
else if (key === 'path' || key === 'scale' || isProperty(key)) {
|
|
316
388
|
overrides[key] = typeof value === 'string' ? spring(value as SpringName) : value
|
|
317
389
|
} else base[key] = value
|
|
318
390
|
}
|
|
319
|
-
return { base, overrides, stagger, relative, haptic }
|
|
391
|
+
return { base, overrides, stagger, relative, haptic, layer }
|
|
320
392
|
}
|
|
321
393
|
|
|
322
394
|
function plan(
|
|
@@ -326,8 +398,16 @@ function plan(
|
|
|
326
398
|
offset: number,
|
|
327
399
|
relative = false,
|
|
328
400
|
path?: PreparedPath,
|
|
401
|
+
layer?: string,
|
|
402
|
+
seed = Math.random(),
|
|
329
403
|
): Plan[] {
|
|
404
|
+
if (layer !== undefined && path)
|
|
405
|
+
throw new Error("A path owns x and y; it can't play on a layer.")
|
|
330
406
|
return expand(keyframes, path).map(([property, frames]) => {
|
|
407
|
+
if (layer !== undefined && !layerable(property))
|
|
408
|
+
throw new Error(
|
|
409
|
+
`Layers apply to x, y, scale, rotation and opacity; "${property}" has a single owner.`,
|
|
410
|
+
)
|
|
331
411
|
if (path?.properties.includes(property as 'x' | 'y' | 'rotate')) {
|
|
332
412
|
if (
|
|
333
413
|
!Number.isFinite(path.transition.delay + offset) ||
|
|
@@ -347,12 +427,13 @@ function plan(
|
|
|
347
427
|
const override =
|
|
348
428
|
overrides[property] ?? (property.startsWith('scale') ? overrides.scale : undefined)
|
|
349
429
|
const transition = resolveTransition(
|
|
350
|
-
override ? mergeTransitions(base, override) : base,
|
|
430
|
+
fitTransition(override ? mergeTransitions(base, override) : base, frames.length),
|
|
351
431
|
property,
|
|
352
432
|
frames.length,
|
|
353
433
|
)
|
|
354
434
|
transition.delay += offset
|
|
355
|
-
|
|
435
|
+
if (transition.seed !== undefined) transition.seed = seed
|
|
436
|
+
return { property, keyframes: frames, transition, relative, layer }
|
|
356
437
|
})
|
|
357
438
|
}
|
|
358
439
|
|
|
@@ -361,8 +442,10 @@ export function startingValues(
|
|
|
361
442
|
animation: Keyframes | PresetName,
|
|
362
443
|
options?: AnimateOptions | SpringName,
|
|
363
444
|
) {
|
|
364
|
-
const { keyframes, relative, path } = prepare(animation, options)
|
|
445
|
+
const { keyframes, relative, path, layer } = prepare(animation, options)
|
|
365
446
|
if (!keyframes) throw new Error(`Unknown preset "${animation}".`)
|
|
447
|
+
if (layer !== undefined)
|
|
448
|
+
return new Map(expand(keyframes, path).map(([property]) => [property, null]))
|
|
366
449
|
return new Map(
|
|
367
450
|
expand(keyframes, path).map(([property, [first]]) => [
|
|
368
451
|
property,
|