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.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  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 { getCurrentCamera } from 'utils'
  6. import { DotCircle, Handle } from './misc'
  7. import useShapeDef from 'hooks/useShape'
  8. import useShapesToRender from 'hooks/useShapesToRender'
  9. export default function Defs(): JSX.Element {
  10. const shapeIdsToRender = useShapesToRender()
  11. return (
  12. <defs>
  13. {shapeIdsToRender.map((id) => (
  14. <Def key={id} id={id} />
  15. ))}
  16. <DotCircle id="dot" r={4} />
  17. <Handle id="handle" r={4} />
  18. <ExpandDef />
  19. </defs>
  20. )
  21. }
  22. const Def = memo(function Def({ id }: { id: string }) {
  23. const shape = useShapeDef(id)
  24. if (!shape) return null
  25. const style = getShapeStyle(shape.style)
  26. return React.cloneElement(
  27. getShapeUtils(shape).render(shape, { isEditing: false }),
  28. { id, ...style }
  29. )
  30. })
  31. function ExpandDef() {
  32. const zoom = useSelector((s) => getCurrentCamera(s.data).zoom)
  33. return (
  34. <filter id="expand">
  35. <feMorphology operator="dilate" radius={2 / zoom} />
  36. </filter>
  37. )
  38. }