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

handles.tsx 1.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import useHandleEvents from 'hooks/useHandleEvents'
  2. import { getShapeUtils } from 'lib/shape-utils'
  3. import { useRef } from 'react'
  4. import { useSelector } from 'state'
  5. import styled from 'styles'
  6. import { deepCompareArrays, getPage } from 'utils/utils'
  7. import * as vec from 'utils/vec'
  8. export default function Handles() {
  9. const selectedIds = useSelector(
  10. (s) => Array.from(s.values.selectedIds.values()),
  11. deepCompareArrays
  12. )
  13. const shape = useSelector(
  14. ({ data }) =>
  15. selectedIds.length === 1 && getPage(data).shapes[selectedIds[0]]
  16. )
  17. const isSelecting = useSelector((s) =>
  18. s.isInAny('notPointing', 'pinching', 'translatingHandles')
  19. )
  20. if (!shape || !shape.handles || !isSelecting) return null
  21. const center = getShapeUtils(shape).getCenter(shape)
  22. console.log(shape)
  23. return (
  24. <g transform={`rotate(${shape.rotation * (180 / Math.PI)},${center})`}>
  25. {Object.values(shape.handles).map((handle) => (
  26. <Handle
  27. key={handle.id}
  28. id={handle.id}
  29. point={vec.add(handle.point, shape.point)}
  30. />
  31. ))}
  32. </g>
  33. )
  34. }
  35. function Handle({ id, point }: { id: string; point: number[] }) {
  36. const rGroup = useRef<SVGGElement>(null)
  37. const events = useHandleEvents(id, rGroup)
  38. return (
  39. <StyledGroup
  40. key={id}
  41. className="handles"
  42. ref={rGroup}
  43. {...events}
  44. pointerEvents="all"
  45. transform={`translate(${point})`}
  46. >
  47. <HandleCircleOuter r={12} />
  48. <use href="#handle" pointerEvents="none" />
  49. </StyledGroup>
  50. )
  51. }
  52. const StyledGroup = styled('g', {
  53. '&:hover': {
  54. cursor: 'pointer',
  55. },
  56. '&:active': {
  57. cursor: 'none',
  58. },
  59. })
  60. const HandleCircleOuter = styled('circle', {
  61. fill: 'transparent',
  62. stroke: 'none',
  63. opacity: 0.2,
  64. pointerEvents: 'all',
  65. cursor: 'pointer',
  66. transform: 'scale(var(--scale))',
  67. '&:hover': {
  68. fill: '$selected',
  69. '& > *': {
  70. stroke: '$selected',
  71. },
  72. },
  73. '&:active': {
  74. fill: '$selected',
  75. },
  76. })