@rafaelaugusto/jolt 0.1.0-beta.0 → 0.1.0-beta.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 +134 -14
- package/dist/animate.d.ts +3 -3
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +40 -19
- package/dist/animate.js.map +1 -1
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +19 -3
- package/dist/driver/ios.js.map +1 -1
- package/dist/engine.d.ts +7 -3
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +28 -5
- package/dist/engine.js.map +1 -1
- package/dist/haptics.d.ts +18 -0
- package/dist/haptics.d.ts.map +1 -0
- package/dist/haptics.js +96 -0
- package/dist/haptics.js.map +1 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/particles.d.ts +39 -0
- package/dist/particles.d.ts.map +1 -0
- package/dist/particles.js +264 -0
- package/dist/particles.js.map +1 -0
- package/dist/presets.d.ts +16 -1
- package/dist/presets.d.ts.map +1 -1
- package/dist/presets.js +24 -6
- package/dist/presets.js.map +1 -1
- package/dist/press.d.ts.map +1 -1
- package/dist/press.js +3 -1
- package/dist/press.js.map +1 -1
- package/dist/sequence.d.ts +3 -2
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +6 -5
- 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 +160 -0
- package/dist/shimmer.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 +186 -0
- package/dist/symbol-effect.js.map +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/animate.ts +64 -19
- package/src/driver/ios.ts +23 -3
- package/src/engine.ts +26 -6
- package/src/haptics.ts +125 -0
- package/src/index.ts +13 -2
- package/src/particles.ts +323 -0
- package/src/presets.ts +31 -7
- package/src/press.ts +7 -1
- package/src/sequence.ts +8 -5
- package/src/shimmer.ts +179 -0
- package/src/symbol-effect.ts +225 -0
- package/src/types.ts +5 -0
package/README.md
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/rafaelaugustos/jolt/main/.github/assets/logo-dark.png">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/rafaelaugustos/jolt/main/.github/assets/logo.png" alt="Jolt" width="280">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
Native animations for <a href="https://nativescript.org">NativeScript</a>: presets, springs, keyframes and stagger, one call each.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/@rafaelaugusto/jolt"><img src="https://img.shields.io/npm/v/@rafaelaugusto/jolt/next?label=npm%40next" alt="npm"></a>
|
|
14
|
+
<a href="https://github.com/rafaelaugustos/jolt/actions/workflows/ci.yml"><img src="https://github.com/rafaelaugustos/jolt/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
15
|
+
<a href="https://github.com/rafaelaugustos/jolt/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@rafaelaugusto/jolt" alt="MIT license"></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://jolt.rafaelaugusto.dev">Documentation</a> · <a href="https://jolt.rafaelaugusto.dev/pt-BR/">Documentação em português</a>
|
|
20
|
+
</p>
|
|
4
21
|
|
|
5
22
|
```ts
|
|
6
23
|
import { animate } from '@rafaelaugusto/jolt'
|
|
@@ -14,6 +31,21 @@ NativeScript's `view.animate()` covers the basics and stops there: one curve for
|
|
|
14
31
|
|
|
15
32
|
Jolt computes the motion once, in JavaScript, when the animation starts, and hands it to the platform as keyframes: Core Animation on iOS, `ObjectAnimator` on Android. Nothing runs in JavaScript while it plays. Springs follow real physics, and an animation that interrupts another one starts from where the view is, at the speed it was going.
|
|
16
33
|
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- [25 presets](#presets) to enter, exit and draw attention: `fadeInUp`, `popIn`, `shake`, `heartbeat`...
|
|
37
|
+
- [Springs](#springs) described by feel (`bouncy`), by `bounce` and `duration`, or by stiffness, damping and mass.
|
|
38
|
+
- [Keyframes and tweens](#tweens) with an easing per segment and exact keyframe times.
|
|
39
|
+
- [Stagger](#several-views) across several views, from the first, the last or the center.
|
|
40
|
+
- [Sequences](#sequences) that start each step once the previous one looks done.
|
|
41
|
+
- [Press effects](#press) that follow the finger and let go when a scroll takes over.
|
|
42
|
+
- [SF Symbol effects](#sf-symbols) and animated icon replacement on iOS 17+.
|
|
43
|
+
- [Shimmer](#shimmer) for loading placeholders on iOS.
|
|
44
|
+
- [Haptics](#haptics) at arrival or at marked points in an animation on iOS.
|
|
45
|
+
- [Particles and confetti](#particles-and-confetti) on iOS.
|
|
46
|
+
- [Interruptions](#interrupting-and-stopping) that pick up the value and velocity on screen, with no jump.
|
|
47
|
+
- [Native playback](#how-it-works): Core Animation on iOS, `ObjectAnimator` on Android, nothing in JavaScript while it plays.
|
|
48
|
+
|
|
17
49
|
## Install
|
|
18
50
|
|
|
19
51
|
```sh
|
|
@@ -22,6 +54,8 @@ npm install @rafaelaugusto/jolt@next
|
|
|
22
54
|
|
|
23
55
|
It's in beta for now, published under the `next` tag. Requires `@nativescript/core` 8.9 or later. It doesn't depend on a framework: it takes a view, or an element that holds one.
|
|
24
56
|
|
|
57
|
+
On iOS 15+, Jolt requests up to 120 Hz on ProMotion displays. Set `CADisableMinimumFrameDurationOnPhone` to `true` in the app's `App_Resources/iOS/Info.plist` and rebuild to enable higher rates on iPhone. See the [iOS setup](https://jolt.rafaelaugusto.dev/guide/install#promotion-on-ios); the system still chooses the actual refresh rate.
|
|
58
|
+
|
|
25
59
|
## Animating
|
|
26
60
|
|
|
27
61
|
`animate(target, keyframes, transition?)` takes a view and where to take it:
|
|
@@ -46,6 +80,15 @@ animate(card, { x: [0, 100] }) // from 0, whatever x is now
|
|
|
46
80
|
animate(card, { x: [null, 20, -20, null] }) // out and back to where it was
|
|
47
81
|
```
|
|
48
82
|
|
|
83
|
+
With `relative: true`, translation and rotation keyframes are offsets from the current value. Scale and opacity keyframes multiply it instead. Each scale axis keeps its own base, and `null` still means the current value.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
animate(card, { x: [0, -10, 10, 0] }, { relative: true }) // shake around its current x
|
|
87
|
+
animate(card, { scale: [1, 1.06, 1] }, { relative: true }) // grow by 6% and return
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The base is captured once when the view is ready and its tracks are created, before any delay or stagger. Repeats reuse that base. A relative step in a sequence resolves when the step starts; an unloaded view waits until it loads.
|
|
91
|
+
|
|
49
92
|
The target can be a view, or anything that holds one: a NativeScript-Vue template ref, an Angular `ElementRef`.
|
|
50
93
|
|
|
51
94
|
```vue
|
|
@@ -59,7 +102,7 @@ const open = () => animate(card.value, 'popIn')
|
|
|
59
102
|
</template>
|
|
60
103
|
```
|
|
61
104
|
|
|
62
|
-
A view that isn't loaded yet takes its first keyframe right away and plays once it's on screen. Calling `animate(title, 'fadeInUp')` in `onMounted` doesn't flash the title before it fades in.
|
|
105
|
+
A view that isn't loaded yet takes its first absolute keyframe right away and plays once it's on screen. Calling `animate(title, 'fadeInUp')` in `onMounted` doesn't flash the title before it fades in. Relative animations leave the view's values alone until it loads.
|
|
63
106
|
|
|
64
107
|
## Transitions
|
|
65
108
|
|
|
@@ -134,7 +177,9 @@ animate(spinner, 'spin', { repeat: Infinity })
|
|
|
134
177
|
| Exit | `fadeOut`, `fadeOutUp`, `fadeOutDown`, `fadeOutLeft`, `fadeOutRight`, `zoomOut`, `popOut` |
|
|
135
178
|
| Attention | `pulse`, `bounce`, `shake`, `wiggle`, `heartbeat`, `jelly`, `flash`, `tada`, `spin` |
|
|
136
179
|
|
|
137
|
-
Directions follow animate.css: `fadeInUp` comes up from below, `fadeOutUp` leaves upwards.
|
|
180
|
+
Directions follow animate.css: `fadeInUp` comes up from below, `fadeOutUp` leaves upwards. Each built-in preset is plain keyframes and a transition, listed in [`src/presets.ts`](./src/presets.ts) and exported as `presets`.
|
|
181
|
+
|
|
182
|
+
Attention presets use `relative: true`: `shake` around `x: 40` returns to 40, `pulse` preserves the current scale, and `flash` returns to the current opacity. `spin` adds a full turn to the current rotation. Pass `{ relative: false }` to use their absolute keyframes instead. Enter and exit presets remain absolute.
|
|
138
183
|
|
|
139
184
|
Options with timing only (`delay`, `repeat`, `stagger`) keep the preset's curves. Options with a curve (`duration`, `ease`, a spring) replace them:
|
|
140
185
|
|
|
@@ -144,6 +189,29 @@ animate(card, 'fadeInUp', { duration: 600 }) // a 600ms tween instead
|
|
|
144
189
|
animate(card, 'fadeInUp', 'bouncy') // a bouncy spring instead
|
|
145
190
|
```
|
|
146
191
|
|
|
192
|
+
Register your own keyframes and transition with `definePreset`:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import { animate, definePreset } from '@rafaelaugusto/jolt'
|
|
196
|
+
|
|
197
|
+
declare module '@rafaelaugusto/jolt' {
|
|
198
|
+
interface Presets {
|
|
199
|
+
cardIn: true
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
definePreset('cardIn', {
|
|
204
|
+
keyframes: { opacity: [0, 1], y: [40, 0] },
|
|
205
|
+
transition: { type: 'spring', bounce: 0.2, opacity: { duration: 150 } },
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
animate(card, 'cardIn')
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Register presets during app startup, before using them in `animate()` or `sequence()`. The `Presets` declaration adds the name to TypeScript; it does not register anything at runtime. Custom presets follow the same timing and curve overrides as built-ins, including per-property options and `stagger`.
|
|
212
|
+
|
|
213
|
+
Registering a custom name again replaces its definition for future animations. Built-in names cannot be replaced through `definePreset`, and the exported `presets` object continues to contain only the built-ins.
|
|
214
|
+
|
|
147
215
|
## Several views
|
|
148
216
|
|
|
149
217
|
Pass an array to animate them together, and `stagger` to start them one after another:
|
|
@@ -167,7 +235,7 @@ await sequence([
|
|
|
167
235
|
|
|
168
236
|
Each step takes the same arguments as `animate`, or is a function that starts an animation. A step starts once the previous one looks done: a spring that's close to its target and staying there counts, even if it's still settling, so steps don't wait on the last pixel. The whole sequence finishes once every step has.
|
|
169
237
|
|
|
170
|
-
Views in later steps take their first keyframe when the sequence starts, so the title above stays hidden until its turn instead of showing up and disappearing.
|
|
238
|
+
Views in later steps take their first absolute keyframe when the sequence starts, so the title above stays hidden until its turn instead of showing up and disappearing. Relative steps and `null` keyframes wait until their step starts to read the current value.
|
|
171
239
|
|
|
172
240
|
## Press
|
|
173
241
|
|
|
@@ -179,6 +247,51 @@ press(tile, { scale: 0.9, rotate: -4 }, 'bouncy')
|
|
|
179
247
|
|
|
180
248
|
Animates to the given values while a finger is down, and back to where the view was once it lifts, or once the touch is cancelled by a scroll taking over. Views with `isEnabled` set to `false` don't react. It returns a function that removes the effect.
|
|
181
249
|
|
|
250
|
+
## SF Symbols
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
import { symbolEffect } from '@rafaelaugusto/jolt'
|
|
254
|
+
|
|
255
|
+
symbolEffect(bell, 'bounce')
|
|
256
|
+
symbolEffect(favorite, { replace: 'sys://heart.fill' })
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Takes a NativeScript `Image` with a `sys://` source, or a ref holding one. Supports `bounce`, `pulse`, `scale` and `variableColor`, with native playback, completion and cancellation. Replacement keeps the Image's source in sync. Scale holds until stopped; bounce, pulse and variable color can repeat with `{ repeat: true }`.
|
|
260
|
+
|
|
261
|
+
Effects require iOS 17+. Earlier iOS versions and Reduce Motion skip decorative effects and replace icons immediately. Android calls resolve with `false` without changing the image. See [SF Symbol effects](https://jolt.rafaelaugusto.dev/guide/symbol-effects) for options and lifecycle behavior.
|
|
262
|
+
|
|
263
|
+
## Shimmer
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { shimmer } from '@rafaelaugusto/jolt'
|
|
267
|
+
|
|
268
|
+
const stopShimmer = shimmer(placeholder, { duration: 1500 })
|
|
269
|
+
stopShimmer() // when the content is ready
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
A native gradient mask sweeps across the placeholder and its children. It follows layout changes, preserves existing masks and releases native resources while the view is unloaded, resuming on load. Reduce Motion keeps the placeholder static. iOS only for now; Android calls return a no-op cleanup function. See the [shimmer guide](https://jolt.rafaelaugusto.dev/guide/shimmer).
|
|
273
|
+
|
|
274
|
+
## Haptics
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
animate(card, { y: 0 }, { type: 'spring', haptic: 'light' })
|
|
278
|
+
animate(button, 'bounce', { haptic: { style: 'light', times: [0.6, 1] } })
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Choose `light`, `medium` or `heavy`. By default, one impact fires when the animation visually arrives. Explicit points can mark each landing of a bounce. Delays and stagger follow the animation; interruptions, stopping and unloading cancel pending feedback. iOS only for now. See the [haptics guide](https://jolt.rafaelaugusto.dev/guide/haptics) for timing and device behavior.
|
|
282
|
+
|
|
283
|
+
## Particles and confetti
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
import { confetti, particles } from '@rafaelaugusto/jolt'
|
|
287
|
+
|
|
288
|
+
confetti(button, { count: 80, colors: ['#facc15', '#ef4444', '#3b82f6'] })
|
|
289
|
+
const stopSnow = particles(scene, { source: 'top', angle: 90, velocity: 45 })
|
|
290
|
+
stopSnow() // remove the emitter and its particles
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Confetti bursts into the target's window and cleans itself up. `particles()` adds an emitter to the view for snow, sparks, bubbles or other effects. Both use Core Animation without JavaScript per frame, respect Reduce Motion and stop on unload. iOS only for now. See the [particles guide](https://jolt.rafaelaugusto.dev/guide/particles).
|
|
294
|
+
|
|
182
295
|
## Interrupting and stopping
|
|
183
296
|
|
|
184
297
|
Starting an animation on a property that's already animating takes it over: the new one starts from the value on screen, with the same velocity, so a card can change its mind halfway without a jump. Other properties of the previous animation keep going.
|
|
@@ -190,8 +303,13 @@ const animation = animate(card, { x: 300 })
|
|
|
190
303
|
animation.stop() // the card stays where it is
|
|
191
304
|
|
|
192
305
|
stop(card) // stops everything running on the card
|
|
306
|
+
stop(card, ['x', 'scale']) // stops translation on x and both scale axes
|
|
193
307
|
```
|
|
194
308
|
|
|
309
|
+
Selected properties stay at their current values; the others keep animating. `scaleX` and `scaleY` can also be stopped separately. Pass an empty array to stop nothing, or omit it to stop everything. This works with arrays of targets too.
|
|
310
|
+
|
|
311
|
+
If part of an animation is stopped, its `finished` promise resolves with `false` once its remaining properties finish.
|
|
312
|
+
|
|
195
313
|
## How it works
|
|
196
314
|
|
|
197
315
|
When an animation starts, Jolt resolves where each property starts from (the value on screen, or the keyframes you gave), and computes the whole curve: easing, keyframes, spring physics. It samples the curve 60 times per second of motion, and keeps keyframe times exact. Linear segments aren't sampled at all.
|
|
@@ -207,21 +325,21 @@ Each running property remembers its curve and start time, so Jolt knows the valu
|
|
|
207
325
|
|
|
208
326
|
## Not there yet
|
|
209
327
|
|
|
210
|
-
-
|
|
211
|
-
- No gestures: dragging something and letting it fly with its velocity is next.
|
|
212
|
-
- No layout or shared element transitions.
|
|
328
|
+
- `animate()` covers transforms and opacity. Colors ([#12](https://github.com/rafaelaugustos/jolt/issues/12)), borders and shadows ([#13](https://github.com/rafaelaugustos/jolt/issues/13)), size and layout changes ([#21](https://github.com/rafaelaugustos/jolt/issues/21)) aren't animated yet.
|
|
329
|
+
- No gestures: dragging something and letting it fly with its velocity is next ([#23](https://github.com/rafaelaugustos/jolt/issues/23)).
|
|
330
|
+
- No layout or shared element transitions ([#21](https://github.com/rafaelaugustos/jolt/issues/21), [#24](https://github.com/rafaelaugustos/jolt/issues/24)).
|
|
213
331
|
|
|
214
332
|
## API
|
|
215
333
|
|
|
216
|
-
**Animating**: `animate(target, keyframes | preset, transition?)`, `stop(target)`, `sequence(steps)`, `press(target, pressed?, transition?)`.
|
|
334
|
+
**Animating**: `animate(target, keyframes | preset, transition?)`, `stop(target, properties?)`, `sequence(steps)`, `press(target, pressed?, transition?)`, `symbolEffect(image, effect, options?)`, `shimmer(target, options?)`, `confetti(target, options?)`, `particles(target, options?)`.
|
|
217
335
|
|
|
218
|
-
**Animations**
|
|
336
|
+
**Animations** from `animate()`, `sequence()` and `symbolEffect()`: `await`, `finished`, `stop()`. `press()`, `shimmer()`, `confetti()` and `particles()` return cleanup functions.
|
|
219
337
|
|
|
220
|
-
**Helpers**: `presets`, `springs`, `cubicBezier`, plus the types (`Keyframes`, `Transition`, `Spring`, `Tween`, `PresetName`, `SpringName`, `Easing`, `Animation`, `Target`...).
|
|
338
|
+
**Helpers**: `definePreset`, `presets`, `springs`, `cubicBezier`, plus the types (`Keyframes`, `Transition`, `Spring`, `Tween`, `Preset`, `Presets`, `PresetName`, `SpringName`, `Easing`, `Animation`, `Target`...).
|
|
221
339
|
|
|
222
340
|
## Demo
|
|
223
341
|
|
|
224
|
-
[`demo/`](./demo) is a NativeScript-Vue app with every preset, the three springs on a ball you can interrupt, stagger, press effects, loops and a sequence on launch.
|
|
342
|
+
[`demo/`](./demo) is a NativeScript-Vue app with every preset, the three springs on a ball you can interrupt, stagger, press effects, SF Symbols, shimmer, haptics and particles on iOS, loops and a sequence on launch.
|
|
225
343
|
|
|
226
344
|
With the [NativeScript CLI](https://docs.nativescript.org/setup/) installed:
|
|
227
345
|
|
|
@@ -244,6 +362,8 @@ npm run build
|
|
|
244
362
|
|
|
245
363
|
The tests run the engine against a fake platform driver ([`test/helpers.ts`](./test/helpers.ts)) with its own clock: it records the keyframes it would play and ends them when the clock passes their end.
|
|
246
364
|
|
|
365
|
+
For on-device measurements, see the [iOS animation startup benchmark](./benchmarks/README.md).
|
|
366
|
+
|
|
247
367
|
### Releasing
|
|
248
368
|
|
|
249
369
|
1. Bump `version` in `package.json` (`npm version <version> --no-git-tag-version`) and move the changes under it in `CHANGELOG.md`.
|
|
@@ -254,4 +374,4 @@ Publishing authenticates with the `NPM_TOKEN` secret, or with [trusted publishin
|
|
|
254
374
|
|
|
255
375
|
## License
|
|
256
376
|
|
|
257
|
-
[MIT](./LICENSE)
|
|
377
|
+
[MIT](./LICENSE). Maintained by Rafael Augusto and [Cortex Labs](https://getcortexlabs.com/).
|
package/dist/animate.d.ts
CHANGED
|
@@ -15,12 +15,12 @@ import type { AnimateOptions, Keyframes, Target } from './types.js';
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
export declare function animate(target: Target | readonly Target[], animation: Keyframes | PresetName, options?: AnimateOptions | SpringName): Animation;
|
|
18
|
-
/** Stops
|
|
19
|
-
export declare function stop(target: Target | readonly Target[]): void;
|
|
18
|
+
/** Stops all or selected properties at their current values. `scale` stops both axes. */
|
|
19
|
+
export declare function stop(target: Target | readonly Target[], properties?: readonly (keyof Keyframes)[]): void;
|
|
20
20
|
/** Plays several animations as one: finished once they all are, and stopped together. */
|
|
21
21
|
export declare function group(animations: readonly Animation[]): Animation;
|
|
22
22
|
export declare function toView(target: Target): View;
|
|
23
23
|
export declare function toViews(target: Target | readonly Target[]): View[];
|
|
24
24
|
/** Each property the animation touches, with the value it starts from when it sets one. */
|
|
25
|
-
export declare function startingValues(animation: Keyframes | PresetName): Map<Property, number>;
|
|
25
|
+
export declare function startingValues(animation: Keyframes | PresetName, options?: AnimateOptions | SpringName): Map<Property, number | null>;
|
|
26
26
|
//# sourceMappingURL=animate.d.ts.map
|
package/dist/animate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animate.d.ts","sourceRoot":"","sources":["../src/animate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAA;AACpB,OAAO,
|
|
1
|
+
{"version":3,"file":"animate.d.ts","sourceRoot":"","sources":["../src/animate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAA;AACpB,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzD,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAKL,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EACV,cAAc,EACd,SAAS,EAGT,MAAM,EACP,MAAM,YAAY,CAAA;AAUnB;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAClC,SAAS,EAAE,SAAS,GAAG,UAAU,EACjC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,GACpC,SAAS,CAgCX;AAED,yFAAyF;AACzF,wBAAgB,IAAI,CAClB,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EAClC,UAAU,CAAC,EAAE,SAAS,CAAC,MAAM,SAAS,CAAC,EAAE,QAM1C;AAED,yFAAyF;AACzF,wBAAgB,KAAK,CAAC,UAAU,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,CAWjE;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAO3C;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI,EAAE,CAElE;AAkFD,2FAA2F;AAC3F,wBAAgB,cAAc,CAC5B,SAAS,EAAE,SAAS,GAAG,UAAU,EACjC,OAAO,CAAC,EAAE,cAAc,GAAG,UAAU,gCAOtC"}
|
package/dist/animate.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { View } from '@nativescript/core';
|
|
2
2
|
import { arrivalOf, setArrival, stopView, ViewAnimation, } from './engine.js';
|
|
3
|
-
import {
|
|
3
|
+
import { getPreset } from './presets.js';
|
|
4
|
+
import { resolveHaptic } from './haptics.js';
|
|
4
5
|
import { isProperty } from './properties.js';
|
|
5
6
|
import { hasCurve, mergeTransitions, resolveTransition, springs, } from './transition.js';
|
|
6
7
|
/**
|
|
@@ -14,17 +15,19 @@ import { hasCurve, mergeTransitions, resolveTransition, springs, } from './trans
|
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
16
17
|
export function animate(target, animation, options) {
|
|
17
|
-
const { keyframes, base, overrides, stagger } = prepare(animation, options);
|
|
18
|
+
const { keyframes, base, overrides, stagger, relative, haptic } = prepare(animation, options);
|
|
19
|
+
const feedback = resolveHaptic(haptic);
|
|
18
20
|
if (!isList(target)) {
|
|
19
|
-
return new ViewAnimation(toView(target), plan(keyframes, base, overrides, 0));
|
|
21
|
+
return new ViewAnimation(toView(target), plan(keyframes, base, overrides, 0, relative), feedback);
|
|
20
22
|
}
|
|
21
23
|
const views = target.map(toView);
|
|
22
|
-
return group(views.map((view, index) => new ViewAnimation(view, plan(keyframes, base, overrides, staggerDelay(stagger, index, views.length)))));
|
|
24
|
+
return group(views.map((view, index) => new ViewAnimation(view, plan(keyframes, base, overrides, staggerDelay(stagger, index, views.length), relative), feedback)));
|
|
23
25
|
}
|
|
24
|
-
/** Stops
|
|
25
|
-
export function stop(target) {
|
|
26
|
+
/** Stops all or selected properties at their current values. `scale` stops both axes. */
|
|
27
|
+
export function stop(target, properties) {
|
|
28
|
+
const expanded = properties?.flatMap((property) => property === 'scale' ? ['scaleX', 'scaleY'] : [property]);
|
|
26
29
|
for (const view of toViews(target))
|
|
27
|
-
stopView(view);
|
|
30
|
+
stopView(view, expanded);
|
|
28
31
|
}
|
|
29
32
|
/** Plays several animations as one: finished once they all are, and stopped together. */
|
|
30
33
|
export function group(animations) {
|
|
@@ -56,9 +59,7 @@ function prepare(animation, options) {
|
|
|
56
59
|
const user = normalize(options);
|
|
57
60
|
if (typeof animation !== 'string')
|
|
58
61
|
return { keyframes: animation, ...user };
|
|
59
|
-
const preset =
|
|
60
|
-
if (!preset)
|
|
61
|
-
throw new Error(`Unknown preset "${animation}".`);
|
|
62
|
+
const preset = getPreset(animation);
|
|
62
63
|
const own = normalize(preset.transition);
|
|
63
64
|
return {
|
|
64
65
|
keyframes: preset.keyframes,
|
|
@@ -66,44 +67,64 @@ function prepare(animation, options) {
|
|
|
66
67
|
overrides: hasCurve(user.base)
|
|
67
68
|
? user.overrides
|
|
68
69
|
: { ...own.overrides, ...user.overrides },
|
|
69
|
-
stagger: user.stagger,
|
|
70
|
+
stagger: user.stagger ?? own.stagger,
|
|
71
|
+
relative: user.relative ?? own.relative,
|
|
72
|
+
haptic: user.haptic ?? own.haptic,
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
function normalize(options) {
|
|
73
76
|
if (options === undefined)
|
|
74
|
-
return {
|
|
77
|
+
return {
|
|
78
|
+
base: {},
|
|
79
|
+
overrides: {},
|
|
80
|
+
stagger: undefined,
|
|
81
|
+
relative: undefined,
|
|
82
|
+
haptic: undefined,
|
|
83
|
+
};
|
|
75
84
|
if (typeof options === 'string')
|
|
76
|
-
return {
|
|
85
|
+
return {
|
|
86
|
+
base: spring(options),
|
|
87
|
+
overrides: {},
|
|
88
|
+
stagger: undefined,
|
|
89
|
+
relative: undefined,
|
|
90
|
+
haptic: undefined,
|
|
91
|
+
};
|
|
77
92
|
const base = {};
|
|
78
93
|
const overrides = {};
|
|
79
94
|
let stagger;
|
|
95
|
+
let relative;
|
|
96
|
+
let haptic;
|
|
80
97
|
for (const [key, value] of Object.entries(options)) {
|
|
81
98
|
if (value === undefined)
|
|
82
99
|
continue;
|
|
83
100
|
if (key === 'stagger')
|
|
84
101
|
stagger = value;
|
|
102
|
+
else if (key === 'relative')
|
|
103
|
+
relative = value;
|
|
104
|
+
else if (key === 'haptic')
|
|
105
|
+
haptic = value;
|
|
85
106
|
else if (key === 'scale' || isProperty(key)) {
|
|
86
107
|
overrides[key] = typeof value === 'string' ? spring(value) : value;
|
|
87
108
|
}
|
|
88
109
|
else
|
|
89
110
|
base[key] = value;
|
|
90
111
|
}
|
|
91
|
-
return { base, overrides, stagger };
|
|
112
|
+
return { base, overrides, stagger, relative, haptic };
|
|
92
113
|
}
|
|
93
|
-
function plan(keyframes, base, overrides, offset) {
|
|
114
|
+
function plan(keyframes, base, overrides, offset, relative = false) {
|
|
94
115
|
return expand(keyframes).map(([property, frames]) => {
|
|
95
116
|
const override = overrides[property] ?? (property.startsWith('scale') ? overrides.scale : undefined);
|
|
96
117
|
const transition = resolveTransition(override ? mergeTransitions(base, override) : base, property, frames.length);
|
|
97
118
|
transition.delay += offset;
|
|
98
|
-
return { property, keyframes: frames, transition };
|
|
119
|
+
return { property, keyframes: frames, transition, relative };
|
|
99
120
|
});
|
|
100
121
|
}
|
|
101
122
|
/** Each property the animation touches, with the value it starts from when it sets one. */
|
|
102
|
-
export function startingValues(animation) {
|
|
103
|
-
const keyframes
|
|
123
|
+
export function startingValues(animation, options) {
|
|
124
|
+
const { keyframes, relative } = prepare(animation, options);
|
|
104
125
|
if (!keyframes)
|
|
105
126
|
throw new Error(`Unknown preset "${animation}".`);
|
|
106
|
-
return new Map(expand(keyframes).map(([property, [first]]) => [property, first]));
|
|
127
|
+
return new Map(expand(keyframes).map(([property, [first]]) => [property, relative ? null : first]));
|
|
107
128
|
}
|
|
108
129
|
function expand(keyframes) {
|
|
109
130
|
const expanded = [];
|
package/dist/animate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"animate.js","sourceRoot":"","sources":["../src/animate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,GAGd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"animate.js","sourceRoot":"","sources":["../src/animate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,GAGd,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAmB,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,aAAa,EAAe,MAAM,cAAc,CAAA;AACzD,OAAO,EAAE,UAAU,EAAiB,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EACL,QAAQ,EACR,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,GAGR,MAAM,iBAAiB,CAAA;AAiBxB;;;;;;;;;GASG;AACH,MAAM,UAAU,OAAO,CACrB,MAAkC,EAClC,SAAiC,EACjC,OAAqC;IAErC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CACvE,SAAS,EACT,OAAO,CACR,CAAA;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,CAAA;IAEtC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,aAAa,CACtB,MAAM,CAAC,MAAM,CAAC,EACd,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,QAAQ,CAAC,EAC7C,QAAQ,CACT,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,KAAK,CACV,KAAK,CAAC,GAAG,CACP,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACd,IAAI,aAAa,CACf,IAAI,EACJ,IAAI,CACF,SAAS,EACT,IAAI,EACJ,SAAS,EACT,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAC1C,QAAQ,CACT,EACD,QAAQ,CACT,CACJ,CACF,CAAA;AACH,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,IAAI,CAClB,MAAkC,EAClC,UAAyC;IAEzC,MAAM,QAAQ,GAAG,UAAU,EAAE,OAAO,CAAW,CAAC,QAAQ,EAAE,EAAE,CAC1D,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CACzD,CAAA;IACD,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;AAC9D,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,KAAK,CAAC,UAAgC;IACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAClF,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CACpC,CAAA;IACD,MAAM,SAAS,GAAc;QAC3B,QAAQ;QACR,IAAI,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC/D,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC;KAC1E,CAAA;IACD,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;IAC7D,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,MAAc;IACnC,IAAI,MAAM,YAAY,IAAI;QAAE,OAAO,MAAM,CAAA;IACzC,MAAM,IAAI,GACP,MAA0C,EAAE,UAAU;QACtD,MAA6C,EAAE,aAAa,CAAA;IAC/D,IAAI,IAAI,YAAY,IAAI;QAAE,OAAO,IAAI,CAAA;IACrC,MAAM,IAAI,SAAS,CAAC,qCAAqC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;AAC7E,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAAkC;IACxD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;AAC/D,CAAC;AAED,SAAS,MAAM,CAAI,MAAwB;IACzC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;AAED,SAAS,OAAO,CACd,SAAiC,EACjC,OAAqC;IAErC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAC/B,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,CAAA;IAE3E,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACxC,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,IAAI,EAAE,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC;QAC3C,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5B,CAAC,CAAC,IAAI,CAAC,SAAS;YAChB,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE;QAC3C,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO;QACpC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ;QACvC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM;KAClC,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,OAAgD;IACjE,IAAI,OAAO,KAAK,SAAS;QACvB,OAAO;YACL,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,SAAS;SAClB,CAAA;IACH,IAAI,OAAO,OAAO,KAAK,QAAQ;QAC7B,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;YACrB,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,SAAS;YAClB,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,SAAS;SAClB,CAAA;IAEH,MAAM,IAAI,GAA4B,EAAE,CAAA;IACxC,MAAM,SAAS,GAAyB,EAAE,CAAA;IAC1C,IAAI,OAA2B,CAAA;IAC/B,IAAI,QAA6B,CAAA;IACjC,IAAI,MAAyB,CAAA;IAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAQ;QACjC,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,GAAG,KAA2B,CAAA;aACvD,IAAI,GAAG,KAAK,UAAU;YAAE,QAAQ,GAAG,KAA4B,CAAA;aAC/D,IAAI,GAAG,KAAK,QAAQ;YAAE,MAAM,GAAG,KAA0B,CAAA;aACzD,IAAI,GAAG,KAAK,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5C,SAAS,CAAC,GAAG,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;QAClF,CAAC;;YAAM,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IAC1B,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;AACvD,CAAC;AAED,SAAS,IAAI,CACX,SAAoB,EACpB,IAAgB,EAChB,SAA+B,EAC/B,MAAc,EACd,QAAQ,GAAG,KAAK;IAEhB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE;QAClD,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QACrF,MAAM,UAAU,GAAG,iBAAiB,CAClC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAClD,QAAQ,EACR,MAAM,CAAC,MAAM,CACd,CAAA;QACD,UAAU,CAAC,KAAK,IAAI,MAAM,CAAA;QAC1B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAA;IAC9D,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAC5B,SAAiC,EACjC,OAAqC;IAErC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAC3D,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,SAAS,IAAI,CAAC,CAAA;IACjE,OAAO,IAAI,GAAG,CACZ,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CACrF,CAAA;AACH,CAAC;AAED,SAAS,MAAM,CAAC,SAAoB;IAClC,MAAM,QAAQ,GAAoC,EAAE,CAAA;IACpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAGhD,EAAE,CAAC;QACJ,IAAI,KAAK,KAAK,SAAS;YAAE,SAAQ;QACjC,IAAI,GAAG,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;QAEnF,MAAM,UAAU,GAAe,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC7E,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,IAAI,GAAG,KAAK,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS;gBAAE,SAAQ;YAClE,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;QACzD,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,QAAkB,EAAE,KAAoB;IAC3D,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAA;IACrE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,IACE,MAAM,CAAC,MAAM,KAAK,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EACjE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACnF,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,YAAY,CAAC,OAA2B,EAAE,KAAa,EAAE,KAAa;IAC7E,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,CAAA;IACnC,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,EAAE,GAC5B,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;IAC3D,MAAM,MAAM,GACV,IAAI,KAAK,OAAO;QACd,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,KAAK,MAAM;YACf,CAAC,CAAC,KAAK,GAAG,CAAC;YACX,CAAC,CAAC,IAAI,KAAK,QAAQ;gBACjB,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;gBACjB,CAAC,CAAC,IAAI,CAAA;IACd,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAA;AACxC,CAAC;AAED,SAAS,MAAM,CAAC,IAAgB;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChC,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,IAAI,CAAC,CAAA;IAC7D,OAAO,UAAU,CAAA;AACnB,CAAC"}
|
package/dist/driver/ios.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../src/driver/ios.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"ios.d.ts","sourceRoot":"","sources":["../../src/driver/ios.ts"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AA4C/C,wBAAgB,eAAe,IAAI,MAAM,CA6DxC"}
|
package/dist/driver/ios.js
CHANGED
|
@@ -36,30 +36,46 @@ export function createIOSDriver() {
|
|
|
36
36
|
const layers = layersOf(view);
|
|
37
37
|
const key = `jolt:${track.property}`;
|
|
38
38
|
const rotation = track.property.startsWith('rotate');
|
|
39
|
+
const infinite = track.repeat === Infinity;
|
|
39
40
|
if (track.property === 'rotateX' || track.property === 'rotateY') {
|
|
40
41
|
ensurePerspective(view, layers);
|
|
41
42
|
}
|
|
42
43
|
const animation = CAKeyframeAnimation.animationWithKeyPath(keyPaths[track.property]);
|
|
44
|
+
// iOS 15+. The app must opt in through CADisableMinimumFrameDurationOnPhone.
|
|
45
|
+
if (animation.respondsToSelector('setPreferredFrameRateRange:')) {
|
|
46
|
+
const nativeView = view.nativeViewProtected;
|
|
47
|
+
const screen = nativeView.window?.screen ?? UIScreen.mainScreen;
|
|
48
|
+
const maximum = Math.min(120, screen.maximumFramesPerSecond);
|
|
49
|
+
animation.preferredFrameRateRange = CAFrameRateRangeMake(Math.min(80, maximum), maximum, maximum);
|
|
50
|
+
}
|
|
43
51
|
animation.values = NSArray.arrayWithArray(track.values.map((value) => (rotation ? radians(value) : value)));
|
|
44
52
|
animation.keyTimes = NSArray.arrayWithArray(track.times);
|
|
45
53
|
animation.duration = Math.max(track.duration, 1) / 1000;
|
|
46
54
|
animation.beginTime = (startedAt + track.delay) / 1000;
|
|
47
55
|
animation.fillMode = kCAFillModeBackwards;
|
|
56
|
+
// Keep infinite loops when iOS removes animations on backgrounding.
|
|
57
|
+
// They are removed explicitly when stopped or replaced.
|
|
58
|
+
animation.removedOnCompletion = !infinite;
|
|
48
59
|
if (track.repeat > 0) {
|
|
49
60
|
animation.autoreverses = track.reverse;
|
|
50
61
|
animation.repeatCount = track.reverse ? (track.repeat + 1) / 2 : track.repeat + 1;
|
|
51
62
|
}
|
|
52
63
|
CATransaction.begin();
|
|
53
|
-
|
|
64
|
+
// iOS completes the transaction on backgrounding even if the loop is retained.
|
|
65
|
+
if (!infinite)
|
|
66
|
+
CATransaction.setCompletionBlock(onEnd);
|
|
54
67
|
for (const layer of layers)
|
|
55
68
|
layer.addAnimationForKey(animation, key);
|
|
56
69
|
CATransaction.commit();
|
|
57
|
-
return { layers, key };
|
|
70
|
+
return { layers, key, onStop: infinite ? onEnd : undefined };
|
|
58
71
|
},
|
|
59
72
|
stop(_view, handle) {
|
|
60
|
-
const
|
|
73
|
+
const playing = handle;
|
|
74
|
+
const { layers, key, onStop } = playing;
|
|
75
|
+
playing.onStop = undefined;
|
|
61
76
|
for (const layer of layers)
|
|
62
77
|
layer.removeAnimationForKey(key);
|
|
78
|
+
onStop?.();
|
|
63
79
|
},
|
|
64
80
|
presented: () => undefined,
|
|
65
81
|
after,
|
package/dist/driver/ios.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/driver/ios.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAe,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"ios.js","sourceRoot":"","sources":["../../src/driver/ios.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAe,MAAM,YAAY,CAAA;AAQ/C,MAAM,QAAQ,GAA6B;IACzC,OAAO,EAAE,SAAS;IAClB,CAAC,EAAE,yBAAyB;IAC5B,CAAC,EAAE,yBAAyB;IAC5B,MAAM,EAAE,mBAAmB;IAC3B,MAAM,EAAE,mBAAmB;IAC3B,MAAM,EAAE,sBAAsB;IAC9B,OAAO,EAAE,sBAAsB;IAC/B,OAAO,EAAE,sBAAsB;CAChC,CAAA;AAED,MAAM,OAAO,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;AAE9D,SAAS,QAAQ,CAAC,IAAU;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,mBAEvB,CAAA;IACD,OAAO,UAAU,CAAC,yBAAyB;QACzC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,yBAAyB,CAAC;QAC1D,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAED,uGAAuG;AACvG,SAAS,iBAAiB,CAAC,IAAU,EAAE,MAAiB;IACtD,aAAa,CAAC,KAAK,EAAE,CAAA;IACrB,aAAa,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QACjC,IAAI,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;YACxB,SAAS,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC,CAAA;YAC9C,KAAK,CAAC,SAAS,GAAG,SAAS,CAAA;QAC7B,CAAC;IACH,CAAC;IACD,aAAa,CAAC,MAAM,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,kBAAkB,EAAE,GAAG,IAAI;QAEtC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK;YAChC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;YAC7B,MAAM,GAAG,GAAG,QAAQ,KAAK,CAAC,QAAQ,EAAE,CAAA;YACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACpD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAA;YAC1C,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACjE,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YACjC,CAAC;YAED,MAAM,SAAS,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;YACpF,6EAA6E;YAC7E,IAAI,SAAS,CAAC,kBAAkB,CAAC,6BAA6B,CAAC,EAAE,CAAC;gBAChE,MAAM,UAAU,GAAG,IAAI,CAAC,mBAA6B,CAAA;gBACrD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAA;gBAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,sBAAsB,CAAC,CAAA;gBAC5D,SAAS,CAAC,uBAAuB,GAAG,oBAAoB,CACtD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,EACrB,OAAO,EACP,OAAO,CACR,CAAA;YACH,CAAC;YACD,SAAS,CAAC,MAAM,GAAG,OAAO,CAAC,cAAc,CACvC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACjE,CAAA;YACD,SAAS,CAAC,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,KAAiB,CAAC,CAAA;YACpE,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,IAAI,CAAA;YACvD,SAAS,CAAC,SAAS,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;YACtD,SAAS,CAAC,QAAQ,GAAG,oBAAoB,CAAA;YACzC,oEAAoE;YACpE,wDAAwD;YACxD,SAAS,CAAC,mBAAmB,GAAG,CAAC,QAAQ,CAAA;YACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,SAAS,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAA;gBACtC,SAAS,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;YACnF,CAAC;YAED,aAAa,CAAC,KAAK,EAAE,CAAA;YACrB,+EAA+E;YAC/E,IAAI,CAAC,QAAQ;gBAAE,aAAa,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;YACtD,KAAK,MAAM,KAAK,IAAI,MAAM;gBAAE,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACpE,aAAa,CAAC,MAAM,EAAE,CAAA;YAEtB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;QAC9D,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,MAAM;YAChB,MAAM,OAAO,GAAG,MAAgB,CAAA;YAChC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;YACvC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAA;YAC1B,KAAK,MAAM,KAAK,IAAI,MAAM;gBAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;YAC5D,MAAM,EAAE,EAAE,CAAA;QACZ,CAAC;QAED,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;QAE1B,KAAK;KACN,CAAA;AACH,CAAC"}
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import type { View } from '@nativescript/core';
|
|
2
|
+
import { type HapticOptions } from './haptics.js';
|
|
2
3
|
import { type Property } from './properties.js';
|
|
3
4
|
import type { ResolvedTransition } from './transition.js';
|
|
4
5
|
export interface Animation extends PromiseLike<boolean> {
|
|
5
6
|
/**
|
|
6
7
|
* Resolves with `true` once the animation played to the end, or with `false`
|
|
7
|
-
* if it was stopped or
|
|
8
|
+
* if it was stopped, superseded or skipped.
|
|
8
9
|
* Never rejects.
|
|
9
10
|
*/
|
|
10
11
|
readonly finished: Promise<boolean>;
|
|
11
|
-
/** Stops
|
|
12
|
+
/** Stops playback. Property animations keep their current values; symbol effects are removed. */
|
|
12
13
|
stop(): void;
|
|
13
14
|
}
|
|
14
15
|
export interface Plan {
|
|
@@ -16,6 +17,7 @@ export interface Plan {
|
|
|
16
17
|
/** `null` stands for the value the property has when the animation starts. */
|
|
17
18
|
keyframes: readonly (number | null)[];
|
|
18
19
|
transition: ResolvedTransition;
|
|
20
|
+
relative?: boolean;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Resolves once the animation looks done, which for a spring is well before
|
|
@@ -25,6 +27,7 @@ export declare function arrivalOf(animation: Animation): Promise<unknown>;
|
|
|
25
27
|
export declare function setArrival(animation: Animation, arrival: Promise<unknown>): void;
|
|
26
28
|
export declare class ViewAnimation implements Animation {
|
|
27
29
|
readonly view: View;
|
|
30
|
+
private readonly haptic?;
|
|
28
31
|
readonly finished: Promise<boolean>;
|
|
29
32
|
private resolve;
|
|
30
33
|
private readonly entries;
|
|
@@ -34,7 +37,8 @@ export declare class ViewAnimation implements Animation {
|
|
|
34
37
|
private cancelWait;
|
|
35
38
|
private arrive;
|
|
36
39
|
private cancelArrival;
|
|
37
|
-
|
|
40
|
+
private haptics;
|
|
41
|
+
constructor(view: View, plans: readonly Plan[], haptic?: HapticOptions | undefined);
|
|
38
42
|
then<A = boolean, B = never>(onfulfilled?: ((finished: boolean) => A | PromiseLike<A>) | null, onrejected?: ((reason: unknown) => B | PromiseLike<B>) | null): Promise<A | B>;
|
|
39
43
|
stop(): void;
|
|
40
44
|
ended(finished: boolean): void;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAEtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEzD,MAAM,WAAW,SAAU,SAAQ,WAAW,CAAC,OAAO,CAAC;IACrD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACnC,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AAE9C,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAyB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAEtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAEzD,MAAM,WAAW,SAAU,SAAQ,WAAW,CAAC,OAAO,CAAC;IACrD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACnC,iGAAiG;IACjG,IAAI,IAAI,IAAI,CAAA;CACb;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,8EAA8E;IAC9E,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;IACrC,UAAU,EAAE,kBAAkB,CAAA;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAaD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,QAEzE;AAED,qBAAa,aAAc,YAAW,SAAS;IAa3C,QAAQ,CAAC,IAAI,EAAE,IAAI;IAEnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAd1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACnC,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,OAAO,CAAI;IACnB,OAAO,CAAC,QAAQ,CAAO;IACvB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,OAAO,CAAgC;IAE/C,YACW,IAAI,EAAE,IAAI,EACnB,KAAK,EAAE,SAAS,IAAI,EAAE,EACL,MAAM,CAAC,EAAE,aAAa,YAAA,EAMxC;IAED,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,KAAK,EACzB,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAChE,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAC5D,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAEhB;IAED,IAAI,SAUH;IAED,KAAK,CAAC,QAAQ,EAAE,OAAO,QAMtB;IAED,OAAO,CAAC,KAAK;IAiEb,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,MAAM;CAUf;AAED,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,QAOpE"}
|