index.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import { Buttons } from './buttons.js';
  2. import { Device } from './device.js';
  3. import { Mouse } from './mouse.js';
  4. import { Pointer } from './pointer.js';
  5. function _define_property(obj, key, value) {
  6. if (key in obj) {
  7. Object.defineProperty(obj, key, {
  8. value: value,
  9. enumerable: true,
  10. configurable: true,
  11. writable: true
  12. });
  13. } else {
  14. obj[key] = value;
  15. }
  16. return obj;
  17. }
  18. class PointerHost {
  19. isKeyPressed(keyDef) {
  20. return this.devices.get(keyDef.pointerType).isPressed(keyDef);
  21. }
  22. async press(instance, keyDef, position) {
  23. this.devices.get(keyDef.pointerType).addPressed(keyDef);
  24. this.buttons.down(keyDef);
  25. const pointerName = this.getPointerName(keyDef);
  26. const pointer = keyDef.pointerType === 'touch' ? this.pointers.new(pointerName, keyDef.pointerType, this.buttons) : this.pointers.get(pointerName);
  27. // TODO: deprecate the following implicit setting of position
  28. pointer.position = position;
  29. if (pointer.pointerType !== 'touch') {
  30. this.mouse.position = position;
  31. }
  32. if (pointer.pointerType === 'touch') {
  33. pointer.init(instance);
  34. }
  35. pointer.down(instance, keyDef.button);
  36. if (pointer.pointerType !== 'touch') {
  37. this.mouse.down(instance, keyDef, pointer.isPrevented);
  38. }
  39. }
  40. async move(instance, pointerName, position) {
  41. const pointer = this.pointers.get(pointerName);
  42. // In (some?) browsers this order of events can be observed.
  43. // This interweaving of events is probably unnecessary.
  44. // While the order of mouse (or pointer) events is defined per spec,
  45. // the order in which they interweave/follow on a user interaction depends on the implementation.
  46. const pointermove = pointer.move(instance, position);
  47. const mousemove = pointer.pointerType === 'touch' ? undefined : this.mouse.move(instance, position, pointer.isPrevented);
  48. pointermove === null || pointermove === undefined ? undefined : pointermove.leave();
  49. mousemove === null || mousemove === undefined ? undefined : mousemove.leave();
  50. pointermove === null || pointermove === undefined ? undefined : pointermove.enter();
  51. mousemove === null || mousemove === undefined ? undefined : mousemove.enter();
  52. pointermove === null || pointermove === undefined ? undefined : pointermove.move();
  53. mousemove === null || mousemove === undefined ? undefined : mousemove.move();
  54. }
  55. async release(instance, keyDef, position) {
  56. const device = this.devices.get(keyDef.pointerType);
  57. device.removePressed(keyDef);
  58. this.buttons.up(keyDef);
  59. const pointer = this.pointers.get(this.getPointerName(keyDef));
  60. const isPrevented = pointer.isPrevented;
  61. // TODO: deprecate the following implicit setting of position
  62. pointer.position = position;
  63. if (pointer.pointerType !== 'touch') {
  64. this.mouse.position = position;
  65. }
  66. if (device.countPressed === 0) {
  67. pointer.up(instance, keyDef.button);
  68. }
  69. if (pointer.pointerType === 'touch') {
  70. pointer.release(instance);
  71. }
  72. if (pointer.pointerType === 'touch' && !pointer.isMultitouch) {
  73. const mousemove = this.mouse.move(instance, position, isPrevented);
  74. mousemove === null || mousemove === undefined ? undefined : mousemove.leave();
  75. mousemove === null || mousemove === undefined ? undefined : mousemove.enter();
  76. mousemove === null || mousemove === undefined ? undefined : mousemove.move();
  77. this.mouse.down(instance, keyDef, isPrevented);
  78. }
  79. if (!pointer.isMultitouch) {
  80. const mousemove = this.mouse.move(instance, position, isPrevented);
  81. mousemove === null || mousemove === undefined ? undefined : mousemove.leave();
  82. mousemove === null || mousemove === undefined ? undefined : mousemove.enter();
  83. mousemove === null || mousemove === undefined ? undefined : mousemove.move();
  84. this.mouse.up(instance, keyDef, isPrevented);
  85. }
  86. }
  87. getPointerName(keyDef) {
  88. return keyDef.pointerType === 'touch' ? keyDef.name : keyDef.pointerType;
  89. }
  90. getPreviousPosition(pointerName) {
  91. return this.pointers.has(pointerName) ? this.pointers.get(pointerName).position : undefined;
  92. }
  93. resetClickCount() {
  94. this.mouse.resetClickCount();
  95. }
  96. getMouseTarget(instance) {
  97. var _this_mouse_position_target;
  98. return (_this_mouse_position_target = this.mouse.position.target) !== null && _this_mouse_position_target !== undefined ? _this_mouse_position_target : instance.config.document.body;
  99. }
  100. setMousePosition(position) {
  101. this.mouse.position = position;
  102. this.pointers.get('mouse').position = position;
  103. }
  104. constructor(system){
  105. _define_property(this, "system", undefined);
  106. _define_property(this, "mouse", undefined);
  107. _define_property(this, "buttons", undefined);
  108. _define_property(this, "devices", new class {
  109. get(k) {
  110. var _this_registry, _k;
  111. var _;
  112. return (_ = (_this_registry = this.registry)[_k = k]) !== null && _ !== undefined ? _ : _this_registry[_k] = new Device();
  113. }
  114. constructor(){
  115. _define_property(this, "registry", {});
  116. }
  117. }());
  118. _define_property(this, "pointers", new class {
  119. new(pointerName, pointerType, buttons) {
  120. const isPrimary = pointerType !== 'touch' || !Object.values(this.registry).some((p)=>p.pointerType === 'touch' && !p.isCancelled);
  121. if (!isPrimary) {
  122. Object.values(this.registry).forEach((p)=>{
  123. if (p.pointerType === pointerType && !p.isCancelled) {
  124. p.isMultitouch = true;
  125. }
  126. });
  127. }
  128. this.registry[pointerName] = new Pointer({
  129. pointerId: this.nextId++,
  130. pointerType,
  131. isPrimary
  132. }, buttons);
  133. return this.registry[pointerName];
  134. }
  135. get(pointerName) {
  136. if (!this.has(pointerName)) {
  137. throw new Error(`Trying to access pointer "${pointerName}" which does not exist.`);
  138. }
  139. return this.registry[pointerName];
  140. }
  141. has(pointerName) {
  142. return pointerName in this.registry;
  143. }
  144. constructor(){
  145. _define_property(this, "registry", {});
  146. _define_property(this, "nextId", 1);
  147. }
  148. }());
  149. this.system = system;
  150. this.buttons = new Buttons();
  151. this.mouse = new Mouse();
  152. this.pointers.new('mouse', 'mouse', this.buttons);
  153. }
  154. }
  155. export { PointerHost };