@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
package/.babelrc ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "presets": [
3
+ [ "react-app", { "absoluteRuntime": false } ]
4
+ ],
5
+ "plugins": ["@babel/plugin-proposal-optional-chaining"]
6
+ }
package/.env ADDED
@@ -0,0 +1 @@
1
+ SKIP_PREFLIGHT_CHECK=true
package/.flowconfig ADDED
@@ -0,0 +1,2 @@
1
+ [options]
2
+ esproposal.optional_chaining=enable
@@ -0,0 +1,32 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ jobs:
7
+ release:
8
+ if: "!contains(github.event.head_commit.message, 'skip ci')"
9
+ name: Release
10
+ runs-on: ubuntu-18.04
11
+ steps:
12
+ - name: Checkout
13
+ uses: actions/checkout@v1
14
+ - name: Setup Node.js
15
+ uses: actions/setup-node@v1
16
+ with:
17
+ node-version: 12
18
+ - name: Install dependencies
19
+ run: npm install
20
+ - name: Build Package
21
+ run: npm run build
22
+ - name: Release
23
+ env:
24
+ GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
25
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
26
+ run: npx semantic-release
27
+ - name: Publish github pages
28
+ run: |
29
+ git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/waoai/react-image-annotate.git
30
+ npm run gh-pages -- -u "github-actions-bot <support+actions@github.com>"
31
+ env:
32
+ GITHUB_TOKEN: ${{ secrets.RELEASE_GITHUB_TOKEN }}
@@ -0,0 +1,16 @@
1
+ name: Test
2
+ on: ["push", "pull_request"]
3
+ jobs:
4
+ test:
5
+ if: "!contains(github.event.head_commit.message, 'skip ci')"
6
+ name: Test
7
+ runs-on: ubuntu-18.04
8
+ steps:
9
+ - name: Checkout
10
+ uses: actions/checkout@v1
11
+ - name: Setup Node.js
12
+ uses: actions/setup-node@v1
13
+ with:
14
+ node-version: 12
15
+ - name: Run Prettier Test
16
+ run: npx prettier --check "src/**/*.js"
package/.prettierrc ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "semi": false
3
+ }
package/.releaserc.js ADDED
@@ -0,0 +1,18 @@
1
+ module.exports = {
2
+ branch: "master",
3
+ plugins: [
4
+ "@semantic-release/commit-analyzer",
5
+ "@semantic-release/release-notes-generator",
6
+ ["@semantic-release/npm", { npmPublish: false }],
7
+ ["@semantic-release/npm", { npmPublish: true, pkgRoot: "dist" }],
8
+ "@semantic-release/github",
9
+ [
10
+ "@semantic-release/git",
11
+ {
12
+ assets: ["package.json"],
13
+ message:
14
+ "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
15
+ },
16
+ ],
17
+ ],
18
+ }
@@ -0,0 +1,2 @@
1
+ import '@storybook/addon-actions/register';
2
+ import '@storybook/addon-links/register';
@@ -0,0 +1,16 @@
1
+ // @flow
2
+
3
+ import React from "react"
4
+ import Theme from "../src/Theme"
5
+ import { configure, addDecorator } from "@storybook/react"
6
+ import { action } from "@storybook/addon-actions"
7
+ import SettingsProvider from "../src/SettingsProvider"
8
+
9
+ addDecorator(storyFn => <Theme>{storyFn()}</Theme>)
10
+ // addDecorator(storyFn => <SettingsProvider>{storyFn()}</SettingsProvider>)
11
+
12
+ function loadStories() {
13
+ require("../src/stories")
14
+ }
15
+
16
+ configure(loadStories, module)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 WorkAround Online Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # React Image Annotate (Searpent fork)
2
+
3
+ [![npm version](https://badge.fury.io/js/react-image-annotate.svg)](https://badge.fury.io/js/react-image-annotate)
4
+
5
+ The best image/video annotation tool ever. [Check out the demo here](https://universaldatatool.github.io/react-image-annotate/). Or the [code sandbox here](https://codesandbox.io/s/react-image-annotate-example-38tsc?file=/src/App.js:0-403).
6
+
7
+ ## Sponsors
8
+
9
+ [![wao.ai sponsorship image](https://s3.amazonaws.com/asset.workaround.online/sponsorship-banner-1.png)](https://wao.ai)
10
+
11
+ ## Features
12
+
13
+ - Simple input/output format
14
+ - Bounding Box, Point and Polygon Annotation
15
+ - Zooming, Scaling, Panning
16
+ - Multiple Images
17
+ - Cursor Crosshair
18
+
19
+ ![Screenshot of Annotator](https://user-images.githubusercontent.com/1910070/51199716-83c72080-18c5-11e9-837c-c3a89c8caef4.png)
20
+
21
+ ## Usage
22
+
23
+ `npm install react-image-annotate`
24
+
25
+ ```javascript
26
+ import React from "react";
27
+ import ReactImageAnnotate from "react-image-annotate";
28
+
29
+ const App = () => (
30
+ <ReactImageAnnotate
31
+ labelImages
32
+ regionClsList={["Alpha", "Beta", "Charlie", "Delta"]}
33
+ regionTagList={["tag1", "tag2", "tag3"]}
34
+ images={[
35
+ {
36
+ src: "https://placekitten.com/408/287",
37
+ name: "Image 1",
38
+ regions: []
39
+ }
40
+ ]}
41
+ />
42
+ );
43
+
44
+ export default App;
45
+
46
+ ```
47
+
48
+ To get the proper fonts, make sure to import the Inter UI or Roboto font, the
49
+ following line added to a css file should suffice.
50
+
51
+ ```css
52
+ @import url("https://rsms.me/inter/inter.css");
53
+ ```
54
+
55
+ ## Props
56
+
57
+ All of the following properties can be defined on the Annotator...
58
+
59
+ | Prop | Type (\* = required) | Description | Default |
60
+ | ------------------------ | ------------------------------------------------ | --------------------------------------------------------------------------------------- | ------------- |
61
+ | `taskDescription` | \*`string` | Markdown description for what to do in the image. | |
62
+ | `allowedArea` | `{ x: number, y: number, w: number, h: number }` | Area that is available for annotation. | Entire image. |
63
+ | `regionTagList` | `Array<string>` | Allowed "tags" (mutually inclusive classifications) for regions. | |
64
+ | `regionClsList` | `Array<string>` | Allowed "classes" (mutually exclusive classifications) for regions. | |
65
+ | `imageTagList` | `Array<string>` | Allowed tags for entire image. | |
66
+ | `imageClsList` | `Array<string>` | Allowed classes for entire image. | |
67
+ | `enabledTools` | `Array<string>` | Tools allowed to be used. e.g. "select", "create-point", "create-box", "create-polygon" | Everything. |
68
+ | `showTags` | `boolean` | Show tags and allow tags on regions. | `true` |
69
+ | `selectedImage` | `string` | URL of initially selected image. | |
70
+ | `images` | `Array<Image>` | Array of images to load into annotator | |
71
+ | `showPointDistances` | `boolean` | Show distances between points. | `false` |
72
+ | `pointDistancePrecision` | `number` | Precision on displayed points (e.g. 3 => 0.123) | |
73
+ | `onExit` | `MainLayoutState => any` | Called when "Save" is called. | |
74
+ | `RegionEditLabel` | `Node` | React Node overriding the form to update the region (see [`RegionLabel`](https://github.com/waoai/react-image-annotate/blob/master/src/RegionLabel/index.js)) | |
75
+ | `allowComments` | `boolean` | Show a textarea to add comments on each annotation. | `false` |
76
+ | `hidePrev` | `boolean` | Hide `Previous Image` button from the header bar. | `false` |
77
+ | `hideNext` | `boolean` | Hide `Next Image` button from the header bar. | `false` |
78
+ | `hideClone` | `boolean` | Hide `Clone` button from the header bar. | `false` |
79
+ | `hideSettings` | `boolean` | Hide `Settings` button from the header bar. | `false` |
80
+ | `hideFullScreen` | `boolean` | Hide `FullScreen/Window` button from the header bar. | `false` |
81
+ | `hideSave` | `boolean` | Hide `Save` button from the header bar. | `false` |
82
+
83
+ ## Developers
84
+
85
+ ### Development
86
+
87
+ This project uses [react-storybook](https://storybook.js.org/). To begin developing run the following commands in the cloned repo.
88
+
89
+ 1. `yarn install`
90
+ 2. `yarn storybook`
91
+
92
+ A browser tab will automatically open with the project components.
93
+
94
+ See more details in the [contributing guidelines](https://github.com/waoai/react-image-annotate/wiki/Setup-for-Development).
95
+
96
+ ### Icons
97
+
98
+ Consult these icon repositories:
99
+
100
+ - [Material Icons](https://material.io/tools/icons/)
101
+ - [Font Awesome Icons](https://fontawesome.com/icons?d=gallery&m=free)
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@searpent/react-image-annotate",
3
+ "version": "2.0.0",
4
+ "dependencies": {
5
+ "@emotion/react": "^11.7.0",
6
+ "@emotion/styled": "^11.6.0",
7
+ "@fortawesome/fontawesome-svg-core": "^1.2.12",
8
+ "@fortawesome/free-solid-svg-icons": "^5.6.3",
9
+ "@fortawesome/react-fontawesome": "^0.1.3",
10
+ "@mui/icons-material": "^5.2.1",
11
+ "@mui/material": "^5.2.3",
12
+ "@mui/styles": "^5.2.3",
13
+ "@semantic-release/git": "^9.0.0",
14
+ "autoseg": "^0.0.12",
15
+ "clamp": "^1.0.1",
16
+ "color-alpha": "^1.0.4",
17
+ "get-image-data": "^3.0.1",
18
+ "material-survey": "^2.1.0",
19
+ "mmgc1-cpp": "^1.0.50",
20
+ "moment": "^2.23.0",
21
+ "react": "^17.0.2",
22
+ "react-dom": "^17.0.2",
23
+ "react-full-screen": "^0.3.1",
24
+ "react-hotkeys": "^2.0.0",
25
+ "react-json-view": "^1.19.1",
26
+ "react-markdown": "^4.0.6",
27
+ "react-material-workspace-layout": "^1.0.10",
28
+ "react-monaco-editor": "^0.25.1",
29
+ "react-remove-scroll": "^2.0.4",
30
+ "react-select": "^3.0.8",
31
+ "react-syntax-highlighter": "^12.2.1",
32
+ "react-use": "^13.27.0",
33
+ "react-use-measure": "^2.0.0",
34
+ "seamless-immutable": "^7.1.4",
35
+ "shallow-equal": "^1.2.1",
36
+ "storybook": "^5.3.14",
37
+ "styled-components": "^5.2.1",
38
+ "transformation-matrix-js": "^2.7.6",
39
+ "use-event-callback": "^0.1.0",
40
+ "use-key-hook": "^1.3.0"
41
+ },
42
+ "peerDependencies": {
43
+ "react": "^17.0.0",
44
+ "react-dom": "^17.0.0"
45
+ },
46
+ "homepage": "/react-image-annotate",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/UniversalDataTool/react-image-annotate.git"
50
+ },
51
+ "scripts": {
52
+ "start": "react-scripts start",
53
+ "test": "react-scripts test",
54
+ "eject": "react-scripts eject",
55
+ "storybook": "start-storybook -p 9090 -s public",
56
+ "build": "npm run build:babel && cp ./package.json ./dist/package.json && cp ./README.md ./dist/README.md",
57
+ "dist": "npm run build && cd dist && npm publish",
58
+ "build:babel": "NODE_ENV=production babel ./src --ignore \"src/**/*.story.js\" --out-dir=./dist && rm dist/index.js && cp dist/lib.js dist/index.js",
59
+ "build-storybook": "build-storybook",
60
+ "build:gh-pages": "CI=false react-scripts build && mkdir build/demo && cp build/index.html build/demo/index.html",
61
+ "gh-pages": "npm run build:gh-pages && gh-pages -d build",
62
+ "prettier": "prettier --write \"src/**/*.js\"",
63
+ "prettier:test": "prettier --check \"src/**/*.js\""
64
+ },
65
+ "eslintConfig": {
66
+ "extends": "react-app"
67
+ },
68
+ "browserslist": [
69
+ ">0.2%",
70
+ "not dead",
71
+ "not ie <= 11",
72
+ "not op_mini all"
73
+ ],
74
+ "devDependencies": {
75
+ "@babel/cli": "^7.2.3",
76
+ "@babel/core": "^7.2.2",
77
+ "@babel/plugin-proposal-optional-chaining": "^7.11.0",
78
+ "@storybook/addon-actions": "^5.3.14",
79
+ "@storybook/addon-links": "^5.3.14",
80
+ "@storybook/addons": "^5.3.14",
81
+ "@storybook/react": "^5.3.14",
82
+ "babel-loader": "^8.0.5",
83
+ "babel-preset-react-app": "^7.0.0",
84
+ "gh-pages": "^2.0.1",
85
+ "prettier": "^2.5.1",
86
+ "raw.macro": "^0.3.0",
87
+ "react-github-btn": "^1.1.1",
88
+ "react-scripts": "^3.4.1"
89
+ },
90
+ "prettier": {
91
+ "semi": false
92
+ }
93
+ }
Binary file
@@ -0,0 +1,38 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
+ <meta name="theme-color" content="#000000">
7
+ <!--
8
+ manifest.json provides metadata used when your web app is added to the
9
+ homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
10
+ -->
11
+ <!--
12
+ Notice the use of %PUBLIC_URL% in the tags above.
13
+ It will be replaced with the URL of the `public` folder during the build.
14
+ Only files inside the `public` folder can be referenced from the HTML.
15
+
16
+ Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
17
+ work correctly both with client-side routing and a non-root public URL.
18
+ Learn how to configure a non-root public URL by running `npm run build`.
19
+ -->
20
+ <title>React Image Annotation</title>
21
+ </head>
22
+ <body>
23
+ <noscript>
24
+ You need to enable JavaScript to run this app.
25
+ </noscript>
26
+ <div id="root"></div>
27
+ <!--
28
+ This HTML file is a template.
29
+ If you open it directly in the browser, you will see an empty page.
30
+
31
+ You can add webfonts, meta tags, or analytics to this file.
32
+ The build step will place the bundled scripts into the <body> tag.
33
+
34
+ To begin the development, run `npm start` or `yarn start`.
35
+ To create a production bundle, use `npm run build` or `yarn build`.
36
+ -->
37
+ </body>
38
+ </html>
Binary file
Binary file
@@ -0,0 +1 @@
1
+ {"0":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870222,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4487209921649774,"y":0.2694362475702937},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.41397696660587197,"y":0.3699387395830733},"rightElbow":{"x":0.5906415033470862,"y":0.364704234790741},"rightHand":{"x":0.6542407365739231,"y":0.4002988673786005}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"479":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4673470463145521,"y":0.19100168229192332},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.4404478609960767,"y":0.3051551630931666},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4328309749571659,"y":0.4222888613021013},"rightElbow":{"x":0.5874898343303621,"y":0.3913183287097443},"rightHand":{"x":0.6415204525487472,"y":0.44683362315624264}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"716":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870222,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4363544745930924,"y":0.3228281964520828},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.585930449033987,"y":0.4044864712124663},"rightHand":{"x":0.6389298100563513,"y":0.4411280047587922}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1095":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4746317908870221,"y":0.17626206226677932},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.44737492639237225,"y":0.476382614412626},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5655850955624976,"y":0.42795303711459537},"rightHand":{"x":0.5894808372714573,"y":0.5232999966249137}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1118":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4976149858125678,"y":0.17778527206277028},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.2893273657811563},"leftHand":{"x":0.4455200023009997,"y":0.4826821239054704},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42592776068568866,"y":0.42512094920834825},"rightElbow":{"x":0.5672683442310021,"y":0.42601155864067825},"rightHand":{"x":0.5935719393363946,"y":0.5165015944201626}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1368":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5017798209688135,"y":0.17963630990999058},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.28932736578115625},"leftHand":{"x":0.48879738488820257,"y":0.356707045987093},"rightShoulder":{"x":0.5370532605355843,"y":0.27885835619649174},"leftElbow":{"x":0.4251806625619568,"y":0.4172075506845399},"rightElbow":{"x":0.564526723209169,"y":0.4061013580655783},"rightHand":{"x":0.5498343845048111,"y":0.4866834521414889}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1373":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.585930449033987,"y":0.4044864712124663},"rightHand":{"x":0.5483298762505795,"y":0.4889846449138738}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"1625":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5454579431886196,"y":0.28828477914079875},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5775664698606539,"y":0.4049712346052037},"rightHand":{"x":0.5085707949521467,"y":0.4088800509647476}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"1794":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4893538356154567,"y":0.35528212616454297},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5071732824961516,"y":0.40718439246878346}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"2235":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.48980642347488146,"y":0.3397084520431372},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4257163155055763,"y":0.41564655218944524},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5067367749125811,"y":0.4064483881453737}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"2623":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.45402092826721374,"y":0.28932736578115636},"leftHand":{"x":0.4872300656474055,"y":0.34559726993451106},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42620073914177703,"y":0.4144124037913681},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646187},"rightHand":{"x":0.5089450816218464,"y":0.40579407504633214}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"2864":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.17967333066693503},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.28932736578115636},"leftHand":{"x":0.49311888353877925,"y":0.37176979389617243},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42650163114261314,"y":0.41364583223483053},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5048965193215269,"y":0.43196659900799356}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3001":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4747072291917559,"y":0.48474464491387376},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4251657205994822,"y":0.4170492827140638},"rightElbow":{"x":0.5719572933515534,"y":0.4052963338646188},"rightHand":{"x":0.5262084056623442,"y":0.515722796174378}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3011":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4820773499924534,"y":0.48104008143610855},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4252973252321734,"y":0.41426597685380695},"rightElbow":{"x":0.5725414114822169,"y":0.40306213118302386},"rightHand":{"x":0.5317642509509198,"y":0.517027301883393}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"3091":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.44306393146210193,"y":0.5274963114680574},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.42635016229370254,"y":0.39199952997175247},"rightElbow":{"x":0.5762984362544342,"y":0.41626308463099676},"rightHand":{"x":0.576666487372645,"y":0.5418911996469712}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"3301":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.5018631176719384,"y":0.179673330666935},"sternum":{"x":0.49229824456114357,"y":0.2736238514041595},"leftShoulder":{"x":0.4540209282672138,"y":0.2893273657811563},"leftHand":{"x":0.4105282826954702,"y":0.3656471031771597},"rightShoulder":{"x":0.5370532605355844,"y":0.27885835619649174},"leftElbow":{"x":0.4291138595802166,"y":0.3335501069063595},"rightElbow":{"x":0.5894808372714573,"y":0.3382702534167713},"rightHand":{"x":0.6601060294334938,"y":0.40435230456253646}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"3537":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4307069090274806,"y":0.2278188250731353},"sternum":{"x":0.47318822762118673,"y":0.2957889348230651},"leftShoulder":{"x":0.44823045294738434,"y":0.29295684691681806},"leftHand":{"x":0.4774363594805573,"y":0.22970688367730002},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.4052181178712569,"y":0.3061732571459711},"rightElbow":{"x":0.5931979526484066,"y":0.26746805576059435},"rightHand":{"x":0.6786916063182402,"y":0.2419792646043707}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"4306":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.45490878631628445,"y":0.20669718671199733},"sternum":{"x":0.4775885689464238,"y":0.2942243690185364},"leftShoulder":{"x":0.44427014575467094,"y":0.28669858369870316},"leftHand":{"x":0.4769963253480336,"y":0.2516108049407023},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.41049852746154136,"y":0.34606968516145387},"rightElbow":{"x":0.5999667042505391,"y":0.2735681705235042},"rightHand":{"x":0.6762419117855385,"y":0.24400117278228467}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"4465":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.45991281556065355,"y":0.2023300339169116},"sternum":{"x":0.4784983924454,"y":0.29390087621890043},"leftShoulder":{"x":0.4434513046055924,"y":0.2854046125001592},"leftHand":{"x":0.476905342998136,"y":0.25613970413560605},"rightShoulder":{"x":0.5257588593808981,"y":0.25613970413560605},"leftElbow":{"x":0.4115903156603128,"y":0.3543187515521714},"rightElbow":{"x":0.5990391339550412,"y":0.30428519854180636},"rightHand":{"x":0.6686022931522351,"y":0.30239713993764167}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"4810":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4980040473937477,"y":0.18459443390996827},"sternum":{"x":0.49527667313378676,"y":0.28906389439882496},"leftShoulder":{"x":0.4547879807463942,"y":0.2854046125001592},"leftHand":{"x":0.46466173276607,"y":0.3488485223537189},"rightShoulder":{"x":0.5398163377954923,"y":0.28032461323598334},"leftElbow":{"x":0.42746166225743537,"y":0.39543309702281276},"rightElbow":{"x":0.5844822636231334,"y":0.3969339197196268},"rightHand":{"x":0.6469935239337719,"y":0.42242271087585054}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"4869":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.504518200084045,"y":0.18156138927109972},"sternum":{"x":0.4981460022949891,"y":0.28823670040640625},"leftShoulder":{"x":0.4567267166661256,"y":0.2854046125001592},"leftHand":{"x":0.46256789797276016,"y":0.36470307387507733},"rightShoulder":{"x":0.5422203703359592,"y":0.2844605831980768},"leftElbow":{"x":0.4301758925450592,"y":0.4024642459583717},"rightElbow":{"x":0.5809845735527162,"y":0.38358365991672455},"rightHand":{"x":0.6484236668202246,"y":0.42323289060418356}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5352":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.509297348425837,"y":0.19005765298984095},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.41849352993179006,"y":0.4968671761666076},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.4434513046055924,"y":0.40624036316670115},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.5751433922460815,"y":0.5563410221977962}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5643":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4434513046055924,"y":0.3014531106355593},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.43229995847474456,"y":0.3448784585313478},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.562930013150391,"y":0.5676693738227845}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"5957":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.49389787043561834,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.4588507825958108,"y":0.29201281761473563},"leftHand":{"x":0.45938179907823223,"y":0.2183785320523117},"rightShoulder":{"x":0.5459374857129085,"y":0.29106878831265337},"leftElbow":{"x":0.41477641455484077,"y":0.3175016087709594},"rightElbow":{"x":0.5639920461152337,"y":0.42700900781251294},"rightHand":{"x":0.5868257548593507,"y":0.5553969928957139}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"6182":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4370365444267241,"y":0.27512838513550697},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41660051697537204,"y":0.3458765353125571},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.5993932064495242,"y":0.5457884600719732}},"highlighted":true,"editingLabels":true,"id":"9442418802498487"}]},"6219":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4333619914395872,"y":0.2844605831980768},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.6012305895492022,"y":0.5461532388538225}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6222":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4333619914395872,"y":0.2844605831980768},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5639920461152337,"y":0.427009007812513},"rightHand":{"x":0.6070043811913611,"y":0.5440686412707255}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6594":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4938978704356184,"y":0.19194571159400564},"sternum":{"x":0.5023941341543596,"y":0.2891807297084886},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.4121213321427341,"y":0.3288299603959477},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.41690048048452605,"y":0.350542634343842},"rightElbow":{"x":0.5708952603867109,"y":0.43456124222917186},"rightHand":{"x":0.5985081174726199,"y":0.5563410221977962}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"6901":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.46681602983213083,"y":0.18533750647942915},"sternum":{"x":0.4869946561641412,"y":0.290124759010571},"leftShoulder":{"x":0.45885078259581086,"y":0.2920128176147357},"leftHand":{"x":0.46150586500791746,"y":0.22970688367730002},"rightShoulder":{"x":0.5459374857129086,"y":0.29106878831265337},"leftElbow":{"x":0.40628015083609953,"y":0.3118374329584653},"rightElbow":{"x":0.5512476505371218,"y":0.4364493008333366},"rightHand":{"x":0.5544337494316498,"y":0.5789977254477728}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]},"7267":{"regions":[{"type":"keypoints","keypointsDefinitionId":"human","points":{"head":{"x":0.4439823210880137,"y":0.21932256135439407},"sternum":{"x":0.47637432651571476,"y":0.2891807297084886},"leftShoulder":{"x":0.4370791068165365,"y":0.30522922784388873},"leftHand":{"x":0.46150586500791746,"y":0.22970688367730002},"rightShoulder":{"x":0.5193866615918421,"y":0.2778523780835004},"leftElbow":{"x":0.3945977882228303,"y":0.30994937435430053},"rightElbow":{"x":0.550185617572279,"y":0.43078512502084254},"rightHand":{"x":0.561336963703127,"y":0.5657813152186197}},"highlighted":true,"editingLabels":false,"id":"9442418802498487"}]}}
@@ -0,0 +1,206 @@
1
+ // @flow
2
+
3
+ import type {
4
+ Action,
5
+ Image,
6
+ MainLayoutState,
7
+ Mode,
8
+ ToolEnum,
9
+ } from "../MainLayout/types"
10
+ import React, { useEffect, useReducer } from "react"
11
+ import makeImmutable, { without } from "seamless-immutable"
12
+
13
+ import type { KeypointsDefinition } from "../ImageCanvas/region-tools"
14
+ import MainLayout from "../MainLayout"
15
+ import type { Node } from "react"
16
+ import SettingsProvider from "../SettingsProvider"
17
+ import combineReducers from "./reducers/combine-reducers.js"
18
+ import generalReducer from "./reducers/general-reducer.js"
19
+ import getFromLocalStorage from "../utils/get-from-local-storage"
20
+ import historyHandler from "./reducers/history-handler.js"
21
+ import imageReducer from "./reducers/image-reducer.js"
22
+ import useEventCallback from "use-event-callback"
23
+ import videoReducer from "./reducers/video-reducer.js"
24
+
25
+ type Props = {
26
+ taskDescription?: string,
27
+ allowedArea?: { x: number, y: number, w: number, h: number },
28
+ regionTagList?: Array<string>,
29
+ regionClsList?: Array<string>,
30
+ imageTagList?: Array<string>,
31
+ imageClsList?: Array<string>,
32
+ enabledTools?: Array<string>,
33
+ selectedTool?: String,
34
+ showTags?: boolean,
35
+ selectedImage?: string | number,
36
+ images?: Array<Image>,
37
+ showPointDistances?: boolean,
38
+ pointDistancePrecision?: number,
39
+ RegionEditLabel?: Node,
40
+ onExit: (MainLayoutState) => any,
41
+ videoTime?: number,
42
+ videoSrc?: string,
43
+ keyframes?: Object,
44
+ videoName?: string,
45
+ keypointDefinitions: KeypointsDefinition,
46
+ fullImageSegmentationMode?: boolean,
47
+ autoSegmentationOptions?:
48
+ | {| type: "simple" |}
49
+ | {| type: "autoseg", maxClusters?: number, slicWeightFactor?: number |},
50
+ hideHeader?: boolean,
51
+ hideHeaderText?: boolean,
52
+ hideNext?: boolean,
53
+ hidePrev?: boolean,
54
+ hideClone?: boolean,
55
+ hideSettings?: boolean,
56
+ hideFullScreen?: boolean,
57
+ hideSave?: boolean,
58
+ }
59
+
60
+ export const Annotator = ({
61
+ images,
62
+ allowedArea,
63
+ selectedImage = images && images.length > 0 ? 0 : undefined,
64
+ showPointDistances,
65
+ pointDistancePrecision,
66
+ showTags = getFromLocalStorage("showTags", true),
67
+ enabledTools = [
68
+ "select",
69
+ "create-point",
70
+ "create-box",
71
+ "create-polygon",
72
+ "create-line",
73
+ "create-expanding-line",
74
+ "show-mask",
75
+ ],
76
+ selectedTool = "select",
77
+ regionTagList = [],
78
+ regionClsList = [],
79
+ imageTagList = [],
80
+ imageClsList = [],
81
+ keyframes = {},
82
+ taskDescription = "",
83
+ fullImageSegmentationMode = false,
84
+ RegionEditLabel,
85
+ videoSrc,
86
+ videoTime = 0,
87
+ videoName,
88
+ onExit,
89
+ onNextImage,
90
+ onPrevImage,
91
+ keypointDefinitions,
92
+ autoSegmentationOptions = { type: "autoseg" },
93
+ hideHeader,
94
+ hideHeaderText,
95
+ hideNext,
96
+ hidePrev,
97
+ hideClone,
98
+ hideSettings,
99
+ hideFullScreen,
100
+ hideSave,
101
+ allowComments,
102
+ }: Props) => {
103
+ if (typeof selectedImage === "string") {
104
+ selectedImage = (images || []).findIndex((img) => img.src === selectedImage)
105
+ if (selectedImage === -1) selectedImage = undefined
106
+ }
107
+ const annotationType = images ? "image" : "video"
108
+ const [state, dispatchToReducer] = useReducer(
109
+ historyHandler(
110
+ combineReducers(
111
+ annotationType === "image" ? imageReducer : videoReducer,
112
+ generalReducer
113
+ )
114
+ ),
115
+ makeImmutable({
116
+ annotationType,
117
+ showTags,
118
+ allowedArea,
119
+ showPointDistances,
120
+ pointDistancePrecision,
121
+ selectedTool,
122
+ fullImageSegmentationMode: fullImageSegmentationMode,
123
+ autoSegmentationOptions,
124
+ mode: null,
125
+ taskDescription,
126
+ showMask: true,
127
+ labelImages: imageClsList.length > 0 || imageTagList.length > 0,
128
+ regionClsList,
129
+ regionTagList,
130
+ imageClsList,
131
+ imageTagList,
132
+ currentVideoTime: videoTime,
133
+ enabledTools,
134
+ history: [],
135
+ videoName,
136
+ keypointDefinitions,
137
+ allowComments,
138
+ ...(annotationType === "image"
139
+ ? {
140
+ selectedImage,
141
+ images,
142
+ selectedImageFrameTime:
143
+ images && images.length > 0 ? images[0].frameTime : undefined,
144
+ }
145
+ : {
146
+ videoSrc,
147
+ keyframes,
148
+ }),
149
+ })
150
+ )
151
+
152
+ const dispatch = useEventCallback((action: Action) => {
153
+ if (action.type === "HEADER_BUTTON_CLICKED") {
154
+ if (["Exit", "Done", "Save", "Complete"].includes(action.buttonName)) {
155
+ return onExit(without(state, "history"))
156
+ } else if (action.buttonName === "Next" && onNextImage) {
157
+ return onNextImage(without(state, "history"))
158
+ } else if (action.buttonName === "Prev" && onPrevImage) {
159
+ return onPrevImage(without(state, "history"))
160
+ }
161
+ }
162
+ dispatchToReducer(action)
163
+ })
164
+
165
+ const onRegionClassAdded = useEventCallback((cls) => {
166
+ dispatchToReducer({
167
+ type: "ON_CLS_ADDED",
168
+ cls: cls,
169
+ })
170
+ })
171
+
172
+ useEffect(() => {
173
+ if (selectedImage === undefined) return
174
+ dispatchToReducer({
175
+ type: "SELECT_IMAGE",
176
+ imageIndex: selectedImage,
177
+ image: state.images[selectedImage],
178
+ })
179
+ }, [selectedImage, state.images])
180
+
181
+ if (!images && !videoSrc)
182
+ return 'Missing required prop "images" or "videoSrc"'
183
+
184
+ return (
185
+ <SettingsProvider>
186
+ <MainLayout
187
+ RegionEditLabel={RegionEditLabel}
188
+ alwaysShowNextButton={Boolean(onNextImage)}
189
+ alwaysShowPrevButton={Boolean(onPrevImage)}
190
+ state={state}
191
+ dispatch={dispatch}
192
+ onRegionClassAdded={onRegionClassAdded}
193
+ hideHeader={hideHeader}
194
+ hideHeaderText={hideHeaderText}
195
+ hideNext={hideNext}
196
+ hidePrev={hidePrev}
197
+ hideClone={hideClone}
198
+ hideSettings={hideSettings}
199
+ hideFullScreen={hideFullScreen}
200
+ hideSave={hideSave}
201
+ />
202
+ </SettingsProvider>
203
+ )
204
+ }
205
+
206
+ export default Annotator