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

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