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.

defs.tsx 1.3KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { getShapeStyle } from 'state/shape-styles'
  2. import { getShapeUtils } from 'state/shape-utils'
  3. import React, { memo } from 'react'
  4. import { useSelector } from 'state'
  5. import { deepCompareArrays, getCurrentCamera, getPage } from 'utils/utils'
  6. import { DotCircle, Handle } from './misc'
  7. export default function Defs(): JSX.Element {
  8. const zoom = useSelector((s) => getCurrentCamera(s.data).zoom)
  9. const currentPageShapeIds = useSelector(({ data }) => {
  10. return Object.values(getPage(data).shapes)
  11. .filter(Boolean)
  12. .filter((shape) => !getShapeUtils(shape).isForeignObject)
  13. .sort((a, b) => a.childIndex - b.childIndex)
  14. .map((shape) => shape.id)
  15. }, deepCompareArrays)
  16. return (
  17. <defs>
  18. {currentPageShapeIds.map((id) => (
  19. <Def key={id} id={id} />
  20. ))}
  21. <DotCircle id="dot" r={4} />
  22. <Handle id="handle" r={4} />
  23. <filter id="expand">
  24. <feMorphology operator="dilate" radius={2 / zoom} />
  25. </filter>
  26. </defs>
  27. )
  28. }
  29. const Def = memo(function Def({ id }: { id: string }) {
  30. const shape = useSelector((s) => getPage(s.data).shapes[id])
  31. if (!shape) return null
  32. const style = getShapeStyle(shape.style)
  33. return React.cloneElement(
  34. getShapeUtils(shape).render(shape, { isEditing: false }),
  35. { id, ...style }
  36. )
  37. })