You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

inputs.tsx 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import React from 'react'
  2. import { PointerInfo } from 'types'
  3. import * as vec from 'utils/vec'
  4. import { isDarwin, getPoint } from 'utils/utils'
  5. const DOUBLE_CLICK_DURATION = 300
  6. class Inputs {
  7. activePointerId?: number
  8. lastPointerUpTime = 0
  9. points: Record<string, PointerInfo> = {}
  10. lastPointer: PointerInfo
  11. touchStart(e: TouchEvent | React.TouchEvent, target: string) {
  12. const { shiftKey, ctrlKey, metaKey, altKey } = e
  13. const touch = e.changedTouches[0]
  14. const info = {
  15. target,
  16. pointerId: touch.identifier,
  17. origin: getPoint(touch),
  18. point: getPoint(touch),
  19. pressure: 0.5,
  20. shiftKey,
  21. ctrlKey,
  22. metaKey: isDarwin() ? metaKey : ctrlKey,
  23. altKey,
  24. }
  25. this.points[touch.identifier] = info
  26. this.activePointerId = touch.identifier
  27. this.lastPointer = info
  28. return info
  29. }
  30. touchMove(e: TouchEvent | React.TouchEvent) {
  31. const { shiftKey, ctrlKey, metaKey, altKey } = e
  32. const touch = e.changedTouches[0]
  33. const prev = this.points[touch.identifier]
  34. const info = {
  35. ...prev,
  36. pointerId: touch.identifier,
  37. point: getPoint(touch),
  38. pressure: 0.5,
  39. shiftKey,
  40. ctrlKey,
  41. metaKey: isDarwin() ? metaKey : ctrlKey,
  42. altKey,
  43. }
  44. if (this.points[touch.identifier]) {
  45. this.points[touch.identifier] = info
  46. }
  47. this.lastPointer = info
  48. return info
  49. }
  50. pointerDown(e: PointerEvent | React.PointerEvent, target: string) {
  51. const { shiftKey, ctrlKey, metaKey, altKey } = e
  52. const info = {
  53. target,
  54. pointerId: e.pointerId,
  55. origin: getPoint(e),
  56. point: getPoint(e),
  57. pressure: e.pressure || 0.5,
  58. shiftKey,
  59. ctrlKey,
  60. metaKey: isDarwin() ? metaKey : ctrlKey,
  61. altKey,
  62. }
  63. this.points[e.pointerId] = info
  64. this.activePointerId = e.pointerId
  65. this.lastPointer = info
  66. return info
  67. }
  68. pointerEnter(e: PointerEvent | React.PointerEvent, target: string) {
  69. const { shiftKey, ctrlKey, metaKey, altKey } = e
  70. const info = {
  71. target,
  72. pointerId: e.pointerId,
  73. origin: getPoint(e),
  74. point: getPoint(e),
  75. pressure: e.pressure || 0.5,
  76. shiftKey,
  77. ctrlKey,
  78. metaKey: isDarwin() ? metaKey : ctrlKey,
  79. altKey,
  80. }
  81. this.lastPointer = info
  82. return info
  83. }
  84. pointerMove(e: PointerEvent | React.PointerEvent) {
  85. const { shiftKey, ctrlKey, metaKey, altKey } = e
  86. const prev = this.points[e.pointerId]
  87. const info = {
  88. ...prev,
  89. pointerId: e.pointerId,
  90. point: getPoint(e),
  91. pressure: e.pressure || 0.5,
  92. shiftKey,
  93. ctrlKey,
  94. metaKey: isDarwin() ? metaKey : ctrlKey,
  95. altKey,
  96. }
  97. if (this.points[e.pointerId]) {
  98. this.points[e.pointerId] = info
  99. }
  100. this.lastPointer = info
  101. return info
  102. }
  103. pointerUp = (e: PointerEvent | React.PointerEvent) => {
  104. const { shiftKey, ctrlKey, metaKey, altKey } = e
  105. const prev = this.points[e.pointerId]
  106. const info = {
  107. ...prev,
  108. origin: prev?.origin || getPoint(e),
  109. point: getPoint(e),
  110. pressure: e.pressure || 0.5,
  111. shiftKey,
  112. ctrlKey,
  113. metaKey: isDarwin() ? metaKey : ctrlKey,
  114. altKey,
  115. }
  116. delete this.points[e.pointerId]
  117. delete this.activePointerId
  118. if (vec.dist(info.origin, info.point) < 8) {
  119. this.lastPointerUpTime = Date.now()
  120. }
  121. this.lastPointer = info
  122. return info
  123. }
  124. wheel = (e: WheelEvent) => {
  125. const { shiftKey, ctrlKey, metaKey, altKey } = e
  126. return { point: getPoint(e), shiftKey, ctrlKey, metaKey, altKey }
  127. }
  128. canAccept = (pointerId: PointerEvent['pointerId']) => {
  129. return (
  130. this.activePointerId === undefined || this.activePointerId === pointerId
  131. )
  132. }
  133. isDoubleClick() {
  134. if (!this.lastPointer) return
  135. const { origin, point } = this.lastPointer
  136. return (
  137. Date.now() - this.lastPointerUpTime < DOUBLE_CLICK_DURATION &&
  138. vec.dist(origin, point) < 8
  139. )
  140. }
  141. get pointer() {
  142. return this.points[Object.keys(this.points)[0]]
  143. }
  144. }
  145. export default new Inputs()