Skip to content

Commit e7cf330

Browse files
authored
feat: Merge pull request #75 from waoai/feat/zoom-on-allowed-area
Zoom on Allowed Area, Update react material workspace layout
2 parents 209acae + 7874868 commit e7cf330

File tree

6 files changed

+73
-23
lines changed

6 files changed

+73
-23
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
"material-survey": "^1.0.34",
1515
"mmgc1-cpp": "^1.0.50",
1616
"moment": "^2.23.0",
17-
"react-full-screen": "^0.2.4",
17+
"react-full-screen": "^0.3.1",
1818
"react-hotkeys": "^2.0.0",
1919
"react-json-view": "^1.19.1",
2020
"react-markdown": "^4.0.6",
21-
"react-material-workspace-layout": "^0.1.16",
21+
"react-material-workspace-layout": "^0.1.17",
2222
"react-monaco-editor": "^0.25.1",
2323
"react-remove-scroll": "^2.0.4",
2424
"react-select": "^3.0.8",

src/ImageCanvas/index.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
// @flow weak
22

3-
import React, { useRef, useState, useLayoutEffect, useMemo } from "react"
3+
import React, {
4+
useRef,
5+
useState,
6+
useLayoutEffect,
7+
useEffect,
8+
useMemo,
9+
} from "react"
410
import type { Node } from "react"
511
import { Matrix } from "transformation-matrix-js"
612
import Crosshairs from "../Crosshairs"
@@ -48,6 +54,7 @@ type Props = {
4854
allowedArea?: { x: number, y: number, w: number, h: number },
4955
RegionEditLabel?: Node,
5056
videoPlaying?: boolean,
57+
zoomOnAllowedArea?: boolean,
5158
fullImageSegmentationMode?: boolean,
5259
autoSegmentationOptions?: Object,
5360

@@ -70,7 +77,15 @@ type Props = {
7077
onChangeVideoPlaying?: Function,
7178
}
7279

73-
const getDefaultMat = () => Matrix.from(1, 0, 0, 1, -10, -10)
80+
const getDefaultMat = (allowedArea = null, { iw, ih } = {}) => {
81+
let mat = Matrix.from(1, 0, 0, 1, -10, -10)
82+
if (allowedArea && iw) {
83+
mat = mat
84+
.translate(allowedArea.x * iw, allowedArea.y * ih)
85+
.scaleU(allowedArea.w + 0.05)
86+
}
87+
return mat
88+
}
7489

7590
export const ImageCanvas = ({
7691
regions,
@@ -110,6 +125,7 @@ export const ImageCanvas = ({
110125
onChangeVideoTime,
111126
onChangeVideoPlaying,
112127
onRegionClassAdded,
128+
zoomOnAllowedArea = true,
113129
}: Props) => {
114130
const classes = useStyles()
115131

@@ -155,6 +171,7 @@ export const ImageCanvas = ({
155171

156172
const [imageDimensions, changeImageDimensions] = useState()
157173
const imageLoaded = Boolean(imageDimensions && imageDimensions.naturalWidth)
174+
158175
const onVideoOrImageLoaded = useEventCallback(
159176
({ naturalWidth, naturalHeight, duration }) => {
160177
const dims = { naturalWidth, naturalHeight, duration }
@@ -190,6 +207,17 @@ export const ImageCanvas = ({
190207
}
191208
}
192209

210+
useEffect(() => {
211+
if (!imageLoaded) return
212+
changeMat(
213+
getDefaultMat(
214+
zoomOnAllowedArea ? allowedArea : null,
215+
layoutParams.current
216+
)
217+
)
218+
// eslint-disable-next-line
219+
}, [imageLoaded])
220+
193221
useLayoutEffect(() => {
194222
if (!imageDimensions) return
195223
const { clientWidth, clientHeight } = canvas

src/ImageCanvas/index.story.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ const events = {
9696

9797
onChangeRegion: action("onChangeRegion"),
9898
onBeginRegionEdit: action("onBeginRegionEdit"),
99-
onChangeRegion: action("onChangeRegion"),
10099
onCloseRegionEdit: action("onCloseRegionEdit"),
101100

102101
onSelectRegion: action("onSelectRegion"),
@@ -139,3 +138,13 @@ storiesOf("ImageCanvas", module)
139138
{...events}
140139
/>
141140
))
141+
.add("Allowed Area (2)", () => (
142+
<ImageCanvas
143+
showTags
144+
regions={[]}
145+
imageSrc={exampleImage}
146+
zoomWithPrimary
147+
allowedArea={{ x: 0.6, y: 0.6, w: 0.2, h: 0.2 }}
148+
{...events}
149+
/>
150+
))

src/MainLayout/index.js

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import useKey from "use-key-hook"
1010
import classnames from "classnames"
1111
import { useSettings } from "../SettingsProvider"
1212
import SettingsDialog from "../SettingsDialog"
13-
import Fullscreen from "../Fullscreen"
13+
// import Fullscreen from "../Fullscreen"
14+
import { FullScreen, useFullScreenHandle } from "react-full-screen"
1415
import getActiveImage from "../Annotator/reducers/get-active-image"
1516
import useImpliedVideoRegions from "./use-implied-video-regions"
1617
import { useDispatchHotkeyHandlers } from "../ShortcutsManager"
@@ -55,6 +56,7 @@ export const MainLayout = ({
5556
}: Props) => {
5657
const classes = useStyles()
5758
const settings = useSettings()
59+
const fullScreenHandle = useFullScreenHandle()
5860

5961
const memoizedActionFns = useRef({})
6062
const action = (type: string, ...params: Array<string>) => {
@@ -103,6 +105,10 @@ export const MainLayout = ({
103105
const canvas = (
104106
<ImageCanvas
105107
{...settings}
108+
showCrosshairs={
109+
settings.showCrosshairs &&
110+
!["select", "pan", "zoom"].includes(state.selectedTool)
111+
}
106112
key={state.selectedImage}
107113
showMask={state.showMask}
108114
fullImageSegmentationMode={state.fullImageSegmentationMode}
@@ -165,6 +171,11 @@ export const MainLayout = ({
165171
})
166172

167173
const onClickHeaderItem = useEventCallback((item) => {
174+
if (item.name === "Fullscreen") {
175+
fullScreenHandle.enter()
176+
} else if (item.name === "Window") {
177+
fullScreenHandle.exit()
178+
}
168179
dispatch({ type: "HEADER_BUTTON_CLICKED", buttonName: item.name })
169180
})
170181

@@ -173,11 +184,12 @@ export const MainLayout = ({
173184
!nextImage || (nextImage.regions && nextImage.regions.length > 0)
174185

175186
return (
176-
<Fullscreen
177-
enabled={state.fullScreen}
187+
<FullScreen
188+
handle={fullScreenHandle}
178189
onChange={(open) => {
179190
if (!open) {
180-
action("HEADER_BUTTON_CLICKED", "buttonName")("Exit Fullscreen")
191+
fullScreenHandle.exit()
192+
action("HEADER_BUTTON_CLICKED", "buttonName")("Window")
181193
}
182194
}}
183195
>
@@ -323,7 +335,7 @@ export const MainLayout = ({
323335
}
324336
/>
325337
</HotkeyDiv>
326-
</Fullscreen>
338+
</FullScreen>
327339
)
328340
}
329341

src/RegionShapes/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ const RegionComponents = {
2424
strokeWidth={2}
2525
x={0}
2626
y={0}
27-
width={region.w * iw}
28-
height={region.h * ih}
27+
width={Math.max(region.w * iw, 0)}
28+
height={Math.max(region.h * ih, 0)}
2929
stroke={colorAlpha(region.color, 0.75)}
3030
fill={colorAlpha(region.color, 0.25)}
3131
/>
@@ -80,6 +80,7 @@ const RegionComponents = {
8080
/>
8181
{points.map(({ x, y, angle }, i) => (
8282
<g
83+
key={i}
8384
transform={`translate(${x * iw} ${y * ih}) rotate(${
8485
(-(angle || 0) * 180) / Math.PI
8586
})`}
@@ -156,6 +157,7 @@ export const RegionShapes = ({
156157
}}
157158
>
158159
<WrappedRegionList
160+
key="wrapped-region-list"
159161
regions={regions}
160162
iw={iw}
161163
ih={ih}

yarn.lock

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8419,7 +8419,7 @@ fs.realpath@^1.0.0:
84198419
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
84208420
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
84218421

8422-
fscreen@^1.0.1:
8422+
fscreen@^1.0.2:
84238423
version "1.0.2"
84248424
resolved "https://registry.yarnpkg.com/fscreen/-/fscreen-1.0.2.tgz#c4c51d96d819d75a19d728e0df445f9be9bb984f"
84258425
integrity sha1-xMUdltgZ11oZ1yjg30Rfm+m7mE8=
@@ -14459,13 +14459,12 @@ react-focus-lock@^2.1.0:
1445914459
use-callback-ref "^1.2.1"
1446014460
use-sidecar "^1.0.1"
1446114461

14462-
react-full-screen@^0.2.4:
14463-
version "0.2.4"
14464-
resolved "https://registry.yarnpkg.com/react-full-screen/-/react-full-screen-0.2.4.tgz#e5bda9535abb6523b65e0e46526c8f21be65ef7e"
14465-
integrity sha512-K6V87g/uopQnnebg6/jM7VL3FcurgCIQU4nTkzknbjGOT9XOOxr3XVwRweI8QPn1TFRZH7j5OpHanUdk5uYlBQ==
14462+
react-full-screen@^0.3.1:
14463+
version "0.3.1"
14464+
resolved "https://registry.yarnpkg.com/react-full-screen/-/react-full-screen-0.3.1.tgz#60bf7b1ab140348bcfee4f5c98e927b6a0766809"
14465+
integrity sha512-lguQkP+vqwyZGHsLXvM90d8Aktp4gTlPUzszYKuQ9YvxNXIXtu+BILdwr/T+j6P2jREvEppgV20UEauv/0WLDg==
1446614466
dependencies:
14467-
"@types/react" "*"
14468-
fscreen "^1.0.1"
14467+
fscreen "^1.0.2"
1446914468

1447014469
react-github-btn@^1.1.1:
1447114470
version "1.1.1"
@@ -14547,10 +14546,10 @@ react-markdown@^4.0.6:
1454714546
unist-util-visit "^1.3.0"
1454814547
xtend "^4.0.1"
1454914548

14550-
react-material-workspace-layout@^0.1.16:
14551-
version "0.1.16"
14552-
resolved "https://registry.yarnpkg.com/react-material-workspace-layout/-/react-material-workspace-layout-0.1.16.tgz#fa51c8a52e19cc3f8cc1627d69f761851447621e"
14553-
integrity sha512-knxP+1dYMueWdpp/LZoTt23P5LJjtoexZsKBTgRZFMZwvc1uXSK3u2Lwxf6jw5AMI55mrTrWNhB7aqOpzROtjA==
14549+
react-material-workspace-layout@^0.1.17:
14550+
version "0.1.17"
14551+
resolved "https://registry.yarnpkg.com/react-material-workspace-layout/-/react-material-workspace-layout-0.1.17.tgz#98a997e7d8671444fafe53caa4298b6643d1b9cb"
14552+
integrity sha512-GY+jFZ14IYKyzIW/KI8/R0Mttb5dTRdYDKdj++YAU/Z3HSQ7kZJ678mv5Nl7X0o081IpMFg5CRiBvvdozUmBtQ==
1455414553
dependencies:
1455514554
"@material-ui/core" "^4.10.0"
1455614555
"@material-ui/icons" "^4.9.1"

0 commit comments

Comments
 (0)