您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

canvas.tsx 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import styled from 'styles'
  2. import state, { useSelector } from 'state'
  3. import inputs from 'state/inputs'
  4. import React, { useCallback, useRef } from 'react'
  5. import useZoomEvents from 'hooks/useZoomEvents'
  6. import useCamera from 'hooks/useCamera'
  7. import Defs from './defs'
  8. import Page from './page'
  9. import Brush from './brush'
  10. import Bounds from './bounds/bounding-box'
  11. import BoundsBg from './bounds/bounds-bg'
  12. import Selected from './selected'
  13. import Handles from './bounds/handles'
  14. import { isMobile } from 'utils/utils'
  15. export default function Canvas() {
  16. const rCanvas = useRef<SVGSVGElement>(null)
  17. const rGroup = useRef<SVGGElement>(null)
  18. useCamera(rGroup)
  19. useZoomEvents()
  20. const isReady = useSelector((s) => s.isIn('ready'))
  21. const handlePointerDown = useCallback((e: React.PointerEvent) => {
  22. if (!inputs.canAccept(e.pointerId)) return
  23. rCanvas.current.setPointerCapture(e.pointerId)
  24. state.send('POINTED_CANVAS', inputs.pointerDown(e, 'canvas'))
  25. }, [])
  26. const handleTouchStart = useCallback((e: React.TouchEvent) => {
  27. if (e.touches.length === 2) {
  28. state.send('TOUCH_UNDO')
  29. } else {
  30. if (isMobile()) {
  31. state.send('TOUCHED_CANVAS')
  32. // state.send('POINTED_CANVAS', inputs.touchStart(e, 'canvas'))
  33. // e.preventDefault()
  34. // e.stopPropagation()
  35. }
  36. }
  37. }, [])
  38. // const handleTouchMove = useCallback((e: React.TouchEvent) => {
  39. // if (!inputs.canAccept(e.touches[0].identifier)) return
  40. // if (inputs.canAccept(e.touches[0].identifier)) {
  41. // state.send('MOVED_POINTER', inputs.touchMove(e))
  42. // }
  43. // }, [])
  44. const handlePointerMove = useCallback((e: React.PointerEvent) => {
  45. if (!inputs.canAccept(e.pointerId)) return
  46. if (inputs.canAccept(e.pointerId)) {
  47. state.send('MOVED_POINTER', inputs.pointerMove(e))
  48. }
  49. }, [])
  50. const handlePointerUp = useCallback((e: React.PointerEvent) => {
  51. if (!inputs.canAccept(e.pointerId)) return
  52. rCanvas.current.releasePointerCapture(e.pointerId)
  53. state.send('STOPPED_POINTING', { id: 'canvas', ...inputs.pointerUp(e) })
  54. }, [])
  55. return (
  56. <MainSVG
  57. ref={rCanvas}
  58. onPointerDown={handlePointerDown}
  59. onPointerMove={handlePointerMove}
  60. onPointerUp={handlePointerUp}
  61. onTouchStart={handleTouchStart}
  62. // onTouchMove={handleTouchMove}
  63. >
  64. <Defs />
  65. {isReady && (
  66. <g ref={rGroup}>
  67. <BoundsBg />
  68. <Page />
  69. {/* <Selected /> */}
  70. <Bounds />
  71. <Handles />
  72. <Brush />
  73. </g>
  74. )}
  75. </MainSVG>
  76. )
  77. }
  78. const MainSVG = styled('svg', {
  79. position: 'fixed',
  80. top: 0,
  81. left: 0,
  82. width: '100%',
  83. height: '100%',
  84. touchAction: 'none',
  85. zIndex: 100,
  86. backgroundColor: '$canvas',
  87. '& *': {
  88. userSelect: 'none',
  89. },
  90. })