@searpent/react-image-annotate 2.0.5 → 2.0.6

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 (195) hide show
  1. package/Annotator/examplePhotos.js +6976 -0
  2. package/Annotator/index.js +262 -0
  3. package/Annotator/reducers/combine-reducers.js +14 -0
  4. package/Annotator/reducers/convert-expanding-line-to-polygon.js +73 -0
  5. package/{src/Annotator → Annotator}/reducers/fix-twisted.js +3 -5
  6. package/Annotator/reducers/general-reducer.js +1152 -0
  7. package/Annotator/reducers/get-active-image.js +27 -0
  8. package/Annotator/reducers/get-implied-video-regions.js +180 -0
  9. package/Annotator/reducers/history-handler.js +38 -0
  10. package/Annotator/reducers/image-reducer.js +20 -0
  11. package/Annotator/reducers/video-reducer.js +88 -0
  12. package/ClassSelectionMenu/index.js +135 -0
  13. package/Crosshairs/index.js +53 -0
  14. package/DebugSidebarBox/index.js +20 -0
  15. package/DemoSite/Editor.js +194 -0
  16. package/DemoSite/ErrorBoundaryDialog.js +64 -0
  17. package/DemoSite/index.js +40 -0
  18. package/Editor/annotation-plugin/annotation.js +613 -0
  19. package/Editor/index.js +57 -0
  20. package/{src/Editor → Editor}/tools.js +2 -3
  21. package/FullImageSegmentationAnnotator/index.js +7 -0
  22. package/GroupSelectorSidebarBox/index.js +63 -0
  23. package/HighlightBox/index.js +99 -0
  24. package/HistorySidebarBox/index.js +71 -0
  25. package/ImageCanvas/index.js +429 -0
  26. package/ImageCanvas/region-tools.js +165 -0
  27. package/{src/ImageCanvas → ImageCanvas}/styles.js +12 -8
  28. package/ImageCanvas/use-mouse.js +180 -0
  29. package/ImageCanvas/use-project-box.js +27 -0
  30. package/ImageCanvas/use-wasd-mode.js +62 -0
  31. package/ImageMask/index.js +133 -0
  32. package/ImageMask/load-image.js +25 -0
  33. package/ImageSelectorSidebarBox/index.js +60 -0
  34. package/KeyframeTimeline/get-time-string.js +27 -0
  35. package/KeyframeTimeline/index.js +233 -0
  36. package/KeyframesSelectorSidebarBox/index.js +93 -0
  37. package/LandingPage/index.js +159 -0
  38. package/MainLayout/icon-dictionary.js +104 -0
  39. package/MainLayout/index.js +469 -0
  40. package/{src/MainLayout → MainLayout}/styles.js +6 -7
  41. package/MainLayout/types.js +0 -0
  42. package/MainLayout/use-implied-video-regions.js +13 -0
  43. package/MetadataEditorSidebarBox/index.js +126 -0
  44. package/PageSelector/index.js +67 -0
  45. package/PointDistances/index.js +73 -0
  46. package/PreventScrollToParents/index.js +51 -0
  47. package/RegionLabel/index.js +205 -0
  48. package/{src/RegionLabel → RegionLabel}/styles.js +12 -15
  49. package/RegionSelectAndTransformBoxes/index.js +167 -0
  50. package/RegionSelectorSidebarBox/index.js +248 -0
  51. package/{src/RegionSelectorSidebarBox → RegionSelectorSidebarBox}/styles.js +13 -14
  52. package/RegionShapes/index.js +294 -0
  53. package/RegionTags/index.js +142 -0
  54. package/SettingsDialog/index.js +52 -0
  55. package/SettingsProvider/index.js +58 -0
  56. package/Shortcuts/ShortcutField.js +46 -0
  57. package/Shortcuts/index.js +133 -0
  58. package/ShortcutsManager/index.js +155 -0
  59. package/Sidebar/index.js +69 -0
  60. package/SidebarBoxContainer/index.js +93 -0
  61. package/SmallToolButton/index.js +42 -0
  62. package/TagsSidebarBox/index.js +105 -0
  63. package/TaskDescriptionSidebarBox/index.js +58 -0
  64. package/Theme/index.js +30 -0
  65. package/VideoOrImageCanvasBackground/index.js +151 -0
  66. package/colors.js +14 -0
  67. package/hooks/use-colors.js +101 -0
  68. package/hooks/use-event-callback.js +10 -0
  69. package/hooks/use-exclude-pattern.js +24 -0
  70. package/hooks/use-load-image.js +26 -0
  71. package/hooks/use-window-size.js +46 -0
  72. package/{src/hooks → hooks}/xpattern.js +1 -1
  73. package/index.js +3 -0
  74. package/lib.js +3 -0
  75. package/package.json +1 -1
  76. package/stories.js +5 -0
  77. package/{src/utils → utils}/filter-only-unique.js +1 -1
  78. package/utils/get-from-local-storage.js +7 -0
  79. package/utils/get-hotkey-help-text.js +9 -0
  80. package/utils/get-landmarks-with-transform.js +40 -0
  81. package/utils/photosToImages.js +53 -0
  82. package/utils/regions-to-blocks.js +16 -0
  83. package/utils/set-in-local-storage.js +3 -0
  84. package/.babelrc +0 -6
  85. package/.env +0 -1
  86. package/.flowconfig +0 -2
  87. package/.github/workflows/release-on-master.yml +0 -32
  88. package/.github/workflows/test.yml +0 -16
  89. package/.prettierrc +0 -3
  90. package/.releaserc.js +0 -18
  91. package/.storybook/addons.js +0 -2
  92. package/.storybook/config.js +0 -16
  93. package/LICENSE +0 -21
  94. package/public/favicon.ico +0 -0
  95. package/public/index.html +0 -38
  96. package/src/Annotator/bike-pic.png +0 -0
  97. package/src/Annotator/bike-pic2.png +0 -0
  98. package/src/Annotator/dab-keyframes.story.json +0 -1
  99. package/src/Annotator/examplePhotos.js +0 -7601
  100. package/src/Annotator/index.js +0 -291
  101. package/src/Annotator/index.story.js +0 -807
  102. package/src/Annotator/poses.story.js +0 -150
  103. package/src/Annotator/reducers/combine-reducers.js +0 -7
  104. package/src/Annotator/reducers/convert-expanding-line-to-polygon.js +0 -53
  105. package/src/Annotator/reducers/general-reducer.js +0 -996
  106. package/src/Annotator/reducers/get-active-image.js +0 -21
  107. package/src/Annotator/reducers/get-implied-video-regions.js +0 -115
  108. package/src/Annotator/reducers/history-handler.js +0 -60
  109. package/src/Annotator/reducers/image-reducer.js +0 -23
  110. package/src/Annotator/reducers/video-reducer.js +0 -85
  111. package/src/Annotator/video.story.js +0 -51
  112. package/src/ClassSelectionMenu/index.js +0 -108
  113. package/src/Crosshairs/index.js +0 -64
  114. package/src/DebugSidebarBox/index.js +0 -36
  115. package/src/DemoSite/Editor.js +0 -235
  116. package/src/DemoSite/ErrorBoundaryDialog.js +0 -34
  117. package/src/DemoSite/index.js +0 -41
  118. package/src/DemoSite/index.story.js +0 -10
  119. package/src/DemoSite/simple-segmentation-example.json +0 -572
  120. package/src/Editor/annotation-plugin/annotation.css +0 -46
  121. package/src/Editor/annotation-plugin/annotation.js +0 -515
  122. package/src/Editor/index.js +0 -24
  123. package/src/FullImageSegmentationAnnotator/hard1.story.jpg +0 -0
  124. package/src/FullImageSegmentationAnnotator/hard2.story.jpg +0 -0
  125. package/src/FullImageSegmentationAnnotator/hard3.story.jpg +0 -0
  126. package/src/FullImageSegmentationAnnotator/index.js +0 -7
  127. package/src/FullImageSegmentationAnnotator/index.story.js +0 -177
  128. package/src/FullImageSegmentationAnnotator/orange.story.png +0 -0
  129. package/src/GroupSelectorSidebarBox/index.js +0 -48
  130. package/src/HighlightBox/index.js +0 -143
  131. package/src/HistorySidebarBox/index.js +0 -78
  132. package/src/ImageCanvas/dancing-man.story.jpg +0 -0
  133. package/src/ImageCanvas/index.js +0 -494
  134. package/src/ImageCanvas/index.story.js +0 -314
  135. package/src/ImageCanvas/mouse_mask.story.png +0 -0
  136. package/src/ImageCanvas/region-tools.js +0 -171
  137. package/src/ImageCanvas/seves_desk.story.jpg +0 -0
  138. package/src/ImageCanvas/use-mouse.js +0 -168
  139. package/src/ImageCanvas/use-project-box.js +0 -23
  140. package/src/ImageCanvas/use-wasd-mode.js +0 -50
  141. package/src/ImageMask/index.js +0 -127
  142. package/src/ImageMask/load-image.js +0 -32
  143. package/src/ImageSelectorSidebarBox/index.js +0 -54
  144. package/src/KeyframeTimeline/get-time-string.js +0 -25
  145. package/src/KeyframeTimeline/index.js +0 -223
  146. package/src/KeyframesSelectorSidebarBox/index.js +0 -93
  147. package/src/LandingPage/content.md +0 -57
  148. package/src/LandingPage/github-markdown.css +0 -964
  149. package/src/LandingPage/index.js +0 -147
  150. package/src/MainLayout/icon-dictionary.js +0 -79
  151. package/src/MainLayout/index.js +0 -510
  152. package/src/MainLayout/index.story.js +0 -240
  153. package/src/MainLayout/types.js +0 -164
  154. package/src/MainLayout/use-implied-video-regions.js +0 -17
  155. package/src/MetadataEditorSidebarBox/index.js +0 -98
  156. package/src/PageSelector/index.js +0 -76
  157. package/src/PageSelector/page-selector.css +0 -69
  158. package/src/PointDistances/index.js +0 -90
  159. package/src/PreventScrollToParents/index.js +0 -48
  160. package/src/PreventScrollToParents/index.story.js +0 -23
  161. package/src/RegionLabel/index.js +0 -222
  162. package/src/RegionSelectAndTransformBoxes/index.js +0 -234
  163. package/src/RegionSelectorSidebarBox/index.js +0 -216
  164. package/src/RegionShapes/index.js +0 -254
  165. package/src/RegionTags/index.js +0 -134
  166. package/src/SettingsDialog/index.js +0 -58
  167. package/src/SettingsProvider/index.js +0 -48
  168. package/src/Shortcuts/ShortcutField.js +0 -44
  169. package/src/Shortcuts/index.js +0 -129
  170. package/src/ShortcutsManager/index.js +0 -162
  171. package/src/Sidebar/index.js +0 -117
  172. package/src/SidebarBoxContainer/index.js +0 -93
  173. package/src/SmallToolButton/index.js +0 -57
  174. package/src/TagsSidebarBox/index.js +0 -93
  175. package/src/TaskDescriptionSidebarBox/index.js +0 -43
  176. package/src/Theme/index.js +0 -36
  177. package/src/VideoOrImageCanvasBackground/index.js +0 -170
  178. package/src/colors.js +0 -32
  179. package/src/hooks/use-colors.js +0 -74
  180. package/src/hooks/use-event-callback.js +0 -11
  181. package/src/hooks/use-exclude-pattern.js +0 -27
  182. package/src/hooks/use-load-image.js +0 -21
  183. package/src/hooks/use-window-size.js +0 -46
  184. package/src/hooks/xpattern.png +0 -0
  185. package/src/index.js +0 -18
  186. package/src/lib.js +0 -7
  187. package/src/screenshot.png +0 -0
  188. package/src/site.css +0 -5
  189. package/src/stories.js +0 -2
  190. package/src/utils/get-from-local-storage.js +0 -7
  191. package/src/utils/get-hotkey-help-text.js +0 -11
  192. package/src/utils/get-landmarks-with-transform.js +0 -23
  193. package/src/utils/photosToImages.js +0 -40
  194. package/src/utils/regions-to-blocks.js +0 -14
  195. package/src/utils/set-in-local-storage.js +0 -6
@@ -1,90 +0,0 @@
1
- // @flow weak
2
-
3
- import React, { Fragment } from "react"
4
- import { styled } from "@mui/material/styles"
5
- import { createTheme, ThemeProvider } from "@mui/material/styles"
6
-
7
- const theme = createTheme()
8
- const Svg = styled("svg")(({ theme }) => ({
9
- pointerEvents: "none",
10
- position: "absolute",
11
- zIndex: 1,
12
- left: 0,
13
- top: 0,
14
- width: "100%",
15
- height: "100%",
16
- "& text": {
17
- fill: "#fff",
18
- },
19
- "& path": {
20
- vectorEffect: "non-scaling-stroke",
21
- strokeWidth: 2,
22
- opacity: 0.5,
23
- stroke: "#FFF",
24
- fill: "none",
25
- strokeDasharray: 5,
26
- animationDuration: "4s",
27
- animationTimingFunction: "linear",
28
- animationIterationCount: "infinite",
29
- animationPlayState: "running",
30
- },
31
- }))
32
-
33
- export const PointDistances = ({
34
- projectRegionBox,
35
- regions,
36
- pointDistancePrecision,
37
- realSize,
38
- }) => {
39
- return (
40
- <ThemeProvider theme={theme}>
41
- <Svg>
42
- {regions
43
- .filter((r1) => r1.type === "point")
44
- .flatMap((r1, i1) =>
45
- regions
46
- .filter((r2, i2) => i2 > i1)
47
- .filter((r2) => r2.type === "point")
48
- .map((r2) => {
49
- const pr1 = projectRegionBox(r1)
50
- const pr2 = projectRegionBox(r2)
51
- const prm = {
52
- x: (pr1.x + pr1.w / 2 + pr2.x + pr2.w / 2) / 2,
53
- y: (pr1.y + pr1.h / 2 + pr2.y + pr2.h / 2) / 2,
54
- }
55
- let displayDistance
56
- if (realSize) {
57
- const { w, h, unitName } = realSize
58
- displayDistance =
59
- Math.sqrt(
60
- Math.pow(r1.x * w - r2.x * w, 2) +
61
- Math.pow(r1.y * h - r2.y * h, 2)
62
- ).toFixed(pointDistancePrecision) + unitName
63
- } else {
64
- displayDistance =
65
- (
66
- Math.sqrt(
67
- Math.pow(r1.x - r2.x, 2) + Math.pow(r1.y - r2.y, 2)
68
- ) * 100
69
- ).toFixed(pointDistancePrecision) + "%"
70
- }
71
- return (
72
- <Fragment>
73
- <path
74
- d={`M${pr1.x + pr1.w / 2},${pr1.y + pr1.h / 2} L${
75
- pr2.x + pr2.w / 2
76
- },${pr2.y + pr2.h / 2}`}
77
- />
78
- <text x={prm.x} y={prm.y}>
79
- {displayDistance}
80
- </text>
81
- </Fragment>
82
- )
83
- })
84
- )}
85
- </Svg>
86
- </ThemeProvider>
87
- )
88
- }
89
-
90
- export default PointDistances
@@ -1,48 +0,0 @@
1
- // @flow
2
-
3
- import React, { useState } from "react"
4
- import { RemoveScroll } from "react-remove-scroll"
5
- import { styled } from "@mui/material/styles"
6
- import { createTheme, ThemeProvider } from "@mui/material/styles"
7
- import useEventCallback from "use-event-callback"
8
-
9
- const theme = createTheme()
10
- const Container = styled("div")(({ theme }) => ({
11
- "& > div": {
12
- width: "100%",
13
- height: "100%",
14
- },
15
- }))
16
-
17
- export const PreventScrollToParents = ({ children, ...otherProps }) => {
18
- const [mouseOver, changeMouseOver] = useState(false)
19
- const onMouseMove = useEventCallback((e) => {
20
- if (!mouseOver) changeMouseOver(true)
21
- if (otherProps.onMouseMove) {
22
- otherProps.onMouseMove(e)
23
- }
24
- })
25
- const onMouseLeave = useEventCallback((e) => {
26
- setTimeout(() => {
27
- if (mouseOver) {
28
- changeMouseOver(false)
29
- }
30
- }, 100)
31
- })
32
-
33
- return (
34
- <ThemeProvider theme={theme}>
35
- <Container
36
- {...otherProps}
37
- onMouseMove={onMouseMove}
38
- onMouseLeave={onMouseLeave}
39
- >
40
- <RemoveScroll enabled={mouseOver} removeScrollBar={false}>
41
- {children}
42
- </RemoveScroll>
43
- </Container>
44
- </ThemeProvider>
45
- )
46
- }
47
-
48
- export default PreventScrollToParents
@@ -1,23 +0,0 @@
1
- // @flow
2
-
3
- import React from "react"
4
-
5
- import { storiesOf } from "@storybook/react"
6
- import { action } from "@storybook/addon-actions"
7
-
8
- import RemoveScrollOnChildren from "./"
9
-
10
- storiesOf("RemoveScrollOnChildren", module).add("Basic", () => (
11
- <div style={{ width: "100vh", textAlign: "center", height: "200vh" }}>
12
- <RemoveScrollOnChildren>
13
- <div
14
- style={{
15
- display: "inline-block",
16
- width: 100,
17
- height: 100,
18
- backgroundColor: "red",
19
- }}
20
- />
21
- </RemoveScrollOnChildren>
22
- </div>
23
- ))
@@ -1,222 +0,0 @@
1
- // @flow
2
-
3
- import React, { useRef, memo } from "react"
4
- import Paper from "@mui/material/Paper"
5
- import { makeStyles } from "@mui/styles"
6
- import { createTheme, ThemeProvider } from "@mui/material/styles"
7
- import styles from "./styles"
8
- import classnames from "classnames"
9
- import type { Region } from "../ImageCanvas/region-tools.js"
10
- import IconButton from "@mui/material/IconButton"
11
- import Button from "@mui/material/Button"
12
- import TrashIcon from "@mui/icons-material/Delete"
13
- import CheckIcon from "@mui/icons-material/Check"
14
- import TextField from "@mui/material/TextField"
15
- import Select from "react-select"
16
- import CreatableSelect from "react-select/creatable"
17
-
18
- import { asMutable } from "seamless-immutable"
19
-
20
- const theme = createTheme()
21
- const useStyles = makeStyles((theme) => styles)
22
-
23
- type Props = {
24
- region: Region,
25
- editing?: boolean,
26
- allowedClasses?: Array<string>,
27
- allowedTags?: Array<string>,
28
- allowedGroups?: Array<{ value: String, label: String }>,
29
- cls?: string,
30
- tags?: Array<string>,
31
- onDelete: (Region) => null,
32
- onChange: (Region) => null,
33
- onClose: (Region) => null,
34
- onOpen: (Region) => null,
35
- onRegionClassAdded: () => {},
36
- allowComments?: boolean,
37
- hideNotEditingLabel?: boolean,
38
- }
39
-
40
- export const RegionLabel = ({
41
- region,
42
- editing,
43
- allowedClasses,
44
- allowedTags,
45
- onDelete,
46
- onChange,
47
- onClose,
48
- onOpen,
49
- onRegionClassAdded,
50
- allowComments,
51
- hideNotEditingLabel,
52
- allowedGroups,
53
- }: Props) => {
54
- const classes = useStyles()
55
- const commentInputRef = useRef(null)
56
- const onCommentInputClick = (_) => {
57
- // The TextField wraps the <input> tag with two divs
58
- const commentInput = commentInputRef.current.children[0].children[0]
59
-
60
- if (commentInput) return commentInput.focus()
61
- }
62
-
63
- if (hideNotEditingLabel && !editing) return null
64
-
65
- return (
66
- <ThemeProvider theme={theme}>
67
- <Paper
68
- onClick={() => (!editing ? onOpen(region) : null)}
69
- className={classnames(classes.regionInfo, {
70
- highlighted: region.highlighted,
71
- })}
72
- >
73
- {!editing ? (
74
- <div>
75
- {region.cls && (
76
- <div className="name">
77
- <div
78
- className="circle"
79
- style={{ backgroundColor: region.color }}
80
- />
81
- {region.cls}
82
- </div>
83
- )}
84
- {region.tags && (
85
- <div className="tags">
86
- {region.tags.map((t) => (
87
- <div key={t} className="tag">
88
- {t}
89
- </div>
90
- ))}
91
- </div>
92
- )}
93
- </div>
94
- ) : (
95
- <div style={{ width: 200 }}>
96
- <div style={{ display: "flex", flexDirection: "row" }}>
97
- <div
98
- style={{
99
- display: "flex",
100
- backgroundColor: region.color || "#888",
101
- color: "#fff",
102
- padding: 4,
103
- paddingLeft: 8,
104
- paddingRight: 8,
105
- borderRadius: 4,
106
- fontWeight: "bold",
107
- textShadow: "0px 0px 5px rgba(0,0,0,0.4)",
108
- }}
109
- >
110
- {region.type}
111
- </div>
112
- <div style={{ flexGrow: 1 }} />
113
- <IconButton
114
- onClick={() => onDelete(region)}
115
- tabIndex={-1}
116
- style={{ width: 22, height: 22 }}
117
- size="small"
118
- variant="outlined"
119
- >
120
- <TrashIcon style={{ marginTop: -8, width: 16, height: 16 }} />
121
- </IconButton>
122
- </div>
123
- {(allowedClasses || []).length > 0 && (
124
- <div style={{ marginTop: 6 }}>
125
- <CreatableSelect
126
- placeholder="Classification"
127
- onChange={(o, actionMeta) => {
128
- if (actionMeta.action == "create-option") {
129
- onRegionClassAdded(o.value)
130
- }
131
- return onChange({
132
- ...(region: any),
133
- cls: o.value,
134
- })
135
- }}
136
- value={
137
- region.cls ? { label: region.cls, value: region.cls } : null
138
- }
139
- options={asMutable(
140
- allowedClasses.map((c) => ({ value: c, label: c }))
141
- )}
142
- />
143
- </div>
144
- )}
145
- {(allowedGroups || []).length > 0 && (
146
- <Select
147
- onChange={(newGroup) => onChange({
148
- ...(region: any),
149
- groupId: newGroup.value,
150
- })
151
-
152
- }
153
- placeholder="Group"
154
- value={
155
- allowedGroups.filter(g => g.value === region.groupId)
156
- }
157
- options={allowedGroups}
158
- />
159
- )}
160
- {(allowedTags || []).length > 0 && (
161
- <div style={{ marginTop: 4 }}>
162
- <Select
163
- onChange={(newTags) =>
164
- onChange({
165
- ...(region: any),
166
- tags: newTags.map((t) => t.value),
167
- })
168
- }
169
- placeholder="Tags"
170
- value={(region.tags || []).map((c) => ({
171
- label: c,
172
- value: c,
173
- }))}
174
- isMulti
175
- options={asMutable(
176
- allowedTags.map((c) => ({ value: c, label: c }))
177
- )}
178
- />
179
- </div>
180
- )}
181
- {allowComments && (
182
- <TextField
183
- InputProps={{
184
- className: classes.commentBox,
185
- }}
186
- fullWidth
187
- multiline
188
- rows={3}
189
- ref={commentInputRef}
190
- onClick={onCommentInputClick}
191
- value={region.comment || ""}
192
- onChange={(event) =>
193
- onChange({ ...(region: any), comment: event.target.value })
194
- }
195
- />
196
- )}
197
- {onClose && (
198
- <div style={{ marginTop: 4, display: "flex" }}>
199
- <div style={{ flexGrow: 1 }} />
200
- <Button
201
- onClick={() => onClose(region)}
202
- size="small"
203
- variant="contained"
204
- color="primary"
205
- >
206
- <CheckIcon />
207
- </Button>
208
- </div>
209
- )}
210
- </div>
211
- )}
212
- </Paper>
213
- </ThemeProvider>
214
- )
215
- }
216
-
217
- export default memo(
218
- RegionLabel,
219
- (prevProps, nextProps) =>
220
- prevProps.editing === nextProps.editing &&
221
- prevProps.region === nextProps.region
222
- )
@@ -1,234 +0,0 @@
1
- import React, { Fragment, memo } from "react"
2
- import HighlightBox from "../HighlightBox"
3
- import { styled } from "@mui/material/styles"
4
- import { createTheme, ThemeProvider } from "@mui/material/styles"
5
- import PreventScrollToParents from "../PreventScrollToParents"
6
- import Tooltip from "@mui/material/Tooltip"
7
-
8
- const theme = createTheme()
9
- const TransformGrabber = styled("div")(({ theme }) => ({
10
- width: 8,
11
- height: 8,
12
- zIndex: 2,
13
- border: "2px solid #FFF",
14
- position: "absolute",
15
- }))
16
-
17
- const boxCursorMap = [
18
- ["nw-resize", "n-resize", "ne-resize"],
19
- ["w-resize", "grab", "e-resize"],
20
- ["sw-resize", "s-resize", "se-resize"],
21
- ]
22
-
23
- const arePropsEqual = (prev, next) => {
24
- return (
25
- prev.region === next.region &&
26
- prev.dragWithPrimary === next.dragWithPrimary &&
27
- prev.createWithPrimary === next.createWithPrimary &&
28
- prev.zoomWithPrimary === next.zoomWithPrimary &&
29
- prev.mat === next.mat
30
- )
31
- }
32
-
33
- export const RegionSelectAndTransformBox = memo(
34
- ({
35
- region: r,
36
- mouseEvents,
37
- projectRegionBox,
38
- dragWithPrimary,
39
- createWithPrimary,
40
- zoomWithPrimary,
41
- onBeginMovePoint,
42
- onSelectRegion,
43
- layoutParams,
44
- fullImageSegmentationMode = false,
45
- mat,
46
- onBeginBoxTransform,
47
- onBeginMovePolygonPoint,
48
- onBeginMoveKeypoint,
49
- onAddPolygonPoint,
50
- showHighlightBox,
51
- }) => {
52
- const pbox = projectRegionBox(r)
53
- const { iw, ih } = layoutParams.current
54
- return (
55
- <ThemeProvider theme={theme}>
56
- <Fragment>
57
- <PreventScrollToParents>
58
- {showHighlightBox && r.type !== "polygon" && (
59
- <HighlightBox
60
- region={r}
61
- mouseEvents={mouseEvents}
62
- dragWithPrimary={dragWithPrimary}
63
- createWithPrimary={createWithPrimary}
64
- zoomWithPrimary={zoomWithPrimary}
65
- onBeginMovePoint={onBeginMovePoint}
66
- onSelectRegion={onSelectRegion}
67
- pbox={pbox}
68
- />
69
- )}
70
- {r.type === "box" &&
71
- !dragWithPrimary &&
72
- !zoomWithPrimary &&
73
- !r.locked &&
74
- r.highlighted &&
75
- mat.a < 1.2 &&
76
- [
77
- [0, 0],
78
- [0.5, 0],
79
- [1, 0],
80
- [1, 0.5],
81
- [1, 1],
82
- [0.5, 1],
83
- [0, 1],
84
- [0, 0.5],
85
- [0.5, 0.5],
86
- ].map(([px, py], i) => (
87
- <TransformGrabber
88
- key={i}
89
- {...mouseEvents}
90
- onMouseDown={(e) => {
91
- if (e.button === 0)
92
- return onBeginBoxTransform(r, [px * 2 - 1, py * 2 - 1])
93
- mouseEvents.onMouseDown(e)
94
- }}
95
- style={{
96
- left: pbox.x - 4 - 2 + pbox.w * px,
97
- top: pbox.y - 4 - 2 + pbox.h * py,
98
- cursor: boxCursorMap[py * 2][px * 2],
99
- borderRadius: px === 0.5 && py === 0.5 ? 4 : undefined,
100
- }}
101
- />
102
- ))}
103
- {r.type === "polygon" &&
104
- !dragWithPrimary &&
105
- !zoomWithPrimary &&
106
- !r.locked &&
107
- r.highlighted &&
108
- r.points.map(([px, py], i) => {
109
- const proj = mat
110
- .clone()
111
- .inverse()
112
- .applyToPoint(px * iw, py * ih)
113
- return (
114
- <TransformGrabber
115
- key={i}
116
- {...mouseEvents}
117
- onMouseDown={(e) => {
118
- if (e.button === 0 && (!r.open || i === 0))
119
- return onBeginMovePolygonPoint(r, i)
120
- mouseEvents.onMouseDown(e)
121
- }}
122
- style={{
123
- cursor: !r.open
124
- ? "move"
125
- : i === 0
126
- ? "pointer"
127
- : undefined,
128
- zIndex: 10,
129
- pointerEvents:
130
- r.open && i === r.points.length - 1
131
- ? "none"
132
- : undefined,
133
- left: proj.x - 4,
134
- top: proj.y - 4,
135
- }}
136
- />
137
- )
138
- })}
139
- {r.type === "polygon" &&
140
- r.highlighted &&
141
- !dragWithPrimary &&
142
- !zoomWithPrimary &&
143
- !r.locked &&
144
- !r.open &&
145
- r.points.length > 1 &&
146
- r.points
147
- .map((p1, i) => [p1, r.points[(i + 1) % r.points.length]])
148
- .map(([p1, p2]) => [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2])
149
- .map((pa, i) => {
150
- const proj = mat
151
- .clone()
152
- .inverse()
153
- .applyToPoint(pa[0] * iw, pa[1] * ih)
154
- return (
155
- <TransformGrabber
156
- key={i}
157
- {...mouseEvents}
158
- onMouseDown={(e) => {
159
- if (e.button === 0)
160
- return onAddPolygonPoint(r, pa, i + 1)
161
- mouseEvents.onMouseDown(e)
162
- }}
163
- style={{
164
- cursor: "copy",
165
- zIndex: 10,
166
- left: proj.x - 4,
167
- top: proj.y - 4,
168
- border: "2px dotted #fff",
169
- opacity: 0.5,
170
- }}
171
- />
172
- )
173
- })}
174
- {r.type === "keypoints" &&
175
- !dragWithPrimary &&
176
- !zoomWithPrimary &&
177
- !r.locked &&
178
- r.highlighted &&
179
- Object.entries(r.points).map(
180
- ([keypointId, { x: px, y: py }], i) => {
181
- const proj = mat
182
- .clone()
183
- .inverse()
184
- .applyToPoint(px * iw, py * ih)
185
- return (
186
- <Tooltip title={keypointId} key={i}>
187
- <TransformGrabber
188
- key={i}
189
- {...mouseEvents}
190
- onMouseDown={(e) => {
191
- if (e.button === 0 && (!r.open || i === 0))
192
- return onBeginMoveKeypoint(r, keypointId)
193
- mouseEvents.onMouseDown(e)
194
- }}
195
- style={{
196
- cursor: !r.open
197
- ? "move"
198
- : i === 0
199
- ? "pointer"
200
- : undefined,
201
- zIndex: 10,
202
- pointerEvents:
203
- r.open && i === r.points.length - 1
204
- ? "none"
205
- : undefined,
206
- left: proj.x - 4,
207
- top: proj.y - 4,
208
- }}
209
- />
210
- </Tooltip>
211
- )
212
- }
213
- )}
214
- </PreventScrollToParents>
215
- </Fragment>
216
- </ThemeProvider>
217
- )
218
- },
219
- arePropsEqual
220
- )
221
-
222
- export const RegionSelectAndTransformBoxes = memo(
223
- (props) => {
224
- return props.regions
225
- .filter((r) => r.visible || r.visible === undefined)
226
- .filter((r) => !r.locked)
227
- .map((r, i) => {
228
- return <RegionSelectAndTransformBox key={r.id} {...props} region={r} />
229
- })
230
- },
231
- (n, p) => n.regions === p.regions && n.mat === p.mat
232
- )
233
-
234
- export default RegionSelectAndTransformBoxes