@rive-app/canvas 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",
3
- "version": "2.37.1",
3
+ "version": "2.37.3",
4
4
  "description": "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.
@@ -1012,7 +1067,7 @@ function Za(a, b) {
1012
1067
  return Ya(c, a, b);
1013
1068
  }));
1014
1069
  }
1015
- var $a, ab, eb = {479810:(a, b, c, d, e) => {
1070
+ var $a, ab, eb = {479986:(a, b, c, d, e) => {
1016
1071
  if ("undefined" === typeof window || void 0 === (window.AudioContext || window.webkitAudioContext)) {
1017
1072
  return 0;
1018
1073
  }
@@ -1075,11 +1130,11 @@ var $a, ab, eb = {479810:(a, b, c, d, e) => {
1075
1130
  }
1076
1131
  window.h.za += 1;
1077
1132
  return 1;
1078
- }, 481988:() => {
1133
+ }, 482164:() => {
1079
1134
  "undefined" !== typeof window.h && (window.h.Sa.map(function(a) {
1080
1135
  document.removeEventListener(a, window.h.unlock, !0);
1081
1136
  }), --window.h.za, 0 === window.h.za && delete window.h);
1082
- }, 482292:() => void 0 !== navigator.mediaDevices && void 0 !== navigator.mediaDevices.getUserMedia, 482396:() => {
1137
+ }, 482468:() => void 0 !== navigator.mediaDevices && void 0 !== navigator.mediaDevices.getUserMedia, 482572:() => {
1083
1138
  try {
1084
1139
  var a = new (window.AudioContext || window.webkitAudioContext)(), b = a.sampleRate;
1085
1140
  a.close();
@@ -1087,7 +1142,7 @@ var $a, ab, eb = {479810:(a, b, c, d, e) => {
1087
1142
  } catch (c) {
1088
1143
  return 0;
1089
1144
  }
1090
- }, 482567:(a, b, c, d, e, f) => {
1145
+ }, 482743:(a, b, c, d, e, f) => {
1091
1146
  if ("undefined" === typeof window.h) {
1092
1147
  return -1;
1093
1148
  }
@@ -1133,7 +1188,7 @@ var $a, ab, eb = {479810:(a, b, c, d, e) => {
1133
1188
  a == window.h.J.xa && g.Z.connect(g.L.destination);
1134
1189
  g.pb = f;
1135
1190
  return window.h.sc(g);
1136
- }, 485444:a => window.h.qa(a).L.sampleRate, 485517:a => {
1191
+ }, 485620:a => window.h.qa(a).L.sampleRate, 485693:a => {
1137
1192
  a = window.h.qa(a);
1138
1193
  void 0 !== a.Z && (a.Z.onaudioprocess = function() {
1139
1194
  }, a.Z.disconnect(), a.Z = void 0);
@@ -1141,13 +1196,13 @@ var $a, ab, eb = {479810:(a, b, c, d, e) => {
1141
1196
  a.L.close();
1142
1197
  a.L = void 0;
1143
1198
  a.pb = void 0;
1144
- }, 485917:a => {
1199
+ }, 486093:a => {
1145
1200
  window.h.Ab(a);
1146
- }, 485967:a => {
1201
+ }, 486143:a => {
1147
1202
  a = window.h.qa(a);
1148
1203
  a.L.resume();
1149
1204
  a.state = window.h.ga.wb;
1150
- }, 486106:a => {
1205
+ }, 486282:a => {
1151
1206
  a = window.h.qa(a);
1152
1207
  a.L.suspend();
1153
1208
  a.state = window.h.ga.stopped;
@@ -3659,7 +3714,7 @@ moduleRtn = ea;
3659
3714
  /* 5 */
3660
3715
  /***/ ((module) => {
3661
3716
 
3662
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@rive-app/canvas","version":"2.37.1","description":"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}}');
3717
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@rive-app/canvas","version":"2.37.3","description":"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}}');
3663
3718
 
3664
3719
  /***/ }),
3665
3720
  /* 6 */
@@ -3703,60 +3758,70 @@ __webpack_require__.r(__webpack_exports__);
3703
3758
  /* harmony export */ });
3704
3759
  var _this = undefined;
3705
3760
  /**
3706
- * Returns the clientX and clientY properties from touch or mouse events. Also
3707
- * calls preventDefault() on the event if it is a touchstart or touchmove to prevent
3708
- * scrolling the page on mobile devices
3709
- * @param event - Either a TouchEvent or a MouseEvent
3710
- * @returns - Coordinates of the clientX and clientY properties from the touch/mouse event
3761
+ * Extracts ClientCoordinates from a TouchList, respecting multi-touch vs.
3762
+ * single-touch mode. In single-touch mode, only the touch matching
3763
+ * primaryTouchId is returned (or the first touch when primaryTouchId is null).
3711
3764
  */
3712
- var getClientCoordinates = function (event, isTouchScrollEnabled, enableMultiTouch) {
3713
- var _a, _b;
3765
+ var getTouchCoordinates = function (changedTouches, enableMultiTouch, primaryTouchId) {
3766
+ var _a;
3714
3767
  var coordinates = [];
3715
- if (["touchstart", "touchmove"].indexOf(event.type) > -1 &&
3716
- ((_a = event.changedTouches) === null || _a === void 0 ? void 0 : _a.length)) {
3717
- // This flag, if false, prevents touch events on the canvas default behavior
3718
- // which may prevent scrolling if a drag motion on the canvas is performed
3719
- if (!isTouchScrollEnabled) {
3720
- event.preventDefault();
3721
- }
3722
- var cnt = 0;
3723
- var totalTouches = enableMultiTouch
3724
- ? event.changedTouches.length
3725
- : 1;
3726
- while (cnt < totalTouches) {
3727
- var touch = event.changedTouches[cnt];
3768
+ if (enableMultiTouch) {
3769
+ for (var i = 0; i < changedTouches.length; i++) {
3770
+ var touch = changedTouches[i];
3728
3771
  coordinates.push({
3729
3772
  clientX: touch.clientX,
3730
3773
  clientY: touch.clientY,
3731
3774
  identifier: touch.identifier,
3732
3775
  });
3733
- cnt++;
3734
3776
  }
3735
3777
  }
3736
- else if (event.type === "touchend" &&
3737
- ((_b = event.changedTouches) === null || _b === void 0 ? void 0 : _b.length)) {
3738
- var cnt = 0;
3739
- var totalTouches = enableMultiTouch
3740
- ? event.changedTouches.length
3741
- : 1;
3742
- while (cnt < totalTouches) {
3743
- var touch = event.changedTouches[cnt];
3778
+ else {
3779
+ // In "single-touch mode", only track the primary finger identified at touchstart.
3780
+ // Search changedTouches for the touch matching the recorded primary touch identifier, or (on initial touchstart)
3781
+ // take the first available touch identifier.
3782
+ var primaryTouch = primaryTouchId !== null
3783
+ ? (_a = Array.from(changedTouches).find(function (t) { return t.identifier === primaryTouchId; })) !== null && _a !== void 0 ? _a : null
3784
+ : changedTouches[0];
3785
+ if (primaryTouch) {
3744
3786
  coordinates.push({
3745
- clientX: touch.clientX,
3746
- clientY: touch.clientY,
3747
- identifier: touch.identifier,
3787
+ clientX: primaryTouch.clientX,
3788
+ clientY: primaryTouch.clientY,
3789
+ identifier: primaryTouch.identifier,
3748
3790
  });
3749
- cnt++;
3750
3791
  }
3751
3792
  }
3752
- else {
3753
- coordinates.push({
3793
+ return coordinates;
3794
+ };
3795
+ /**
3796
+ * Returns the clientX and clientY properties from touch or mouse events. Also
3797
+ * calls preventDefault() on the event if it is a touchstart or touchmove to prevent
3798
+ * scrolling the page on mobile devices
3799
+ * @param event - Either a TouchEvent or a MouseEvent
3800
+ * @param isTouchScrollEnabled - Whether touch scrolling is enabled
3801
+ * @param enableMultiTouch - Whether to process multiple simultaneous touches
3802
+ * @param primaryTouchId - When working with single touches, only process the touch
3803
+ * with this identifier. Pass null to accept any touch (used during touchstart to
3804
+ * capture the first finger down).
3805
+ * @returns - Coordinates of the clientX and clientY properties from the touch/mouse event
3806
+ */
3807
+ var getClientCoordinates = function (event, isTouchScrollEnabled, enableMultiTouch, primaryTouchId) {
3808
+ var _a;
3809
+ var touchEvent = event;
3810
+ if ((_a = touchEvent.changedTouches) === null || _a === void 0 ? void 0 : _a.length) {
3811
+ // This flag, if false, prevents touch events on the canvas default behavior
3812
+ // which may prevent scrolling if a drag motion on the canvas is performed
3813
+ if (!isTouchScrollEnabled && ["touchstart", "touchmove"].includes(event.type)) {
3814
+ event.preventDefault();
3815
+ }
3816
+ return getTouchCoordinates(touchEvent.changedTouches, enableMultiTouch, primaryTouchId);
3817
+ }
3818
+ return [
3819
+ {
3754
3820
  clientX: event.clientX,
3755
3821
  clientY: event.clientY,
3756
3822
  identifier: 0,
3757
- });
3758
- }
3759
- return coordinates;
3823
+ },
3824
+ ];
3760
3825
  };
3761
3826
  /**
3762
3827
  * Registers mouse move/up/down callback handlers on the canvas to send meaningful coordinates to
@@ -3788,7 +3853,15 @@ var registerTouchInteractions = function (_a) {
3788
3853
  **/
3789
3854
  var _prevEventType = null;
3790
3855
  var _syntheticEventsActive = false;
3856
+ /**
3857
+ * When enableMultiTouch is false ("single-touch mode"), we track the identifier of the first finger that touched down.
3858
+ * All subsequent touch events are filtered to this identifier so that a second finger
3859
+ * moving cannot displace the tracked pointer position.
3860
+ * Reset to null when the primary finger lifts (or touchcancel is called)
3861
+ */
3862
+ var _primaryTouchId = null;
3791
3863
  var processEventCallback = function (event) {
3864
+ var _a;
3792
3865
  // Exit early out of all synthetic mouse events
3793
3866
  // https://stackoverflow.com/questions/9656990/how-to-prevent-simulated-mouse-events-in-mobile-browsers
3794
3867
  // https://stackoverflow.com/questions/25572070/javascript-touchend-versus-click-dilemma
@@ -3807,7 +3880,15 @@ var registerTouchInteractions = function (_a) {
3807
3880
  _prevEventType === "touchstart";
3808
3881
  _prevEventType = event.type;
3809
3882
  var boundingRect = event.currentTarget.getBoundingClientRect();
3810
- var coordinateSets = getClientCoordinates(event, isTouchScrollEnabled, enableMultiTouch);
3883
+ // On touchstart in single-touch mode, record the first new finger as the primary
3884
+ // touch if we aren't already tracking one.
3885
+ if (!enableMultiTouch && event.type === "touchstart" && _primaryTouchId === null) {
3886
+ var firstTouch = (_a = event.changedTouches) === null || _a === void 0 ? void 0 : _a[0];
3887
+ if (firstTouch) {
3888
+ _primaryTouchId = firstTouch.identifier;
3889
+ }
3890
+ }
3891
+ var coordinateSets = getClientCoordinates(event, isTouchScrollEnabled, enableMultiTouch, enableMultiTouch ? null : _primaryTouchId);
3811
3892
  var forwardMatrix = rive.computeAlignment(fit, alignment, {
3812
3893
  minX: 0,
3813
3894
  minY: 0,
@@ -3872,8 +3953,8 @@ var registerTouchInteractions = function (_a) {
3872
3953
  stateMachine.pointerMove(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
3873
3954
  });
3874
3955
  };
3875
- for (var _a = 0, stateMachines_2 = stateMachines; _a < stateMachines_2.length; _a++) {
3876
- var stateMachine = stateMachines_2[_a];
3956
+ for (var _b = 0, stateMachines_2 = stateMachines; _b < stateMachines_2.length; _b++) {
3957
+ var stateMachine = stateMachines_2[_b];
3877
3958
  _loop_2(stateMachine);
3878
3959
  }
3879
3960
  break;
@@ -3886,8 +3967,8 @@ var registerTouchInteractions = function (_a) {
3886
3967
  stateMachine.pointerDown(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
3887
3968
  });
3888
3969
  };
3889
- for (var _b = 0, stateMachines_3 = stateMachines; _b < stateMachines_3.length; _b++) {
3890
- var stateMachine = stateMachines_3[_b];
3970
+ for (var _c = 0, stateMachines_3 = stateMachines; _c < stateMachines_3.length; _c++) {
3971
+ var stateMachine = stateMachines_3[_c];
3891
3972
  _loop_3(stateMachine);
3892
3973
  }
3893
3974
  break;
@@ -3900,10 +3981,16 @@ var registerTouchInteractions = function (_a) {
3900
3981
  stateMachine.pointerExit(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
3901
3982
  });
3902
3983
  };
3903
- for (var _c = 0, stateMachines_4 = stateMachines; _c < stateMachines_4.length; _c++) {
3904
- var stateMachine = stateMachines_4[_c];
3984
+ for (var _d = 0, stateMachines_4 = stateMachines; _d < stateMachines_4.length; _d++) {
3985
+ var stateMachine = stateMachines_4[_d];
3905
3986
  _loop_4(stateMachine);
3906
3987
  }
3988
+ // Release the primary touch lock once that finger lifts so the next
3989
+ // touchstart can claim a new primary finger.
3990
+ if (!enableMultiTouch &&
3991
+ coordinateSets.some(function (c) { return c.identifier === _primaryTouchId; })) {
3992
+ _primaryTouchId = null;
3993
+ }
3907
3994
  break;
3908
3995
  }
3909
3996
  case "mouseup": {
@@ -3912,8 +3999,8 @@ var registerTouchInteractions = function (_a) {
3912
3999
  stateMachine.pointerUp(coordinateSet.transformedX, coordinateSet.transformedY, coordinateSet.identifier);
3913
4000
  });
3914
4001
  };
3915
- for (var _d = 0, stateMachines_5 = stateMachines; _d < stateMachines_5.length; _d++) {
3916
- var stateMachine = stateMachines_5[_d];
4002
+ for (var _e = 0, stateMachines_5 = stateMachines; _e < stateMachines_5.length; _e++) {
4003
+ var stateMachine = stateMachines_5[_e];
3917
4004
  _loop_5(stateMachine);
3918
4005
  }
3919
4006
  break;
@@ -3921,6 +4008,9 @@ var registerTouchInteractions = function (_a) {
3921
4008
  default:
3922
4009
  }
3923
4010
  };
4011
+ var touchCancelCallback = function () {
4012
+ _primaryTouchId = null;
4013
+ };
3924
4014
  var callback = processEventCallback.bind(_this);
3925
4015
  canvas.addEventListener("mouseover", callback);
3926
4016
  canvas.addEventListener("mouseout", callback);
@@ -3934,6 +4024,7 @@ var registerTouchInteractions = function (_a) {
3934
4024
  passive: isTouchScrollEnabled,
3935
4025
  });
3936
4026
  canvas.addEventListener("touchend", callback);
4027
+ canvas.addEventListener("touchcancel", touchCancelCallback);
3937
4028
  return function () {
3938
4029
  canvas.removeEventListener("mouseover", callback);
3939
4030
  canvas.removeEventListener("mouseout", callback);
@@ -3943,6 +4034,7 @@ var registerTouchInteractions = function (_a) {
3943
4034
  canvas.removeEventListener("touchmove", callback);
3944
4035
  canvas.removeEventListener("touchstart", callback);
3945
4036
  canvas.removeEventListener("touchend", callback);
4037
+ canvas.removeEventListener("touchcancel", touchCancelCallback);
3946
4038
  };
3947
4039
  };
3948
4040