@rafaelaugusto/jolt 0.1.0-beta.12 → 0.1.0-beta.13

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.
Files changed (103) hide show
  1. package/README.md +4 -1
  2. package/dist/animate.d.ts +6 -4
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +3 -1
  5. package/dist/animate.js.map +1 -1
  6. package/dist/drag.js +3 -3
  7. package/dist/drag.js.map +1 -1
  8. package/dist/driver/android.d.ts.map +1 -1
  9. package/dist/driver/android.js +2 -0
  10. package/dist/driver/android.js.map +1 -1
  11. package/dist/driver/frame.d.ts +3 -0
  12. package/dist/driver/frame.d.ts.map +1 -0
  13. package/dist/driver/frame.js +7 -0
  14. package/dist/driver/frame.js.map +1 -0
  15. package/dist/driver/index.d.ts +2 -0
  16. package/dist/driver/index.d.ts.map +1 -1
  17. package/dist/driver/index.js.map +1 -1
  18. package/dist/driver/ios.d.ts.map +1 -1
  19. package/dist/driver/ios.js +2 -0
  20. package/dist/driver/ios.js.map +1 -1
  21. package/dist/engine.d.ts +2 -1
  22. package/dist/engine.d.ts.map +1 -1
  23. package/dist/engine.js +23 -2
  24. package/dist/engine.js.map +1 -1
  25. package/dist/image-effect.d.ts +1 -0
  26. package/dist/image-effect.d.ts.map +1 -1
  27. package/dist/image-effect.js +10 -2
  28. package/dist/image-effect.js.map +1 -1
  29. package/dist/index.d.ts +5 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +2 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/motion-scope.d.ts +2 -1
  34. package/dist/motion-scope.d.ts.map +1 -1
  35. package/dist/motion-scope.js +4 -1
  36. package/dist/motion-scope.js.map +1 -1
  37. package/dist/motion-value.d.ts +45 -8
  38. package/dist/motion-value.d.ts.map +1 -1
  39. package/dist/motion-value.js +289 -91
  40. package/dist/motion-value.js.map +1 -1
  41. package/dist/native/index.d.ts +6 -0
  42. package/dist/native/index.d.ts.map +1 -0
  43. package/dist/native/index.js +3 -0
  44. package/dist/native/index.js.map +1 -0
  45. package/dist/native-properties.d.ts +28 -0
  46. package/dist/native-properties.d.ts.map +1 -0
  47. package/dist/native-properties.js +154 -0
  48. package/dist/native-properties.js.map +1 -0
  49. package/dist/native-property-driver.d.ts +19 -0
  50. package/dist/native-property-driver.d.ts.map +1 -0
  51. package/dist/native-property-driver.js +69 -0
  52. package/dist/native-property-driver.js.map +1 -0
  53. package/dist/native-property.d.ts +35 -0
  54. package/dist/native-property.d.ts.map +1 -0
  55. package/dist/native-property.js +277 -0
  56. package/dist/native-property.js.map +1 -0
  57. package/dist/playback-group.d.ts.map +1 -1
  58. package/dist/playback-group.js +17 -1
  59. package/dist/playback-group.js.map +1 -1
  60. package/dist/playback.d.ts +15 -0
  61. package/dist/playback.d.ts.map +1 -1
  62. package/dist/playback.js +23 -0
  63. package/dist/playback.js.map +1 -1
  64. package/dist/sequence.d.ts +24 -0
  65. package/dist/sequence.d.ts.map +1 -1
  66. package/dist/sequence.js +181 -19
  67. package/dist/sequence.js.map +1 -1
  68. package/dist/timed-animation.d.ts +38 -0
  69. package/dist/timed-animation.d.ts.map +1 -0
  70. package/dist/timed-animation.js +177 -0
  71. package/dist/timed-animation.js.map +1 -0
  72. package/dist/value-observers.d.ts +19 -0
  73. package/dist/value-observers.d.ts.map +1 -0
  74. package/dist/value-observers.js +111 -0
  75. package/dist/value-observers.js.map +1 -0
  76. package/dist/value-track.d.ts +13 -0
  77. package/dist/value-track.d.ts.map +1 -0
  78. package/dist/value-track.js +59 -0
  79. package/dist/value-track.js.map +1 -0
  80. package/package.json +6 -2
  81. package/src/android-plugin.d.ts +37 -0
  82. package/src/animate.ts +13 -7
  83. package/src/drag.ts +3 -3
  84. package/src/driver/android.ts +2 -0
  85. package/src/driver/frame.ts +10 -0
  86. package/src/driver/index.ts +2 -0
  87. package/src/driver/ios.ts +2 -0
  88. package/src/engine.ts +23 -2
  89. package/src/image-effect.ts +10 -2
  90. package/src/index.ts +5 -0
  91. package/src/ios-plugin.d.ts +33 -0
  92. package/src/motion-scope.ts +5 -1
  93. package/src/motion-value.ts +331 -99
  94. package/src/native/index.ts +16 -0
  95. package/src/native-properties.ts +188 -0
  96. package/src/native-property-driver.ts +123 -0
  97. package/src/native-property.ts +353 -0
  98. package/src/playback-group.ts +17 -1
  99. package/src/playback.ts +41 -0
  100. package/src/sequence.ts +209 -20
  101. package/src/timed-animation.ts +192 -0
  102. package/src/value-observers.ts +133 -0
  103. package/src/value-track.ts +71 -0
@@ -0,0 +1,177 @@
1
+ import { getDriver } from './driver/index.js';
2
+ import { Trace } from '@nativescript/core';
3
+ import { setArrival, setArrivalTiming } from './engine.js';
4
+ import { createClock, registerPlayback, validateProgress, } from './playback.js';
5
+ /** A sampled resource's control clock. Native sinks play frames; JS runs only at boundaries. */
6
+ export class TimedAnimation {
7
+ duration;
8
+ arrival;
9
+ update;
10
+ finish;
11
+ finished;
12
+ resolve;
13
+ arrive;
14
+ clock;
15
+ notifyPlayback;
16
+ listeners = new Set();
17
+ cancelEnd;
18
+ cancelArrival;
19
+ _paused = false;
20
+ settled = false;
21
+ completed = false;
22
+ arrived = false;
23
+ active = false;
24
+ constructor(duration, arrival, update, finish) {
25
+ this.duration = duration;
26
+ this.arrival = arrival;
27
+ this.update = update;
28
+ this.finish = finish;
29
+ const driver = getDriver();
30
+ this.clock = driver.clock?.(duration) ?? createClock(() => driver.now());
31
+ this.finished = new Promise((resolve) => {
32
+ this.resolve = resolve;
33
+ });
34
+ setArrival(this, new Promise((resolve) => {
35
+ this.arrive = resolve;
36
+ }));
37
+ this.notifyPlayback = registerPlayback(this, () => ({
38
+ time: this.time,
39
+ duration,
40
+ paused: this._paused,
41
+ ready: this.active,
42
+ settled: this.settled,
43
+ completed: this.completed,
44
+ }));
45
+ setArrivalTiming(this, {
46
+ read: () => ({
47
+ remaining: Math.max(0, arrival - this.time),
48
+ paused: this.paused,
49
+ arrived: this.arrived,
50
+ }),
51
+ subscribe: (callback) => {
52
+ this.listeners.add(callback);
53
+ return () => {
54
+ this.listeners.delete(callback);
55
+ };
56
+ },
57
+ });
58
+ }
59
+ get time() {
60
+ return Math.max(0, Math.min(this.duration, this.clock.time()));
61
+ }
62
+ get paused() {
63
+ return this._paused;
64
+ }
65
+ get done() {
66
+ return this.settled;
67
+ }
68
+ get progress() {
69
+ if (!Number.isFinite(this.duration))
70
+ throw new RangeError('Progress requires a finite animation.');
71
+ return this.completed ? 1 : this.duration ? this.time / this.duration : 0;
72
+ }
73
+ set progress(value) {
74
+ validateProgress(value, this.duration);
75
+ this.seekTime(value * this.duration);
76
+ }
77
+ start() {
78
+ if (this.active || this.settled)
79
+ return;
80
+ this.active = true;
81
+ this.schedule();
82
+ this.notify();
83
+ }
84
+ pause() {
85
+ if (this._paused || this.settled)
86
+ return;
87
+ this.clock.pause();
88
+ this._paused = true;
89
+ this.cancelTimers();
90
+ this.update(this.time, true, 'pause');
91
+ this.notify();
92
+ }
93
+ play() {
94
+ if (!this._paused || this.settled)
95
+ return;
96
+ this._paused = false;
97
+ this.clock.play();
98
+ this.update(this.time, false, 'play');
99
+ this.schedule();
100
+ this.notify();
101
+ }
102
+ seekTime(time) {
103
+ if (!Number.isFinite(time) || time < 0)
104
+ throw new RangeError('Seek time must be finite and nonnegative.');
105
+ if (this.settled)
106
+ return;
107
+ this.clock.seek(Math.min(this.duration, time));
108
+ this.update(this.time, this._paused, 'seek');
109
+ this.schedule();
110
+ this.notify();
111
+ }
112
+ stop() {
113
+ this.settle(false);
114
+ }
115
+ then(onfulfilled, onrejected) {
116
+ return this.finished.then(onfulfilled, onrejected);
117
+ }
118
+ notify() {
119
+ this.notifyPlayback();
120
+ for (const callback of [...this.listeners])
121
+ callback();
122
+ }
123
+ cancelTimers() {
124
+ this.cancelEnd?.();
125
+ this.cancelArrival?.();
126
+ this.cancelEnd = this.cancelArrival = undefined;
127
+ }
128
+ schedule() {
129
+ this.cancelTimers();
130
+ if (!this.active || this._paused || this.settled)
131
+ return;
132
+ const driver = getDriver();
133
+ if (Number.isFinite(this.duration)) {
134
+ const remaining = this.duration - this.time;
135
+ if (remaining <= 0) {
136
+ this.settle(true);
137
+ return;
138
+ }
139
+ this.cancelEnd = driver.after(remaining, () => this.settle(true));
140
+ }
141
+ if (!this.arrived && Number.isFinite(this.arrival)) {
142
+ const remaining = this.arrival - this.time;
143
+ const arrive = () => {
144
+ this.arrived = true;
145
+ this.arrive();
146
+ this.notify();
147
+ };
148
+ if (remaining <= 0)
149
+ arrive();
150
+ else
151
+ this.cancelArrival = driver.after(remaining, arrive);
152
+ }
153
+ }
154
+ settle(completed) {
155
+ if (this.settled)
156
+ return;
157
+ this.settled = true;
158
+ this.completed = completed;
159
+ this.cancelTimers();
160
+ if (completed)
161
+ this.clock.seek(this.duration);
162
+ this.clock.cancel();
163
+ try {
164
+ this.finish(completed);
165
+ }
166
+ catch (error) {
167
+ this.completed = false;
168
+ Trace.write(`Jolt sampled playback failed: ${String(error)}`, Trace.categories.Error, Trace.messageType.error);
169
+ }
170
+ this.arrived = true;
171
+ this.arrive();
172
+ this.notify();
173
+ this.resolve(this.completed);
174
+ this.listeners.clear();
175
+ }
176
+ }
177
+ //# sourceMappingURL=timed-animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timed-animation.js","sourceRoot":"","sources":["../src/timed-animation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Color } from '@nativescript/core';
2
+ export interface SubscribeOptions {
3
+ /** Deliver the current value synchronously when subscribing. Defaults to true. */
4
+ immediate?: boolean;
5
+ }
6
+ /** `time` is milliseconds on the native animation clock, shared by a notification batch. */
7
+ export type ValueListener<T> = (value: T, time: number) => void;
8
+ /** Root-owned subscriptions; mappings are evaluated only for consumers that opted in. */
9
+ export declare class ValueObservers {
10
+ private readonly read;
11
+ private readonly observers;
12
+ private running;
13
+ constructor(read: (time: number) => number);
14
+ get active(): boolean;
15
+ subscribe(read: (value: number) => number, color: boolean, listener: ValueListener<number | Color>, options?: SubscribeOptions): () => void;
16
+ changed(running: boolean): void;
17
+ snapshot(time: number): () => void;
18
+ }
19
+ //# sourceMappingURL=value-observers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-observers.d.ts","sourceRoot":"","sources":["../src/value-observers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,EAAS,MAAM,oBAAoB,CAAA;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,kFAAkF;IAClF,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,4FAA4F;AAC5F,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;AAqE/D,yFAAyF;AACzF,qBAAa,cAAc;IAIb,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,OAAO,CAAQ;IAEvB,YAA6B,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAI;IAE/D,IAAI,MAAM,YAET;IAED,SAAS,CACP,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAC/B,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,aAAa,CAAC,MAAM,GAAG,KAAK,CAAC,EACvC,OAAO,GAAE,gBAAqB,GAC7B,MAAM,IAAI,CAeZ;IAED,OAAO,CAAC,OAAO,EAAE,OAAO,QAMvB;IAED,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CAYjC;CACF"}
@@ -0,0 +1,111 @@
1
+ import { Application, Color, Trace } from '@nativescript/core';
2
+ import { getDriver } from './driver/index.js';
3
+ // Only sources that need a frame live here. Idle subscriptions retain no global root reference.
4
+ const pending = new Set();
5
+ let cancelFrame;
6
+ let listening = false;
7
+ let suspended = false;
8
+ function suspend() {
9
+ suspended = true;
10
+ cancelFrame?.();
11
+ cancelFrame = undefined;
12
+ }
13
+ function resume() {
14
+ suspended = false;
15
+ schedule();
16
+ }
17
+ function schedule() {
18
+ if (!pending.size) {
19
+ cancelFrame?.();
20
+ cancelFrame = undefined;
21
+ if (listening && !suspended) {
22
+ Application.off(Application.suspendEvent, suspend);
23
+ Application.off(Application.resumeEvent, resume);
24
+ listening = false;
25
+ }
26
+ return;
27
+ }
28
+ if (!listening) {
29
+ Application.on(Application.suspendEvent, suspend);
30
+ Application.on(Application.resumeEvent, resume);
31
+ listening = true;
32
+ }
33
+ if (cancelFrame || suspended)
34
+ return;
35
+ cancelFrame = getDriver().frame(() => {
36
+ cancelFrame = undefined;
37
+ const time = getDriver().now();
38
+ const sources = [...pending];
39
+ pending.clear();
40
+ // Capture every source before calling any listener: reentrant writes belong to the next batch.
41
+ const deliveries = sources.map((source) => source.snapshot(time));
42
+ for (const source of sources)
43
+ if (source.active)
44
+ pending.add(source);
45
+ for (const deliver of deliveries)
46
+ deliver();
47
+ schedule();
48
+ });
49
+ }
50
+ function deliver(observer, value, time) {
51
+ try {
52
+ observer.listener(observer.color ? new Color(value) : value, time);
53
+ }
54
+ catch (error) {
55
+ // A consumer failure must not interrupt other consumers or strand the shared frame source.
56
+ Trace.write(`Jolt motion value subscriber failed: ${error instanceof Error ? error.stack : String(error)}`, Trace.categories.Error, Trace.messageType.error);
57
+ }
58
+ }
59
+ /** Root-owned subscriptions; mappings are evaluated only for consumers that opted in. */
60
+ export class ValueObservers {
61
+ read;
62
+ observers = new Set();
63
+ running = false;
64
+ constructor(read) {
65
+ this.read = read;
66
+ }
67
+ get active() {
68
+ return this.running && this.observers.size > 0;
69
+ }
70
+ subscribe(read, color, listener, options = {}) {
71
+ if (typeof listener !== 'function')
72
+ throw new TypeError('subscribe() needs a listener function.');
73
+ const time = getDriver().now();
74
+ const observer = { read, color, listener, previous: read(this.read(time)) };
75
+ this.observers.add(observer);
76
+ if (options.immediate !== false)
77
+ deliver(observer, observer.previous, time);
78
+ if (this.active)
79
+ this.changed(true);
80
+ return () => {
81
+ this.observers.delete(observer);
82
+ if (!this.observers.size) {
83
+ pending.delete(this);
84
+ schedule();
85
+ }
86
+ };
87
+ }
88
+ changed(running) {
89
+ this.running = running;
90
+ if (this.observers.size) {
91
+ pending.add(this);
92
+ schedule();
93
+ }
94
+ }
95
+ snapshot(time) {
96
+ const value = this.read(time);
97
+ const deliveries = [...this.observers].flatMap((observer) => {
98
+ const next = observer.read(value);
99
+ if (Object.is(next, observer.previous))
100
+ return [];
101
+ observer.previous = next;
102
+ return [{ observer, next }];
103
+ });
104
+ return () => {
105
+ for (const { observer, next } of deliveries)
106
+ if (this.observers.has(observer))
107
+ deliver(observer, next, time);
108
+ };
109
+ }
110
+ }
111
+ //# sourceMappingURL=value-observers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-observers.js","sourceRoot":"","sources":["../src/value-observers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type Track } from './track.js';
2
+ export interface ValuePart {
3
+ readonly track: Track;
4
+ readonly elapsed: number;
5
+ readonly base: number;
6
+ readonly span: number;
7
+ }
8
+ /** Compile scalar addition before any binding's mapping. The snapshot is independent of later edits. */
9
+ export declare function valueTrack(parts: readonly ValuePart[], rest: number): {
10
+ track: Track;
11
+ windowed: boolean;
12
+ };
13
+ //# sourceMappingURL=value-track.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-track.d.ts","sourceRoot":"","sources":["../src/value-track.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,wGAAwG;AACxG,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM;;;EAiDnE"}
@@ -0,0 +1,59 @@
1
+ import { instantTrack } from './track.js';
2
+ /** Compile scalar addition before any binding's mapping. The snapshot is independent of later edits. */
3
+ export function valueTrack(parts, rest) {
4
+ const value = (time) => parts.reduce((sum, part) => sum + part.base + part.span * part.track.valueAt(part.elapsed + time), rest);
5
+ let finite = 0;
6
+ const periods = [];
7
+ for (const { track, elapsed } of parts) {
8
+ if (Number.isFinite(track.end))
9
+ finite = Math.max(finite, track.end - elapsed);
10
+ else if (elapsed < track.delay)
11
+ finite = Math.max(finite, track.delay - elapsed);
12
+ else
13
+ periods.push(Math.max(1, track.duration * (track.reverse ? 2 : 1)));
14
+ }
15
+ if (finite <= 0 && !periods.length)
16
+ return { track: instantTrack('x', value(0)), windowed: false };
17
+ const loop = finite <= 0 && periods.length ? commonPeriod(periods) : undefined;
18
+ // Bound finite compositions too: a minutes-long base must not undersample a short pulse.
19
+ const duration = finite > 0 ? Math.min(finite, 4000) : (loop ?? 4000);
20
+ const steps = Math.max(1, Math.min(6000, Math.ceil((duration * 60) / 1000)));
21
+ const times = Array.from({ length: steps + 1 }, (_, i) => i / steps);
22
+ const values = times.map((time) => value(time * duration));
23
+ const endless = loop !== undefined;
24
+ const at = (time) => value(endless
25
+ ? ((time % duration) + duration) % duration
26
+ : Math.min(duration, Math.max(0, time)));
27
+ const track = {
28
+ property: 'x',
29
+ delay: 0,
30
+ duration,
31
+ repeat: endless ? Infinity : 0,
32
+ reverse: false,
33
+ times,
34
+ values,
35
+ to: endless ? values[0] : values[steps],
36
+ end: endless ? Infinity : duration,
37
+ arrival: endless ? Infinity : duration,
38
+ valueAt: at,
39
+ velocityAt: (time) => (at(time + 0.5) - at(time - 0.5)) * 1000,
40
+ };
41
+ return {
42
+ track,
43
+ windowed: finite > duration ||
44
+ (!endless && parts.some(({ track }) => !Number.isFinite(track.end))),
45
+ };
46
+ }
47
+ function commonPeriod(periods) {
48
+ const gcd = (a, b) => (b ? gcd(b, a % b) : a);
49
+ let total = 1;
50
+ for (const period of periods) {
51
+ if (!Number.isInteger(period))
52
+ return undefined;
53
+ total = (total / gcd(total, period)) * period;
54
+ if (total > 30000)
55
+ return undefined;
56
+ }
57
+ return total;
58
+ }
59
+ //# sourceMappingURL=value-track.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-track.js","sourceRoot":"","sources":["../src/value-track.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.12",
3
+ "version": "0.1.0-beta.13",
4
4
  "description": "Native animations for NativeScript: presets, springs, keyframes and stagger in one call.",
5
5
  "keywords": [
6
6
  "nativescript",
@@ -33,7 +33,11 @@
33
33
  "types": "./dist/vue/index.d.ts",
34
34
  "default": "./dist/vue/index.js"
35
35
  },
36
- "./package.json": "./package.json"
36
+ "./package.json": "./package.json",
37
+ "./native": {
38
+ "types": "./dist/native/index.d.ts",
39
+ "default": "./dist/native/index.js"
40
+ }
37
41
  },
38
42
  "files": [
39
43
  "dist",
@@ -209,3 +209,40 @@ declare namespace org.rafaelaugusto.jolt {
209
209
  }
210
210
  }
211
211
  }
212
+
213
+ declare namespace org.rafaelaugusto.jolt {
214
+ class PropertySink extends java.lang.Object {
215
+ static scalar(target: any, getter: string, setter: string): PropertySink
216
+ getDimensions(): number
217
+ isAlive(): boolean
218
+ isCompiled(): boolean
219
+ read(): native.Array<number>
220
+ write(values: native.Array<number>): void
221
+ dispose(): void
222
+ }
223
+ class MapLibrePropertySink extends PropertySink {
224
+ constructor(target: any, camera: boolean)
225
+ }
226
+ class PropertyPlayer extends java.lang.Object {
227
+ constructor(
228
+ sink: PropertySink,
229
+ times: native.Array<number>,
230
+ values: native.Array<number>,
231
+ finalValue: native.Array<number>,
232
+ duration: number,
233
+ delay: number,
234
+ repeat: number,
235
+ reverse: boolean,
236
+ listener: PropertyPlayer.Listener,
237
+ )
238
+ static activeCount(): number
239
+ getFrames(): number
240
+ control(time: number, paused: boolean): void
241
+ cancel(): void
242
+ }
243
+ namespace PropertyPlayer {
244
+ class Listener extends java.lang.Object {
245
+ constructor(implementation: { onEnd(completed: boolean): void })
246
+ }
247
+ }
248
+ }
package/src/animate.ts CHANGED
@@ -29,6 +29,7 @@ import {
29
29
  detachBindings,
30
30
  isMotionValue,
31
31
  type MotionValue,
32
+ type ValueAnimationOptions,
32
33
  } from './motion-value.js'
33
34
  import { resolveHaptic, type Haptic } from './haptics.js'
34
35
  import { layerable } from './mixer.js'
@@ -77,8 +78,8 @@ interface Options {
77
78
  export function animate(
78
79
  value: MotionValue,
79
80
  to: number | readonly (number | null)[],
80
- transition?: Transition | SpringName,
81
- ): Animation
81
+ transition?: ValueAnimationOptions | SpringName,
82
+ ): PlaybackAnimation
82
83
  export function animate(
83
84
  target: Target | readonly Target[],
84
85
  animation: Keyframes | PresetName,
@@ -92,7 +93,7 @@ export function animate(
92
93
  if (isMotionValue(target))
93
94
  return asRoot(target).animate(
94
95
  animation as number | readonly (number | null)[],
95
- options as Transition | SpringName | undefined,
96
+ options as ValueAnimationOptions | SpringName | undefined,
96
97
  )
97
98
  return prepareAnimation(
98
99
  target as Target | readonly Target[],
@@ -237,7 +238,7 @@ export function decay(
237
238
  * Stops all or selected properties at their current values. `scale` stops both axes.
238
239
  * A motion value stops where it is, and so do the views bound to it.
239
240
  */
240
- export function stop(value: MotionValue): void
241
+ export function stop(value: MotionValue, options?: { layer?: string }): void
241
242
  export function stop(
242
243
  target: Target | readonly Target[],
243
244
  properties?: readonly KeyframeProperty[],
@@ -245,11 +246,16 @@ export function stop(
245
246
  ): void
246
247
  export function stop(
247
248
  target: Target | readonly Target[] | MotionValue,
248
- properties?: readonly KeyframeProperty[],
249
+ properties?: readonly KeyframeProperty[] | { layer?: string },
249
250
  options?: { layer?: string },
250
251
  ) {
251
- if (isMotionValue(target)) return asRoot(target).stop()
252
- const expanded = properties?.flatMap<Property>((property) =>
252
+ if (isMotionValue(target))
253
+ return asRoot(target).stop((properties as { layer?: string } | undefined)?.layer)
254
+ if (properties && !Array.isArray(properties))
255
+ throw new TypeError('View properties must be an array.')
256
+ const expanded = (
257
+ properties as readonly KeyframeProperty[] | undefined
258
+ )?.flatMap<Property>((property) =>
253
259
  property === 'scale' ? ['scaleX', 'scaleY'] : [property],
254
260
  )
255
261
  for (const view of toViews(target as Target | readonly Target[]))
package/src/drag.ts CHANGED
@@ -247,7 +247,7 @@ class DragController implements Drag {
247
247
  }
248
248
  get position(): DragPoint {
249
249
  const value = this.config.value
250
- if (value) return { x: 0, y: 0, [this.config.axes[0]!]: value.raw() }
250
+ if (value) return { x: 0, y: 0, [this.config.axes[0]!]: value.base() }
251
251
  return { x: currentValue(this.view, 'x'), y: currentValue(this.view, 'y') }
252
252
  }
253
253
  cancel = () => {
@@ -338,7 +338,7 @@ class DragController implements Drag {
338
338
  this.blocked = false
339
339
  const value = this.config.value
340
340
  if (value) {
341
- value.stop()
341
+ value.stopBase()
342
342
  this.origin = this.position
343
343
  } else {
344
344
  // Claim just the enabled axes, preserving the native presentation on takeover.
@@ -385,7 +385,7 @@ class DragController implements Drag {
385
385
  : clampDrag(raw, curve.bounds)
386
386
  if (axis === 'x') vx = input.velocityX * resistance
387
387
  else vy = input.velocityY * resistance
388
- if (this.config.value) this.config.value.set(position[axis])
388
+ if (this.config.value) this.config.value.setBase(position[axis])
389
389
  else {
390
390
  stopBase(this.view, [axis])
391
391
  setBase(this.view, axis, position[axis])
@@ -12,6 +12,7 @@ import {
12
12
  import { Application, Utils, type View } from '@nativescript/core'
13
13
  import type { NumericProperty } from '../properties.js'
14
14
  import type { Driver } from './index.js'
15
+ import { frame } from './frame.js'
15
16
  import { isColorProperty } from '../color.js'
16
17
  import {
17
18
  playAndroidColor,
@@ -109,6 +110,7 @@ export function createAndroidDriver(): Driver {
109
110
 
110
111
  return {
111
112
  now: () => android.os.SystemClock.uptimeMillis(),
113
+ frame,
112
114
  clock,
113
115
  control(_view, handle, elapsed, paused, command) {
114
116
  ;(handle as Handle).control(elapsed, paused, command)
@@ -0,0 +1,10 @@
1
+ import {
2
+ cancelAnimationFrame,
3
+ requestAnimationFrame,
4
+ } from '@nativescript/core/animation-frame'
5
+
6
+ /** NativeScript schedules subsequent frames with CADisplayLink / Choreographer. */
7
+ export function frame(callback: () => void): () => void {
8
+ const id = requestAnimationFrame(callback)
9
+ return () => cancelAnimationFrame(id)
10
+ }
@@ -15,6 +15,8 @@ export interface LayoutFrame {
15
15
  export interface Driver {
16
16
  /** Milliseconds, on the clock the platform's animations run on. */
17
17
  now(): number
18
+ /** One native animation frame; returns an idempotent cancellation function. */
19
+ frame(callback: () => void): () => void
18
20
  /** Starts the track at `startedAt + track.delay` and calls `onEnd` once, however it ends. */
19
21
  play(
20
22
  view: View,
package/src/driver/ios.ts CHANGED
@@ -13,6 +13,7 @@ import { playIOSColor, presentedIOSColor } from './ios-color.js'
13
13
  import { after, type Driver } from './index.js'
14
14
  import { hasInteractionSurface } from '../interaction-surface.js'
15
15
  import { retainInteractiveLayout } from './ios-layout.js'
16
+ import { frame } from './frame.js'
16
17
 
17
18
  interface Handle {
18
19
  stop(): void
@@ -59,6 +60,7 @@ function ensurePerspective(view: View, layers: CALayer[]) {
59
60
  export function createIOSDriver(): Driver {
60
61
  return {
61
62
  now: () => CACurrentMediaTime() * 1000,
63
+ frame,
62
64
 
63
65
  play(view, track, startedAt, onEnd): Handle {
64
66
  if (isDecorationProperty(track.property))