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.

selected.tsx 1.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import styled from 'styles'
  2. import { useSelector } from 'state'
  3. import { deepCompareArrays, getPage } from 'utils/utils'
  4. import { getShapeUtils } from 'lib/shape-utils'
  5. import useShapeEvents from 'hooks/useShapeEvents'
  6. import { useRef } from 'react'
  7. export default function Selected() {
  8. const currentPageShapeIds = useSelector(({ data }) => {
  9. return Array.from(data.selectedIds.values())
  10. }, deepCompareArrays)
  11. const isSelecting = useSelector((s) => s.isIn('selecting'))
  12. if (!isSelecting) return null
  13. return (
  14. <g>
  15. {currentPageShapeIds.map((id) => (
  16. <ShapeOutline key={id} id={id} />
  17. ))}
  18. </g>
  19. )
  20. }
  21. export function ShapeOutline({ id }: { id: string }) {
  22. const rIndicator = useRef<SVGUseElement>(null)
  23. const shape = useSelector(({ data }) => getPage(data).shapes[id])
  24. const events = useShapeEvents(id, rIndicator)
  25. if (!shape) return null
  26. const transform = `
  27. rotate(${shape.rotation * (180 / Math.PI)},
  28. ${getShapeUtils(shape).getCenter(shape)})
  29. translate(${shape.point})`
  30. return (
  31. <Indicator
  32. ref={rIndicator}
  33. as="use"
  34. href={'#' + id}
  35. transform={transform}
  36. isLocked={shape.isLocked}
  37. {...events}
  38. />
  39. )
  40. }
  41. const Indicator = styled('path', {
  42. zStrokeWidth: 1,
  43. strokeLineCap: 'round',
  44. strokeLinejoin: 'round',
  45. stroke: '$selected',
  46. fill: 'transparent',
  47. pointerEvents: 'all',
  48. variants: {
  49. isLocked: {
  50. true: {
  51. zDash: 2,
  52. },
  53. false: {},
  54. },
  55. },
  56. })