@tarsis/toolkit 0.5.1 → 0.5.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.
@@ -2303,6 +2303,12 @@ class NativeAnimation extends WithPromise {
2303
2303
  super();
2304
2304
  this.finishedTime = null;
2305
2305
  this.isStopped = false;
2306
+ /**
2307
+ * Tracks a manually-set start time that takes precedence over WAAPI's
2308
+ * dynamic startTime. This is cleared when play() or time setter is called,
2309
+ * allowing WAAPI to take over timing.
2310
+ */
2311
+ this.manualStartTime = null;
2306
2312
  if (!options)
2307
2313
  return;
2308
2314
  const { element, name, keyframes, pseudoElement, allowFlatten = false, finalKeyframe, onComplete, } = options;
@@ -2338,6 +2344,7 @@ class NativeAnimation extends WithPromise {
2338
2344
  play() {
2339
2345
  if (this.isStopped)
2340
2346
  return;
2347
+ this.manualStartTime = null;
2341
2348
  this.animation.play();
2342
2349
  if (this.state === "finished") {
2343
2350
  this.updateFinished();
@@ -2401,6 +2408,7 @@ class NativeAnimation extends WithPromise {
2401
2408
  return millisecondsToSeconds(Number(this.animation.currentTime) || 0);
2402
2409
  }
2403
2410
  set time(newTime) {
2411
+ this.manualStartTime = null;
2404
2412
  this.finishedTime = null;
2405
2413
  this.animation.currentTime = secondsToMilliseconds(newTime);
2406
2414
  }
@@ -2423,10 +2431,10 @@ class NativeAnimation extends WithPromise {
2423
2431
  : this.animation.playState;
2424
2432
  }
2425
2433
  get startTime() {
2426
- return Number(this.animation.startTime);
2434
+ return this.manualStartTime ?? Number(this.animation.startTime);
2427
2435
  }
2428
2436
  set startTime(newStartTime) {
2429
- this.animation.startTime = newStartTime;
2437
+ this.manualStartTime = this.animation.startTime = newStartTime;
2430
2438
  }
2431
2439
  /**
2432
2440
  * Attaches a timeline to the animation, for instance the `ScrollTimeline`.
@@ -2488,7 +2496,7 @@ class NativeAnimationExtended extends NativeAnimation {
2488
2496
  */
2489
2497
  replaceTransitionType(options);
2490
2498
  super(options);
2491
- if (options.startTime) {
2499
+ if (options.startTime !== undefined) {
2492
2500
  this.startTime = options.startTime;
2493
2501
  }
2494
2502
  this.options = options;
@@ -2513,8 +2521,14 @@ class NativeAnimationExtended extends NativeAnimation {
2513
2521
  ...options,
2514
2522
  autoplay: false,
2515
2523
  });
2516
- const sampleTime = secondsToMilliseconds(this.finishedTime ?? this.time);
2517
- motionValue.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
2524
+ /**
2525
+ * Use wall-clock elapsed time for sampling.
2526
+ * Under CPU load, WAAPI's currentTime may not reflect actual
2527
+ * elapsed time, causing incorrect sampling and visual jumps.
2528
+ */
2529
+ const sampleTime = Math.max(sampleDelta, time.now() - this.startTime);
2530
+ const delta = clamp(0, sampleDelta, sampleTime - sampleDelta);
2531
+ motionValue.setWithVelocity(sampleAnimation.sample(Math.max(0, sampleTime - delta)).value, sampleAnimation.sample(sampleTime).value, delta);
2518
2532
  sampleAnimation.stop();
2519
2533
  }
2520
2534
  }
@@ -2305,6 +2305,12 @@ class NativeAnimation extends WithPromise {
2305
2305
  super();
2306
2306
  this.finishedTime = null;
2307
2307
  this.isStopped = false;
2308
+ /**
2309
+ * Tracks a manually-set start time that takes precedence over WAAPI's
2310
+ * dynamic startTime. This is cleared when play() or time setter is called,
2311
+ * allowing WAAPI to take over timing.
2312
+ */
2313
+ this.manualStartTime = null;
2308
2314
  if (!options)
2309
2315
  return;
2310
2316
  const { element, name, keyframes, pseudoElement, allowFlatten = false, finalKeyframe, onComplete, } = options;
@@ -2340,6 +2346,7 @@ class NativeAnimation extends WithPromise {
2340
2346
  play() {
2341
2347
  if (this.isStopped)
2342
2348
  return;
2349
+ this.manualStartTime = null;
2343
2350
  this.animation.play();
2344
2351
  if (this.state === "finished") {
2345
2352
  this.updateFinished();
@@ -2403,6 +2410,7 @@ class NativeAnimation extends WithPromise {
2403
2410
  return millisecondsToSeconds(Number(this.animation.currentTime) || 0);
2404
2411
  }
2405
2412
  set time(newTime) {
2413
+ this.manualStartTime = null;
2406
2414
  this.finishedTime = null;
2407
2415
  this.animation.currentTime = secondsToMilliseconds(newTime);
2408
2416
  }
@@ -2425,10 +2433,10 @@ class NativeAnimation extends WithPromise {
2425
2433
  : this.animation.playState;
2426
2434
  }
2427
2435
  get startTime() {
2428
- return Number(this.animation.startTime);
2436
+ return this.manualStartTime ?? Number(this.animation.startTime);
2429
2437
  }
2430
2438
  set startTime(newStartTime) {
2431
- this.animation.startTime = newStartTime;
2439
+ this.manualStartTime = this.animation.startTime = newStartTime;
2432
2440
  }
2433
2441
  /**
2434
2442
  * Attaches a timeline to the animation, for instance the `ScrollTimeline`.
@@ -2490,7 +2498,7 @@ class NativeAnimationExtended extends NativeAnimation {
2490
2498
  */
2491
2499
  replaceTransitionType(options);
2492
2500
  super(options);
2493
- if (options.startTime) {
2501
+ if (options.startTime !== undefined) {
2494
2502
  this.startTime = options.startTime;
2495
2503
  }
2496
2504
  this.options = options;
@@ -2515,8 +2523,14 @@ class NativeAnimationExtended extends NativeAnimation {
2515
2523
  ...options,
2516
2524
  autoplay: false,
2517
2525
  });
2518
- const sampleTime = secondsToMilliseconds(this.finishedTime ?? this.time);
2519
- motionValue.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
2526
+ /**
2527
+ * Use wall-clock elapsed time for sampling.
2528
+ * Under CPU load, WAAPI's currentTime may not reflect actual
2529
+ * elapsed time, causing incorrect sampling and visual jumps.
2530
+ */
2531
+ const sampleTime = Math.max(sampleDelta, time.now() - this.startTime);
2532
+ const delta = clamp(0, sampleDelta, sampleTime - sampleDelta);
2533
+ motionValue.setWithVelocity(sampleAnimation.sample(Math.max(0, sampleTime - delta)).value, sampleAnimation.sample(sampleTime).value, delta);
2520
2534
  sampleAnimation.stop();
2521
2535
  }
2522
2536
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarsis/toolkit",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -79,13 +79,13 @@
79
79
  "@use-gesture/react": "^10.3.1",
80
80
  "bowser": "^2.13.1",
81
81
  "canvas-confetti": "^1.9.4",
82
- "classnames": "^2.5.1",
82
+ "clsx": "^2.1.1",
83
83
  "flickity": "^2.3.0",
84
84
  "gsap": "^3.14.2",
85
85
  "howler": "^2.2.4",
86
86
  "html2canvas": "^1.4.1",
87
87
  "load-bmfont": "1.4.1",
88
- "motion": "^12.24.10",
88
+ "motion": "^12.24.11",
89
89
  "p5": "^2.0.5",
90
90
  "react-flip-toolkit": "^7.2.4",
91
91
  "react-icons": "^5.5.0",