@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.
- package/README.md +4 -1
- package/dist/animate.d.ts +6 -4
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +3 -1
- package/dist/animate.js.map +1 -1
- package/dist/drag.js +3 -3
- package/dist/drag.js.map +1 -1
- package/dist/driver/android.d.ts.map +1 -1
- package/dist/driver/android.js +2 -0
- package/dist/driver/android.js.map +1 -1
- package/dist/driver/frame.d.ts +3 -0
- package/dist/driver/frame.d.ts.map +1 -0
- package/dist/driver/frame.js +7 -0
- package/dist/driver/frame.js.map +1 -0
- package/dist/driver/index.d.ts +2 -0
- package/dist/driver/index.d.ts.map +1 -1
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +2 -0
- package/dist/driver/ios.js.map +1 -1
- package/dist/engine.d.ts +2 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +23 -2
- package/dist/engine.js.map +1 -1
- package/dist/image-effect.d.ts +1 -0
- package/dist/image-effect.d.ts.map +1 -1
- package/dist/image-effect.js +10 -2
- package/dist/image-effect.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/motion-scope.d.ts +2 -1
- package/dist/motion-scope.d.ts.map +1 -1
- package/dist/motion-scope.js +4 -1
- package/dist/motion-scope.js.map +1 -1
- package/dist/motion-value.d.ts +45 -8
- package/dist/motion-value.d.ts.map +1 -1
- package/dist/motion-value.js +289 -91
- package/dist/motion-value.js.map +1 -1
- package/dist/native/index.d.ts +6 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +3 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native-properties.d.ts +28 -0
- package/dist/native-properties.d.ts.map +1 -0
- package/dist/native-properties.js +154 -0
- package/dist/native-properties.js.map +1 -0
- package/dist/native-property-driver.d.ts +19 -0
- package/dist/native-property-driver.d.ts.map +1 -0
- package/dist/native-property-driver.js +69 -0
- package/dist/native-property-driver.js.map +1 -0
- package/dist/native-property.d.ts +35 -0
- package/dist/native-property.d.ts.map +1 -0
- package/dist/native-property.js +277 -0
- package/dist/native-property.js.map +1 -0
- package/dist/playback-group.d.ts.map +1 -1
- package/dist/playback-group.js +17 -1
- package/dist/playback-group.js.map +1 -1
- package/dist/playback.d.ts +15 -0
- package/dist/playback.d.ts.map +1 -1
- package/dist/playback.js +23 -0
- package/dist/playback.js.map +1 -1
- package/dist/sequence.d.ts +24 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +181 -19
- package/dist/sequence.js.map +1 -1
- package/dist/timed-animation.d.ts +38 -0
- package/dist/timed-animation.d.ts.map +1 -0
- package/dist/timed-animation.js +177 -0
- package/dist/timed-animation.js.map +1 -0
- package/dist/value-observers.d.ts +19 -0
- package/dist/value-observers.d.ts.map +1 -0
- package/dist/value-observers.js +111 -0
- package/dist/value-observers.js.map +1 -0
- package/dist/value-track.d.ts +13 -0
- package/dist/value-track.d.ts.map +1 -0
- package/dist/value-track.js +59 -0
- package/dist/value-track.js.map +1 -0
- package/package.json +6 -2
- package/src/android-plugin.d.ts +37 -0
- package/src/animate.ts +13 -7
- package/src/drag.ts +3 -3
- package/src/driver/android.ts +2 -0
- package/src/driver/frame.ts +10 -0
- package/src/driver/index.ts +2 -0
- package/src/driver/ios.ts +2 -0
- package/src/engine.ts +23 -2
- package/src/image-effect.ts +10 -2
- package/src/index.ts +5 -0
- package/src/ios-plugin.d.ts +33 -0
- package/src/motion-scope.ts +5 -1
- package/src/motion-value.ts +331 -99
- package/src/native/index.ts +16 -0
- package/src/native-properties.ts +188 -0
- package/src/native-property-driver.ts +123 -0
- package/src/native-property.ts +353 -0
- package/src/playback-group.ts +17 -1
- package/src/playback.ts +41 -0
- package/src/sequence.ts +209 -20
- package/src/timed-animation.ts +192 -0
- package/src/value-observers.ts +133 -0
- 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.
|
|
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",
|
package/src/android-plugin.d.ts
CHANGED
|
@@ -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?:
|
|
81
|
-
):
|
|
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
|
|
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))
|
|
252
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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])
|
package/src/driver/android.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/driver/index.ts
CHANGED
|
@@ -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))
|