Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

useKeyboardEvents.ts 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
  2. import { useEffect } from 'react'
  3. import state from 'state'
  4. import { MoveType } from 'types'
  5. import { getKeyboardEventInfo, metaKey } from 'utils'
  6. export default function useKeyboardEvents() {
  7. useEffect(() => {
  8. function handleKeyDown(e: KeyboardEvent) {
  9. if (
  10. metaKey(e) &&
  11. ![
  12. 'a',
  13. 'i',
  14. 'r',
  15. 'j',
  16. 'ArrowLeft',
  17. 'ArrowRight',
  18. 'ArrowUp',
  19. 'ArrowDown',
  20. 'z',
  21. ].includes(e.key)
  22. ) {
  23. e.preventDefault()
  24. }
  25. const info = getKeyboardEventInfo(e)
  26. switch (e.key) {
  27. case 'ArrowUp': {
  28. state.send('NUDGED', { delta: [0, -1], ...info })
  29. break
  30. }
  31. case 'ArrowRight': {
  32. state.send('NUDGED', { delta: [1, 0], ...info })
  33. break
  34. }
  35. case 'ArrowDown': {
  36. state.send('NUDGED', { delta: [0, 1], ...info })
  37. break
  38. }
  39. case 'ArrowLeft': {
  40. state.send('NUDGED', { delta: [-1, 0], ...info })
  41. break
  42. }
  43. case '=': {
  44. if (e.metaKey) {
  45. state.send('ZOOMED_IN')
  46. }
  47. break
  48. }
  49. case '-': {
  50. if (e.metaKey) {
  51. state.send('ZOOMED_OUT')
  52. }
  53. break
  54. }
  55. case '!': {
  56. // Shift + 1
  57. if (e.shiftKey) {
  58. state.send('ZOOMED_TO_FIT')
  59. }
  60. break
  61. }
  62. case '@': {
  63. // Shift + 2
  64. if (e.shiftKey) {
  65. state.send('ZOOMED_TO_SELECTION')
  66. }
  67. break
  68. }
  69. case ')': {
  70. // Shift + 0
  71. if (e.shiftKey) {
  72. state.send('ZOOMED_TO_ACTUAL')
  73. }
  74. break
  75. }
  76. case 'Escape': {
  77. state.send('CANCELLED')
  78. break
  79. }
  80. case 'z': {
  81. if (metaKey(e)) {
  82. if (e.shiftKey) {
  83. state.send('REDO', info)
  84. } else {
  85. state.send('UNDO', info)
  86. }
  87. }
  88. break
  89. }
  90. case '‘': {
  91. if (metaKey(e)) {
  92. state.send('MOVED', {
  93. ...info,
  94. type: MoveType.ToFront,
  95. })
  96. }
  97. break
  98. }
  99. case '“': {
  100. if (metaKey(e)) {
  101. state.send('MOVED', {
  102. ...info,
  103. type: MoveType.ToBack,
  104. })
  105. }
  106. break
  107. }
  108. case ']': {
  109. if (metaKey(e)) {
  110. state.send('MOVED', {
  111. ...info,
  112. type: MoveType.Forward,
  113. })
  114. }
  115. break
  116. }
  117. case '[': {
  118. if (metaKey(e)) {
  119. state.send('MOVED', {
  120. ...info,
  121. type: MoveType.Backward,
  122. })
  123. }
  124. break
  125. }
  126. case 'Shift': {
  127. state.send('PRESSED_SHIFT_KEY', info)
  128. break
  129. }
  130. case 'Alt': {
  131. state.send('PRESSED_ALT_KEY', info)
  132. break
  133. }
  134. case 'Backspace': {
  135. if (metaKey(e)) {
  136. state.send('RESET_PAGE', info)
  137. } else {
  138. state.send('DELETED', info)
  139. }
  140. break
  141. }
  142. case 'g': {
  143. if (metaKey(e)) {
  144. if (e.shiftKey) {
  145. state.send('UNGROUPED', info)
  146. } else {
  147. state.send('GROUPED', info)
  148. }
  149. }
  150. break
  151. }
  152. case 's': {
  153. if (metaKey(e)) {
  154. if (e.shiftKey) {
  155. state.send('SAVED_AS_TO_FILESYSTEM', info)
  156. } else {
  157. state.send('SAVED', info)
  158. }
  159. }
  160. break
  161. }
  162. case 'o': {
  163. if (metaKey(e)) {
  164. break
  165. } else {
  166. state.send('SELECTED_DOT_TOOL', info)
  167. }
  168. break
  169. }
  170. case 'v': {
  171. if (metaKey(e)) {
  172. state.send('PASTED', info)
  173. } else {
  174. state.send('SELECTED_SELECT_TOOL', info)
  175. }
  176. break
  177. }
  178. case 'a': {
  179. if (metaKey(e)) {
  180. state.send('SELECTED_ALL', info)
  181. } else {
  182. state.send('SELECTED_ARROW_TOOL', info)
  183. }
  184. break
  185. }
  186. case 'd': {
  187. if (metaKey(e)) {
  188. state.send('DUPLICATED', info)
  189. } else {
  190. state.send('SELECTED_DRAW_TOOL', info)
  191. }
  192. break
  193. }
  194. case 't': {
  195. state.send('SELECTED_TEXT_TOOL', info)
  196. break
  197. }
  198. case 'c': {
  199. if (metaKey(e)) {
  200. if (e.shiftKey) {
  201. state.send('COPIED_TO_SVG', info)
  202. } else {
  203. state.send('COPIED', info)
  204. }
  205. } else {
  206. state.send('SELECTED_ELLIPSE_TOOL', info)
  207. }
  208. break
  209. }
  210. case 'i': {
  211. if (metaKey(e)) {
  212. break
  213. } else {
  214. state.send('SELECTED_CIRCLE_TOOL', info)
  215. }
  216. break
  217. }
  218. case 'l': {
  219. if (metaKey(e)) {
  220. if (e.shiftKey) {
  221. state.send('LOADED_FROM_FILE_STSTEM', info)
  222. }
  223. } else {
  224. state.send('SELECTED_LINE_TOOL', info)
  225. }
  226. break
  227. }
  228. case 'y': {
  229. if (metaKey(e)) {
  230. break
  231. } else {
  232. state.send('SELECTED_RAY_TOOL', info)
  233. }
  234. break
  235. }
  236. case 'p': {
  237. if (metaKey(e)) {
  238. break
  239. } else {
  240. state.send('SELECTED_POLYLINE_TOOL', info)
  241. }
  242. break
  243. }
  244. case 'r': {
  245. if (metaKey(e)) {
  246. break
  247. } else {
  248. state.send('SELECTED_RECTANGLE_TOOL', info)
  249. }
  250. break
  251. }
  252. case '|': {
  253. state.send('COPIED_STATE_TO_CLIPBOARD')
  254. break
  255. }
  256. default: {
  257. state.send('PRESSED_KEY', info)
  258. }
  259. }
  260. }
  261. function handleKeyUp(e: KeyboardEvent) {
  262. const info = getKeyboardEventInfo(e)
  263. if (e.key === 'Shift') {
  264. state.send('RELEASED_SHIFT_KEY', info)
  265. }
  266. if (e.key === 'Alt') {
  267. state.send('RELEASED_ALT_KEY', info)
  268. }
  269. state.send('RELEASED_KEY', info)
  270. }
  271. document.body.addEventListener('keydown', handleKeyDown)
  272. document.body.addEventListener('keyup', handleKeyUp)
  273. return () => {
  274. document.body.removeEventListener('keydown', handleKeyDown)
  275. document.body.removeEventListener('keyup', handleKeyUp)
  276. }
  277. }, [])
  278. }