@searpent/react-image-annotate 2.0.3 → 2.0.4

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 (187) hide show
  1. package/.babelrc +6 -0
  2. package/.env +1 -0
  3. package/.flowconfig +2 -0
  4. package/.github/workflows/release-on-master.yml +32 -0
  5. package/.github/workflows/test.yml +16 -0
  6. package/.prettierrc +3 -0
  7. package/.releaserc.js +18 -0
  8. package/.storybook/addons.js +2 -0
  9. package/.storybook/config.js +16 -0
  10. package/LICENSE +21 -0
  11. package/package.json +4 -1
  12. package/public/favicon.ico +0 -0
  13. package/public/index.html +38 -0
  14. package/src/Annotator/bike-pic.png +0 -0
  15. package/src/Annotator/bike-pic2.png +0 -0
  16. package/src/Annotator/dab-keyframes.story.json +1 -0
  17. package/src/Annotator/examplePhotos.js +7601 -0
  18. package/src/Annotator/index.js +291 -0
  19. package/src/Annotator/index.story.js +807 -0
  20. package/src/Annotator/poses.story.js +150 -0
  21. package/src/Annotator/reducers/combine-reducers.js +7 -0
  22. package/src/Annotator/reducers/convert-expanding-line-to-polygon.js +53 -0
  23. package/{Annotator → src/Annotator}/reducers/fix-twisted.js +5 -3
  24. package/src/Annotator/reducers/general-reducer.js +996 -0
  25. package/src/Annotator/reducers/get-active-image.js +21 -0
  26. package/src/Annotator/reducers/get-implied-video-regions.js +115 -0
  27. package/src/Annotator/reducers/history-handler.js +60 -0
  28. package/src/Annotator/reducers/image-reducer.js +23 -0
  29. package/src/Annotator/reducers/video-reducer.js +85 -0
  30. package/src/Annotator/video.story.js +51 -0
  31. package/src/ClassSelectionMenu/index.js +108 -0
  32. package/src/Crosshairs/index.js +64 -0
  33. package/src/DebugSidebarBox/index.js +36 -0
  34. package/src/DemoSite/Editor.js +235 -0
  35. package/src/DemoSite/ErrorBoundaryDialog.js +34 -0
  36. package/src/DemoSite/index.js +41 -0
  37. package/src/DemoSite/index.story.js +10 -0
  38. package/src/DemoSite/simple-segmentation-example.json +572 -0
  39. package/src/Editor/annotation-plugin/annotation.css +46 -0
  40. package/src/Editor/annotation-plugin/annotation.js +515 -0
  41. package/src/Editor/index.js +24 -0
  42. package/src/Editor/tools.js +6 -0
  43. package/src/FullImageSegmentationAnnotator/hard1.story.jpg +0 -0
  44. package/src/FullImageSegmentationAnnotator/hard2.story.jpg +0 -0
  45. package/src/FullImageSegmentationAnnotator/hard3.story.jpg +0 -0
  46. package/src/FullImageSegmentationAnnotator/index.js +7 -0
  47. package/src/FullImageSegmentationAnnotator/index.story.js +177 -0
  48. package/src/FullImageSegmentationAnnotator/orange.story.png +0 -0
  49. package/src/GroupSelectorSidebarBox/index.js +48 -0
  50. package/src/HighlightBox/index.js +143 -0
  51. package/src/HistorySidebarBox/index.js +78 -0
  52. package/src/ImageCanvas/dancing-man.story.jpg +0 -0
  53. package/src/ImageCanvas/index.js +494 -0
  54. package/src/ImageCanvas/index.story.js +314 -0
  55. package/src/ImageCanvas/mouse_mask.story.png +0 -0
  56. package/src/ImageCanvas/region-tools.js +171 -0
  57. package/src/ImageCanvas/seves_desk.story.jpg +0 -0
  58. package/{ImageCanvas → src/ImageCanvas}/styles.js +8 -12
  59. package/src/ImageCanvas/use-mouse.js +168 -0
  60. package/src/ImageCanvas/use-project-box.js +23 -0
  61. package/src/ImageCanvas/use-wasd-mode.js +50 -0
  62. package/src/ImageMask/index.js +127 -0
  63. package/src/ImageMask/load-image.js +32 -0
  64. package/src/ImageSelectorSidebarBox/index.js +54 -0
  65. package/src/KeyframeTimeline/get-time-string.js +25 -0
  66. package/src/KeyframeTimeline/index.js +223 -0
  67. package/src/KeyframesSelectorSidebarBox/index.js +93 -0
  68. package/src/LandingPage/content.md +57 -0
  69. package/src/LandingPage/github-markdown.css +964 -0
  70. package/src/LandingPage/index.js +147 -0
  71. package/src/MainLayout/icon-dictionary.js +79 -0
  72. package/src/MainLayout/index.js +510 -0
  73. package/src/MainLayout/index.story.js +240 -0
  74. package/{MainLayout → src/MainLayout}/styles.js +7 -6
  75. package/src/MainLayout/types.js +164 -0
  76. package/src/MainLayout/use-implied-video-regions.js +17 -0
  77. package/src/MetadataEditorSidebarBox/index.js +98 -0
  78. package/src/PageSelector/index.js +76 -0
  79. package/src/PageSelector/page-selector.css +69 -0
  80. package/src/PointDistances/index.js +90 -0
  81. package/src/PreventScrollToParents/index.js +48 -0
  82. package/src/PreventScrollToParents/index.story.js +23 -0
  83. package/src/RegionLabel/index.js +222 -0
  84. package/{RegionLabel → src/RegionLabel}/styles.js +15 -12
  85. package/src/RegionSelectAndTransformBoxes/index.js +234 -0
  86. package/src/RegionSelectorSidebarBox/index.js +216 -0
  87. package/{RegionSelectorSidebarBox → src/RegionSelectorSidebarBox}/styles.js +14 -13
  88. package/src/RegionShapes/index.js +254 -0
  89. package/src/RegionTags/index.js +134 -0
  90. package/src/SettingsDialog/index.js +58 -0
  91. package/src/SettingsProvider/index.js +48 -0
  92. package/src/Shortcuts/ShortcutField.js +44 -0
  93. package/src/Shortcuts/index.js +129 -0
  94. package/src/ShortcutsManager/index.js +162 -0
  95. package/src/Sidebar/index.js +117 -0
  96. package/src/SidebarBoxContainer/index.js +93 -0
  97. package/src/SmallToolButton/index.js +57 -0
  98. package/src/TagsSidebarBox/index.js +93 -0
  99. package/src/TaskDescriptionSidebarBox/index.js +43 -0
  100. package/src/Theme/index.js +36 -0
  101. package/src/VideoOrImageCanvasBackground/index.js +170 -0
  102. package/src/colors.js +32 -0
  103. package/src/hooks/use-colors.js +74 -0
  104. package/src/hooks/use-event-callback.js +11 -0
  105. package/src/hooks/use-exclude-pattern.js +27 -0
  106. package/src/hooks/use-load-image.js +21 -0
  107. package/src/hooks/use-window-size.js +46 -0
  108. package/{hooks → src/hooks}/xpattern.js +1 -1
  109. package/src/hooks/xpattern.png +0 -0
  110. package/src/index.js +18 -0
  111. package/src/lib.js +7 -0
  112. package/src/screenshot.png +0 -0
  113. package/src/site.css +5 -0
  114. package/src/stories.js +2 -0
  115. package/src/utils/filter-only-unique.js +5 -0
  116. package/src/utils/get-from-local-storage.js +7 -0
  117. package/src/utils/get-hotkey-help-text.js +11 -0
  118. package/src/utils/get-landmarks-with-transform.js +23 -0
  119. package/src/utils/photosToImages.js +40 -0
  120. package/src/utils/regions-to-blocks.js +14 -0
  121. package/src/utils/set-in-local-storage.js +6 -0
  122. package/Annotator/index.js +0 -169
  123. package/Annotator/reducers/combine-reducers.js +0 -14
  124. package/Annotator/reducers/convert-expanding-line-to-polygon.js +0 -73
  125. package/Annotator/reducers/general-reducer.js +0 -1058
  126. package/Annotator/reducers/get-active-image.js +0 -27
  127. package/Annotator/reducers/get-implied-video-regions.js +0 -180
  128. package/Annotator/reducers/history-handler.js +0 -38
  129. package/Annotator/reducers/image-reducer.js +0 -20
  130. package/Annotator/reducers/video-reducer.js +0 -88
  131. package/ClassSelectionMenu/index.js +0 -135
  132. package/Crosshairs/index.js +0 -53
  133. package/DebugSidebarBox/index.js +0 -20
  134. package/DemoSite/Editor.js +0 -194
  135. package/DemoSite/ErrorBoundaryDialog.js +0 -64
  136. package/DemoSite/index.js +0 -40
  137. package/FullImageSegmentationAnnotator/index.js +0 -7
  138. package/GroupSelectorSidebarBox/index.js +0 -63
  139. package/HighlightBox/index.js +0 -99
  140. package/HistorySidebarBox/index.js +0 -71
  141. package/ImageCanvas/index.js +0 -424
  142. package/ImageCanvas/region-tools.js +0 -165
  143. package/ImageCanvas/use-mouse.js +0 -180
  144. package/ImageCanvas/use-project-box.js +0 -27
  145. package/ImageCanvas/use-wasd-mode.js +0 -62
  146. package/ImageMask/index.js +0 -133
  147. package/ImageMask/load-image.js +0 -25
  148. package/ImageSelectorSidebarBox/index.js +0 -60
  149. package/KeyframeTimeline/get-time-string.js +0 -27
  150. package/KeyframeTimeline/index.js +0 -233
  151. package/KeyframesSelectorSidebarBox/index.js +0 -93
  152. package/LandingPage/index.js +0 -159
  153. package/MainLayout/icon-dictionary.js +0 -104
  154. package/MainLayout/index.js +0 -366
  155. package/MainLayout/types.js +0 -0
  156. package/MainLayout/use-implied-video-regions.js +0 -13
  157. package/PointDistances/index.js +0 -73
  158. package/PreventScrollToParents/index.js +0 -51
  159. package/RegionLabel/index.js +0 -191
  160. package/RegionSelectAndTransformBoxes/index.js +0 -167
  161. package/RegionSelectorSidebarBox/index.js +0 -248
  162. package/RegionShapes/index.js +0 -274
  163. package/RegionTags/index.js +0 -138
  164. package/SettingsDialog/index.js +0 -52
  165. package/SettingsProvider/index.js +0 -53
  166. package/Shortcuts/ShortcutField.js +0 -46
  167. package/Shortcuts/index.js +0 -133
  168. package/ShortcutsManager/index.js +0 -155
  169. package/Sidebar/index.js +0 -69
  170. package/SidebarBoxContainer/index.js +0 -93
  171. package/SmallToolButton/index.js +0 -42
  172. package/TagsSidebarBox/index.js +0 -105
  173. package/TaskDescriptionSidebarBox/index.js +0 -58
  174. package/Theme/index.js +0 -30
  175. package/VideoOrImageCanvasBackground/index.js +0 -151
  176. package/colors.js +0 -14
  177. package/hooks/use-event-callback.js +0 -10
  178. package/hooks/use-exclude-pattern.js +0 -24
  179. package/hooks/use-load-image.js +0 -26
  180. package/hooks/use-window-size.js +0 -46
  181. package/index.js +0 -3
  182. package/lib.js +0 -3
  183. package/stories.js +0 -5
  184. package/utils/get-from-local-storage.js +0 -7
  185. package/utils/get-hotkey-help-text.js +0 -9
  186. package/utils/get-landmarks-with-transform.js +0 -40
  187. package/utils/set-in-local-storage.js +0 -3
@@ -0,0 +1,494 @@
1
+ // @flow weak
2
+
3
+ import React, {
4
+ useRef,
5
+ useState,
6
+ useLayoutEffect,
7
+ useEffect,
8
+ useMemo,
9
+ } from "react"
10
+ import type { Node } from "react"
11
+ import { Matrix } from "transformation-matrix-js"
12
+ import Crosshairs from "../Crosshairs"
13
+ import type {
14
+ Region,
15
+ Point,
16
+ Polygon,
17
+ Box,
18
+ Keypoints,
19
+ KeypointsDefinition,
20
+ } from "./region-tools.js"
21
+ import { makeStyles } from "@mui/styles"
22
+ import { createTheme, ThemeProvider } from "@mui/material/styles"
23
+ import styles from "./styles"
24
+ import PreventScrollToParents from "../PreventScrollToParents"
25
+ import useWindowSize from "../hooks/use-window-size.js"
26
+ import useMouse from "./use-mouse"
27
+ import useProjectRegionBox from "./use-project-box"
28
+ import useExcludePattern from "../hooks/use-exclude-pattern"
29
+ import { useRafState } from "react-use"
30
+ import PointDistances from "../PointDistances"
31
+ import RegionTags from "../RegionTags"
32
+ import RegionLabel from "../RegionLabel"
33
+ import ImageMask from "../ImageMask"
34
+ import RegionSelectAndTransformBoxes from "../RegionSelectAndTransformBoxes"
35
+ import VideoOrImageCanvasBackground from "../VideoOrImageCanvasBackground"
36
+ import useEventCallback from "use-event-callback"
37
+ import RegionShapes from "../RegionShapes"
38
+ import useWasdMode from "./use-wasd-mode"
39
+
40
+ const theme = createTheme()
41
+ const useStyles = makeStyles((theme) => styles)
42
+
43
+ type Props = {
44
+ regions: Array<Region>,
45
+ imageSrc?: string,
46
+ videoSrc?: string,
47
+ videoTime?: number,
48
+ keypointDefinitions?: KeypointDefinitions,
49
+ onMouseMove?: ({ x: number, y: number }) => any,
50
+ onMouseDown?: ({ x: number, y: number }) => any,
51
+ onMouseUp?: ({ x: number, y: number }) => any,
52
+ dragWithPrimary?: boolean,
53
+ zoomWithPrimary?: boolean,
54
+ createWithPrimary?: boolean,
55
+ showTags?: boolean,
56
+ realSize?: { width: number, height: number, unitName: string },
57
+ showCrosshairs?: boolean,
58
+ showMask?: boolean,
59
+ showHighlightBox?: boolean,
60
+ showPointDistances?: boolean,
61
+ pointDistancePrecision?: number,
62
+ regionClsList?: Array<string>,
63
+ regionTagList?: Array<string>,
64
+ allowedArea?: { x: number, y: number, w: number, h: number },
65
+ RegionEditLabel?: Node,
66
+ videoPlaying?: boolean,
67
+ zoomOnAllowedArea?: boolean,
68
+ fullImageSegmentationMode?: boolean,
69
+ autoSegmentationOptions?: Object,
70
+ modifyingAllowedArea?: boolean,
71
+ allowComments?: Boolean,
72
+ onChangeRegion: (Region) => any,
73
+ onBeginRegionEdit: (Region) => any,
74
+ onCloseRegionEdit: (Region) => any,
75
+ onDeleteRegion: (Region) => any,
76
+ onBeginBoxTransform: (Box, [number, number]) => any,
77
+ onBeginMovePolygonPoint: (Polygon, index: number) => any,
78
+ onBeginMoveKeypoint: (Keypoints, index: number) => any,
79
+ onAddPolygonPoint: (Polygon, point: [number, number], index: number) => any,
80
+ onSelectRegion: (Region) => any,
81
+ onBeginMovePoint: (Point) => any,
82
+ onImageOrVideoLoaded: ({
83
+ naturalWidth: number,
84
+ naturalHeight: number,
85
+ duration?: number,
86
+ }) => any,
87
+ onChangeVideoTime: (number) => any,
88
+ onRegionClassAdded: () => {},
89
+ onChangeVideoPlaying?: Function,
90
+ hideNotEditingLabel?: boolean,
91
+ allowedGroups?: Object
92
+ }
93
+
94
+ const getDefaultMat = (allowedArea = null, { iw, ih } = {}) => {
95
+ let mat = Matrix.from(1, 0, 0, 1, -10, -10)
96
+ if (allowedArea && iw) {
97
+ mat = mat
98
+ .translate(allowedArea.x * iw, allowedArea.y * ih)
99
+ .scaleU(allowedArea.w + 0.05)
100
+ }
101
+ return mat
102
+ }
103
+
104
+ export const ImageCanvas = ({
105
+ regions,
106
+ imageSrc,
107
+ videoSrc,
108
+ videoTime,
109
+ realSize,
110
+ showTags,
111
+ onMouseMove = (p) => null,
112
+ onMouseDown = (p) => null,
113
+ onMouseUp = (p) => null,
114
+ dragWithPrimary = false,
115
+ zoomWithPrimary = false,
116
+ createWithPrimary = false,
117
+ pointDistancePrecision = 0,
118
+ regionClsList,
119
+ regionTagList,
120
+ showCrosshairs,
121
+ showHighlightBox = true,
122
+ showPointDistances,
123
+ allowedArea,
124
+ RegionEditLabel = null,
125
+ videoPlaying = false,
126
+ showMask = true,
127
+ fullImageSegmentationMode,
128
+ autoSegmentationOptions,
129
+ onImageOrVideoLoaded,
130
+ onChangeRegion,
131
+ onBeginRegionEdit,
132
+ onCloseRegionEdit,
133
+ onBeginBoxTransform,
134
+ onBeginMovePolygonPoint,
135
+ onAddPolygonPoint,
136
+ onBeginMoveKeypoint,
137
+ onSelectRegion,
138
+ onBeginMovePoint,
139
+ onDeleteRegion,
140
+ onChangeVideoTime,
141
+ onChangeVideoPlaying,
142
+ onRegionClassAdded,
143
+ zoomOnAllowedArea = true,
144
+ modifyingAllowedArea = false,
145
+ keypointDefinitions,
146
+ allowComments,
147
+ hideNotEditingLabel = false,
148
+ allowedGroups,
149
+ }: Props) => {
150
+ const classes = useStyles()
151
+
152
+ const canvasEl = useRef(null)
153
+ const layoutParams = useRef({})
154
+ const [dragging, changeDragging] = useRafState(false)
155
+ const [maskImagesLoaded, changeMaskImagesLoaded] = useRafState(0)
156
+ const [zoomStart, changeZoomStart] = useRafState(null)
157
+ const [zoomEnd, changeZoomEnd] = useRafState(null)
158
+ const [mat, changeMat] = useRafState(getDefaultMat())
159
+ const maskImages = useRef({})
160
+ const windowSize = useWindowSize()
161
+
162
+ const getLatestMat = useEventCallback(() => mat)
163
+ useWasdMode({ getLatestMat, changeMat })
164
+
165
+ const { mouseEvents, mousePosition } = useMouse({
166
+ canvasEl,
167
+ dragging,
168
+ mat,
169
+ layoutParams,
170
+ changeMat,
171
+ zoomStart,
172
+ zoomEnd,
173
+ changeZoomStart,
174
+ changeZoomEnd,
175
+ changeDragging,
176
+ zoomWithPrimary,
177
+ dragWithPrimary,
178
+ onMouseMove,
179
+ onMouseDown,
180
+ onMouseUp,
181
+ })
182
+
183
+ useLayoutEffect(() => changeMat(mat.clone()), [windowSize])
184
+
185
+ const innerMousePos = mat.applyToPoint(
186
+ mousePosition.current.x,
187
+ mousePosition.current.y
188
+ )
189
+
190
+ const projectRegionBox = useProjectRegionBox({ layoutParams, mat })
191
+
192
+ const [imageDimensions, changeImageDimensions] = useState()
193
+ const imageLoaded = Boolean(imageDimensions && imageDimensions.naturalWidth)
194
+
195
+ const onVideoOrImageLoaded = useEventCallback(
196
+ ({ naturalWidth, naturalHeight, duration }) => {
197
+ const dims = { naturalWidth, naturalHeight, duration }
198
+ if (onImageOrVideoLoaded) onImageOrVideoLoaded(dims)
199
+ changeImageDimensions(dims)
200
+ // Redundant update to fix rerendering issues
201
+ setTimeout(() => changeImageDimensions(dims), 10)
202
+ }
203
+ )
204
+
205
+ const excludePattern = useExcludePattern()
206
+
207
+ const canvas = canvasEl.current
208
+ if (canvas && imageLoaded) {
209
+ const { clientWidth, clientHeight } = canvas
210
+
211
+ const fitScale = Math.max(
212
+ imageDimensions.naturalWidth / (clientWidth - 20),
213
+ imageDimensions.naturalHeight / (clientHeight - 20)
214
+ )
215
+
216
+ const [iw, ih] = [
217
+ imageDimensions.naturalWidth / fitScale,
218
+ imageDimensions.naturalHeight / fitScale,
219
+ ]
220
+
221
+ layoutParams.current = {
222
+ iw,
223
+ ih,
224
+ fitScale,
225
+ canvasWidth: clientWidth,
226
+ canvasHeight: clientHeight,
227
+ }
228
+ }
229
+
230
+ useEffect(() => {
231
+ if (!imageLoaded) return
232
+ changeMat(
233
+ getDefaultMat(
234
+ zoomOnAllowedArea ? allowedArea : null,
235
+ layoutParams.current
236
+ )
237
+ )
238
+ // eslint-disable-next-line
239
+ }, [imageLoaded])
240
+
241
+ useLayoutEffect(() => {
242
+ if (!imageDimensions) return
243
+ const { clientWidth, clientHeight } = canvas
244
+ canvas.width = clientWidth
245
+ canvas.height = clientHeight
246
+ const context = canvas.getContext("2d")
247
+
248
+ context.save()
249
+ context.transform(...mat.clone().inverse().toArray())
250
+
251
+ const { iw, ih } = layoutParams.current
252
+
253
+ if (allowedArea) {
254
+ // Pattern to indicate the NOT allowed areas
255
+ const { x, y, w, h } = allowedArea
256
+ context.save()
257
+ context.globalAlpha = 1
258
+ const outer = [
259
+ [0, 0],
260
+ [iw, 0],
261
+ [iw, ih],
262
+ [0, ih],
263
+ ]
264
+ const inner = [
265
+ [x * iw, y * ih],
266
+ [x * iw + w * iw, y * ih],
267
+ [x * iw + w * iw, y * ih + h * ih],
268
+ [x * iw, y * ih + h * ih],
269
+ ]
270
+ context.moveTo(...outer[0])
271
+ outer.forEach((p) => context.lineTo(...p))
272
+ context.lineTo(...outer[0])
273
+ context.closePath()
274
+
275
+ inner.reverse()
276
+ context.moveTo(...inner[0])
277
+ inner.forEach((p) => context.lineTo(...p))
278
+ context.lineTo(...inner[0])
279
+
280
+ context.fillStyle = excludePattern || "#f00"
281
+ context.fill()
282
+
283
+ context.restore()
284
+ }
285
+
286
+ context.restore()
287
+ })
288
+
289
+ const { iw, ih } = layoutParams.current
290
+
291
+ let zoomBox =
292
+ !zoomStart || !zoomEnd
293
+ ? null
294
+ : {
295
+ ...mat.clone().inverse().applyToPoint(zoomStart.x, zoomStart.y),
296
+ w: (zoomEnd.x - zoomStart.x) / mat.a,
297
+ h: (zoomEnd.y - zoomStart.y) / mat.d,
298
+ }
299
+ if (zoomBox) {
300
+ if (zoomBox.w < 0) {
301
+ zoomBox.x += zoomBox.w
302
+ zoomBox.w *= -1
303
+ }
304
+ if (zoomBox.h < 0) {
305
+ zoomBox.y += zoomBox.h
306
+ zoomBox.h *= -1
307
+ }
308
+ }
309
+
310
+ const imagePosition = {
311
+ topLeft: mat.clone().inverse().applyToPoint(0, 0),
312
+ bottomRight: mat.clone().inverse().applyToPoint(iw, ih),
313
+ }
314
+
315
+ const highlightedRegion = useMemo(() => {
316
+ const highlightedRegions = regions.filter((r) => r.highlighted)
317
+ if (highlightedRegions.length !== 1) return null
318
+ return highlightedRegions[0]
319
+ }, [regions])
320
+
321
+ return (
322
+ <ThemeProvider theme={theme}>
323
+ <div
324
+ style={{
325
+ width: "100%",
326
+ height: "100%",
327
+ maxHeight: "calc(100vh - 68px)",
328
+ position: "relative",
329
+ overflow: "hidden",
330
+ cursor: createWithPrimary
331
+ ? "crosshair"
332
+ : dragging
333
+ ? "grabbing"
334
+ : dragWithPrimary
335
+ ? "grab"
336
+ : zoomWithPrimary
337
+ ? mat.a < 1
338
+ ? "zoom-out"
339
+ : "zoom-in"
340
+ : undefined,
341
+ }}
342
+ >
343
+ {showCrosshairs && (
344
+ <Crosshairs key="crossHairs" mousePosition={mousePosition} />
345
+ )}
346
+ {imageLoaded && !dragging && (
347
+ <RegionSelectAndTransformBoxes
348
+ key="regionSelectAndTransformBoxes"
349
+ regions={
350
+ !modifyingAllowedArea || !allowedArea
351
+ ? regions
352
+ : [
353
+ {
354
+ type: "box",
355
+ id: "$$allowed_area",
356
+ cls: "allowed_area",
357
+ highlighted: true,
358
+ x: allowedArea.x,
359
+ y: allowedArea.y,
360
+ w: allowedArea.w,
361
+ h: allowedArea.h,
362
+ visible: true,
363
+ color: "#ff0",
364
+ },
365
+ ]
366
+ }
367
+ mouseEvents={mouseEvents}
368
+ projectRegionBox={projectRegionBox}
369
+ dragWithPrimary={dragWithPrimary}
370
+ createWithPrimary={createWithPrimary}
371
+ zoomWithPrimary={zoomWithPrimary}
372
+ onBeginMovePoint={onBeginMovePoint}
373
+ onSelectRegion={onSelectRegion}
374
+ layoutParams={layoutParams}
375
+ mat={mat}
376
+ onBeginBoxTransform={onBeginBoxTransform}
377
+ onBeginMovePolygonPoint={onBeginMovePolygonPoint}
378
+ onBeginMoveKeypoint={onBeginMoveKeypoint}
379
+ onAddPolygonPoint={onAddPolygonPoint}
380
+ showHighlightBox={showHighlightBox}
381
+ />
382
+ )}
383
+ {imageLoaded && showTags && !dragging && (
384
+ <PreventScrollToParents key="regionTags">
385
+ <RegionTags
386
+ regions={regions}
387
+ projectRegionBox={projectRegionBox}
388
+ mouseEvents={mouseEvents}
389
+ regionClsList={regionClsList}
390
+ regionTagList={regionTagList}
391
+ onBeginRegionEdit={onBeginRegionEdit}
392
+ onChangeRegion={onChangeRegion}
393
+ onCloseRegionEdit={onCloseRegionEdit}
394
+ onDeleteRegion={onDeleteRegion}
395
+ layoutParams={layoutParams}
396
+ imageSrc={imageSrc}
397
+ RegionEditLabel={RegionEditLabel}
398
+ onRegionClassAdded={onRegionClassAdded}
399
+ allowComments={allowComments}
400
+ hideNotEditingLabel={hideNotEditingLabel}
401
+ allowedGroups={allowedGroups}
402
+ />
403
+ </PreventScrollToParents>
404
+ )}
405
+ {!showTags && highlightedRegion && (
406
+ <div key="topLeftTag" className={classes.fixedRegionLabel}>
407
+ <RegionLabel
408
+ disableClose
409
+ allowedClasses={regionClsList}
410
+ allowedTags={regionTagList}
411
+ onChange={onChangeRegion}
412
+ onDelete={onDeleteRegion}
413
+ editing
414
+ region={highlightedRegion}
415
+ imageSrc={imageSrc}
416
+ allowComments={allowComments}
417
+ />
418
+ </div>
419
+ )}
420
+
421
+ {zoomWithPrimary && zoomBox !== null && (
422
+ <div
423
+ key="zoomBox"
424
+ style={{
425
+ position: "absolute",
426
+ zIndex: 1,
427
+ border: "1px solid #fff",
428
+ pointerEvents: "none",
429
+ left: zoomBox.x,
430
+ top: zoomBox.y,
431
+ width: zoomBox.w,
432
+ height: zoomBox.h,
433
+ }}
434
+ />
435
+ )}
436
+ {showPointDistances && (
437
+ <PointDistances
438
+ key="pointDistances"
439
+ regions={regions}
440
+ realSize={realSize}
441
+ projectRegionBox={projectRegionBox}
442
+ pointDistancePrecision={pointDistancePrecision}
443
+ />
444
+ )}
445
+ <PreventScrollToParents
446
+ style={{ width: "100%", height: "100%" }}
447
+ {...mouseEvents}
448
+ >
449
+ <>
450
+ {fullImageSegmentationMode && (
451
+ <ImageMask
452
+ hide={!showMask}
453
+ autoSegmentationOptions={autoSegmentationOptions}
454
+ imagePosition={imagePosition}
455
+ regionClsList={regionClsList}
456
+ imageSrc={imageSrc}
457
+ regions={regions}
458
+ />
459
+ )}
460
+ <canvas
461
+ style={{ opacity: 0.25 }}
462
+ className={classes.canvas}
463
+ ref={canvasEl}
464
+ />
465
+ <RegionShapes
466
+ mat={mat}
467
+ keypointDefinitions={keypointDefinitions}
468
+ imagePosition={imagePosition}
469
+ regions={regions}
470
+ fullSegmentationMode={fullImageSegmentationMode}
471
+ />
472
+ <VideoOrImageCanvasBackground
473
+ videoPlaying={videoPlaying}
474
+ imagePosition={imagePosition}
475
+ mouseEvents={mouseEvents}
476
+ onLoad={onVideoOrImageLoaded}
477
+ videoTime={videoTime}
478
+ videoSrc={videoSrc}
479
+ imageSrc={imageSrc}
480
+ useCrossOrigin={fullImageSegmentationMode}
481
+ onChangeVideoTime={onChangeVideoTime}
482
+ onChangeVideoPlaying={onChangeVideoPlaying}
483
+ />
484
+ </>
485
+ </PreventScrollToParents>
486
+ <div className={classes.zoomIndicator}>
487
+ {((1 / mat.a) * 100).toFixed(0)}%
488
+ </div>
489
+ </div>
490
+ </ThemeProvider>
491
+ )
492
+ }
493
+
494
+ export default ImageCanvas