@searpent/react-image-annotate 2.0.0

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 (109) 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/README.md +101 -0
  12. package/package.json +93 -0
  13. package/public/favicon.ico +0 -0
  14. package/public/index.html +38 -0
  15. package/src/Annotator/bike-pic.png +0 -0
  16. package/src/Annotator/bike-pic2.png +0 -0
  17. package/src/Annotator/dab-keyframes.story.json +1 -0
  18. package/src/Annotator/index.js +206 -0
  19. package/src/Annotator/index.story.js +727 -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/src/Annotator/reducers/fix-twisted.js +6 -0
  24. package/src/Annotator/reducers/general-reducer.js +914 -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/FullImageSegmentationAnnotator/hard1.story.jpg +0 -0
  40. package/src/FullImageSegmentationAnnotator/hard2.story.jpg +0 -0
  41. package/src/FullImageSegmentationAnnotator/hard3.story.jpg +0 -0
  42. package/src/FullImageSegmentationAnnotator/index.js +7 -0
  43. package/src/FullImageSegmentationAnnotator/index.story.js +177 -0
  44. package/src/FullImageSegmentationAnnotator/orange.story.png +0 -0
  45. package/src/HighlightBox/index.js +143 -0
  46. package/src/HistorySidebarBox/index.js +78 -0
  47. package/src/ImageCanvas/dancing-man.story.jpg +0 -0
  48. package/src/ImageCanvas/index.js +488 -0
  49. package/src/ImageCanvas/index.story.js +214 -0
  50. package/src/ImageCanvas/mouse_mask.story.png +0 -0
  51. package/src/ImageCanvas/region-tools.js +171 -0
  52. package/src/ImageCanvas/seves_desk.story.jpg +0 -0
  53. package/src/ImageCanvas/styles.js +27 -0
  54. package/src/ImageCanvas/use-mouse.js +168 -0
  55. package/src/ImageCanvas/use-project-box.js +23 -0
  56. package/src/ImageCanvas/use-wasd-mode.js +50 -0
  57. package/src/ImageMask/index.js +127 -0
  58. package/src/ImageMask/load-image.js +32 -0
  59. package/src/ImageSelectorSidebarBox/index.js +54 -0
  60. package/src/KeyframeTimeline/get-time-string.js +25 -0
  61. package/src/KeyframeTimeline/index.js +223 -0
  62. package/src/KeyframesSelectorSidebarBox/index.js +93 -0
  63. package/src/LandingPage/content.md +57 -0
  64. package/src/LandingPage/github-markdown.css +964 -0
  65. package/src/LandingPage/index.js +147 -0
  66. package/src/MainLayout/icon-dictionary.js +79 -0
  67. package/src/MainLayout/index.js +420 -0
  68. package/src/MainLayout/index.story.js +240 -0
  69. package/src/MainLayout/styles.js +26 -0
  70. package/src/MainLayout/types.js +156 -0
  71. package/src/MainLayout/use-implied-video-regions.js +17 -0
  72. package/src/PointDistances/index.js +90 -0
  73. package/src/PreventScrollToParents/index.js +48 -0
  74. package/src/PreventScrollToParents/index.story.js +23 -0
  75. package/src/RegionLabel/index.js +201 -0
  76. package/src/RegionLabel/styles.js +51 -0
  77. package/src/RegionSelectAndTransformBoxes/index.js +234 -0
  78. package/src/RegionSelectorSidebarBox/index.js +216 -0
  79. package/src/RegionSelectorSidebarBox/styles.js +54 -0
  80. package/src/RegionShapes/index.js +236 -0
  81. package/src/RegionTags/index.js +130 -0
  82. package/src/SettingsDialog/index.js +58 -0
  83. package/src/SettingsProvider/index.js +44 -0
  84. package/src/Shortcuts/ShortcutField.js +44 -0
  85. package/src/Shortcuts/index.js +129 -0
  86. package/src/ShortcutsManager/index.js +162 -0
  87. package/src/Sidebar/index.js +117 -0
  88. package/src/SidebarBoxContainer/index.js +93 -0
  89. package/src/SmallToolButton/index.js +57 -0
  90. package/src/TagsSidebarBox/index.js +93 -0
  91. package/src/TaskDescriptionSidebarBox/index.js +43 -0
  92. package/src/Theme/index.js +36 -0
  93. package/src/VideoOrImageCanvasBackground/index.js +170 -0
  94. package/src/colors.js +32 -0
  95. package/src/hooks/use-event-callback.js +11 -0
  96. package/src/hooks/use-exclude-pattern.js +27 -0
  97. package/src/hooks/use-load-image.js +21 -0
  98. package/src/hooks/use-window-size.js +46 -0
  99. package/src/hooks/xpattern.js +1 -0
  100. package/src/hooks/xpattern.png +0 -0
  101. package/src/index.js +18 -0
  102. package/src/lib.js +7 -0
  103. package/src/screenshot.png +0 -0
  104. package/src/site.css +5 -0
  105. package/src/stories.js +2 -0
  106. package/src/utils/get-from-local-storage.js +7 -0
  107. package/src/utils/get-hotkey-help-text.js +11 -0
  108. package/src/utils/get-landmarks-with-transform.js +23 -0
  109. package/src/utils/set-in-local-storage.js +6 -0
@@ -0,0 +1,727 @@
1
+ // @flow
2
+
3
+ import React, { useState } from "react"
4
+
5
+ import { storiesOf } from "@storybook/react"
6
+ import { action as actionAddon } from "@storybook/addon-actions"
7
+ import exampleImage from "../ImageCanvas/seves_desk.story.jpg"
8
+ import bikeImg1 from "./bike-pic.png"
9
+ import bikeImg2 from "./bike-pic2.png"
10
+ import { HotKeys } from "react-hotkeys"
11
+ import { defaultKeyMap } from "../ShortcutsManager"
12
+
13
+ import Annotator from "./"
14
+
15
+ import { testRegions } from "../ImageCanvas/index.story"
16
+
17
+ const middlewares = [
18
+ (store) => (next) => (action) => {
19
+ actionAddon(action.type)(action)
20
+ return next(action)
21
+ },
22
+ ]
23
+
24
+ storiesOf("Annotator", module)
25
+ .add("Basic", () => (
26
+ <Annotator
27
+ onExit={actionAddon("onExit")}
28
+ middlewares={middlewares}
29
+ labelImages
30
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
31
+ regionTagList={["tag1", "tag2", "tag3"]}
32
+ imageClsList={["Alpha", "Beta", "Charlie", "Delta"]}
33
+ imageTagList={["tag1", "tag2", "tag3"]}
34
+ images={[
35
+ {
36
+ src: exampleImage,
37
+ name: "Seve's Desk",
38
+ regions: testRegions,
39
+ },
40
+ {
41
+ src: "https://loremflickr.com/100/100/cars?lock=1",
42
+ name: "Frame 0036",
43
+ },
44
+ {
45
+ src: "https://loremflickr.com/100/100/cars?lock=2",
46
+ name: "Frame 0037",
47
+ },
48
+ {
49
+ src: "https://loremflickr.com/100/100/cars?lock=3",
50
+ name: "Frame 0038",
51
+ },
52
+ ]}
53
+ />
54
+ ))
55
+ .add("Basic - Allow Comments", () => (
56
+ <Annotator
57
+ onExit={actionAddon("onExit")}
58
+ middlewares={middlewares}
59
+ labelImages
60
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
61
+ regionTagList={["tag1", "tag2", "tag3"]}
62
+ imageClsList={["Alpha", "Beta", "Charlie", "Delta"]}
63
+ imageTagList={["tag1", "tag2", "tag3"]}
64
+ images={[
65
+ {
66
+ src: exampleImage,
67
+ name: "Seve's Desk",
68
+ regions: testRegions,
69
+ },
70
+ {
71
+ src: "https://loremflickr.com/100/100/cars?lock=1",
72
+ name: "Frame 0036",
73
+ },
74
+ {
75
+ src: "https://loremflickr.com/100/100/cars?lock=2",
76
+ name: "Frame 0037",
77
+ },
78
+ {
79
+ src: "https://loremflickr.com/100/100/cars?lock=3",
80
+ name: "Frame 0038",
81
+ },
82
+ ]}
83
+ allowComments
84
+ />
85
+ ))
86
+ .add("Fixed Size Container", () => (
87
+ <div style={{ width: 500, height: 500 }}>
88
+ <Annotator
89
+ onExit={actionAddon("onExit")}
90
+ middlewares={[
91
+ (store) => (next) => (action) => {
92
+ actionAddon(action.type)(action)
93
+ return next(action)
94
+ },
95
+ ]}
96
+ labelImages
97
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
98
+ regionTagList={["tag1", "tag2", "tag3"]}
99
+ imageClsList={["Alpha", "Beta", "Charlie", "Delta"]}
100
+ imageTagList={["tag1", "tag2", "tag3"]}
101
+ images={[
102
+ {
103
+ src: exampleImage,
104
+ name: "Seve's Desk",
105
+ regions: testRegions,
106
+ },
107
+ {
108
+ src: "https://loremflickr.com/100/100/cars?lock=1",
109
+ name: "Frame 0036",
110
+ },
111
+ {
112
+ src: "https://loremflickr.com/100/100/cars?lock=2",
113
+ name: "Frame 0037",
114
+ },
115
+ {
116
+ src: "https://loremflickr.com/100/100/cars?lock=3",
117
+ name: "Frame 0038",
118
+ },
119
+ ]}
120
+ />
121
+ </div>
122
+ ))
123
+ .add("Shrunk Annotator (Test Fullscreen)", () => (
124
+ <div style={{ padding: 100 }}>
125
+ <Annotator
126
+ onExit={actionAddon("onExit")}
127
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
128
+ regionTagList={["tag1", "tag2", "tag3"]}
129
+ middlewares={[
130
+ (store) => (next) => (action) => {
131
+ actionAddon(action.type)(action)
132
+ return next(action)
133
+ },
134
+ ]}
135
+ images={[
136
+ {
137
+ src: exampleImage,
138
+ name: "Seve's Desk",
139
+ regions: testRegions,
140
+ },
141
+ ]}
142
+ />
143
+ </div>
144
+ ))
145
+ .add("Annotator w/o No Region Labels or Image Labels", () => (
146
+ <Annotator
147
+ onExit={actionAddon("onExit")}
148
+ middlewares={middlewares}
149
+ images={[
150
+ {
151
+ src: exampleImage,
152
+ name: "Seve's Desk",
153
+ regions: testRegions,
154
+ },
155
+ ]}
156
+ />
157
+ ))
158
+ .add("Annotator with no enabled tools", () => (
159
+ <Annotator
160
+ onExit={actionAddon("onExit")}
161
+ enabledTools={[]}
162
+ showTags={false}
163
+ middlewares={middlewares}
164
+ images={[
165
+ {
166
+ src: exampleImage,
167
+ name: "Seve's Desk",
168
+ regions: testRegions,
169
+ },
170
+ ]}
171
+ />
172
+ ))
173
+ .add("Bounding Box Annotator with output to console.log", () => (
174
+ <Annotator
175
+ onExit={(out) => {
176
+ window.lastOutput = out
177
+ console.log(out)
178
+ }}
179
+ taskDescription={`## Annotate Hands\nDraw a bounding box around each hand.`}
180
+ enabledTools={["select", "create-box"]}
181
+ regionClsList={["Hand", "Face"]}
182
+ regionTagList={["Open Pinch", "Closed Pinch", "In Frame"]}
183
+ showTags={false}
184
+ images={[
185
+ {
186
+ src: "https://s3.amazonaws.com/jobstorage.workaround.online/Atheer/video-frames/VID_20190111_161054.mp4_frame017.png",
187
+ name: "Bounding Box Test",
188
+ regions: [],
189
+ },
190
+ {
191
+ src: "https://s3.amazonaws.com/jobstorage.workaround.online/Atheer/video-frames/VID_20190111_161054.mp4_frame001.png",
192
+ name: "Bounding Box Test",
193
+ regions: [],
194
+ },
195
+ ]}
196
+ />
197
+ ))
198
+ .add("Bounding Box Annotator with allowed area", () => (
199
+ <Annotator
200
+ taskDescription={`## Annotate Hands\nDraw a bounding box around each hand.`}
201
+ enabledTools={["select", "create-box"]}
202
+ regionClsList={["Hand", "Face"]}
203
+ regionTagList={["Open Pinch", "Closed Pinch", "In Frame"]}
204
+ showTags={false}
205
+ allowedArea={{ x: 0, y: 0.6, w: 0.3, h: 0.3 }}
206
+ images={[
207
+ {
208
+ src: "https://s3.amazonaws.com/jobstorage.workaround.online/Atheer/video-frames/VID_20190111_161054.mp4_frame017.png",
209
+ name: "Bounding Box Test",
210
+ regions: [],
211
+ },
212
+ ]}
213
+ />
214
+ ))
215
+ .add("Car Annotation", () => (
216
+ <Annotator
217
+ onExit={actionAddon("onExit")}
218
+ middlewares={middlewares}
219
+ labelImages
220
+ regionClsList={["Car", "Sign", "Construction Barrier"]}
221
+ regionTagList={["Moving", "Stopped", "Obstacle"]}
222
+ imageClsList={["On Street", "Sidewalk", "Other"]}
223
+ // imageTagList={["tag1", "tag2", "tag3"]}
224
+ images={[
225
+ {
226
+ src: bikeImg1,
227
+ name: "Frame 03021",
228
+ regions: [
229
+ {
230
+ cls: "Car",
231
+ color: "hsl(82,100%,50%)",
232
+ h: 0.45921666772960146,
233
+ w: 0.3932156342484836,
234
+ x: 0.6302148980776354,
235
+ y: 0.5559504689545722,
236
+ type: "box",
237
+ id: "8776160642957009",
238
+ tags: ["Stopped"],
239
+ highlighted: false,
240
+ editingLabels: false,
241
+ },
242
+ {
243
+ cls: "Car",
244
+ color: "hsl(264,100%,50%)",
245
+ type: "box",
246
+ id: "885140028730734",
247
+ tags: ["Moving"],
248
+ w: 0.2627711048576583,
249
+ x: 0.20751775748638238,
250
+ y: 0.5566583219431673,
251
+ h: 0.268717618171478,
252
+ highlighted: false,
253
+ editingLabels: false,
254
+ },
255
+ {
256
+ cls: "Car",
257
+ color: "hsl(127,100%,50%)",
258
+ w: 0.033016094117647055,
259
+ x: 0.5051247779336334,
260
+ y: 0.5396378545840628,
261
+ h: 0.03423999999999994,
262
+ type: "box",
263
+ id: "5952553512262024",
264
+ tags: ["Stopped"],
265
+ highlighted: false,
266
+ editingLabels: false,
267
+ },
268
+ {
269
+ type: "box",
270
+ x: 0.7847296794208894,
271
+ y: 0.3635007199404308,
272
+ w: 0.04871147880041349,
273
+ h: 0.10995961095800888,
274
+ highlighted: true,
275
+ editingLabels: false,
276
+ color: "hsl(268,100%,50%)",
277
+ id: "5647593040225252",
278
+ cls: "Sign",
279
+ },
280
+ ],
281
+ },
282
+ {
283
+ src: bikeImg2,
284
+ name: "Frame 03022",
285
+ regions: [
286
+ {
287
+ type: "box",
288
+ x: 0.12226982552783494,
289
+ y: 0.5578947368421052,
290
+ w: 0.3301518695958121,
291
+ h: 0.33562583001232194,
292
+ highlighted: false,
293
+ editingLabels: false,
294
+ color: "hsl(171,100%,50%)",
295
+ id: "014393439034159128",
296
+ cls: "Car",
297
+ tags: ["Stopped"],
298
+ },
299
+ {
300
+ type: "box",
301
+ x: 0.5018477698901193,
302
+ y: 0.5954194079501558,
303
+ w: 0.07194249496837657,
304
+ h: 0.06826906557009338,
305
+ highlighted: false,
306
+ editingLabels: false,
307
+ color: "hsl(17,100%,50%)",
308
+ id: "02954614542034717",
309
+ cls: "Car",
310
+ tags: ["Moving"],
311
+ },
312
+ {
313
+ type: "box",
314
+ x: 0.6483083881082046,
315
+ y: 0.6217109311709718,
316
+ w: 0.08786544324705947,
317
+ h: 0.20450608002345438,
318
+ highlighted: true,
319
+ editingLabels: true,
320
+ color: "hsl(337,100%,50%)",
321
+ id: "9124138360972984",
322
+ cls: "Construction Barrier",
323
+ tags: ["Obstacle"],
324
+ },
325
+ {
326
+ type: "box",
327
+ x: 0.7628671305695606,
328
+ y: 0.6299511028935285,
329
+ w: 0.12734928166820647,
330
+ h: 0.2689292407634438,
331
+ highlighted: false,
332
+ editingLabels: false,
333
+ color: "hsl(89,100%,50%)",
334
+ id: "5960600741979638",
335
+ cls: "Construction Barrier",
336
+ },
337
+ {
338
+ type: "box",
339
+ x: 0.5871362440754417,
340
+ y: 0.6232091442114366,
341
+ w: 0.06562102723514573,
342
+ h: 0.15281773012741662,
343
+ highlighted: false,
344
+ editingLabels: false,
345
+ color: "hsl(326,100%,50%)",
346
+ id: "7955287536996538",
347
+ cls: "Construction Barrier",
348
+ },
349
+ {
350
+ type: "box",
351
+ x: 0.42943330004934643,
352
+ y: 0.6054718359824862,
353
+ w: 0.053210066743122564,
354
+ h: 0.054984658299147116,
355
+ highlighted: false,
356
+ editingLabels: false,
357
+ color: "hsl(66,100%,50%)",
358
+ id: "49573139861381166",
359
+ cls: "Car",
360
+ tags: ["Stopped"],
361
+ },
362
+ ],
363
+ },
364
+ ]}
365
+ onExit={(out) => {
366
+ window.lastOutput = out
367
+ console.log(JSON.stringify(out.images))
368
+ }}
369
+ />
370
+ ))
371
+ .add("Annotator blocks scroll from propagating", () => (
372
+ <div style={{ height: "200vh" }}>
373
+ <Annotator
374
+ onExit={actionAddon("onExit")}
375
+ showTags={false}
376
+ middlewares={[
377
+ (store) => (next) => (action) => {
378
+ actionAddon(action.type)(action)
379
+ return next(action)
380
+ },
381
+ ]}
382
+ images={[
383
+ {
384
+ src: exampleImage,
385
+ name: "Seve's Desk",
386
+ regions: testRegions,
387
+ },
388
+ ]}
389
+ />
390
+ <div style={{ color: "red" }}>You shouldn't be able to see this</div>
391
+ </div>
392
+ ))
393
+ .add("Annotator should not expand beyond parent", () => (
394
+ <div
395
+ style={{
396
+ width: "100vw",
397
+ height: "100vh",
398
+ padding: 100,
399
+ boxSizing: "border-box",
400
+ }}
401
+ >
402
+ <Annotator
403
+ onExit={actionAddon("onExit")}
404
+ showTags={false}
405
+ middlewares={[
406
+ (store) => (next) => (action) => {
407
+ actionAddon(action.type)(action)
408
+ return next(action)
409
+ },
410
+ ]}
411
+ images={[
412
+ {
413
+ src: exampleImage,
414
+ name: "Seve's Desk",
415
+ regions: testRegions,
416
+ },
417
+ ]}
418
+ />
419
+ </div>
420
+ ))
421
+ .add("Video with frames as each image", () => (
422
+ <div
423
+ style={{
424
+ width: "100vw",
425
+ height: "100vh",
426
+ boxSizing: "border-box",
427
+ }}
428
+ >
429
+ <Annotator
430
+ onExit={actionAddon("onExit")}
431
+ showTags={false}
432
+ middlewares={[
433
+ (store) => (next) => (action) => {
434
+ actionAddon(action.type)(action)
435
+ return next(action)
436
+ },
437
+ ]}
438
+ images={[
439
+ {
440
+ src: "https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4",
441
+ frameTime: 0,
442
+ name: "Frame 1",
443
+ },
444
+ {
445
+ src: "https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4",
446
+ frameTime: 4500,
447
+ name: "Frame 2",
448
+ },
449
+ ]}
450
+ />
451
+ </div>
452
+ ))
453
+ .add("Keyframe video", () => (
454
+ <div
455
+ style={{
456
+ width: "100vw",
457
+ height: "100vh",
458
+ boxSizing: "border-box",
459
+ }}
460
+ >
461
+ <Annotator
462
+ onExit={(...args) => {
463
+ console.log(...args)
464
+ actionAddon("onExit")(...args)
465
+ }}
466
+ showTags
467
+ videoSrc="https://s3.amazonaws.com/asset.workaround.online/SampleVideo_1280x720_1mb.mp4"
468
+ videoTime={1000}
469
+ keyframes={{
470
+ 0: {
471
+ regions: [
472
+ {
473
+ type: "point",
474
+ x: 0.1608187134502924,
475
+ y: 0.5769980506822612,
476
+ highlighted: true,
477
+ editingLabels: false,
478
+ color: "hsl(238,100%,50%)",
479
+ id: "9995495728521284",
480
+ },
481
+ {
482
+ type: "box",
483
+ x: 0.089171974522293,
484
+ y: 0.36801132342533616,
485
+ w: 0.30573248407643316,
486
+ h: 0.4170794998820476,
487
+ highlighted: true,
488
+ editingLabels: false,
489
+ color: "hsl(263,100%,50%)",
490
+ id: "04858393322065635",
491
+ },
492
+ ],
493
+ },
494
+ 3333: {
495
+ regions: [
496
+ {
497
+ type: "point",
498
+ x: 0.1608187134502924,
499
+ y: 0.5769980506822612,
500
+ highlighted: true,
501
+ editingLabels: false,
502
+ color: "hsl(238,100%,50%)",
503
+ id: "9995495728521284",
504
+ },
505
+ {
506
+ type: "box",
507
+ x: 0.14861995753715496,
508
+ y: 0.0934182590233546,
509
+ w: 0.3163481953290871,
510
+ h: 0.7596131163010142,
511
+ highlighted: true,
512
+ editingLabels: false,
513
+ color: "hsl(263,100%,50%)",
514
+ id: "04858393322065635",
515
+ },
516
+ ],
517
+ },
518
+ }}
519
+ />
520
+ </div>
521
+ ))
522
+ .add("Override Next/Prev Button Handling", () => {
523
+ const images = [
524
+ exampleImage,
525
+ "https://loremflickr.com/100/100/cars?lock=1",
526
+ "https://loremflickr.com/100/100/cars?lock=2",
527
+ ]
528
+ const [selectedImageIndex, changeSelectedImageIndex] = useState(0)
529
+
530
+ return (
531
+ <Annotator
532
+ onExit={actionAddon("onExit")}
533
+ onNextImage={() => {
534
+ actionAddon("onNextImage")()
535
+ changeSelectedImageIndex((selectedImageIndex + 1) % 3)
536
+ }}
537
+ onPrevImage={() => {
538
+ actionAddon("onPrevImage")()
539
+ changeSelectedImageIndex((selectedImageIndex - 1 + 3) % 3)
540
+ }}
541
+ labelImages
542
+ selectedImage={images[selectedImageIndex]}
543
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
544
+ imageClsList={["Alpha", "Beta", "Charlie", "Delta"]}
545
+ images={[
546
+ {
547
+ src: exampleImage,
548
+ name: "Seve's Desk",
549
+ },
550
+ {
551
+ src: images[1],
552
+ name: "Frame 0036",
553
+ },
554
+ {
555
+ src: images[2],
556
+ name: "Frame 0037",
557
+ },
558
+ ]}
559
+ />
560
+ )
561
+ })
562
+ .add("Override RegionEditLabel", () => {
563
+ const images = [
564
+ exampleImage,
565
+ "https://loremflickr.com/100/100/cars?lock=1",
566
+ "https://loremflickr.com/100/100/cars?lock=2",
567
+ ]
568
+
569
+ const NewRegionEditLabel = ({
570
+ region,
571
+ editing,
572
+ onDelete,
573
+ onChange,
574
+ onClose,
575
+ onOpen,
576
+ }) => {
577
+ return (
578
+ <div style={{ backgroundColor: "white" }}>
579
+ I'm the closed part
580
+ <div style={{ display: editing ? "block" : "none" }}>
581
+ I'm the part that shows when it's being edited!
582
+ <button onClick={() => onDelete(region)}>Delete This Region</button>
583
+ <button
584
+ onClick={() => onChange({ ...region, cls: "awesome-value" })}
585
+ >
586
+ Set Classification to "awesome-value"
587
+ </button>
588
+ <button onClick={() => onClose(region)}>Close the edit mode</button>
589
+ </div>
590
+ </div>
591
+ )
592
+ }
593
+
594
+ return (
595
+ <Annotator
596
+ onExit={actionAddon("onExit")}
597
+ labelImages
598
+ selectedImage={images[0]}
599
+ RegionEditLabel={NewRegionEditLabel}
600
+ images={[
601
+ {
602
+ src: exampleImage,
603
+ name: "Seve's Desk",
604
+ },
605
+ {
606
+ src: images[1],
607
+ name: "Frame 0036",
608
+ },
609
+ {
610
+ src: images[2],
611
+ name: "Frame 0037",
612
+ },
613
+ ]}
614
+ />
615
+ )
616
+ })
617
+ .add("Two on sample page w/ hotkeys", () => {
618
+ return (
619
+ <HotKeys keyMap={defaultKeyMap}>
620
+ <div>
621
+ <div style={{ height: 600 }}>
622
+ <Annotator
623
+ onExit={actionAddon("onExit")}
624
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
625
+ imageClsList={["Alpha", "Beta", "Charlie", "Delta"]}
626
+ middlewares={[
627
+ (store) => (next) => (action) => {
628
+ actionAddon(action.type)(action)
629
+ return next(action)
630
+ },
631
+ ]}
632
+ images={[
633
+ {
634
+ src: exampleImage,
635
+ name: "Seve's Desk",
636
+ regions: testRegions,
637
+ },
638
+ ]}
639
+ />
640
+ </div>
641
+ <div style={{ height: 600 }}>
642
+ <Annotator
643
+ onExit={actionAddon("onExit")}
644
+ middlewares={[
645
+ (store) => (next) => (action) => {
646
+ actionAddon(action.type)(action)
647
+ return next(action)
648
+ },
649
+ ]}
650
+ images={[
651
+ {
652
+ src: exampleImage,
653
+ name: "Seve's Desk",
654
+ regions: testRegions,
655
+ },
656
+ ]}
657
+ />
658
+ </div>
659
+ </div>
660
+ </HotKeys>
661
+ )
662
+ })
663
+ .add("CORs Error (Pixel Segmentation)", () => (
664
+ <Annotator
665
+ onExit={actionAddon("onExit")}
666
+ middlewares={middlewares}
667
+ labelImages
668
+ fullImageSegmentationMode
669
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
670
+ images={[
671
+ {
672
+ src: "https://placebear.com/200/300",
673
+ name: "Frame 0036",
674
+ },
675
+ ]}
676
+ />
677
+ ))
678
+ .add("Modify Allowed Area", () => (
679
+ <Annotator
680
+ onExit={actionAddon("onExit")}
681
+ middlewares={middlewares}
682
+ labelImages
683
+ fullImageSegmentationMode
684
+ allowedArea={{ x: 0, y: 0.6, w: 0.3, h: 0.3 }}
685
+ enabledTools={["modify-allowed-area"]}
686
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
687
+ images={[
688
+ {
689
+ src: exampleImage,
690
+ name: "Frame 0036",
691
+ },
692
+ ]}
693
+ />
694
+ ))
695
+ .add("Hide Next, Hide Header Text", () => (
696
+ <Annotator
697
+ onExit={actionAddon("onExit")}
698
+ labelImages
699
+ hideNext
700
+ hideHeaderText
701
+ fullImageSegmentationMode
702
+ enabledTools={["modify-allowed-area"]}
703
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
704
+ images={[
705
+ {
706
+ src: exampleImage,
707
+ name: "Frame 0036",
708
+ },
709
+ ]}
710
+ />
711
+ ))
712
+ .add("Hide Header", () => (
713
+ <Annotator
714
+ onExit={actionAddon("onExit")}
715
+ labelImages
716
+ hideHeader
717
+ fullImageSegmentationMode
718
+ enabledTools={["modify-allowed-area"]}
719
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
720
+ images={[
721
+ {
722
+ src: exampleImage,
723
+ name: "Frame 0036",
724
+ },
725
+ ]}
726
+ />
727
+ ))