@searpent/react-image-annotate 2.0.77 → 2.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/Annotator/exampleImages.js +41 -0
  2. package/Annotator/examplePhotos.js +6980 -0
  3. package/Annotator/index.js +417 -0
  4. package/Annotator/reducers/combine-reducers.js +14 -0
  5. package/Annotator/reducers/convert-expanding-line-to-polygon.js +73 -0
  6. package/{src/Annotator → Annotator}/reducers/fix-twisted.js +3 -5
  7. package/Annotator/reducers/general-reducer.js +1430 -0
  8. package/Annotator/reducers/get-active-image.js +27 -0
  9. package/Annotator/reducers/get-implied-video-regions.js +180 -0
  10. package/Annotator/reducers/history-handler.js +38 -0
  11. package/Annotator/reducers/image-reducer.js +20 -0
  12. package/Annotator/reducers/video-reducer.js +88 -0
  13. package/ClassSelectionMenu/index.js +140 -0
  14. package/Crosshairs/index.js +53 -0
  15. package/DebugSidebarBox/index.js +20 -0
  16. package/DemoSite/Editor.js +194 -0
  17. package/DemoSite/ErrorBoundaryDialog.js +64 -0
  18. package/DemoSite/index.js +40 -0
  19. package/Editor/annotation-plugin/annotation.js +697 -0
  20. package/Editor/index.js +93 -0
  21. package/Editor/readOnly.js +123 -0
  22. package/{src/Editor → Editor}/tools.js +2 -3
  23. package/Errorer/index.js +11 -0
  24. package/FullImageSegmentationAnnotator/index.js +7 -0
  25. package/GroupSelectorSidebarBox/index.js +63 -0
  26. package/GroupsEditorSidebarBox/index.js +138 -0
  27. package/HelpSidebarBox/index.js +58 -0
  28. package/HighlightBox/index.js +102 -0
  29. package/HistorySidebarBox/index.js +71 -0
  30. package/ImageCanvas/index.js +441 -0
  31. package/ImageCanvas/region-tools.js +165 -0
  32. package/{src/ImageCanvas → ImageCanvas}/styles.js +12 -8
  33. package/ImageCanvas/use-mouse.js +180 -0
  34. package/ImageCanvas/use-project-box.js +27 -0
  35. package/ImageCanvas/use-wasd-mode.js +62 -0
  36. package/ImageMask/index.js +133 -0
  37. package/ImageMask/load-image.js +25 -0
  38. package/ImageSelectorSidebarBox/index.js +60 -0
  39. package/KeyframeTimeline/get-time-string.js +27 -0
  40. package/KeyframeTimeline/index.js +233 -0
  41. package/KeyframesSelectorSidebarBox/index.js +93 -0
  42. package/LandingPage/index.js +159 -0
  43. package/Locker/index.js +11 -0
  44. package/MainLayout/RightSidebarItemsWrapper.js +19 -0
  45. package/MainLayout/icon-dictionary.js +104 -0
  46. package/MainLayout/index.js +526 -0
  47. package/{src/MainLayout → MainLayout}/styles.js +6 -7
  48. package/MainLayout/types.js +0 -0
  49. package/MainLayout/use-implied-video-regions.js +13 -0
  50. package/MetadataEditorSidebarBox/index.js +231 -0
  51. package/PageSelector/index.js +180 -0
  52. package/PointDistances/index.js +73 -0
  53. package/PreventScrollToParents/index.js +51 -0
  54. package/RegionLabel/index.js +232 -0
  55. package/{src/RegionLabel → RegionLabel}/styles.js +12 -15
  56. package/RegionSelectAndTransformBoxes/index.js +169 -0
  57. package/RegionSelectorSidebarBox/index.js +254 -0
  58. package/{src/RegionSelectorSidebarBox → RegionSelectorSidebarBox}/styles.js +13 -14
  59. package/RegionShapes/index.js +294 -0
  60. package/RegionTags/index.js +144 -0
  61. package/SettingsDialog/index.js +52 -0
  62. package/SettingsProvider/index.js +60 -0
  63. package/Shortcuts/ShortcutField.js +46 -0
  64. package/Shortcuts/index.js +133 -0
  65. package/ShortcutsManager/index.js +155 -0
  66. package/Sidebar/index.js +69 -0
  67. package/SidebarBoxContainer/index.js +93 -0
  68. package/SmallToolButton/index.js +42 -0
  69. package/TagsSidebarBox/index.js +105 -0
  70. package/TaskDescriptionSidebarBox/index.js +58 -0
  71. package/Theme/index.js +30 -0
  72. package/VideoOrImageCanvasBackground/index.js +151 -0
  73. package/colors.js +14 -0
  74. package/hooks/use-colors.js +127 -0
  75. package/hooks/use-event-callback.js +10 -0
  76. package/hooks/use-exclude-pattern.js +24 -0
  77. package/hooks/use-load-image.js +26 -0
  78. package/hooks/use-window-size.js +46 -0
  79. package/{src/hooks → hooks}/xpattern.js +1 -1
  80. package/index.js +3 -0
  81. package/lib.js +3 -0
  82. package/package.json +1 -1
  83. package/stories.js +5 -0
  84. package/utils/blocks-to-article.js +60 -0
  85. package/{src/utils → utils}/blocks-to-article.test.js +5 -8
  86. package/{src/utils → utils}/default-locked-until.js +2 -1
  87. package/{src/utils → utils}/filter-only-unique.js +1 -1
  88. package/utils/get-from-local-storage.js +7 -0
  89. package/utils/get-hotkey-help-text.js +9 -0
  90. package/utils/get-landmarks-with-transform.js +40 -0
  91. package/utils/photosToImages.js +85 -0
  92. package/utils/regions-groups.js +28 -0
  93. package/utils/regions-to-blocks.js +18 -0
  94. package/utils/saveable-actions-enum.js +3 -0
  95. package/utils/set-in-local-storage.js +3 -0
  96. package/utils/sleep.js +7 -0
  97. package/utils/uuid-to-hash.js +5 -0
  98. package/.babelrc +0 -6
  99. package/.env +0 -1
  100. package/.flowconfig +0 -2
  101. package/.github/workflows/release-on-master.yml +0 -32
  102. package/.github/workflows/test.yml +0 -16
  103. package/.prettierrc +0 -3
  104. package/.releaserc.js +0 -18
  105. package/.storybook/addons.js +0 -2
  106. package/.storybook/config.js +0 -16
  107. package/LICENSE +0 -21
  108. package/public/favicon.ico +0 -0
  109. package/public/index.html +0 -38
  110. package/src/Annotator/bike-pic.png +0 -0
  111. package/src/Annotator/bike-pic2.png +0 -0
  112. package/src/Annotator/dab-keyframes.story.json +0 -1
  113. package/src/Annotator/exampleImages.js +0 -48
  114. package/src/Annotator/examplePhotos.js +0 -7603
  115. package/src/Annotator/index.js +0 -380
  116. package/src/Annotator/index.story.js +0 -899
  117. package/src/Annotator/poses.story.js +0 -150
  118. package/src/Annotator/reducers/combine-reducers.js +0 -7
  119. package/src/Annotator/reducers/convert-expanding-line-to-polygon.js +0 -53
  120. package/src/Annotator/reducers/general-reducer.js +0 -1228
  121. package/src/Annotator/reducers/get-active-image.js +0 -21
  122. package/src/Annotator/reducers/get-implied-video-regions.js +0 -115
  123. package/src/Annotator/reducers/history-handler.js +0 -60
  124. package/src/Annotator/reducers/image-reducer.js +0 -23
  125. package/src/Annotator/reducers/video-reducer.js +0 -85
  126. package/src/Annotator/video.story.js +0 -51
  127. package/src/ClassSelectionMenu/index.js +0 -112
  128. package/src/Crosshairs/index.js +0 -64
  129. package/src/DebugSidebarBox/index.js +0 -36
  130. package/src/DemoSite/Editor.js +0 -235
  131. package/src/DemoSite/ErrorBoundaryDialog.js +0 -34
  132. package/src/DemoSite/index.js +0 -41
  133. package/src/DemoSite/index.story.js +0 -10
  134. package/src/DemoSite/simple-segmentation-example.json +0 -572
  135. package/src/Editor/annotation-plugin/annotation.js +0 -546
  136. package/src/Editor/index.js +0 -50
  137. package/src/Editor/readOnly.js +0 -31
  138. package/src/Errorer/index.js +0 -13
  139. package/src/FullImageSegmentationAnnotator/hard1.story.jpg +0 -0
  140. package/src/FullImageSegmentationAnnotator/hard2.story.jpg +0 -0
  141. package/src/FullImageSegmentationAnnotator/hard3.story.jpg +0 -0
  142. package/src/FullImageSegmentationAnnotator/index.js +0 -7
  143. package/src/FullImageSegmentationAnnotator/index.story.js +0 -177
  144. package/src/FullImageSegmentationAnnotator/orange.story.png +0 -0
  145. package/src/GroupSelectorSidebarBox/index.js +0 -48
  146. package/src/GroupsEditorSidebarBox/index.js +0 -108
  147. package/src/HelpSidebarBox/index.js +0 -43
  148. package/src/HighlightBox/index.js +0 -143
  149. package/src/HistorySidebarBox/index.js +0 -78
  150. package/src/ImageCanvas/dancing-man.story.jpg +0 -0
  151. package/src/ImageCanvas/index.js +0 -515
  152. package/src/ImageCanvas/index.story.js +0 -314
  153. package/src/ImageCanvas/mouse_mask.story.png +0 -0
  154. package/src/ImageCanvas/region-tools.js +0 -171
  155. package/src/ImageCanvas/seves_desk.story.jpg +0 -0
  156. package/src/ImageCanvas/use-mouse.js +0 -168
  157. package/src/ImageCanvas/use-project-box.js +0 -23
  158. package/src/ImageCanvas/use-wasd-mode.js +0 -50
  159. package/src/ImageMask/index.js +0 -127
  160. package/src/ImageMask/load-image.js +0 -32
  161. package/src/ImageSelectorSidebarBox/index.js +0 -54
  162. package/src/KeyframeTimeline/get-time-string.js +0 -25
  163. package/src/KeyframeTimeline/index.js +0 -223
  164. package/src/KeyframesSelectorSidebarBox/index.js +0 -93
  165. package/src/LandingPage/content.md +0 -57
  166. package/src/LandingPage/github-markdown.css +0 -964
  167. package/src/LandingPage/index.js +0 -147
  168. package/src/Locker/index.js +0 -13
  169. package/src/MainLayout/RightSidebarItemsWrapper.js +0 -21
  170. package/src/MainLayout/icon-dictionary.js +0 -79
  171. package/src/MainLayout/index.js +0 -564
  172. package/src/MainLayout/index.story.js +0 -240
  173. package/src/MainLayout/types.js +0 -171
  174. package/src/MainLayout/use-implied-video-regions.js +0 -17
  175. package/src/MetadataEditorSidebarBox/index.js +0 -160
  176. package/src/PageSelector/index.js +0 -159
  177. package/src/PointDistances/index.js +0 -90
  178. package/src/PreventScrollToParents/index.js +0 -48
  179. package/src/PreventScrollToParents/index.story.js +0 -23
  180. package/src/RegionLabel/index.js +0 -236
  181. package/src/RegionSelectAndTransformBoxes/index.js +0 -236
  182. package/src/RegionSelectorSidebarBox/index.js +0 -220
  183. package/src/RegionShapes/index.js +0 -254
  184. package/src/RegionTags/index.js +0 -136
  185. package/src/SettingsDialog/index.js +0 -58
  186. package/src/SettingsProvider/index.js +0 -57
  187. package/src/Shortcuts/ShortcutField.js +0 -44
  188. package/src/Shortcuts/index.js +0 -129
  189. package/src/ShortcutsManager/index.js +0 -162
  190. package/src/Sidebar/index.js +0 -117
  191. package/src/SidebarBoxContainer/index.js +0 -93
  192. package/src/SmallToolButton/index.js +0 -57
  193. package/src/TagsSidebarBox/index.js +0 -93
  194. package/src/TaskDescriptionSidebarBox/index.js +0 -43
  195. package/src/Theme/index.js +0 -36
  196. package/src/VideoOrImageCanvasBackground/index.js +0 -170
  197. package/src/colors.js +0 -32
  198. package/src/hooks/use-colors.js +0 -95
  199. package/src/hooks/use-event-callback.js +0 -11
  200. package/src/hooks/use-exclude-pattern.js +0 -27
  201. package/src/hooks/use-load-image.js +0 -21
  202. package/src/hooks/use-window-size.js +0 -46
  203. package/src/hooks/xpattern.png +0 -0
  204. package/src/index.js +0 -18
  205. package/src/lib.js +0 -7
  206. package/src/screenshot.png +0 -0
  207. package/src/site.css +0 -5
  208. package/src/stories.js +0 -2
  209. package/src/utils/blocks-to-article.js +0 -61
  210. package/src/utils/get-from-local-storage.js +0 -7
  211. package/src/utils/get-hotkey-help-text.js +0 -11
  212. package/src/utils/get-landmarks-with-transform.js +0 -23
  213. package/src/utils/photosToImages.js +0 -67
  214. package/src/utils/regions-groups.js +0 -19
  215. package/src/utils/regions-to-blocks.js +0 -16
  216. package/src/utils/saveable-actions-enum.js +0 -5
  217. package/src/utils/set-in-local-storage.js +0 -6
  218. package/src/utils/sleep.js +0 -3
  219. package/src/utils/uuid-to-hash.js +0 -5
  220. /package/{src/Editor → Editor}/annotation-plugin/annotation.css +0 -0
  221. /package/{src/Errorer → Errorer}/errorer.css +0 -0
  222. /package/{src/Locker → Locker}/locker.css +0 -0
  223. /package/{src/PageSelector → PageSelector}/page-selector.css +0 -0
  224. /package/{src/utils → utils}/next-group-id.js +0 -0
@@ -1,236 +0,0 @@
1
- import React, { Fragment, memo } from "react"
2
- import HighlightBox from "../HighlightBox"
3
- import { styled } from "@mui/material/styles"
4
- import { createTheme, ThemeProvider } from "@mui/material/styles"
5
- import PreventScrollToParents from "../PreventScrollToParents"
6
- import Tooltip from "@mui/material/Tooltip"
7
-
8
- const theme = createTheme()
9
- const TransformGrabber = styled("div")(({ theme }) => ({
10
- width: 8,
11
- height: 8,
12
- zIndex: 10,
13
- backgroundColor: "#454545",
14
- border: "2px solid black",
15
- borderRadius: "50%",
16
- position: "absolute",
17
- }))
18
-
19
- const boxCursorMap = [
20
- ["nw-resize", "n-resize", "ne-resize"],
21
- ["w-resize", "grab", "e-resize"],
22
- ["sw-resize", "s-resize", "se-resize"],
23
- ]
24
-
25
- const arePropsEqual = (prev, next) => {
26
- return (
27
- prev.region === next.region &&
28
- prev.dragWithPrimary === next.dragWithPrimary &&
29
- prev.createWithPrimary === next.createWithPrimary &&
30
- prev.zoomWithPrimary === next.zoomWithPrimary &&
31
- prev.mat === next.mat
32
- )
33
- }
34
-
35
- export const RegionSelectAndTransformBox = memo(
36
- ({
37
- region: r,
38
- mouseEvents,
39
- projectRegionBox,
40
- dragWithPrimary,
41
- createWithPrimary,
42
- zoomWithPrimary,
43
- onBeginMovePoint,
44
- onSelectRegion,
45
- layoutParams,
46
- fullImageSegmentationMode = false,
47
- mat,
48
- onBeginBoxTransform,
49
- onBeginMovePolygonPoint,
50
- onBeginMoveKeypoint,
51
- onAddPolygonPoint,
52
- showHighlightBox,
53
- }) => {
54
- const pbox = projectRegionBox(r)
55
- const { iw, ih } = layoutParams.current
56
- return (
57
- <ThemeProvider theme={theme}>
58
- <Fragment>
59
- <PreventScrollToParents>
60
- {showHighlightBox && r.type !== "polygon" && (
61
- <HighlightBox
62
- region={r}
63
- mouseEvents={mouseEvents}
64
- dragWithPrimary={dragWithPrimary}
65
- createWithPrimary={createWithPrimary}
66
- zoomWithPrimary={zoomWithPrimary}
67
- onBeginMovePoint={onBeginMovePoint}
68
- onSelectRegion={onSelectRegion}
69
- pbox={pbox}
70
- />
71
- )}
72
- {r.type === "box" &&
73
- !dragWithPrimary &&
74
- !zoomWithPrimary &&
75
- !r.locked &&
76
- r.highlighted &&
77
- mat.a < 1.2 &&
78
- [
79
- [0, 0],
80
- [0.5, 0],
81
- [1, 0],
82
- [1, 0.5],
83
- [1, 1],
84
- [0.5, 1],
85
- [0, 1],
86
- [0, 0.5],
87
- [0.5, 0.5],
88
- ].map(([px, py], i) => (
89
- <TransformGrabber
90
- key={i}
91
- {...mouseEvents}
92
- onMouseDown={(e) => {
93
- if (e.button === 0)
94
- return onBeginBoxTransform(r, [px * 2 - 1, py * 2 - 1])
95
- mouseEvents.onMouseDown(e)
96
- }}
97
- style={{
98
- left: pbox.x - 4 - 2 + pbox.w * px,
99
- top: pbox.y - 4 - 2 + pbox.h * py,
100
- cursor: boxCursorMap[py * 2][px * 2],
101
- borderRadius: px === 0.5 && py === 0.5 ? 4 : undefined,
102
- }}
103
- />
104
- ))}
105
- {r.type === "polygon" &&
106
- !dragWithPrimary &&
107
- !zoomWithPrimary &&
108
- !r.locked &&
109
- r.highlighted &&
110
- r.points.map(([px, py], i) => {
111
- const proj = mat
112
- .clone()
113
- .inverse()
114
- .applyToPoint(px * iw, py * ih)
115
- return (
116
- <TransformGrabber
117
- key={i}
118
- {...mouseEvents}
119
- onMouseDown={(e) => {
120
- if (e.button === 0 && (!r.open || i === 0))
121
- return onBeginMovePolygonPoint(r, i)
122
- mouseEvents.onMouseDown(e)
123
- }}
124
- style={{
125
- cursor: !r.open
126
- ? "move"
127
- : i === 0
128
- ? "pointer"
129
- : undefined,
130
- zIndex: 10,
131
- pointerEvents:
132
- r.open && i === r.points.length - 1
133
- ? "none"
134
- : undefined,
135
- left: proj.x - 4,
136
- top: proj.y - 4,
137
- }}
138
- />
139
- )
140
- })}
141
- {r.type === "polygon" &&
142
- r.highlighted &&
143
- !dragWithPrimary &&
144
- !zoomWithPrimary &&
145
- !r.locked &&
146
- !r.open &&
147
- r.points.length > 1 &&
148
- r.points
149
- .map((p1, i) => [p1, r.points[(i + 1) % r.points.length]])
150
- .map(([p1, p2]) => [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2])
151
- .map((pa, i) => {
152
- const proj = mat
153
- .clone()
154
- .inverse()
155
- .applyToPoint(pa[0] * iw, pa[1] * ih)
156
- return (
157
- <TransformGrabber
158
- key={i}
159
- {...mouseEvents}
160
- onMouseDown={(e) => {
161
- if (e.button === 0)
162
- return onAddPolygonPoint(r, pa, i + 1)
163
- mouseEvents.onMouseDown(e)
164
- }}
165
- style={{
166
- cursor: "copy",
167
- zIndex: 10,
168
- left: proj.x - 4,
169
- top: proj.y - 4,
170
- border: "2px dotted #fff",
171
- opacity: 0.5,
172
- }}
173
- />
174
- )
175
- })}
176
- {r.type === "keypoints" &&
177
- !dragWithPrimary &&
178
- !zoomWithPrimary &&
179
- !r.locked &&
180
- r.highlighted &&
181
- Object.entries(r.points).map(
182
- ([keypointId, { x: px, y: py }], i) => {
183
- const proj = mat
184
- .clone()
185
- .inverse()
186
- .applyToPoint(px * iw, py * ih)
187
- return (
188
- <Tooltip title={keypointId} key={i}>
189
- <TransformGrabber
190
- key={i}
191
- {...mouseEvents}
192
- onMouseDown={(e) => {
193
- if (e.button === 0 && (!r.open || i === 0))
194
- return onBeginMoveKeypoint(r, keypointId)
195
- mouseEvents.onMouseDown(e)
196
- }}
197
- style={{
198
- cursor: !r.open
199
- ? "move"
200
- : i === 0
201
- ? "pointer"
202
- : undefined,
203
- zIndex: 10,
204
- pointerEvents:
205
- r.open && i === r.points.length - 1
206
- ? "none"
207
- : undefined,
208
- left: proj.x - 4,
209
- top: proj.y - 4,
210
- }}
211
- />
212
- </Tooltip>
213
- )
214
- }
215
- )}
216
- </PreventScrollToParents>
217
- </Fragment>
218
- </ThemeProvider>
219
- )
220
- },
221
- arePropsEqual
222
- )
223
-
224
- export const RegionSelectAndTransformBoxes = memo(
225
- (props) => {
226
- return props.regions
227
- .filter((r) => r.visible || r.visible === undefined)
228
- .filter((r) => !r.locked)
229
- .map((r, i) => {
230
- return <RegionSelectAndTransformBox key={r.id} {...props} region={r} />
231
- })
232
- },
233
- (n, p) => n.regions === p.regions && n.mat === p.mat
234
- )
235
-
236
- export default RegionSelectAndTransformBoxes
@@ -1,220 +0,0 @@
1
- // @flow
2
-
3
- import React, { Fragment, useState, memo } from "react"
4
- import SidebarBoxContainer from "../SidebarBoxContainer"
5
- import { makeStyles } from "@mui/styles"
6
- import { createTheme, ThemeProvider } from "@mui/material/styles"
7
- import { styled } from "@mui/material/styles"
8
- import { grey } from "@mui/material/colors"
9
- import RegionIcon from "@mui/icons-material/PictureInPicture"
10
- import Grid from "@mui/material/Grid"
11
- import ReorderIcon from "@mui/icons-material/SwapVert"
12
- import PieChartIcon from "@mui/icons-material/PieChart"
13
- import TrashIcon from "@mui/icons-material/Delete"
14
- import LockIcon from "@mui/icons-material/Lock"
15
- import UnlockIcon from "@mui/icons-material/LockOpen"
16
- import VisibleIcon from "@mui/icons-material/Visibility"
17
- import VisibleOffIcon from "@mui/icons-material/VisibilityOff"
18
- import styles from "./styles"
19
- import classnames from "classnames"
20
- import isEqual from "lodash/isEqual"
21
- import useColors from "../hooks/use-colors"
22
-
23
- const theme = createTheme()
24
- const useStyles = makeStyles((theme) => styles)
25
-
26
- const HeaderSep = styled("div")(({ theme }) => ({
27
- borderTop: `1px solid ${grey[200]}`,
28
- marginTop: 2,
29
- marginBottom: 2,
30
- }))
31
-
32
- const Chip = ({ color, text }) => {
33
- const classes = useStyles()
34
- return (
35
- <span className={classes.chip}>
36
- <div className="color" style={{ backgroundColor: color }} />
37
- <div className="text">{text}</div>
38
- </span>
39
- )
40
- }
41
-
42
- const RowLayout = ({
43
- header,
44
- highlighted,
45
- order,
46
- classification,
47
- area,
48
- tags,
49
- trash,
50
- lock,
51
- visible,
52
- onClick,
53
- }) => {
54
- const classes = useStyles()
55
- const [mouseOver, changeMouseOver] = useState(false)
56
- return (
57
- <div
58
- onClick={onClick}
59
- onMouseEnter={() => changeMouseOver(true)}
60
- onMouseLeave={() => changeMouseOver(false)}
61
- className={classnames(classes.row, { header, highlighted })}
62
- >
63
- <Grid container alignItems="center">
64
- <Grid item xs={2}>
65
- <div style={{ textAlign: "right", paddingRight: 10 }}>{order}</div>
66
- </Grid>
67
- <Grid item xs={5}>
68
- {classification}
69
- </Grid>
70
- <Grid item xs={2}>
71
- <div style={{ textAlign: "right", paddingRight: 6 }}>{area}</div>
72
- </Grid>
73
- <Grid item xs={1}>
74
- {trash}
75
- </Grid>
76
- <Grid item xs={1}>
77
- {lock}
78
- </Grid>
79
- <Grid item xs={1}>
80
- {visible}
81
- </Grid>
82
- </Grid>
83
- </div>
84
- )
85
- }
86
-
87
- const RowHeader = () => {
88
- return (
89
- <RowLayout
90
- header
91
- highlighted={false}
92
- order={<ReorderIcon className="icon" />}
93
- classification={<div style={{ paddingLeft: 10 }}>Class</div>}
94
- area={<PieChartIcon className="icon" />}
95
- trash={<TrashIcon className="icon" />}
96
- lock={<LockIcon className="icon" />}
97
- visible={<VisibleIcon className="icon" />}
98
- />
99
- )
100
- }
101
-
102
- const MemoRowHeader = memo(RowHeader)
103
-
104
- const Row = ({
105
- region: r,
106
- highlighted,
107
- onSelectRegion,
108
- onDeleteRegion,
109
- onChangeRegion,
110
- visible,
111
- locked,
112
- color,
113
- cls,
114
- index,
115
- }) => {
116
- const { groupColor } = useColors()
117
- const gc = groupColor(r.groupId)
118
-
119
- return (
120
- <RowLayout
121
- header={false}
122
- highlighted={highlighted}
123
- onClick={() => onSelectRegion(r)}
124
- order={`#${index + 1}`}
125
- classification={<Chip text={cls || ""} color={color || gc || "lime"} />}
126
- area=""
127
- trash={<TrashIcon onClick={() => onDeleteRegion(r)} className="icon2" />}
128
- lock={
129
- r.locked ? (
130
- <LockIcon
131
- onClick={() => onChangeRegion({ ...r, locked: false })}
132
- className="icon2"
133
- />
134
- ) : (
135
- <UnlockIcon
136
- onClick={() => onChangeRegion({ ...r, locked: true })}
137
- className="icon2"
138
- />
139
- )
140
- }
141
- visible={
142
- r.visible || r.visible === undefined ? (
143
- <VisibleIcon
144
- onClick={() => onChangeRegion({ ...r, visible: false })}
145
- className="icon2"
146
- />
147
- ) : (
148
- <VisibleOffIcon
149
- onClick={() => onChangeRegion({ ...r, visible: true })}
150
- className="icon2"
151
- />
152
- )
153
- }
154
- />
155
- )
156
- }
157
-
158
- const MemoRow = memo(
159
- Row,
160
- (prevProps, nextProps) =>
161
- prevProps.highlighted === nextProps.highlighted &&
162
- prevProps.visible === nextProps.visible &&
163
- prevProps.locked === nextProps.locked &&
164
- prevProps.id === nextProps.id &&
165
- prevProps.index === nextProps.index &&
166
- prevProps.cls === nextProps.cls &&
167
- prevProps.color === nextProps.color
168
- )
169
-
170
- const emptyArr = []
171
-
172
- export const RegionSelectorSidebarBox = ({
173
- regions = emptyArr,
174
- onDeleteRegion,
175
- onChangeRegion,
176
- onSelectRegion,
177
- }) => {
178
- const classes = useStyles()
179
- return (
180
- <ThemeProvider theme={theme}>
181
- <SidebarBoxContainer
182
- title="Regions"
183
- subTitle=""
184
- icon={<RegionIcon style={{ color: grey[700] }} />}
185
- expandedByDefault
186
- >
187
- <div className={classes.container}>
188
- <MemoRowHeader />
189
- <HeaderSep />
190
- {regions.map((r, i) => (
191
- <MemoRow
192
- key={r.id}
193
- {...r}
194
- region={r}
195
- index={i}
196
- onSelectRegion={onSelectRegion}
197
- onDeleteRegion={onDeleteRegion}
198
- onChangeRegion={onChangeRegion}
199
- />
200
- ))}
201
- </div>
202
- </SidebarBoxContainer>
203
- </ThemeProvider>
204
- )
205
- }
206
-
207
- const mapUsedRegionProperties = (r) => [
208
- r.id,
209
- r.color,
210
- r.locked,
211
- r.visible,
212
- r.highlighted,
213
- ]
214
-
215
- export default memo(RegionSelectorSidebarBox, (prevProps, nextProps) =>
216
- isEqual(
217
- (prevProps.regions || emptyArr).map(mapUsedRegionProperties),
218
- (nextProps.regions || emptyArr).map(mapUsedRegionProperties)
219
- )
220
- )
@@ -1,254 +0,0 @@
1
- // @flow
2
-
3
- import React, { memo } from "react"
4
- import colorAlpha from "color-alpha"
5
- import useColors from '../hooks/use-colors';
6
-
7
-
8
- function clamp(num, min, max) {
9
- return num <= min ? min : num >= max ? max : num
10
- }
11
-
12
- const RegionComponents = {
13
- point: memo(({ region, iw, ih }) => (
14
- <g transform={`translate(${region.x * iw} ${region.y * ih})`}>
15
- <path
16
- d={"M0 8L8 0L0 -8L-8 0Z"}
17
- strokeWidth={2}
18
- stroke={region.color}
19
- fill="transparent"
20
- />
21
- </g>
22
- )),
23
- line: memo(({ region, iw, ih }) => (
24
- <g transform={`translate(${region.x1 * iw} ${region.y1 * ih})`}>
25
- <line
26
- strokeWidth={2}
27
- x1={0}
28
- y1={0}
29
- x2={(region.x2 - region.x1) * iw}
30
- y2={(region.y2 - region.y1) * ih}
31
- stroke={colorAlpha(region.color, 0.75)}
32
- fill={colorAlpha(region.color, 0.25)}
33
- />
34
- </g>
35
- )),
36
- box: memo(({ region, iw, ih }) => {
37
- const { clsColor, groupColor } = useColors();
38
-
39
- if (region.groupId !== undefined) {
40
- return <g transform={`translate(${region.x * iw} ${region.y * ih})`}>
41
- <rect
42
- strokeWidth={(region.groupHighlighted) ? 3 : 0}
43
- x={0}
44
- y={0}
45
- width={Math.max(region.w * iw, 0)}
46
- height={Math.max(region.h * ih, 0)}
47
- stroke={colorAlpha(clsColor(region.cls), 0.85)}
48
- fill={(region.groupHighlighted) ? colorAlpha(clsColor(region.cls), 0.15) : colorAlpha(groupColor(region.groupId), 0.5)}
49
- />
50
- </g>
51
- } else {
52
- return <g transform={`translate(${region.x * iw} ${region.y * ih})`}>
53
- <rect
54
- strokeWidth={2}
55
- x={0}
56
- y={0}
57
- width={Math.max(region.w * iw, 0)}
58
- height={Math.max(region.h * ih, 0)}
59
- stroke={colorAlpha(clsColor(region.cls), 0.85)}
60
- fill={colorAlpha(clsColor(region.cls), 0.85)}
61
- />
62
- </g>
63
- }
64
- }
65
- ),
66
- polygon: memo(({ region, iw, ih, fullSegmentationMode }) => {
67
- const Component = region.open ? "polyline" : "polygon"
68
- const alphaBase = fullSegmentationMode ? 0.5 : 1
69
- return (
70
- <Component
71
- points={region.points
72
- .map(([x, y]) => [x * iw, y * ih])
73
- .map((a) => a.join(" "))
74
- .join(" ")}
75
- strokeWidth={2}
76
- stroke={colorAlpha(region.color, 0.75)}
77
- fill={colorAlpha(region.color, 0.25)}
78
- />
79
- )
80
- }),
81
- keypoints: ({ region, iw, ih, keypointDefinitions }) => {
82
- const { points, keypointsDefinitionId } = region
83
- if (!keypointDefinitions[keypointsDefinitionId]) {
84
- throw new Error(
85
- `No definition for keypoint configuration "${keypointsDefinitionId}"`
86
- )
87
- }
88
- const { landmarks, connections } =
89
- keypointDefinitions[keypointsDefinitionId]
90
- return (
91
- <g>
92
- {Object.entries(points).map(([keypointId, { x, y }], i) => (
93
- <g key={i} transform={`translate(${x * iw} ${y * ih})`}>
94
- <path
95
- d={"M0 8L8 0L0 -8L-8 0Z"}
96
- strokeWidth={2}
97
- stroke={landmarks[keypointId].color}
98
- fill="transparent"
99
- />
100
- </g>
101
- ))}
102
- {connections.map(([kp1Id, kp2Id]) => {
103
- const kp1 = points[kp1Id]
104
- const kp2 = points[kp2Id]
105
- const midPoint = { x: (kp1.x + kp2.x) / 2, y: (kp1.y + kp2.y) / 2 }
106
-
107
- return (
108
- <g key={`${kp1.x},${kp1.y}.${kp2.x},${kp2.y}`}>
109
- <line
110
- x1={kp1.x * iw}
111
- y1={kp1.y * ih}
112
- x2={midPoint.x * iw}
113
- y2={midPoint.y * ih}
114
- strokeWidth={2}
115
- stroke={landmarks[kp1Id].color}
116
- />
117
- <line
118
- x1={kp2.x * iw}
119
- y1={kp2.y * ih}
120
- x2={midPoint.x * iw}
121
- y2={midPoint.y * ih}
122
- strokeWidth={2}
123
- stroke={landmarks[kp2Id].color}
124
- />
125
- </g>
126
- )
127
- })}
128
- </g>
129
- )
130
- },
131
- "expanding-line": memo(({ region, iw, ih }) => {
132
- let { expandingWidth = 0.005, points } = region
133
- expandingWidth = points.slice(-1)[0].width || expandingWidth
134
- const pointPairs = points.map(({ x, y, angle, width }, i) => {
135
- if (!angle) {
136
- const n = points[clamp(i + 1, 0, points.length - 1)]
137
- const p = points[clamp(i - 1, 0, points.length - 1)]
138
- angle = Math.atan2(p.x - n.x, p.y - n.y) + Math.PI / 2
139
- }
140
- const dx = (Math.sin(angle) * (width || expandingWidth)) / 2
141
- const dy = (Math.cos(angle) * (width || expandingWidth)) / 2
142
- return [
143
- { x: x + dx, y: y + dy },
144
- { x: x - dx, y: y - dy },
145
- ]
146
- })
147
- const firstSection = pointPairs.map(([p1, p2]) => p1)
148
- const secondSection = pointPairs.map(([p1, p2]) => p2).asMutable()
149
- secondSection.reverse()
150
- const lastPoint = points.slice(-1)[0]
151
- return (
152
- <>
153
- <polygon
154
- points={firstSection
155
- .concat(region.candidatePoint ? [region.candidatePoint] : [])
156
- .concat(secondSection)
157
- .map((p) => `${p.x * iw} ${p.y * ih}`)
158
- .join(" ")}
159
- strokeWidth={2}
160
- stroke={colorAlpha(region.color, 0.75)}
161
- fill={colorAlpha(region.color, 0.25)}
162
- />
163
- {points.map(({ x, y, angle }, i) => (
164
- <g
165
- key={i}
166
- transform={`translate(${x * iw} ${y * ih}) rotate(${(-(angle || 0) * 180) / Math.PI
167
- })`}
168
- >
169
- <g>
170
- <rect
171
- x={-5}
172
- y={-5}
173
- width={10}
174
- height={10}
175
- strokeWidth={2}
176
- stroke={colorAlpha(region.color, 0.75)}
177
- fill={colorAlpha(region.color, 0.25)}
178
- />
179
- </g>
180
- </g>
181
- ))}
182
- <rect
183
- x={lastPoint.x * iw - 8}
184
- y={lastPoint.y * ih - 8}
185
- width={16}
186
- height={16}
187
- strokeWidth={4}
188
- stroke={colorAlpha(region.color, 0.5)}
189
- fill={"transparent"}
190
- />
191
- </>
192
- )
193
- }),
194
- pixel: () => null,
195
- }
196
-
197
- export const WrappedRegionList = memo(
198
- ({ regions, keypointDefinitions, iw, ih, fullSegmentationMode }) => {
199
- return regions
200
- .filter((r) => r.visible !== false)
201
- .map((r) => {
202
- const Component = RegionComponents[r.type]
203
- return (
204
- <Component
205
- key={r.id}
206
- region={r}
207
- iw={iw}
208
- ih={ih}
209
- keypointDefinitions={keypointDefinitions}
210
- fullSegmentationMode={fullSegmentationMode}
211
- />
212
- )
213
- })
214
- },
215
- (n, p) => n.regions === p.regions && n.iw === p.iw && n.ih === p.ih
216
- )
217
-
218
- export const RegionShapes = ({
219
- mat,
220
- imagePosition,
221
- regions = [],
222
- keypointDefinitions,
223
- fullSegmentationMode,
224
- }) => {
225
- const iw = imagePosition.bottomRight.x - imagePosition.topLeft.x
226
- const ih = imagePosition.bottomRight.y - imagePosition.topLeft.y
227
- if (isNaN(iw) || isNaN(ih)) return null
228
- return (
229
- <svg
230
- width={iw}
231
- height={ih}
232
- style={{
233
- position: "absolute",
234
- zIndex: 2,
235
- left: imagePosition.topLeft.x,
236
- top: imagePosition.topLeft.y,
237
- pointerEvents: "none",
238
- width: iw,
239
- height: ih,
240
- }}
241
- >
242
- <WrappedRegionList
243
- key="wrapped-region-list"
244
- regions={regions}
245
- iw={iw}
246
- ih={ih}
247
- keypointDefinitions={keypointDefinitions}
248
- fullSegmentationMode={fullSegmentationMode}
249
- />
250
- </svg>
251
- )
252
- }
253
-
254
- export default RegionShapes