@visactor/vrender-core 1.1.12 → 1.1.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 (74) hide show
  1. package/cjs/canvas/conical-gradient.js +1 -1
  2. package/cjs/canvas/constants.js +1 -1
  3. package/cjs/canvas/empty-context.js +1 -1
  4. package/cjs/canvas/index.js +1 -1
  5. package/cjs/canvas/util.js +1 -1
  6. package/cjs/common/bezier-utils.js +1 -2
  7. package/cjs/common/contribution-store-state.js +2 -1
  8. package/cjs/common/path-svg.js +1 -2
  9. package/cjs/common/render-command-list.js +2 -1
  10. package/cjs/common/seg-context.js +1 -1
  11. package/cjs/common/simplify.js +1 -1
  12. package/cjs/common/sort.js +1 -1
  13. package/cjs/common/split-path.js +1 -1
  14. package/cjs/common/text.js +1 -1
  15. package/cjs/core/contributions/layerHandler/modules.js +4 -2
  16. package/cjs/core/contributions/layerHandler/modules.js.map +1 -1
  17. package/cjs/core/stage.d.ts +10 -3
  18. package/cjs/core/stage.js +39 -20
  19. package/cjs/core/stage.js.map +1 -1
  20. package/cjs/event/event-manager.d.ts +29 -1
  21. package/cjs/event/event-manager.js +161 -42
  22. package/cjs/event/event-manager.js.map +1 -1
  23. package/cjs/event/event-system.d.ts +19 -3
  24. package/cjs/event/event-system.js +110 -62
  25. package/cjs/event/event-system.js.map +1 -1
  26. package/cjs/event/federated-event/base-event.js +3 -1
  27. package/cjs/event/federated-event/base-event.js.map +1 -1
  28. package/cjs/event/input-source.d.ts +7 -0
  29. package/cjs/event/input-source.js +37 -0
  30. package/cjs/event/input-source.js.map +1 -0
  31. package/cjs/interface/event.d.ts +9 -0
  32. package/cjs/interface/event.js.map +1 -1
  33. package/cjs/interface/stage.d.ts +10 -2
  34. package/cjs/interface/stage.js.map +1 -1
  35. package/cjs/render/contributions/render/draw-interceptor.js +13 -3
  36. package/cjs/render/contributions/render/draw-interceptor.js.map +1 -1
  37. package/dist/index.es.js +622 -145
  38. package/es/canvas/conical-gradient.js +1 -1
  39. package/es/canvas/constants.js +1 -1
  40. package/es/canvas/empty-context.js +1 -1
  41. package/es/canvas/index.js +1 -1
  42. package/es/canvas/util.js +1 -1
  43. package/es/common/bezier-utils.js +1 -2
  44. package/es/common/contribution-store-state.js +2 -1
  45. package/es/common/path-svg.js +1 -2
  46. package/es/common/render-command-list.js +2 -1
  47. package/es/common/seg-context.js +1 -1
  48. package/es/common/simplify.js +1 -1
  49. package/es/common/sort.js +1 -1
  50. package/es/common/split-path.js +1 -1
  51. package/es/common/text.js +1 -1
  52. package/es/core/contributions/layerHandler/modules.js +6 -2
  53. package/es/core/contributions/layerHandler/modules.js.map +1 -1
  54. package/es/core/stage.d.ts +10 -3
  55. package/es/core/stage.js +40 -21
  56. package/es/core/stage.js.map +1 -1
  57. package/es/event/event-manager.d.ts +29 -1
  58. package/es/event/event-manager.js +162 -41
  59. package/es/event/event-manager.js.map +1 -1
  60. package/es/event/event-system.d.ts +19 -3
  61. package/es/event/event-system.js +110 -62
  62. package/es/event/event-system.js.map +1 -1
  63. package/es/event/federated-event/base-event.js +2 -1
  64. package/es/event/federated-event/base-event.js.map +1 -1
  65. package/es/event/input-source.d.ts +7 -0
  66. package/es/event/input-source.js +29 -0
  67. package/es/event/input-source.js.map +1 -0
  68. package/es/interface/event.d.ts +9 -0
  69. package/es/interface/event.js.map +1 -1
  70. package/es/interface/stage.d.ts +10 -2
  71. package/es/interface/stage.js.map +1 -1
  72. package/es/render/contributions/render/draw-interceptor.js +12 -3
  73. package/es/render/contributions/render/draw-interceptor.js.map +1 -1
  74. package/package.json +1 -1
package/dist/index.es.js CHANGED
@@ -1336,13 +1336,14 @@ class FederatedEvent {
1336
1336
  }
1337
1337
  }
1338
1338
  preventDefault() {
1339
+ var _a;
1339
1340
  try {
1340
1341
  if (this.nativeEvent instanceof Event && this.nativeEvent.cancelable) {
1341
1342
  this.nativeEvent.preventDefault();
1342
1343
  }
1343
1344
  }
1344
1345
  catch (err) {
1345
- this.nativeEvent.preventDefault &&
1346
+ ((_a = this.nativeEvent) === null || _a === void 0 ? void 0 : _a.preventDefault) &&
1346
1347
  isFunction(this.nativeEvent.preventDefault) &&
1347
1348
  this.nativeEvent.preventDefault();
1348
1349
  }
@@ -1515,6 +1516,43 @@ class CustomEvent extends FederatedEvent {
1515
1516
  }
1516
1517
  }
1517
1518
 
1519
+ class InputSource {
1520
+ constructor() {
1521
+ this.listeners = {};
1522
+ this.source = {
1523
+ on: (type, listener) => {
1524
+ var _a;
1525
+ this.listeners[type] = ((_a = this.listeners[type]) !== null && _a !== void 0 ? _a : []).concat(listener);
1526
+ },
1527
+ off: (type, listener) => {
1528
+ const list = this.listeners[type];
1529
+ if (list) {
1530
+ this.listeners[type] = list.filter(fn => fn !== listener);
1531
+ }
1532
+ }
1533
+ };
1534
+ }
1535
+ emit(type, event, valid) {
1536
+ const list = this.listeners[type];
1537
+ if (!list) {
1538
+ return;
1539
+ }
1540
+ const originalType = event.type;
1541
+ event.type = type;
1542
+ try {
1543
+ for (let i = 0; i < list.length && valid(); i++) {
1544
+ list[i](event);
1545
+ }
1546
+ }
1547
+ finally {
1548
+ event.type = originalType;
1549
+ }
1550
+ }
1551
+ clear() {
1552
+ this.listeners = {};
1553
+ }
1554
+ }
1555
+
1518
1556
  const WILDCARD = '*';
1519
1557
 
1520
1558
  const clock = typeof performance === 'object' && performance.now ? performance : Date;
@@ -1524,6 +1562,16 @@ function isMouseLike(pointerType) {
1524
1562
  return pointerType === 'mouse' || pointerType === 'pen';
1525
1563
  }
1526
1564
  const DEFAULT_CLICK_INTERVAL = 200;
1565
+ const TOUCH_INPUT_TYPES = {
1566
+ pointerdown: 'touchstart',
1567
+ pointermove: 'touchmove',
1568
+ pointerup: 'touchend'
1569
+ };
1570
+ const MOUSE_INPUT_TYPES = {
1571
+ pointerdown: 'mousedown',
1572
+ pointermove: 'mousemove',
1573
+ pointerup: 'mouseup'
1574
+ };
1527
1575
  class EventManager {
1528
1576
  constructor(root, config) {
1529
1577
  this.dispatch = new EventEmitter();
@@ -1533,12 +1581,26 @@ class EventManager {
1533
1581
  trackingData: {}
1534
1582
  };
1535
1583
  this.eventPool = new Map();
1584
+ this.canvasInput = new InputSource();
1585
+ this.windowInput = new InputSource();
1586
+ this.input = { canvas: this.canvasInput.source, window: this.windowInput.source };
1587
+ this.currentGeneration = 0;
1588
+ this.terminalDepth = 0;
1589
+ this.inputValid = () => !!this.rootTarget &&
1590
+ (this.terminalDepth > 0 || !this.currentTracking || this.currentTracking.generation === this.currentGeneration);
1591
+ this.onPointerCancel = (from) => {
1592
+ if (from instanceof FederatedPointerEvent) {
1593
+ this.cancelPointer(from.pointerId);
1594
+ }
1595
+ };
1536
1596
  this.onPointerDown = (from, target) => {
1537
1597
  if (!(from instanceof FederatedPointerEvent)) {
1538
1598
  Logger.getInstance().warn('EventManager cannot map a non-pointer event as a pointer event');
1539
1599
  return;
1540
1600
  }
1541
1601
  const e = this.createPointerEvent(from, from.type, target);
1602
+ const trackingData = this.trackingData(from.pointerId);
1603
+ trackingData.pressTargetsByButton[from.button] = e.composedPath();
1542
1604
  this.dispatchEvent(e, 'pointerdown');
1543
1605
  if (e.pointerType === 'touch') {
1544
1606
  this.dispatchEvent(e, 'touchstart');
@@ -1547,8 +1609,6 @@ class EventManager {
1547
1609
  const isRightButton = e.button === 2;
1548
1610
  this.dispatchEvent(e, isRightButton ? 'rightdown' : 'mousedown');
1549
1611
  }
1550
- const trackingData = this.trackingData(from.pointerId);
1551
- trackingData.pressTargetsByButton[from.button] = e.composedPath();
1552
1612
  this.freeEvent(e);
1553
1613
  };
1554
1614
  this.onPointerMove = (from, target) => {
@@ -1591,13 +1651,13 @@ class EventManager {
1591
1651
  this.dispatchEvent(overEvent, 'mouseover');
1592
1652
  }
1593
1653
  let overTargetAncestor = outTarget === null || outTarget === void 0 ? void 0 : outTarget.parent;
1594
- while (overTargetAncestor && overTargetAncestor !== this.rootTarget.parent) {
1654
+ while (this.inputValid() && overTargetAncestor && overTargetAncestor !== this.rootTarget.parent) {
1595
1655
  if (overTargetAncestor === e.target) {
1596
1656
  break;
1597
1657
  }
1598
1658
  overTargetAncestor = overTargetAncestor.parent;
1599
1659
  }
1600
- const didPointerEnter = !overTargetAncestor || overTargetAncestor === this.rootTarget.parent;
1660
+ const didPointerEnter = this.inputValid() && (!overTargetAncestor || overTargetAncestor === this.rootTarget.parent);
1601
1661
  if (didPointerEnter) {
1602
1662
  const enterEvent = this.clonePointerEvent(e, 'pointerenter');
1603
1663
  enterEvent.eventPhase = enterEvent.AT_TARGET;
@@ -1608,7 +1668,10 @@ class EventManager {
1608
1668
  outTargetAncestors.add(ancestor);
1609
1669
  ancestor = ancestor.parent;
1610
1670
  }
1611
- while (currentTarget && currentTarget !== outTarget && currentTarget !== this.rootTarget.parent) {
1671
+ while (this.inputValid() &&
1672
+ currentTarget &&
1673
+ currentTarget !== outTarget &&
1674
+ currentTarget !== this.rootTarget.parent) {
1612
1675
  if (!outTargetAncestors.has(currentTarget)) {
1613
1676
  enterEvent.currentTarget = currentTarget;
1614
1677
  this.notifyTarget(enterEvent);
@@ -1627,12 +1690,14 @@ class EventManager {
1627
1690
  if (e.pointerType === 'touch') {
1628
1691
  this[propagationMethod](e, 'touchmove');
1629
1692
  }
1630
- if (isMouse) {
1693
+ if (isMouse && this.inputValid()) {
1631
1694
  this[propagationMethod](e, 'mousemove');
1632
1695
  this.cursorTarget = e.target;
1633
1696
  this.cursor = ((_b = (_a = e.target) === null || _a === void 0 ? void 0 : _a.attribute) === null || _b === void 0 ? void 0 : _b.cursor) || this.rootTarget.getCursor();
1634
1697
  }
1635
- trackingData.overTargets = e.composedPath();
1698
+ if (this.inputValid()) {
1699
+ trackingData.overTargets = e.composedPath();
1700
+ }
1636
1701
  this.freeEvent(e);
1637
1702
  };
1638
1703
  this.onPointerOver = (from, target) => {
@@ -1648,13 +1713,13 @@ class EventManager {
1648
1713
  if (isMouse) {
1649
1714
  this.dispatchEvent(e, 'mouseover');
1650
1715
  }
1651
- if (e.pointerType === 'mouse') {
1716
+ if (e.pointerType === 'mouse' && this.inputValid()) {
1652
1717
  this.cursorTarget = e.target;
1653
1718
  this.cursor = ((_b = (_a = e.target) === null || _a === void 0 ? void 0 : _a.attribute) === null || _b === void 0 ? void 0 : _b.cursor) || this.rootTarget.getCursor();
1654
1719
  }
1655
1720
  const enterEvent = this.clonePointerEvent(e, 'pointerenter');
1656
1721
  enterEvent.eventPhase = enterEvent.AT_TARGET;
1657
- while (enterEvent.target && enterEvent.target !== this.rootTarget.parent) {
1722
+ while (this.inputValid() && enterEvent.target && enterEvent.target !== this.rootTarget.parent) {
1658
1723
  enterEvent.currentTarget = enterEvent.target;
1659
1724
  this.notifyTarget(enterEvent);
1660
1725
  if (isMouse) {
@@ -1662,7 +1727,9 @@ class EventManager {
1662
1727
  }
1663
1728
  enterEvent.target = enterEvent.target.parent;
1664
1729
  }
1665
- trackingData.overTargets = e.composedPath();
1730
+ if (this.inputValid()) {
1731
+ trackingData.overTargets = e.composedPath();
1732
+ }
1666
1733
  this.freeEvent(e);
1667
1734
  this.freeEvent(enterEvent);
1668
1735
  };
@@ -1682,7 +1749,7 @@ class EventManager {
1682
1749
  }
1683
1750
  const leaveEvent = this.createPointerEvent(from, 'pointerleave', outTarget || undefined);
1684
1751
  leaveEvent.eventPhase = leaveEvent.AT_TARGET;
1685
- while (leaveEvent.target && leaveEvent.target !== this.rootTarget.parent) {
1752
+ while (this.inputValid() && leaveEvent.target && leaveEvent.target !== this.rootTarget.parent) {
1686
1753
  leaveEvent.currentTarget = leaveEvent.target;
1687
1754
  this.notifyTarget(leaveEvent);
1688
1755
  if (isMouse) {
@@ -1705,6 +1772,9 @@ class EventManager {
1705
1772
  }
1706
1773
  const now = clock.now();
1707
1774
  const e = this.createPointerEvent(from, from.type, target);
1775
+ const trackingData = this.trackingData(from.pointerId);
1776
+ trackingData.ending = trackingData.pressTargetsByButton[from.button];
1777
+ delete trackingData.pressTargetsByButton[from.button];
1708
1778
  this.dispatchEvent(e, 'pointerup');
1709
1779
  if (e.pointerType === 'touch') {
1710
1780
  this.dispatchEvent(e, 'touchend');
@@ -1713,8 +1783,7 @@ class EventManager {
1713
1783
  const isRightButton = e.button === 2;
1714
1784
  this.dispatchEvent(e, isRightButton ? 'rightup' : 'mouseup');
1715
1785
  }
1716
- const trackingData = this.trackingData(from.pointerId);
1717
- const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);
1786
+ const pressTarget = this.findMountedTarget(trackingData.ending);
1718
1787
  let clickTarget = pressTarget;
1719
1788
  if (pressTarget && !e.composedPath().includes(pressTarget)) {
1720
1789
  let currentTarget = pressTarget;
@@ -1733,7 +1802,8 @@ class EventManager {
1733
1802
  delete trackingData.pressTargetsByButton[from.button];
1734
1803
  clickTarget = currentTarget;
1735
1804
  }
1736
- if (clickTarget) {
1805
+ this.emitPointerInput(e, 'pointerup');
1806
+ if (clickTarget && this.inputValid()) {
1737
1807
  const clickEvent = this.clonePointerEvent(e, 'click');
1738
1808
  clickEvent.target = clickTarget;
1739
1809
  clickEvent.path = [];
@@ -1758,17 +1828,22 @@ class EventManager {
1758
1828
  clickEvent.detail = clickHistory.clickCount;
1759
1829
  if (isMouseLike(clickEvent.pointerType)) {
1760
1830
  this.dispatchEvent(clickEvent, 'click');
1831
+ this.emitInput(clickEvent, 'click');
1761
1832
  if (clickHistory.clickCount === 2) {
1762
1833
  this.dispatchEvent(clickEvent, 'dblclick');
1834
+ this.emitInput(clickEvent, 'dblclick');
1763
1835
  }
1764
1836
  }
1765
1837
  else if (clickEvent.pointerType === 'touch' && this._config.supportsTouchEvents) {
1766
1838
  this.dispatchEvent(clickEvent, 'tap');
1839
+ this.emitInput(clickEvent, 'tap');
1767
1840
  if (clickHistory.clickCount === 2) {
1768
1841
  this.dispatchEvent(clickEvent, 'dbltap');
1842
+ this.emitInput(clickEvent, 'dbltap');
1769
1843
  }
1770
1844
  }
1771
1845
  this.dispatchEvent(clickEvent, 'pointertap');
1846
+ this.emitInput(clickEvent, 'pointertap');
1772
1847
  this.freeEvent(clickEvent);
1773
1848
  }
1774
1849
  this.freeEvent(e);
@@ -1779,7 +1854,9 @@ class EventManager {
1779
1854
  return;
1780
1855
  }
1781
1856
  const trackingData = this.trackingData(from.pointerId);
1782
- const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);
1857
+ trackingData.ending = trackingData.pressTargetsByButton[from.button];
1858
+ delete trackingData.pressTargetsByButton[from.button];
1859
+ const pressTarget = this.findMountedTarget(trackingData.ending);
1783
1860
  const e = this.createPointerEvent(from, from.type, target);
1784
1861
  if (pressTarget) {
1785
1862
  let currentTarget = pressTarget;
@@ -1796,6 +1873,7 @@ class EventManager {
1796
1873
  }
1797
1874
  delete trackingData.pressTargetsByButton[from.button];
1798
1875
  }
1876
+ this.emitPointerInput(e, 'pointerup');
1799
1877
  this.freeEvent(e);
1800
1878
  };
1801
1879
  this.onWheel = (from, target) => {
@@ -1817,8 +1895,159 @@ class EventManager {
1817
1895
  this.addEventMapping('pointerover', this.onPointerOver);
1818
1896
  this.addEventMapping('pointerup', this.onPointerUp);
1819
1897
  this.addEventMapping('pointerupoutside', this.onPointerUpOutside);
1898
+ this.addEventMapping('pointercancel', this.onPointerCancel);
1820
1899
  this.addEventMapping('wheel', this.onWheel);
1821
1900
  }
1901
+ hasPointer(id) {
1902
+ const data = this.mappingState.trackingData[id];
1903
+ if (!data) {
1904
+ return false;
1905
+ }
1906
+ if (data.inside || data.ending) {
1907
+ return true;
1908
+ }
1909
+ for (const button in data.pressTargetsByButton) {
1910
+ if (data.pressTargetsByButton[button]) {
1911
+ return true;
1912
+ }
1913
+ }
1914
+ return false;
1915
+ }
1916
+ cancelAllPointers() {
1917
+ for (const id in this.mappingState.trackingData) {
1918
+ this.cancelPointer(Number(id));
1919
+ }
1920
+ }
1921
+ cancelPointer(id) {
1922
+ var _a;
1923
+ if (!this.rootTarget || !this.hasPointer(id)) {
1924
+ return;
1925
+ }
1926
+ const data = this.trackingData(id);
1927
+ let press = data.ending;
1928
+ for (const button in data.pressTargetsByButton) {
1929
+ press = data.pressTargetsByButton[button];
1930
+ break;
1931
+ }
1932
+ const over = data.overTargets;
1933
+ const inside = data.inside;
1934
+ data.generation++;
1935
+ data.pressTargetsByButton = {};
1936
+ data.clicksByButton = {};
1937
+ data.ending = undefined;
1938
+ data.inside = false;
1939
+ data.overTargets = [];
1940
+ if (this.dispatchingEvent instanceof FederatedPointerEvent && this.dispatchingEvent.pointerId === id) {
1941
+ this.dispatchingEvent.stopImmediatePropagation();
1942
+ }
1943
+ const event = this.allocateEvent(FederatedPointerEvent);
1944
+ event.type = 'pointercancel';
1945
+ event.pointerId = id;
1946
+ event.pointerType = data.pointerType;
1947
+ event.button = data.button;
1948
+ event.nativeEvent = null;
1949
+ event.canvas.x = data.canvasX;
1950
+ event.canvas.y = data.canvasY;
1951
+ event.viewport.x = data.viewX;
1952
+ event.viewport.y = data.viewY;
1953
+ event.target = (_a = this.findMountedTarget(press)) !== null && _a !== void 0 ? _a : this.findMountedTarget(over);
1954
+ this.terminalDepth++;
1955
+ try {
1956
+ this.dispatchEvent(event);
1957
+ if (event.pointerType === 'touch') {
1958
+ this.dispatchEvent(event, 'touchcancel');
1959
+ }
1960
+ this.windowInput.emit('pointercancel', event, this.inputValid);
1961
+ if (event.pointerType === 'touch') {
1962
+ this.windowInput.emit('touchcancel', event, this.inputValid);
1963
+ }
1964
+ if (inside) {
1965
+ this.canvasInput.emit('pointercancel', event, this.inputValid);
1966
+ if (event.pointerType === 'touch') {
1967
+ this.canvasInput.emit('touchcancel', event, this.inputValid);
1968
+ }
1969
+ this.emitBoundary(event, false);
1970
+ }
1971
+ if ((over === null || over === void 0 ? void 0 : over.length) && this.rootTarget) {
1972
+ event.target = this.findMountedTarget(over);
1973
+ event.path = [];
1974
+ this.dispatchEvent(event, 'pointerout');
1975
+ if (isMouseLike(event.pointerType)) {
1976
+ this.dispatchEvent(event, 'mouseout');
1977
+ }
1978
+ event.eventPhase = event.AT_TARGET;
1979
+ while (event.target && this.rootTarget) {
1980
+ event.currentTarget = event.target;
1981
+ this.notifyTarget(event, 'pointerleave');
1982
+ if (isMouseLike(event.pointerType)) {
1983
+ this.notifyTarget(event, 'mouseleave');
1984
+ }
1985
+ event.target = event.target.parent;
1986
+ }
1987
+ }
1988
+ }
1989
+ finally {
1990
+ this.terminalDepth--;
1991
+ this.freeEvent(event);
1992
+ this.cursorTarget = null;
1993
+ this.cursor = '';
1994
+ }
1995
+ }
1996
+ emitBoundary(event, inside) {
1997
+ this.canvasInput.emit(inside ? 'pointerover' : 'pointerout', event, this.inputValid);
1998
+ this.canvasInput.emit(inside ? 'pointerenter' : 'pointerleave', event, this.inputValid);
1999
+ if (isMouseLike(event.pointerType)) {
2000
+ this.canvasInput.emit(inside ? 'mouseover' : 'mouseout', event, this.inputValid);
2001
+ this.canvasInput.emit(inside ? 'mouseenter' : 'mouseleave', event, this.inputValid);
2002
+ }
2003
+ }
2004
+ emitInput(event, type = event.type) {
2005
+ if (!this.inputValid()) {
2006
+ return;
2007
+ }
2008
+ this.windowInput.emit(type, event, this.inputValid);
2009
+ if (!this.inputValid()) {
2010
+ return;
2011
+ }
2012
+ const data = event instanceof FederatedPointerEvent ? this.trackingData(event.pointerId) : undefined;
2013
+ if (data && data.previousInside !== data.inside) {
2014
+ data.previousInside = data.inside;
2015
+ this.emitBoundary(event, data.inside);
2016
+ }
2017
+ if (!data || data.inside) {
2018
+ this.canvasInput.emit(type, event, this.inputValid);
2019
+ }
2020
+ }
2021
+ emitPointerInput(event, type = event.type) {
2022
+ if (!this.inputValid()) {
2023
+ return;
2024
+ }
2025
+ if (type === 'pointerover' || type === 'pointerout' || type === 'pointerleave') {
2026
+ const data = this.trackingData(event.pointerId);
2027
+ if (data.previousInside !== data.inside) {
2028
+ data.previousInside = data.inside;
2029
+ this.emitBoundary(event, data.inside);
2030
+ }
2031
+ return;
2032
+ }
2033
+ this.emitInput(event, type);
2034
+ if (event.pointerType === 'touch') {
2035
+ const alias = TOUCH_INPUT_TYPES[type];
2036
+ if (alias) {
2037
+ this.emitInput(event, alias);
2038
+ }
2039
+ }
2040
+ else if (isMouseLike(event.pointerType)) {
2041
+ const alias = event.button === 2 && type === 'pointerdown'
2042
+ ? 'rightdown'
2043
+ : event.button === 2 && type === 'pointerup'
2044
+ ? 'rightup'
2045
+ : MOUSE_INPUT_TYPES[type];
2046
+ if (alias) {
2047
+ this.emitInput(event, alias);
2048
+ }
2049
+ }
2050
+ }
1822
2051
  addEventMapping(type, fn) {
1823
2052
  if (!this.mappingTable[type]) {
1824
2053
  this.mappingTable[type] = [];
@@ -1830,41 +2059,90 @@ class EventManager {
1830
2059
  this.mappingTable[type].sort((a, b) => a.priority - b.priority);
1831
2060
  }
1832
2061
  dispatchEvent(e, type) {
2062
+ if (!this.inputValid()) {
2063
+ return;
2064
+ }
2065
+ const previous = this.dispatchingEvent;
2066
+ this.dispatchingEvent = e;
1833
2067
  e.propagationStopped = false;
1834
2068
  e.propagationImmediatelyStopped = false;
1835
- this.propagate(e, type);
1836
- this.dispatch.emit(type || e.type, e);
2069
+ try {
2070
+ this.propagate(e, type);
2071
+ if (this.inputValid()) {
2072
+ this.dispatch.emit(type || e.type, e);
2073
+ }
2074
+ }
2075
+ finally {
2076
+ this.dispatchingEvent = previous;
2077
+ }
1837
2078
  }
1838
- mapEvent(e) {
1839
- var _a, _b, _c, _d, _e, _f, _g;
2079
+ mapEvent(e, inViewport = true) {
2080
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1840
2081
  if (!this.rootTarget) {
1841
2082
  return;
1842
2083
  }
1843
- const mappers = this.mappingTable[e.type];
1844
- let target;
1845
- const cacheKey = `${e.canvasX}-${e.canvasY}`;
1846
- if (((_a = this._prePointTargetCache) === null || _a === void 0 ? void 0 : _a[cacheKey]) &&
1847
- ((_c = (_b = this._prePointTargetCache) === null || _b === void 0 ? void 0 : _b[cacheKey]) === null || _c === void 0 ? void 0 : _c.stage) &&
1848
- ((_e = (_d = this._prePointTargetCache) === null || _d === void 0 ? void 0 : _d[cacheKey]) === null || _e === void 0 ? void 0 : _e.stage.renderCount) ===
1849
- ((_f = this._prePointTargetCache) === null || _f === void 0 ? void 0 : _f.stageRenderCount)) {
1850
- target = this._prePointTargetCache[cacheKey];
1851
- }
1852
- else {
1853
- target = this.pickTarget(e.viewX, e.viewY, e);
1854
- if (!e.pickParams) {
1855
- this._prePointTargetCache = {
1856
- [cacheKey]: target,
1857
- stageRenderCount: (_g = target === null || target === void 0 ? void 0 : target.stage.renderCount) !== null && _g !== void 0 ? _g : -1
1858
- };
2084
+ const previous = this.currentTracking;
2085
+ const generation = this.currentGeneration;
2086
+ const tracking = e instanceof FederatedPointerEvent ? this.trackingData(e.pointerId) : undefined;
2087
+ this.currentTracking = tracking;
2088
+ this.currentGeneration = (_a = tracking === null || tracking === void 0 ? void 0 : tracking.generation) !== null && _a !== void 0 ? _a : 0;
2089
+ if (tracking) {
2090
+ tracking.previousInside = tracking.inside;
2091
+ tracking.inside = inViewport;
2092
+ tracking.pointerType = e.pointerType;
2093
+ tracking.button = e.button;
2094
+ tracking.canvasX = e.canvasX;
2095
+ tracking.canvasY = e.canvasY;
2096
+ tracking.viewX = e.viewX;
2097
+ tracking.viewY = e.viewY;
2098
+ }
2099
+ const type = e.type === 'pointerup' && !inViewport ? 'pointerupoutside' : e.type;
2100
+ const mappers = this.mappingTable[type];
2101
+ try {
2102
+ let target;
2103
+ const cacheKey = `${e.canvasX}-${e.canvasY}`;
2104
+ if (!inViewport) {
2105
+ target = null;
1859
2106
  }
1860
- }
1861
- if (mappers) {
1862
- for (let i = 0, j = mappers.length; i < j; i++) {
1863
- mappers[i].fn(e, target);
2107
+ else if (((_b = this._prePointTargetCache) === null || _b === void 0 ? void 0 : _b[cacheKey]) &&
2108
+ ((_d = (_c = this._prePointTargetCache) === null || _c === void 0 ? void 0 : _c[cacheKey]) === null || _d === void 0 ? void 0 : _d.stage) &&
2109
+ ((_f = (_e = this._prePointTargetCache) === null || _e === void 0 ? void 0 : _e[cacheKey]) === null || _f === void 0 ? void 0 : _f.stage.renderCount) ===
2110
+ ((_g = this._prePointTargetCache) === null || _g === void 0 ? void 0 : _g.stageRenderCount)) {
2111
+ target = this._prePointTargetCache[cacheKey];
2112
+ }
2113
+ else {
2114
+ target = this.pickTarget(e.viewX, e.viewY, e);
2115
+ if (!e.pickParams) {
2116
+ this._prePointTargetCache = {
2117
+ [cacheKey]: target,
2118
+ stageRenderCount: (_h = target === null || target === void 0 ? void 0 : target.stage.renderCount) !== null && _h !== void 0 ? _h : -1
2119
+ };
2120
+ }
2121
+ }
2122
+ if (mappers) {
2123
+ for (let i = 0, j = mappers.length; i < j && this.inputValid(); i++) {
2124
+ mappers[i].fn(e, target);
2125
+ }
2126
+ }
2127
+ else {
2128
+ Logger.getInstance().warn(`[EventManager]: Event mapping not defined for ${e.type}`);
2129
+ }
2130
+ if (e instanceof FederatedPointerEvent &&
2131
+ type !== 'pointerup' &&
2132
+ type !== 'pointerupoutside' &&
2133
+ type !== 'pointercancel') {
2134
+ this.emitPointerInput(e);
2135
+ }
2136
+ else if (e instanceof FederatedWheelEvent) {
2137
+ this.emitInput(e);
1864
2138
  }
1865
2139
  }
1866
- else {
1867
- Logger.getInstance().warn(`[EventManager]: Event mapping not defined for ${e.type}`);
2140
+ finally {
2141
+ if (tracking) {
2142
+ tracking.ending = undefined;
2143
+ }
2144
+ this.currentTracking = previous;
2145
+ this.currentGeneration = generation;
1868
2146
  }
1869
2147
  }
1870
2148
  propagate(e, type) {
@@ -1908,13 +2186,17 @@ class EventManager {
1908
2186
  return propagationPath;
1909
2187
  }
1910
2188
  notifyTarget(e, type) {
2189
+ if (!this.inputValid()) {
2190
+ e.stopImmediatePropagation();
2191
+ return;
2192
+ }
1911
2193
  if (this.pauseNotify) {
1912
2194
  return;
1913
2195
  }
1914
2196
  type = type !== null && type !== void 0 ? type : e.type;
1915
2197
  const key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET ? `${type}capture` : type;
1916
2198
  this.notifyListeners(e, key);
1917
- if (e.eventPhase === e.AT_TARGET) {
2199
+ if (e.eventPhase === e.AT_TARGET && this.inputValid() && !e.propagationImmediatelyStopped) {
1918
2200
  this.notifyListeners(e, type);
1919
2201
  }
1920
2202
  }
@@ -1941,7 +2223,7 @@ class EventManager {
1941
2223
  this.copyData(from, event);
1942
2224
  event.nativeEvent = from.nativeEvent;
1943
2225
  event.originalEvent = from;
1944
- if (target) {
2226
+ if (target !== undefined) {
1945
2227
  event.target = target;
1946
2228
  }
1947
2229
  else {
@@ -2030,6 +2312,9 @@ class EventManager {
2030
2312
  trackingData(id) {
2031
2313
  if (!this.mappingState.trackingData[id]) {
2032
2314
  this.mappingState.trackingData[id] = {
2315
+ generation: 0,
2316
+ inside: false,
2317
+ previousInside: false,
2033
2318
  pressTargetsByButton: {},
2034
2319
  clicksByButton: {},
2035
2320
  overTarget: null
@@ -2052,6 +2337,11 @@ class EventManager {
2052
2337
  }
2053
2338
  freeEvent(event) {
2054
2339
  var _a;
2340
+ event.nativeEvent = null;
2341
+ event.originalEvent = null;
2342
+ if (!this.rootTarget) {
2343
+ return;
2344
+ }
2055
2345
  if (event.manager !== this) {
2056
2346
  throw new Error('It is illegal to free an event not managed by this EventManager!');
2057
2347
  }
@@ -2069,6 +2359,9 @@ class EventManager {
2069
2359
  (_a = this.eventPool.get(constructor)) === null || _a === void 0 ? void 0 : _a.push(event);
2070
2360
  }
2071
2361
  notifyListeners(e, type) {
2362
+ if (!this.inputValid() || !e.currentTarget) {
2363
+ return;
2364
+ }
2072
2365
  const events = e.currentTarget._events;
2073
2366
  const listeners = events[type];
2074
2367
  if (listeners) {
@@ -2079,7 +2372,7 @@ class EventManager {
2079
2372
  listeners.fn.call(listeners.context, e);
2080
2373
  }
2081
2374
  else {
2082
- for (let i = 0, j = listeners.length; i < j && !e.propagationImmediatelyStopped; i++) {
2375
+ for (let i = 0, j = listeners.length; i < j && this.inputValid() && !e.propagationImmediatelyStopped; i++) {
2083
2376
  if (listeners[i].once) {
2084
2377
  e.currentTarget.removeEventListener(type, listeners[i].fn, { once: true });
2085
2378
  }
@@ -2087,9 +2380,14 @@ class EventManager {
2087
2380
  }
2088
2381
  }
2089
2382
  }
2090
- this.emitDelegation(e, type);
2383
+ if (this.inputValid()) {
2384
+ this.emitDelegation(e, type);
2385
+ }
2091
2386
  }
2092
2387
  emitDelegation(e, type) {
2388
+ if (!this.inputValid() || !e.currentTarget) {
2389
+ return;
2390
+ }
2093
2391
  const events = e.currentTarget._events;
2094
2392
  const listeners = events[WILDCARD];
2095
2393
  if (listeners) {
@@ -2097,7 +2395,7 @@ class EventManager {
2097
2395
  listeners.fn.call(listeners.context, e, type);
2098
2396
  }
2099
2397
  else {
2100
- for (let i = 0, j = listeners.length; i < j && !e.propagationImmediatelyStopped; i++) {
2398
+ for (let i = 0, j = listeners.length; i < j && this.inputValid() && !e.propagationImmediatelyStopped; i++) {
2101
2399
  listeners[i].fn.call(listeners[i].context, e, type);
2102
2400
  }
2103
2401
  }
@@ -2124,11 +2422,15 @@ class EventManager {
2124
2422
  return target;
2125
2423
  }
2126
2424
  release() {
2425
+ var _a;
2127
2426
  this.dispatch.removeAllListeners();
2128
2427
  this.eventPool.clear();
2129
2428
  this.rootTarget = null;
2130
2429
  this.mappingTable = null;
2131
- this.mappingState = null;
2430
+ this.mappingState = { trackingData: {} };
2431
+ this.canvasInput.clear();
2432
+ this.windowInput.clear();
2433
+ (_a = this.dispatchingEvent) === null || _a === void 0 ? void 0 : _a.stopImmediatePropagation();
2132
2434
  this.cursorTarget = null;
2133
2435
  }
2134
2436
  }
@@ -2162,70 +2464,15 @@ const TOUCH_TO_POINTER = {
2162
2464
  class EventSystem {
2163
2465
  constructor(params) {
2164
2466
  this.resolution = 1;
2165
- this.onPointerDown = (nativeEvent) => {
2166
- if (this.supportsTouchEvents && nativeEvent.pointerType === 'touch') {
2167
- return;
2168
- }
2169
- const events = this.normalizeToPointerData(nativeEvent);
2170
- if (this.autoPreventDefault && events[0].isNormalized) {
2171
- const cancelable = nativeEvent.cancelable || !('cancelable' in nativeEvent);
2172
- if (cancelable) {
2173
- nativeEvent.preventDefault();
2174
- }
2175
- }
2176
- for (let i = 0, j = events.length; i < j; i++) {
2177
- const nativeEvent = events[i];
2178
- const federatedEvent = this.bootstrapEvent(this.rootPointerEvent, nativeEvent);
2179
- this.manager.mapEvent(federatedEvent);
2180
- }
2181
- this.setCursor(this.manager.cursor, this.manager.cursorTarget);
2182
- this.rootPointerEvent.nativeEvent = null;
2183
- };
2184
- this.onPointerMove = (nativeEvent) => {
2185
- if (this.supportsTouchEvents && nativeEvent.pointerType === 'touch') {
2186
- return;
2187
- }
2188
- if (this.isEventOutsideOfTargetElement(nativeEvent)) {
2189
- return;
2190
- }
2191
- const normalizedEvents = this.normalizeToPointerData(nativeEvent);
2192
- for (let i = 0, j = normalizedEvents.length; i < j; i++) {
2193
- const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]);
2194
- this.manager.mapEvent(event);
2195
- }
2196
- this.setCursor(this.manager.cursor, this.manager.cursorTarget);
2197
- this.rootPointerEvent.nativeEvent = null;
2198
- };
2199
- this.onPointerUp = (nativeEvent) => {
2200
- if (this.supportsTouchEvents && nativeEvent.pointerType === 'touch') {
2201
- return;
2202
- }
2203
- const outside = this.isEventOutsideOfTargetViewPort(nativeEvent) ? 'outside' : '';
2204
- const normalizedEvents = this.normalizeToPointerData(nativeEvent);
2205
- for (let i = 0, j = normalizedEvents.length; i < j; i++) {
2206
- const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]);
2207
- event.type += outside;
2208
- this.manager.mapEvent(event);
2209
- }
2210
- this.setCursor(this.manager.cursor, this.manager.cursorTarget);
2211
- this.rootPointerEvent.nativeEvent = null;
2212
- };
2213
- this.onPointerOverOut = (nativeEvent) => {
2214
- if (this.supportsTouchEvents && nativeEvent.pointerType === 'touch') {
2215
- return;
2216
- }
2217
- const normalizedEvents = this.normalizeToPointerData(nativeEvent);
2218
- for (let i = 0, j = normalizedEvents.length; i < j; i++) {
2219
- const event = this.bootstrapEvent(this.rootPointerEvent, normalizedEvents[i]);
2220
- this.manager.mapEvent(event);
2221
- }
2222
- this.setCursor(this.manager.cursor, this.manager.cursorTarget);
2223
- this.rootPointerEvent.nativeEvent = null;
2224
- };
2225
- this.onWheel = (nativeEvent) => {
2226
- const wheelEvent = this.normalizeWheelEvent(nativeEvent);
2227
- this.manager.mapEvent(wheelEvent);
2228
- };
2467
+ this.released = false;
2468
+ this.processingInput = false;
2469
+ this.onPointerDown = (event) => this.handleNativeEvent(event);
2470
+ this.onPointerMove = (event) => this.handleNativeEvent(event);
2471
+ this.onPointerUp = (event) => this.handleNativeEvent(event);
2472
+ this.onPointerCancel = (event) => this.handleNativeEvent(event);
2473
+ this.onPointerOverOut = (event) => this.handleNativeEvent(event);
2474
+ this.onWheel = (event) => this.handleNativeEvent(event);
2475
+ this.onBlur = () => this.cancelAllPointers();
2229
2476
  const { targetElement, resolution, rootNode, global, autoPreventDefault = false, clickInterval, supportsTouchEvents = global.supportsTouchEvents, supportsPointerEvents = global.supportsPointerEvents } = params;
2230
2477
  this.manager = new EventManager(rootNode, {
2231
2478
  clickInterval,
@@ -2244,15 +2491,25 @@ class EventSystem {
2244
2491
  default: 'inherit',
2245
2492
  pointer: 'pointer'
2246
2493
  };
2494
+ this.useNativeEvents = params.useNativeEvents !== false;
2247
2495
  this.resolution = resolution;
2248
2496
  this.setTargetElement(targetElement);
2249
2497
  }
2250
2498
  release() {
2251
- this.removeEvents();
2252
- this.manager && this.manager.release();
2253
- this.domElement = null;
2254
- this.manager = null;
2255
- this.globalObj = null;
2499
+ if (this.released) {
2500
+ return;
2501
+ }
2502
+ this.released = true;
2503
+ this.pendingInputs = undefined;
2504
+ try {
2505
+ this.manager.cancelAllPointers();
2506
+ }
2507
+ finally {
2508
+ this.removeEvents();
2509
+ this.manager.release();
2510
+ this.domElement = null;
2511
+ this.globalObj = null;
2512
+ }
2256
2513
  }
2257
2514
  setCursor(mode, target) {
2258
2515
  if (!target && !this.manager.rootTarget.window._handler.canvas.controled) {
@@ -2282,13 +2539,118 @@ class EventSystem {
2282
2539
  domElement.style.cursor = mode;
2283
2540
  }
2284
2541
  }
2542
+ get input() {
2543
+ return this.manager.input;
2544
+ }
2545
+ handleNativeEvent(event, options) {
2546
+ var _a;
2547
+ if (this.released) {
2548
+ return;
2549
+ }
2550
+ if (this.processingInput) {
2551
+ ((_a = this.pendingInputs) !== null && _a !== void 0 ? _a : (this.pendingInputs = [])).push({
2552
+ event,
2553
+ options: options && {
2554
+ canvasPoint: { x: options.canvasPoint.x, y: options.canvasPoint.y },
2555
+ inViewport: options.inViewport
2556
+ }
2557
+ });
2558
+ return;
2559
+ }
2560
+ this.processingInput = true;
2561
+ try {
2562
+ this.processInput(event, options);
2563
+ this.drainInputQueue();
2564
+ }
2565
+ finally {
2566
+ this.processingInput = false;
2567
+ this.pendingInputs = undefined;
2568
+ this.rootPointerEvent.nativeEvent = null;
2569
+ this.rootWheelEvent.nativeEvent = null;
2570
+ }
2571
+ }
2572
+ cancelPointer(pointerId) {
2573
+ this.cancelInput(pointerId);
2574
+ }
2575
+ cancelAllPointers() {
2576
+ this.cancelInput();
2577
+ }
2578
+ cancelInput(pointerId) {
2579
+ if (this.released) {
2580
+ return;
2581
+ }
2582
+ const processing = this.processingInput;
2583
+ this.processingInput = true;
2584
+ try {
2585
+ if (pointerId === undefined) {
2586
+ this.manager.cancelAllPointers();
2587
+ }
2588
+ else {
2589
+ this.manager.cancelPointer(pointerId);
2590
+ }
2591
+ if (!processing) {
2592
+ this.drainInputQueue();
2593
+ }
2594
+ }
2595
+ finally {
2596
+ this.processingInput = processing;
2597
+ if (!processing) {
2598
+ this.pendingInputs = undefined;
2599
+ this.rootPointerEvent.nativeEvent = null;
2600
+ this.rootWheelEvent.nativeEvent = null;
2601
+ }
2602
+ }
2603
+ }
2604
+ drainInputQueue() {
2605
+ var _a;
2606
+ while (!this.released && ((_a = this.pendingInputs) === null || _a === void 0 ? void 0 : _a.length)) {
2607
+ const next = this.pendingInputs.shift();
2608
+ this.processInput(next.event, next.options);
2609
+ }
2610
+ }
2611
+ processInput(nativeEvent, options) {
2612
+ var _a, _b, _c;
2613
+ if (!options && this.supportsTouchEvents && nativeEvent.pointerType === 'touch') {
2614
+ return;
2615
+ }
2616
+ if (nativeEvent.type === 'wheel') {
2617
+ const event = this.normalizeWheelEvent(nativeEvent, options === null || options === void 0 ? void 0 : options.canvasPoint);
2618
+ if ((_a = options === null || options === void 0 ? void 0 : options.inViewport) !== null && _a !== void 0 ? _a : !this.isEventOutsideOfTargetViewPort(nativeEvent, event)) {
2619
+ this.manager.mapEvent(event);
2620
+ }
2621
+ return;
2622
+ }
2623
+ const events = this.normalizeToPointerData(nativeEvent);
2624
+ if (this.autoPreventDefault && ((_b = events[0]) === null || _b === void 0 ? void 0 : _b.isNormalized) && nativeEvent.cancelable) {
2625
+ nativeEvent.preventDefault();
2626
+ }
2627
+ for (let i = 0; i < events.length && !this.released; i++) {
2628
+ const event = this.bootstrapEvent(this.rootPointerEvent, events[i], options === null || options === void 0 ? void 0 : options.canvasPoint);
2629
+ event.nativeEvent = nativeEvent;
2630
+ if (event.type === 'pointercancel') {
2631
+ this.manager.cancelPointer(event.pointerId);
2632
+ continue;
2633
+ }
2634
+ const inside = event.type !== 'pointerout' &&
2635
+ event.type !== 'pointerleave' &&
2636
+ ((_c = options === null || options === void 0 ? void 0 : options.inViewport) !== null && _c !== void 0 ? _c : !this.isEventOutsideOfTargetViewPort(nativeEvent, event));
2637
+ if (!inside && (event.type === 'pointerdown' || !this.manager.hasPointer(event.pointerId))) {
2638
+ continue;
2639
+ }
2640
+ this.manager.mapEvent(event, inside);
2641
+ }
2642
+ if (!options && !this.released) {
2643
+ this.setCursor(this.manager.cursor, this.manager.cursorTarget);
2644
+ }
2645
+ }
2285
2646
  setTargetElement(element) {
2286
2647
  this.removeEvents();
2287
2648
  this.domElement = element;
2288
2649
  this.addEvents();
2289
2650
  }
2290
2651
  addEvents() {
2291
- if (this.eventsAdded || !this.domElement) {
2652
+ var _a, _b, _c;
2653
+ if (!this.useNativeEvents || this.eventsAdded || !this.domElement) {
2292
2654
  return;
2293
2655
  }
2294
2656
  const { globalObj, domElement } = this;
@@ -2296,10 +2658,12 @@ class EventSystem {
2296
2658
  if (globalObj.getDocument()) {
2297
2659
  globalObj.addEventListener('pointermove', this.onPointerMove, true);
2298
2660
  globalObj.addEventListener('pointerup', this.onPointerUp, true);
2661
+ globalObj.addEventListener('pointercancel', this.onPointerCancel, true);
2299
2662
  }
2300
2663
  else {
2301
2664
  domElement.addEventListener('pointermove', this.onPointerMove, true);
2302
2665
  domElement.addEventListener('pointerup', this.onPointerUp, true);
2666
+ domElement.addEventListener('pointercancel', this.onPointerCancel, true);
2303
2667
  }
2304
2668
  domElement.addEventListener('pointerdown', this.onPointerDown, true);
2305
2669
  domElement.addEventListener('pointerleave', this.onPointerOverOut, true);
@@ -2321,26 +2685,32 @@ class EventSystem {
2321
2685
  if (this.supportsTouchEvents) {
2322
2686
  domElement.addEventListener('touchstart', this.onPointerDown, true);
2323
2687
  domElement.addEventListener('touchend', this.onPointerUp, true);
2324
- domElement.addEventListener('touchmove', this.onPointerMove, true);
2688
+ domElement.addEventListener('touchcancel', this.onPointerCancel, true);
2689
+ domElement.addEventListener('touchmove', this.onPointerMove, { capture: true, passive: false });
2325
2690
  }
2326
2691
  domElement.addEventListener('wheel', this.onWheel, {
2327
2692
  capture: true
2328
2693
  });
2694
+ (_c = (_b = (_a = globalObj.getDocument) === null || _a === void 0 ? void 0 : _a.call(globalObj)) === null || _b === void 0 ? void 0 : _b.defaultView) === null || _c === void 0 ? void 0 : _c.addEventListener('blur', this.onBlur);
2329
2695
  this.eventsAdded = true;
2330
2696
  }
2331
2697
  removeEvents() {
2698
+ var _a, _b, _c;
2332
2699
  if (!this.eventsAdded || !this.domElement) {
2333
2700
  return;
2334
2701
  }
2335
2702
  const { globalObj, domElement } = this;
2703
+ (_c = (_b = (_a = globalObj.getDocument) === null || _a === void 0 ? void 0 : _a.call(globalObj)) === null || _b === void 0 ? void 0 : _b.defaultView) === null || _c === void 0 ? void 0 : _c.removeEventListener('blur', this.onBlur);
2336
2704
  if (this.supportsPointerEvents) {
2337
2705
  if (globalObj.getDocument()) {
2338
2706
  globalObj.removeEventListener('pointermove', this.onPointerMove, true);
2339
2707
  globalObj.removeEventListener('pointerup', this.onPointerUp, true);
2708
+ globalObj.removeEventListener('pointercancel', this.onPointerCancel, true);
2340
2709
  }
2341
2710
  else {
2342
2711
  domElement.removeEventListener('pointermove', this.onPointerMove, true);
2343
2712
  domElement.removeEventListener('pointerup', this.onPointerUp, true);
2713
+ domElement.removeEventListener('pointercancel', this.onPointerCancel, true);
2344
2714
  }
2345
2715
  domElement.removeEventListener('pointerdown', this.onPointerDown, true);
2346
2716
  domElement.removeEventListener('pointerleave', this.onPointerOverOut, true);
@@ -2362,6 +2732,7 @@ class EventSystem {
2362
2732
  if (this.supportsTouchEvents) {
2363
2733
  domElement.removeEventListener('touchstart', this.onPointerDown, true);
2364
2734
  domElement.removeEventListener('touchend', this.onPointerUp, true);
2735
+ domElement.removeEventListener('touchcancel', this.onPointerCancel, true);
2365
2736
  domElement.removeEventListener('touchmove', this.onPointerMove, true);
2366
2737
  }
2367
2738
  domElement.removeEventListener('wheel', this.onWheel, true);
@@ -2492,14 +2863,14 @@ class EventSystem {
2492
2863
  }
2493
2864
  return normalizedEvents;
2494
2865
  }
2495
- normalizeWheelEvent(nativeEvent) {
2866
+ normalizeWheelEvent(nativeEvent, canvasPoint) {
2496
2867
  const event = this.rootWheelEvent;
2497
2868
  this.transferMouseData(event, nativeEvent);
2498
2869
  event.deltaMode = nativeEvent.deltaMode;
2499
2870
  event.deltaX = nativeEvent.deltaX;
2500
2871
  event.deltaY = nativeEvent.deltaY;
2501
2872
  event.deltaZ = nativeEvent.deltaZ;
2502
- const { x: canvasX, y: canvasY } = this.mapToCanvasPoint(nativeEvent);
2873
+ const { x: canvasX, y: canvasY } = canvasPoint !== null && canvasPoint !== void 0 ? canvasPoint : this.mapToCanvasPoint(nativeEvent);
2503
2874
  event.canvas.x = canvasX;
2504
2875
  event.canvas.y = canvasY;
2505
2876
  event.global.x = canvasX;
@@ -2513,7 +2884,7 @@ class EventSystem {
2513
2884
  event.type = nativeEvent.type;
2514
2885
  return event;
2515
2886
  }
2516
- bootstrapEvent(event, nativeEvent) {
2887
+ bootstrapEvent(event, nativeEvent, canvasPoint) {
2517
2888
  event.originalEvent = null;
2518
2889
  event.nativeEvent = nativeEvent;
2519
2890
  event.pointerId = nativeEvent.pointerId;
@@ -2527,7 +2898,7 @@ class EventSystem {
2527
2898
  event.tiltY = nativeEvent.tiltY;
2528
2899
  event.twist = nativeEvent.twist;
2529
2900
  this.transferMouseData(event, nativeEvent);
2530
- const { x: canvasX, y: canvasY } = this.mapToCanvasPoint(nativeEvent);
2901
+ const { x: canvasX, y: canvasY } = canvasPoint !== null && canvasPoint !== void 0 ? canvasPoint : this.mapToCanvasPoint(nativeEvent);
2531
2902
  event.canvas.x = canvasX;
2532
2903
  event.canvas.y = canvasY;
2533
2904
  event.global.x = canvasX;
@@ -2568,12 +2939,12 @@ class EventSystem {
2568
2939
  event.page.y = nativeEvent.pageY;
2569
2940
  event.relatedTarget = null;
2570
2941
  }
2571
- isEventOutsideOfTargetViewPort(nativeEvent) {
2942
+ isEventOutsideOfTargetViewPort(nativeEvent, event) {
2572
2943
  if (this.isEventOutsideOfTargetElement(nativeEvent)) {
2573
2944
  return true;
2574
2945
  }
2575
2946
  if (this.domElement.getViewBox) {
2576
- const p = this.mapToViewportPoint(this.mapToCanvasPoint(nativeEvent));
2947
+ const p = event.viewport;
2577
2948
  const b = this.domElement.getViewBox();
2578
2949
  const w = b.width();
2579
2950
  const h = b.height();
@@ -19958,7 +20329,7 @@ class Stage extends Group {
19958
20329
  this.pickerServiceFactory =
19959
20330
  (_e = deps.pickerServiceFactory) !== null && _e !== void 0 ? _e : (deps.pickerService
19960
20331
  ? () => deps.pickerService
19961
- : (_f = application.pickerServiceFactory) !== null && _f !== void 0 ? _f : (() => new DefaultGlobalPickerService()));
20332
+ : ((_f = application.pickerServiceFactory) !== null && _f !== void 0 ? _f : (() => new DefaultGlobalPickerService())));
19962
20333
  this.window = (_g = deps.window) !== null && _g !== void 0 ? _g : this.windowFactory();
19963
20334
  this.renderService =
19964
20335
  (_l = (_k = (_h = deps.renderService) !== null && _h !== void 0 ? _h : (_j = application.renderServiceFactory) === null || _j === void 0 ? void 0 : _j.call(application)) !== null && _k !== void 0 ? _k : application.renderService) !== null && _l !== void 0 ? _l : new DefaultRenderService();
@@ -20344,6 +20715,9 @@ class Stage extends Group {
20344
20715
  canvasId
20345
20716
  });
20346
20717
  this.appendChild(layer);
20718
+ if (this.interactiveLayer && layer !== this.interactiveLayer) {
20719
+ this.appendChild(this.interactiveLayer);
20720
+ }
20347
20721
  return layer;
20348
20722
  }
20349
20723
  sortLayer(cb) {
@@ -20353,6 +20727,9 @@ class Stage extends Group {
20353
20727
  children.forEach(c => {
20354
20728
  this.appendChild(c);
20355
20729
  });
20730
+ if (this.interactiveLayer) {
20731
+ this.appendChild(this.interactiveLayer);
20732
+ }
20356
20733
  }
20357
20734
  removeLayer(ILayerId) {
20358
20735
  return this.removeChild(this.findChildByUid(ILayerId));
@@ -20362,12 +20739,18 @@ class Stage extends Group {
20362
20739
  return;
20363
20740
  }
20364
20741
  if (this.supportInteractiveLayer && !this.interactiveLayer) {
20365
- this.interactiveLayer = this.createLayer();
20742
+ this.interactiveLayer = this.createLayer(undefined, this.params.interactiveLayerMode);
20366
20743
  this.interactiveLayer.name = '_builtin_interactive';
20367
20744
  this.interactiveLayer.attribute.pickable = false;
20368
20745
  this.nextFrameRenderLayerSet.add(this.interactiveLayer);
20369
20746
  }
20370
20747
  }
20748
+ prepareRenderLayers() {
20749
+ if (this.params.interactiveLayerMode === 'virtual') {
20750
+ this.tryInitInteractiveLayer();
20751
+ }
20752
+ this.layerService.prepareStageLayer(this);
20753
+ }
20371
20754
  clearViewBox(color) {
20372
20755
  this.window.clearViewBox(color);
20373
20756
  }
@@ -20375,14 +20758,18 @@ class Stage extends Group {
20375
20758
  if (this.releaseStatus === 'released') {
20376
20759
  return;
20377
20760
  }
20761
+ if (this.params.requestRender) {
20762
+ this.params.requestRender();
20763
+ return;
20764
+ }
20378
20765
  this.startAnimate();
20379
20766
  const state = this.state;
20380
20767
  this.state = 'rendering';
20381
- this.layerService.prepareStageLayer(this);
20382
20768
  if (!this._skipRender) {
20383
20769
  this.lastRenderparams = params;
20384
20770
  this.hooks.beforeRender.call(this);
20385
20771
  if (!this._skipRender) {
20772
+ this.prepareRenderLayers();
20386
20773
  this.renderLayerList(this.children);
20387
20774
  this.combineLayersToWindow();
20388
20775
  this.nextFrameRenderLayerSet.clear();
@@ -20408,6 +20795,15 @@ class Stage extends Group {
20408
20795
  return;
20409
20796
  }
20410
20797
  renderNextFrame(layers, force) {
20798
+ if (this.releaseStatus === 'released') {
20799
+ return;
20800
+ }
20801
+ if (this.params.requestRender) {
20802
+ if (this.state !== 'rendering') {
20803
+ this.params.requestRender();
20804
+ }
20805
+ return;
20806
+ }
20411
20807
  if (this.nextFrameRenderLayerSet.size !== this.childrenCount) {
20412
20808
  (layers || this).forEach((layer) => {
20413
20809
  this.nextFrameRenderLayerSet.add(layer);
@@ -20435,10 +20831,10 @@ class Stage extends Group {
20435
20831
  this.startAnimate();
20436
20832
  const state = this.state;
20437
20833
  this.state = 'rendering';
20438
- this.layerService.prepareStageLayer(this);
20439
20834
  if (this.nextFrameRenderLayerSet.size && !this._skipRender) {
20440
20835
  this.hooks.beforeRender.call(this);
20441
20836
  if (!this._skipRender) {
20837
+ this.prepareRenderLayers();
20442
20838
  this.renderLayerList(Array.from(this.nextFrameRenderLayerSet.values()), this.lastRenderparams || {});
20443
20839
  this.combineLayersToWindow();
20444
20840
  this.nextFrameRenderLayerSet.clear();
@@ -20605,20 +21001,35 @@ class Stage extends Group {
20605
21001
  const layer = this.children.filter(layer => layer.name === name);
20606
21002
  return layer[0];
20607
21003
  }
20608
- renderTo(window) {
21004
+ renderTo(window, _params, options) {
20609
21005
  if (this.releaseStatus === 'released') {
20610
21006
  return;
20611
21007
  }
20612
- this.forEachChildren((layer, i) => {
20613
- layer.drawTo(window, {
20614
- renderService: this.renderService,
20615
- viewBox: window.getViewBox(),
20616
- transMatrix: window.getViewBoxTransform(),
20617
- background: layer === this.defaultLayer ? this.background : undefined,
20618
- clear: i === 0,
20619
- updateBounds: !!(this.dirtyBounds && !this.dirtyBounds.empty())
21008
+ const state = this.state;
21009
+ this.state = 'rendering';
21010
+ try {
21011
+ if (this.params.requestRender) {
21012
+ this.hooks.beforeRender.call(this);
21013
+ }
21014
+ this.prepareRenderLayers();
21015
+ this.forEachChildren((layer, i) => {
21016
+ var _a, _b;
21017
+ layer.drawTo(window, {
21018
+ renderService: this.renderService,
21019
+ viewBox: (_a = options === null || options === void 0 ? void 0 : options.viewBox) !== null && _a !== void 0 ? _a : window.getViewBox(),
21020
+ transMatrix: (_b = options === null || options === void 0 ? void 0 : options.transMatrix) !== null && _b !== void 0 ? _b : window.getViewBoxTransform(),
21021
+ background: layer === this.defaultLayer ? this.background : undefined,
21022
+ clear: i === 0 && (options === null || options === void 0 ? void 0 : options.clear) !== false,
21023
+ updateBounds: !!(this.dirtyBounds && !this.dirtyBounds.empty())
21024
+ });
20620
21025
  });
20621
- });
21026
+ if (this.params.requestRender) {
21027
+ this.hooks.afterRender.call(this);
21028
+ }
21029
+ }
21030
+ finally {
21031
+ this.state = state;
21032
+ }
20622
21033
  }
20623
21034
  renderToNewWindow(fullImage = true, viewBox) {
20624
21035
  if (this.releaseStatus === 'released') {
@@ -20675,6 +21086,9 @@ class Stage extends Group {
20675
21086
  return this._cursor;
20676
21087
  }
20677
21088
  eventPointTransform(e) {
21089
+ if (e instanceof FederatedMouseEvent) {
21090
+ return { x: e.viewX, y: e.viewY };
21091
+ }
20678
21092
  const point = this.global.mapToCanvasPoint(e, this.window);
20679
21093
  return this.stage.window.pointTransform(point.x, point.y);
20680
21094
  }
@@ -21868,9 +22282,60 @@ class CanvasLayerHandlerContribution {
21868
22282
  }
21869
22283
  }
21870
22284
 
22285
+ class EmptyLayerHandlerContribution {
22286
+ constructor() {
22287
+ this.offscreen = false;
22288
+ this.type = 'virtual';
22289
+ this.global = application.global;
22290
+ }
22291
+ setDpr(dpr) {
22292
+ return;
22293
+ }
22294
+ init(layer, window, params) {
22295
+ this.layer = layer;
22296
+ this.window = window;
22297
+ if (params.main) {
22298
+ throw new Error('virtual layer不能作为main layer');
22299
+ }
22300
+ this.main = false;
22301
+ this.canvas = null;
22302
+ this.context = null;
22303
+ }
22304
+ resize(w, h) {
22305
+ return;
22306
+ }
22307
+ resizeView(w, h) {
22308
+ return;
22309
+ }
22310
+ render(group, params, userParams) {
22311
+ this.mainHandler.render(group, params, Object.assign(Object.assign({}, userParams), { clear: false }));
22312
+ return;
22313
+ }
22314
+ merge(layerHandlers) {
22315
+ return;
22316
+ }
22317
+ prepare(dirtyBounds, params) {
22318
+ return;
22319
+ }
22320
+ drawTo(target, group, params) {
22321
+ var _a;
22322
+ const context = target.getContext();
22323
+ params.renderService.render(group, Object.assign(Object.assign({ context }, params), { clear: params.clear ? (_a = params.background) !== null && _a !== void 0 ? _a : '#fff' : undefined }));
22324
+ return;
22325
+ }
22326
+ getContext() {
22327
+ return null;
22328
+ }
22329
+ release() {
22330
+ return;
22331
+ }
22332
+ }
22333
+
21871
22334
  function bindLayerHandlerModules({ bind }) {
21872
22335
  bind(CanvasLayerHandlerContribution).toSelf();
22336
+ bind(EmptyLayerHandlerContribution).toSelf();
21873
22337
  bind(StaticLayerHandlerContribution).toService(CanvasLayerHandlerContribution);
22338
+ bind(VirtualLayerHandlerContribution).toService(EmptyLayerHandlerContribution);
21874
22339
  }
21875
22340
 
21876
22341
  function load$1(container) {
@@ -23708,12 +24173,24 @@ class InteractiveDrawItemInterceptorContribution {
23708
24173
  this.processing = true;
23709
24174
  const { context } = drawContext;
23710
24175
  context.highPerformanceSave();
23711
- context.setTransformFromMatrix(baseGraphic.parent.globalTransMatrix, true);
23712
- baseGraphic.isContainer
23713
- ? drawContribution.renderGroup(baseGraphic, drawContext, baseGraphic.parent.globalTransMatrix)
23714
- : drawContribution.renderItem(baseGraphic, drawContext);
23715
- context.highPerformanceRestore();
23716
- this.processing = false;
24176
+ const parent = baseGraphic.parent.globalTransMatrix;
24177
+ const matrix = matrixAllocate.allocateByObj(parent);
24178
+ if (drawContext.transMatrix) {
24179
+ const outer = drawContext.transMatrix;
24180
+ matrix.setValue(outer.a, outer.b, outer.c, outer.d, outer.e, outer.f);
24181
+ matrix.multiply(parent.a, parent.b, parent.c, parent.d, parent.e, parent.f);
24182
+ }
24183
+ try {
24184
+ context.setTransformFromMatrix(matrix, true);
24185
+ baseGraphic.isContainer
24186
+ ? drawContribution.renderGroup(baseGraphic, drawContext, matrix)
24187
+ : drawContribution.renderItem(baseGraphic, drawContext);
24188
+ }
24189
+ finally {
24190
+ context.highPerformanceRestore();
24191
+ matrixAllocate.free(matrix);
24192
+ this.processing = false;
24193
+ }
23717
24194
  return true;
23718
24195
  }
23719
24196
  return false;