@searpent/react-image-annotate 2.0.2 → 2.0.5

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 (186) 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 -161
  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/HighlightBox/index.js +0 -99
  139. package/HistorySidebarBox/index.js +0 -71
  140. package/ImageCanvas/index.js +0 -424
  141. package/ImageCanvas/region-tools.js +0 -165
  142. package/ImageCanvas/use-mouse.js +0 -180
  143. package/ImageCanvas/use-project-box.js +0 -27
  144. package/ImageCanvas/use-wasd-mode.js +0 -62
  145. package/ImageMask/index.js +0 -133
  146. package/ImageMask/load-image.js +0 -25
  147. package/ImageSelectorSidebarBox/index.js +0 -60
  148. package/KeyframeTimeline/get-time-string.js +0 -27
  149. package/KeyframeTimeline/index.js +0 -233
  150. package/KeyframesSelectorSidebarBox/index.js +0 -93
  151. package/LandingPage/index.js +0 -159
  152. package/MainLayout/icon-dictionary.js +0 -104
  153. package/MainLayout/index.js +0 -352
  154. package/MainLayout/types.js +0 -0
  155. package/MainLayout/use-implied-video-regions.js +0 -13
  156. package/PointDistances/index.js +0 -73
  157. package/PreventScrollToParents/index.js +0 -51
  158. package/RegionLabel/index.js +0 -191
  159. package/RegionSelectAndTransformBoxes/index.js +0 -167
  160. package/RegionSelectorSidebarBox/index.js +0 -248
  161. package/RegionShapes/index.js +0 -274
  162. package/RegionTags/index.js +0 -138
  163. package/SettingsDialog/index.js +0 -52
  164. package/SettingsProvider/index.js +0 -53
  165. package/Shortcuts/ShortcutField.js +0 -46
  166. package/Shortcuts/index.js +0 -133
  167. package/ShortcutsManager/index.js +0 -155
  168. package/Sidebar/index.js +0 -69
  169. package/SidebarBoxContainer/index.js +0 -93
  170. package/SmallToolButton/index.js +0 -42
  171. package/TagsSidebarBox/index.js +0 -105
  172. package/TaskDescriptionSidebarBox/index.js +0 -58
  173. package/Theme/index.js +0 -30
  174. package/VideoOrImageCanvasBackground/index.js +0 -151
  175. package/colors.js +0 -14
  176. package/hooks/use-event-callback.js +0 -10
  177. package/hooks/use-exclude-pattern.js +0 -24
  178. package/hooks/use-load-image.js +0 -26
  179. package/hooks/use-window-size.js +0 -46
  180. package/index.js +0 -3
  181. package/lib.js +0 -3
  182. package/stories.js +0 -5
  183. package/utils/get-from-local-storage.js +0 -7
  184. package/utils/get-hotkey-help-text.js +0 -9
  185. package/utils/get-landmarks-with-transform.js +0 -40
  186. package/utils/set-in-local-storage.js +0 -3
@@ -0,0 +1,291 @@
1
+ // @flow
2
+
3
+ import type {
4
+ Action,
5
+ Image,
6
+ MainLayoutState,
7
+ Mode,
8
+ ToolEnum,
9
+ Metadata
10
+ } from "../MainLayout/types"
11
+ import React, { useEffect, useReducer } from "react"
12
+ import makeImmutable, { without } from "seamless-immutable"
13
+
14
+ import type { KeypointsDefinition } from "../ImageCanvas/region-tools"
15
+ import MainLayout from "../MainLayout"
16
+ import type { Node } from "react"
17
+ import SettingsProvider from "../SettingsProvider"
18
+ import combineReducers from "./reducers/combine-reducers.js"
19
+ import generalReducer from "./reducers/general-reducer.js"
20
+ import getFromLocalStorage from "../utils/get-from-local-storage"
21
+ import historyHandler from "./reducers/history-handler.js"
22
+ import imageReducer from "./reducers/image-reducer.js"
23
+ import useEventCallback from "use-event-callback"
24
+ import videoReducer from "./reducers/video-reducer.js"
25
+
26
+ type Props = {
27
+ taskDescription?: string,
28
+ allowedArea?: { x: number, y: number, w: number, h: number },
29
+ regionTagList?: Array<string>,
30
+ regionClsList?: Array<string>,
31
+ imageTagList?: Array<string>,
32
+ imageClsList?: Array<string>,
33
+ enabledTools?: Array<string>,
34
+ selectedTool?: String,
35
+ showTags?: boolean,
36
+ selectedImage?: string | number,
37
+ images?: Array<Image>,
38
+ showPointDistances?: boolean,
39
+ pointDistancePrecision?: number,
40
+ RegionEditLabel?: Node,
41
+ onExit: (MainLayoutState) => any,
42
+ videoTime?: number,
43
+ videoSrc?: string,
44
+ keyframes?: Object,
45
+ videoName?: string,
46
+ keypointDefinitions: KeypointsDefinition,
47
+ fullImageSegmentationMode?: boolean,
48
+ autoSegmentationOptions?:
49
+ | {| type: "simple" |}
50
+ | {| type: "autoseg", maxClusters ?: number, slicWeightFactor ?: number |},
51
+ hideHeader ?: boolean,
52
+ hideHeaderText ?: boolean,
53
+ hideNext ?: boolean,
54
+ hidePrev ?: boolean,
55
+ hideClone ?: boolean,
56
+ hideSettings ?: boolean,
57
+ hideFullScreen ?: boolean,
58
+ hideSave ?: boolean,
59
+ onImagesChange ?: (any) => any,
60
+ groups ?: Array < any >,
61
+ onGroupSelect ?: (any) => any,
62
+ hideHistory ?: boolean,
63
+ hideNotEditingLabel ?: boolean,
64
+ showEditor ?: boolean,
65
+ showPageSelector ?: boolean,
66
+ clsColors ?: Object,
67
+ groupColors ?: Object,
68
+ onRecalc ?: (any) => any,
69
+ onSave ?: (any) => any,
70
+ allowedGroups ?: Object,
71
+ metadata ?: Array < Metadata >,
72
+ }
73
+
74
+ export const Annotator = ({
75
+ images,
76
+ allowedArea,
77
+ selectedImage = images && images.length > 0 ? 0 : undefined,
78
+ showPointDistances,
79
+ pointDistancePrecision,
80
+ showTags = getFromLocalStorage("showTags", true),
81
+ enabledTools = [
82
+ "select",
83
+ "create-point",
84
+ "create-box",
85
+ "create-polygon",
86
+ "create-line",
87
+ "create-expanding-line",
88
+ "show-mask",
89
+ ],
90
+ selectedTool = "select",
91
+ regionTagList = [],
92
+ regionClsList = [],
93
+ imageTagList = [],
94
+ imageClsList = [],
95
+ keyframes = {},
96
+ taskDescription = "",
97
+ fullImageSegmentationMode = false,
98
+ RegionEditLabel,
99
+ videoSrc,
100
+ videoTime = 0,
101
+ videoName,
102
+ onExit,
103
+ onNextImage,
104
+ onPrevImage,
105
+ keypointDefinitions,
106
+ autoSegmentationOptions = { type: "autoseg" },
107
+ hideHeader,
108
+ hideHeaderText,
109
+ hideNext,
110
+ hidePrev,
111
+ hideClone,
112
+ hideSettings,
113
+ hideFullScreen,
114
+ hideSave,
115
+ allowComments,
116
+ onImagesChange,
117
+ groups,
118
+ onGroupSelect,
119
+ hideHistory,
120
+ hideNotEditingLabel,
121
+ showEditor,
122
+ showPageSelector,
123
+ clsColors,
124
+ groupColors,
125
+ onRecalc,
126
+ onSave,
127
+ allowedGroups,
128
+ metadata
129
+ }: Props) => {
130
+ if (typeof selectedImage === "string") {
131
+ selectedImage = (images || []).findIndex((img) => img.src === selectedImage)
132
+ if (selectedImage === -1) selectedImage = undefined
133
+ }
134
+ const annotationType = images ? "image" : "video"
135
+ const [state, dispatchToReducer] = useReducer(
136
+ historyHandler(
137
+ combineReducers(
138
+ annotationType === "image" ? imageReducer : videoReducer,
139
+ generalReducer
140
+ )
141
+ ),
142
+ makeImmutable({
143
+ annotationType,
144
+ showTags,
145
+ allowedArea,
146
+ showPointDistances,
147
+ pointDistancePrecision,
148
+ selectedTool,
149
+ fullImageSegmentationMode: fullImageSegmentationMode,
150
+ autoSegmentationOptions,
151
+ mode: null,
152
+ taskDescription,
153
+ showMask: true,
154
+ labelImages: imageClsList.length > 0 || imageTagList.length > 0,
155
+ regionClsList,
156
+ regionTagList,
157
+ imageClsList,
158
+ imageTagList,
159
+ currentVideoTime: videoTime,
160
+ enabledTools,
161
+ history: [],
162
+ videoName,
163
+ keypointDefinitions,
164
+ allowComments,
165
+ ...(annotationType === "image"
166
+ ? {
167
+ selectedImage,
168
+ images,
169
+ selectedImageFrameTime:
170
+ images && images.length > 0 ? images[0].frameTime : undefined,
171
+ }
172
+ : {
173
+ videoSrc,
174
+ keyframes,
175
+ }),
176
+ imagesUpdatedAt: null,
177
+ imagesSavedAt: null,
178
+ metadata,
179
+ })
180
+ )
181
+
182
+ const dispatch = useEventCallback((action: Action) => {
183
+ if (action.type === "HEADER_BUTTON_CLICKED") {
184
+ if (["Exit", "Done", "Save", "Complete"].includes(action.buttonName)) {
185
+ return onExit(without(state, "history"))
186
+ } else if (action.buttonName === "Next" && onNextImage) {
187
+ return onNextImage(without(state, "history"))
188
+ } else if (action.buttonName === "Prev" && onPrevImage) {
189
+ return onPrevImage(without(state, "history"))
190
+ }
191
+ }
192
+ dispatchToReducer(action)
193
+ })
194
+
195
+ const onRegionClassAdded = useEventCallback((cls) => {
196
+ dispatchToReducer({
197
+ type: "ON_CLS_ADDED",
198
+ cls: cls,
199
+ })
200
+ })
201
+
202
+ const handleSaveClick = async (e) => {
203
+ e.preventDefault()
204
+ if (onSave) {
205
+ onSave()
206
+ dispatchToReducer({
207
+ type: "IMAGES_SAVED",
208
+ savedAt: new Date()
209
+ })
210
+ }
211
+ }
212
+
213
+ const handleRecalcClick = (e) => {
214
+ e.preventDefault()
215
+ if (onRecalc) {
216
+ onRecalc()
217
+ }
218
+ }
219
+
220
+ const handleMetadataChange = ({ name, value, imageIndex }) => {
221
+ dispatchToReducer({
222
+ type: "UPDATE_METADATA",
223
+ name,
224
+ value,
225
+ imageIndex
226
+ })
227
+ }
228
+
229
+ // trigger this on every BBox manipulation (there is currently no way to detect adding of new box!)
230
+ useEffect(() => {
231
+ if (!state.lastAction || !["BEGIN_BOX_TRANSFORM", "CHANGE_REGION", "DELETE_REGION"].includes(state.lastAction.type)) { return }
232
+ if (onImagesChange) {
233
+ onImagesChange(state.images)
234
+ }
235
+ dispatchToReducer({
236
+ type: "IMAGES_UPDATED",
237
+ updatedAt: new Date()
238
+ })
239
+ }, [onImagesChange, state.images, state.lastAction])
240
+
241
+ useEffect(() => {
242
+ if (selectedImage === undefined) return
243
+ dispatchToReducer({
244
+ type: "SELECT_IMAGE",
245
+ imageIndex: selectedImage,
246
+ image: state.images[selectedImage],
247
+ })
248
+ // eslint-disable-next-line react-hooks/exhaustive-deps
249
+ }, [onImagesChange, selectedImage])
250
+
251
+ if (!images && !videoSrc)
252
+ return 'Missing required prop "images" or "videoSrc"'
253
+
254
+
255
+ const [recalcActive, saveActive] = state.imagesSavedAt < state.imagesUpdatedAt ? [true, true] : [false, false];
256
+
257
+ return (
258
+ <SettingsProvider clsColors={clsColors} groupColors={groupColors}>
259
+ <MainLayout
260
+ RegionEditLabel={RegionEditLabel}
261
+ alwaysShowNextButton={Boolean(onNextImage)}
262
+ alwaysShowPrevButton={Boolean(onPrevImage)}
263
+ state={state}
264
+ dispatch={dispatch}
265
+ onRegionClassAdded={onRegionClassAdded}
266
+ hideHeader={hideHeader}
267
+ hideHeaderText={hideHeaderText}
268
+ hideNext={hideNext}
269
+ hidePrev={hidePrev}
270
+ hideClone={hideClone}
271
+ hideSettings={hideSettings}
272
+ hideFullScreen={hideFullScreen}
273
+ hideSave={hideSave}
274
+ groups={groups}
275
+ onGroupSelect={onGroupSelect}
276
+ hideHistory={hideHistory}
277
+ hideNotEditingLabel={hideNotEditingLabel}
278
+ showEditor={showEditor}
279
+ showPageSelector={showPageSelector}
280
+ onRecalc={handleRecalcClick}
281
+ onSave={handleSaveClick}
282
+ saveActive={recalcActive}
283
+ recalcActive={saveActive}
284
+ allowedGroups={allowedGroups}
285
+ onMetadataChange={handleMetadataChange}
286
+ />
287
+ </SettingsProvider>
288
+ )
289
+ }
290
+
291
+ export default Annotator