Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

shape.tsx 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import React, { useCallback, useRef, memo } from "react"
  2. import state, { useSelector } from "state"
  3. import inputs from "state/inputs"
  4. import { getShapeUtils } from "lib/shapes"
  5. import styled from "styles"
  6. function Shape({ id }: { id: string }) {
  7. const rGroup = useRef<SVGGElement>(null)
  8. const isHovered = useSelector((state) => state.data.hoveredId === id)
  9. const isSelected = useSelector((state) => state.values.selectedIds.has(id))
  10. const shape = useSelector(
  11. ({ data }) => data.document.pages[data.currentPageId].shapes[id]
  12. )
  13. const handlePointerDown = useCallback(
  14. (e: React.PointerEvent) => {
  15. e.stopPropagation()
  16. rGroup.current.setPointerCapture(e.pointerId)
  17. state.send("POINTED_SHAPE", inputs.pointerDown(e, id))
  18. },
  19. [id]
  20. )
  21. const handlePointerUp = useCallback(
  22. (e: React.PointerEvent) => {
  23. e.stopPropagation()
  24. rGroup.current.releasePointerCapture(e.pointerId)
  25. state.send("STOPPED_POINTING", inputs.pointerUp(e))
  26. },
  27. [id]
  28. )
  29. const handlePointerEnter = useCallback(
  30. (e: React.PointerEvent) => {
  31. state.send("HOVERED_SHAPE", inputs.pointerEnter(e, id))
  32. },
  33. [id, shape]
  34. )
  35. const handlePointerMove = useCallback(
  36. (e: React.PointerEvent) => {
  37. state.send("MOVED_OVER_SHAPE", inputs.pointerEnter(e, id))
  38. },
  39. [id, shape]
  40. )
  41. const handlePointerLeave = useCallback(
  42. () => state.send("UNHOVERED_SHAPE", { target: id }),
  43. [id]
  44. )
  45. return (
  46. <StyledGroup
  47. ref={rGroup}
  48. isHovered={isHovered}
  49. isSelected={isSelected}
  50. transform={`translate(${shape.point})`}
  51. onPointerDown={handlePointerDown}
  52. onPointerUp={handlePointerUp}
  53. onPointerEnter={handlePointerEnter}
  54. onPointerLeave={handlePointerLeave}
  55. onPointerMove={handlePointerMove}
  56. >
  57. <defs>{getShapeUtils(shape).render(shape)}</defs>
  58. <HoverIndicator as="use" xlinkHref={"#" + id} />
  59. <MainShape as="use" xlinkHref={"#" + id} {...shape.style} />
  60. <Indicator as="use" xlinkHref={"#" + id} />
  61. </StyledGroup>
  62. )
  63. }
  64. const MainShape = styled("use", {
  65. zStrokeWidth: 1,
  66. })
  67. const Indicator = styled("path", {
  68. fill: "none",
  69. stroke: "transparent",
  70. zStrokeWidth: 1,
  71. pointerEvents: "none",
  72. strokeLineCap: "round",
  73. strokeLinejoin: "round",
  74. })
  75. const HoverIndicator = styled("path", {
  76. fill: "none",
  77. stroke: "transparent",
  78. zStrokeWidth: [8, 4],
  79. pointerEvents: "all",
  80. strokeLinecap: "round",
  81. strokeLinejoin: "round",
  82. transform: "all .2s",
  83. })
  84. const StyledGroup = styled("g", {
  85. [`& ${HoverIndicator}`]: {
  86. opacity: "0",
  87. },
  88. variants: {
  89. isSelected: {
  90. true: {
  91. [`& ${Indicator}`]: {
  92. stroke: "$selected",
  93. },
  94. },
  95. false: {},
  96. },
  97. isHovered: {
  98. true: {},
  99. false: {},
  100. },
  101. },
  102. compoundVariants: [
  103. {
  104. isSelected: true,
  105. isHovered: true,
  106. css: {
  107. [`& ${HoverIndicator}`]: {
  108. opacity: "1",
  109. stroke: "$hint",
  110. zStrokeWidth: [8, 4],
  111. },
  112. },
  113. },
  114. {
  115. isSelected: true,
  116. isHovered: false,
  117. css: {
  118. [`& ${HoverIndicator}`]: {
  119. opacity: "1",
  120. stroke: "$hint",
  121. zStrokeWidth: [6, 3],
  122. },
  123. },
  124. },
  125. {
  126. isSelected: false,
  127. isHovered: true,
  128. css: {
  129. [`& ${HoverIndicator}`]: {
  130. opacity: "1",
  131. stroke: "$hint",
  132. zStrokeWidth: [8, 4],
  133. },
  134. },
  135. },
  136. ],
  137. })
  138. export { Indicator, HoverIndicator }
  139. export default memo(Shape)