@rive-app/canvas-lite 2.37.1 → 2.37.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rive-app/canvas-lite",
3
- "version": "2.37.1",
3
+ "version": "2.37.3",
4
4
  "description": "A lite version of Rive's canvas based web api.",
5
5
  "main": "rive.js",
6
6
  "homepage": "https://rive.app",
package/rive.js CHANGED
@@ -155,6 +155,17 @@ __webpack_require__.r(__webpack_exports__);
155
155
  /* harmony export */ });
156
156
  /* harmony import */ var _rive_advanced_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
157
157
  /* harmony import */ var package_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5);
158
+ var __assign = (undefined && undefined.__assign) || function () {
159
+ __assign = Object.assign || function(t) {
160
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
161
+ s = arguments[i];
162
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
163
+ t[p] = s[p];
164
+ }
165
+ return t;
166
+ };
167
+ return __assign.apply(this, arguments);
168
+ };
158
169
 
159
170
 
160
171
  // Runtime singleton; use getInstance to provide a callback that returns the
@@ -165,12 +176,15 @@ var RuntimeLoader = /** @class */ (function () {
165
176
  }
166
177
  // Loads the runtime
167
178
  RuntimeLoader.loadRuntime = function () {
179
+ // Capture the URL at call time so the catch closure always refers to the
180
+ // URL this particular attempt used, even if wasmURL is mutated for a retry.
181
+ var attemptedUrl = RuntimeLoader.wasmURL;
182
+ var wasmBinary = RuntimeLoader.wasmBinary;
168
183
  if (RuntimeLoader.enablePerfMarks)
169
184
  performance.mark('rive:wasm-init:start');
170
- _rive_advanced_mjs__WEBPACK_IMPORTED_MODULE_0__["default"]({
185
+ _rive_advanced_mjs__WEBPACK_IMPORTED_MODULE_0__["default"](__assign({
171
186
  // Loads Wasm bundle
172
- locateFile: function () { return RuntimeLoader.wasmURL; },
173
- })
187
+ locateFile: function () { return attemptedUrl; } }, (wasmBinary ? { wasmBinary: wasmBinary } : {})))
174
188
  .then(function (rive) {
175
189
  var _a;
176
190
  if (RuntimeLoader.enablePerfMarks) {
@@ -195,18 +209,30 @@ var RuntimeLoader = /** @class */ (function () {
195
209
  };
196
210
  // Log detailed error for debugging
197
211
  console.debug("Rive WASM load error details:", errorDetails);
198
- // In case unpkg fails, or the wasm was not supported, we try to load the fallback module from jsdelivr.
199
- // This `rive_fallback.wasm` is compiled to support older architecture.
200
- // TODO: (Gordon): preemptively test browser support and load the correct wasm file. Then use jsdelvr only if unpkg fails.
201
- var backupJsdelivrUrl = "https://cdn.jsdelivr.net/npm/".concat(package_json__WEBPACK_IMPORTED_MODULE_1__.name, "@").concat(package_json__WEBPACK_IMPORTED_MODULE_1__.version, "/rive_fallback.wasm");
202
- if (RuntimeLoader.wasmURL.toLowerCase() !== backupJsdelivrUrl) {
203
- console.warn("Failed to load WASM from ".concat(RuntimeLoader.wasmURL, " (").concat(errorDetails.message, "), trying jsdelivr as a backup"));
204
- RuntimeLoader.setWasmUrl(backupJsdelivrUrl);
212
+ // In case the primary URL fails, or the wasm was not supported, try the
213
+ // fallback URL (a rive_fallback.wasm compiled for older architectures).
214
+ // The fallback can be customised or disabled via setWasmFallbackUrl().
215
+ // TODO: (Gordon): preemptively test browser support and load the correct wasm file. Then use the fallback only if the primary fails.
216
+ var fallbackUrl = RuntimeLoader.wasmFallbackURL;
217
+ var alreadyOnFallback = fallbackUrl !== null &&
218
+ attemptedUrl.toLowerCase() === fallbackUrl.toLowerCase();
219
+ if (fallbackUrl !== null && !alreadyOnFallback) {
220
+ console.warn("Failed to load WASM from ".concat(attemptedUrl, " (").concat(errorDetails.message, "), trying fallback URL: ").concat(fallbackUrl));
221
+ // Clear wasmBinary so the retry actually fetches via locateFile
222
+ // instead of re-using the same (failing) in-memory binary.
223
+ RuntimeLoader.wasmBinary = null;
224
+ RuntimeLoader.setWasmUrl(fallbackUrl);
205
225
  RuntimeLoader.loadRuntime();
206
226
  }
207
227
  else {
228
+ // When alreadyOnFallback is true, wasmURL has already been overwritten
229
+ // with the fallback URL, so we can no longer recover the original
230
+ // primary URL here. The primary URL was logged in the earlier warning.
231
+ var triedUrls = alreadyOnFallback
232
+ ? "the configured WASM URL or its fallback (".concat(fallbackUrl, ")")
233
+ : attemptedUrl;
208
234
  var errorMessage = [
209
- "Could not load Rive WASM file from ".concat(RuntimeLoader.wasmURL, " or ").concat(backupJsdelivrUrl, "."),
235
+ "Could not load Rive WASM file from ".concat(triedUrls, "."),
210
236
  "Possible reasons:",
211
237
  "- Network connection is down",
212
238
  "- WebAssembly is not supported in this environment",
@@ -252,6 +278,31 @@ var RuntimeLoader = /** @class */ (function () {
252
278
  RuntimeLoader.getWasmUrl = function () {
253
279
  return RuntimeLoader.wasmURL;
254
280
  };
281
+ /**
282
+ * Sets the URL used as a fallback when the primary WASM URL fails to load.
283
+ * Pass `null` to disable the fallback entirely.
284
+ *
285
+ * Defaults to pulling from the jsdelivr CDN.
286
+ */
287
+ RuntimeLoader.setWasmFallbackUrl = function (url) {
288
+ RuntimeLoader.wasmFallbackURL = url;
289
+ };
290
+ // Gets the current fallback wasm url (null means fallback is disabled)
291
+ RuntimeLoader.getWasmFallbackUrl = function () {
292
+ return RuntimeLoader.wasmFallbackURL;
293
+ };
294
+ // Manually sets the wasm binary or clears it with null
295
+ RuntimeLoader.setWasmBinary = function (value) {
296
+ if ((value instanceof ArrayBuffer) || value === null) {
297
+ RuntimeLoader.wasmBinary = value;
298
+ return;
299
+ }
300
+ console.error("setWasmBinary expects an ArrayBuffer or null");
301
+ };
302
+ // Gets the current wasm build as ArrayBuffer or null
303
+ RuntimeLoader.getWasmBinary = function () {
304
+ return RuntimeLoader.wasmBinary;
305
+ };
255
306
  // Flag to indicate that loading has started/completed
256
307
  RuntimeLoader.isLoading = false;
257
308
  // List of callbacks for the runtime that come in while loading
@@ -259,6 +310,10 @@ var RuntimeLoader = /** @class */ (function () {
259
310
  // Path to the Wasm file; default path works for testing only;
260
311
  // if embedded wasm is used then this is never used.
261
312
  RuntimeLoader.wasmURL = "https://unpkg.com/".concat(package_json__WEBPACK_IMPORTED_MODULE_1__.name, "@").concat(package_json__WEBPACK_IMPORTED_MODULE_1__.version, "/rive.wasm");
313
+ // Fallback WASM URL tried when the primary URL fails. Set to null to disable
314
+ // the fallback entirely. Defaults to pulling from the jsdelivr CDN.
315
+ RuntimeLoader.wasmFallbackURL = "https://cdn.jsdelivr.net/npm/".concat(package_json__WEBPACK_IMPORTED_MODULE_1__.name, "@").concat(package_json__WEBPACK_IMPORTED_MODULE_1__.version, "/rive_fallback.wasm");
316
+ RuntimeLoader.wasmBinary = null;
262
317
  /**
263
318
  * When true, performance.mark / performance.measure entries are emitted for
264
319
  * WASM initialization.
@@ -2474,7 +2529,7 @@ moduleRtn = da;
2474
2529
  /* 5 */
2475
2530
  /***/ ((module) => {
2476
2531
 
2477
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@rive-app/canvas-lite","version":"2.37.1","description":"A lite version of Rive\'s canvas based web api.","main":"rive.js","homepage":"https://rive.app","repository":{"type":"git","url":"https://github.com/rive-app/rive-wasm/tree/master/js"},"keywords":["rive","animation"],"author":"Rive","contributors":["Luigi Rosso <luigi@rive.app> (https://rive.app)","Maxwell Talbot <max@rive.app> (https://rive.app)","Arthur Vivian <arthur@rive.app> (https://rive.app)","Umberto Sonnino <umberto@rive.app> (https://rive.app)","Matthew Sullivan <matt.j.sullivan@gmail.com> (mailto:matt.j.sullivan@gmail.com)"],"license":"MIT","files":["rive.js","rive.js.map","rive.wasm","rive_fallback.wasm","rive.d.ts","rive_advanced.mjs.d.ts","runtimeLoader.d.ts","utils"],"typings":"rive.d.ts","dependencies":{},"browser":{"fs":false,"path":false}}');
2532
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@rive-app/canvas-lite","version":"2.37.3","description":"A lite version of Rive\'s canvas based web api.","main":"rive.js","homepage":"https://rive.app","repository":{"type":"git","url":"https://github.com/rive-app/rive-wasm/tree/master/js"},"keywords":["rive","animation"],"author":"Rive","contributors":["Luigi Rosso <luigi@rive.app> (https://rive.app)","Maxwell Talbot <max@rive.app> (https://rive.app)","Arthur Vivian <arthur@rive.app> (https://rive.app)","Umberto Sonnino <umberto@rive.app> (https://rive.app)","Matthew Sullivan <matt.j.sullivan@gmail.com> (mailto:matt.j.sullivan@gmail.com)"],"license":"MIT","files":["rive.js","rive.js.map","rive.wasm","rive_fallback.wasm","rive.d.ts","rive_advanced.mjs.d.ts","runtimeLoader.d.ts","utils"],"typings":"rive.d.ts","dependencies":{},"browser":{"fs":false,"path":false}}');
2478
2533
 
2479
2534
  /***/ }),
2480
2535
  /* 6 */
@@ -2518,60 +2573,70 @@ __webpack_require__.r(__webpack_exports__);
2518
2573
  /* harmony export */ });
2519
2574
  var _this = undefined;
2520
2575
  /**
2521
- * Returns the clientX and clientY properties from touch or mouse events. Also
2522
- * calls preventDefault() on the event if it is a touchstart or touchmove to prevent
2523
- * scrolling the page on mobile devices
2524
- * @param event - Either a TouchEvent or a MouseEvent
2525
- * @returns - Coordinates of the clientX and clientY properties from the touch/mouse event
2576
+ * Extracts ClientCoordinates from a TouchList, respecting multi-touch vs.
2577
+ * single-touch mode. In single-touch mode, only the touch matching
2578
+ * primaryTouchId is returned (or the first touch when primaryTouchId is null).
2526
2579
  */
2527
- var getClientCoordinates = function (event, isTouchScrollEnabled, enableMultiTouch) {
2528
- var _a, _b;
2580
+ var getTouchCoordinates = function (changedTouches, enableMultiTouch, primaryTouchId) {
2581
+ var _a;
2529
2582
  var coordinates = [];
2530
- if (["touchstart", "touchmove"].indexOf(event.type) > -1 &&
2531
- ((_a = event.changedTouches) === null || _a === void 0 ? void 0 : _a.length)) {
2532
- // This flag, if false, prevents touch events on the canvas default behavior
2533
- // which may prevent scrolling if a drag motion on the canvas is performed
2534
- if (!isTouchScrollEnabled) {
2535
- event.preventDefault();
2536
- }
2537
- var cnt = 0;
2538
- var totalTouches = enableMultiTouch
2539
- ? event.changedTouches.length
2540
- : 1;
2541
- while (cnt < totalTouches) {
2542
- var touch = event.changedTouches[cnt];
2583
+ if (enableMultiTouch) {
2584
+ for (var i = 0; i < changedTouches.length; i++) {
2585
+ var touch = changedTouches[i];
2543
2586
  coordinates.push({
2544
2587
  clientX: touch.clientX,
2545
2588
  clientY: touch.clientY,
2546
2589
  identifier: touch.identifier,
2547
2590
  });
2548
- cnt++;
2549
2591
  }
2550
2592
  }
2551
- else if (event.type === "touchend" &&
2552
- ((_b = event.changedTouches) === null || _b === void 0 ? void 0 : _b.length)) {
2553
- var cnt = 0;
2554
- var totalTouches = enableMultiTouch
2555
- ? event.changedTouches.length
2556
- : 1;
2557
- while (cnt < totalTouches) {
2558
- var touch = event.changedTouches[cnt];
2593
+ else {
2594
+ // In "single-touch mode", only track the primary finger identified at touchstart.
2595
+ // Search changedTouches for the touch matching the recorded primary touch identifier, or (on initial touchstart)
2596
+ // take the first available touch identifier.
2597
+ var primaryTouch = primaryTouchId !== null
2598
+ ? (_a = Array.from(changedTouches).find(function (t) { return t.identifier === primaryTouchId; })) !== null && _a !== void 0 ? _a : null
2599
+ : changedTouches[0];
2600
+ if (primaryTouch) {
2559
2601
  coordinates.push({
2560
- clientX: touch.clientX,
2561
- clientY: touch.clientY,
2562
- identifier: touch.identifier,
2602
+ clientX: primaryTouch.clientX,
2603
+ clientY: primaryTouch.clientY,
2604
+ identifier: primaryTouch.identifier,
2563
2605
  });
2564
- cnt++;
2565
2606
  }
2566
2607
  }
2567
- else {
2568
- coordinates.push({
2608
+ return coordinates;
2609
+ };
2610
+ /**
2611
+ * Returns the clientX and clientY properties from touch or mouse events. Also
2612
+ * calls preventDefault() on the event if it is a touchstart or touchmove to prevent
2613
+ * scrolling the page on mobile devices
2614
+ * @param event - Either a TouchEvent or a MouseEvent
2615
+ * @param isTouchScrollEnabled - Whether touch scrolling is enabled
2616
+ * @param enableMultiTouch - Whether to process multiple simultaneous touches
2617
+ * @param primaryTouchId - When working with single touches, only process the touch
2618
+ * with this identifier. Pass null to accept any touch (used during touchstart to
2619
+ * capture the first finger down).
2620
+ * @returns - Coordinates of the clientX and clientY properties from the touch/mouse event
2621
+ */
2622
+ var getClientCoordinates = function (event, isTouchScrollEnabled, enableMultiTouch, primaryTouchId) {
2623
+ var _a;
2624
+ var touchEvent = event;
2625
+ if ((_a = touchEvent.changedTouches) === null || _a === void 0 ? void 0 : _a.length) {
2626
+ // This flag, if false, prevents touch events on the canvas default behavior
2627
+ // which may prevent scrolling if a drag motion on the canvas is performed
2628
+ if (!isTouchScrollEnabled && ["touchstart", "touchmove"].includes(event.type)) {
2629
+ event.preventDefault();
2630
+ }
2631
+ return getTouchCoordinates(touchEvent.changedTouches, enableMultiTouch, primaryTouchId);
2632
+ }
2633
+ return [
2634
+ {
2569
2635
  clientX: event.clientX,
2570
2636
  clientY: event.clientY,
2571
2637
  identifier: 0,
2572
- });
2573
- }
2574
- return coordinates;
2638
+ },
2639
+ ];
2575
2640
  };
2576
2641
  /**
2577
2642
  * Registers mouse move/up/down callback handlers on the canvas to send meaningful coordinates to
@@ -2603,7 +2668,15 @@ var registerTouchInteractions = function (_a) {
2603
2668
  **/
2604
2669
  var _prevEventType = null;
2605
2670
  var _syntheticEventsActive = false;
2671
+ /**
2672
+ * When enableMultiTouch is false ("single-touch mode"), we track the identifier of the first finger that touched down.
2673
+ * All subsequent touch events are filtered to this identifier so that a second finger
2674
+ * moving cannot displace the tracked pointer position.
2675
+ * Reset to null when the primary finger lifts (or touchcancel is called)
2676
+ */
2677
+ var _primaryTouchId = null;
2606
2678
  var processEventCallback = function (event) {
2679
+ var _a;
2607
2680
  // Exit early out of all synthetic mouse events
2608
2681
  // https://stackoverflow.com/questions/9656990/how-to-prevent-simulated-mouse-events-in-mobile-browsers
2609
2682
  // https://stackoverflow.com/questions/25572070/javascript-touchend-versus-click-dilemma
@@ -2622,7 +2695,15 @@ var registerTouchInteractions = function (_a) {
2622
2695
  _prevEventType === "touchstart";
2623
2696
  _prevEventType = event.type;
2624
2697
  var boundingRect = event.currentTarget.getBoundingClientRect();
2625
- var coordinateSets = getClientCoordinates(event, isTouchScrollEnabled, enableMultiTouch);
2698
+ // On touchstart in single-touch mode, record the first new finger as the primary
2699
+ // touch if we aren't already tracking one.
2700
+ if (!enableMultiTouch && event.type === "touchstart" && _primaryTouchId === null) {
2701
+ var firstTouch = (_a = event.changedTouches) === null || _a === void 0 ? void 0 : _a[0];
2702
+ if (firstTouch) {
2703
+ _primaryTouchId = firstTouch.identifier;
2704
+ }
2705
+ }
2706
+ var coordinateSets = getClientCoordinates(event, isTouchScrollEnabled, enableMultiTouch, enableMultiTouch ? null : _primaryTouchId);
2626
2707
  var forwardMatrix = rive.computeAlignment(fit, alignment, {
2627
2708
  minX: 0,
2628
2709
  minY: 0,
@@ -2687,8 +2768,8 @@ var registerTouchInteractions = function (_a) {
2687
2768
  stateMachine.pointerMove(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
2688
2769
  });
2689
2770
  };
2690
- for (var _a = 0, stateMachines_2 = stateMachines; _a < stateMachines_2.length; _a++) {
2691
- var stateMachine = stateMachines_2[_a];
2771
+ for (var _b = 0, stateMachines_2 = stateMachines; _b < stateMachines_2.length; _b++) {
2772
+ var stateMachine = stateMachines_2[_b];
2692
2773
  _loop_2(stateMachine);
2693
2774
  }
2694
2775
  break;
@@ -2701,8 +2782,8 @@ var registerTouchInteractions = function (_a) {
2701
2782
  stateMachine.pointerDown(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
2702
2783
  });
2703
2784
  };
2704
- for (var _b = 0, stateMachines_3 = stateMachines; _b < stateMachines_3.length; _b++) {
2705
- var stateMachine = stateMachines_3[_b];
2785
+ for (var _c = 0, stateMachines_3 = stateMachines; _c < stateMachines_3.length; _c++) {
2786
+ var stateMachine = stateMachines_3[_c];
2706
2787
  _loop_3(stateMachine);
2707
2788
  }
2708
2789
  break;
@@ -2715,10 +2796,16 @@ var registerTouchInteractions = function (_a) {
2715
2796
  stateMachine.pointerExit(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
2716
2797
  });
2717
2798
  };
2718
- for (var _c = 0, stateMachines_4 = stateMachines; _c < stateMachines_4.length; _c++) {
2719
- var stateMachine = stateMachines_4[_c];
2799
+ for (var _d = 0, stateMachines_4 = stateMachines; _d < stateMachines_4.length; _d++) {
2800
+ var stateMachine = stateMachines_4[_d];
2720
2801
  _loop_4(stateMachine);
2721
2802
  }
2803
+ // Release the primary touch lock once that finger lifts so the next
2804
+ // touchstart can claim a new primary finger.
2805
+ if (!enableMultiTouch &&
2806
+ coordinateSets.some(function (c) { return c.identifier === _primaryTouchId; })) {
2807
+ _primaryTouchId = null;
2808
+ }
2722
2809
  break;
2723
2810
  }
2724
2811
  case "mouseup": {
@@ -2727,8 +2814,8 @@ var registerTouchInteractions = function (_a) {
2727
2814
  stateMachine.pointerUp(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
2728
2815
  });
2729
2816
  };
2730
- for (var _d = 0, stateMachines_5 = stateMachines; _d < stateMachines_5.length; _d++) {
2731
- var stateMachine = stateMachines_5[_d];
2817
+ for (var _e = 0, stateMachines_5 = stateMachines; _e < stateMachines_5.length; _e++) {
2818
+ var stateMachine = stateMachines_5[_e];
2732
2819
  _loop_5(stateMachine);
2733
2820
  }
2734
2821
  break;
@@ -2736,6 +2823,9 @@ var registerTouchInteractions = function (_a) {
2736
2823
  default:
2737
2824
  }
2738
2825
  };
2826
+ var touchCancelCallback = function () {
2827
+ _primaryTouchId = null;
2828
+ };
2739
2829
  var callback = processEventCallback.bind(_this);
2740
2830
  canvas.addEventListener("mouseover", callback);
2741
2831
  canvas.addEventListener("mouseout", callback);
@@ -2749,6 +2839,7 @@ var registerTouchInteractions = function (_a) {
2749
2839
  passive: isTouchScrollEnabled,
2750
2840
  });
2751
2841
  canvas.addEventListener("touchend", callback);
2842
+ canvas.addEventListener("touchcancel", touchCancelCallback);
2752
2843
  return function () {
2753
2844
  canvas.removeEventListener("mouseover", callback);
2754
2845
  canvas.removeEventListener("mouseout", callback);
@@ -2758,6 +2849,7 @@ var registerTouchInteractions = function (_a) {
2758
2849
  canvas.removeEventListener("touchmove", callback);
2759
2850
  canvas.removeEventListener("touchstart", callback);
2760
2851
  canvas.removeEventListener("touchend", callback);
2852
+ canvas.removeEventListener("touchcancel", touchCancelCallback);
2761
2853
  };
2762
2854
  };
2763
2855