Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-image-annotate",
"version": "1.4.1",
"version": "1.4.2",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.12",
"@fortawesome/free-solid-svg-icons": "^5.6.3",
Expand All @@ -14,11 +14,11 @@
"material-survey": "^1.0.34",
"mmgc1-cpp": "^1.0.50",
"moment": "^2.23.0",
"react-full-screen": "^0.2.4",
"react-full-screen": "^0.3.1",
"react-hotkeys": "^2.0.0",
"react-json-view": "^1.19.1",
"react-markdown": "^4.0.6",
"react-material-workspace-layout": "^0.1.16",
"react-material-workspace-layout": "^0.1.17",
"react-monaco-editor": "^0.25.1",
"react-remove-scroll": "^2.0.4",
"react-select": "^3.0.8",
Expand Down
32 changes: 30 additions & 2 deletions src/ImageCanvas/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// @flow weak

import React, { useRef, useState, useLayoutEffect, useMemo } from "react"
import React, {
useRef,
useState,
useLayoutEffect,
useEffect,
useMemo,
} from "react"
import type { Node } from "react"
import { Matrix } from "transformation-matrix-js"
import Crosshairs from "../Crosshairs"
Expand Down Expand Up @@ -48,6 +54,7 @@ type Props = {
allowedArea?: { x: number, y: number, w: number, h: number },
RegionEditLabel?: Node,
videoPlaying?: boolean,
zoomOnAllowedArea?: boolean,
fullImageSegmentationMode?: boolean,
autoSegmentationOptions?: Object,

Expand All @@ -70,7 +77,15 @@ type Props = {
onChangeVideoPlaying?: Function,
}

const getDefaultMat = () => Matrix.from(1, 0, 0, 1, -10, -10)
const getDefaultMat = (allowedArea = null, { iw, ih } = {}) => {
let mat = Matrix.from(1, 0, 0, 1, -10, -10)
if (allowedArea && iw) {
mat = mat
.translate(allowedArea.x * iw, allowedArea.y * ih)
.scaleU(allowedArea.w + 0.05)
}
return mat
}

export const ImageCanvas = ({
regions,
Expand Down Expand Up @@ -110,6 +125,7 @@ export const ImageCanvas = ({
onChangeVideoTime,
onChangeVideoPlaying,
onRegionClassAdded,
zoomOnAllowedArea = true,
}: Props) => {
const classes = useStyles()

Expand Down Expand Up @@ -155,6 +171,7 @@ export const ImageCanvas = ({

const [imageDimensions, changeImageDimensions] = useState()
const imageLoaded = Boolean(imageDimensions && imageDimensions.naturalWidth)

const onVideoOrImageLoaded = useEventCallback(
({ naturalWidth, naturalHeight, duration }) => {
const dims = { naturalWidth, naturalHeight, duration }
Expand Down Expand Up @@ -190,6 +207,17 @@ export const ImageCanvas = ({
}
}

useEffect(() => {
if (!imageLoaded) return
changeMat(
getDefaultMat(
zoomOnAllowedArea ? allowedArea : null,
layoutParams.current
)
)
// eslint-disable-next-line
}, [imageLoaded])

useLayoutEffect(() => {
if (!imageDimensions) return
const { clientWidth, clientHeight } = canvas
Expand Down
11 changes: 10 additions & 1 deletion src/ImageCanvas/index.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ const events = {

onChangeRegion: action("onChangeRegion"),
onBeginRegionEdit: action("onBeginRegionEdit"),
onChangeRegion: action("onChangeRegion"),
onCloseRegionEdit: action("onCloseRegionEdit"),

onSelectRegion: action("onSelectRegion"),
Expand Down Expand Up @@ -139,3 +138,13 @@ storiesOf("ImageCanvas", module)
{...events}
/>
))
.add("Allowed Area (2)", () => (
<ImageCanvas
showTags
regions={[]}
imageSrc={exampleImage}
zoomWithPrimary
allowedArea={{ x: 0.6, y: 0.6, w: 0.2, h: 0.2 }}
{...events}
/>
))
22 changes: 17 additions & 5 deletions src/MainLayout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import useKey from "use-key-hook"
import classnames from "classnames"
import { useSettings } from "../SettingsProvider"
import SettingsDialog from "../SettingsDialog"
import Fullscreen from "../Fullscreen"
// import Fullscreen from "../Fullscreen"
import { FullScreen, useFullScreenHandle } from "react-full-screen"
import getActiveImage from "../Annotator/reducers/get-active-image"
import useImpliedVideoRegions from "./use-implied-video-regions"
import { useDispatchHotkeyHandlers } from "../ShortcutsManager"
Expand Down Expand Up @@ -55,6 +56,7 @@ export const MainLayout = ({
}: Props) => {
const classes = useStyles()
const settings = useSettings()
const fullScreenHandle = useFullScreenHandle()

const memoizedActionFns = useRef({})
const action = (type: string, ...params: Array<string>) => {
Expand Down Expand Up @@ -103,6 +105,10 @@ export const MainLayout = ({
const canvas = (
<ImageCanvas
{...settings}
showCrosshairs={
settings.showCrosshairs &&
!["select", "pan", "zoom"].includes(state.selectedTool)
}
key={state.selectedImage}
showMask={state.showMask}
fullImageSegmentationMode={state.fullImageSegmentationMode}
Expand Down Expand Up @@ -165,6 +171,11 @@ export const MainLayout = ({
})

const onClickHeaderItem = useEventCallback((item) => {
if (item.name === "Fullscreen") {
fullScreenHandle.enter()
} else if (item.name === "Window") {
fullScreenHandle.exit()
}
dispatch({ type: "HEADER_BUTTON_CLICKED", buttonName: item.name })
})

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

return (
<Fullscreen
enabled={state.fullScreen}
<FullScreen
handle={fullScreenHandle}
onChange={(open) => {
if (!open) {
action("HEADER_BUTTON_CLICKED", "buttonName")("Exit Fullscreen")
fullScreenHandle.exit()
action("HEADER_BUTTON_CLICKED", "buttonName")("Window")
}
}}
>
Expand Down Expand Up @@ -323,7 +335,7 @@ export const MainLayout = ({
}
/>
</HotkeyDiv>
</Fullscreen>
</FullScreen>
)
}

Expand Down
6 changes: 4 additions & 2 deletions src/RegionShapes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const RegionComponents = {
strokeWidth={2}
x={0}
y={0}
width={region.w * iw}
height={region.h * ih}
width={Math.max(region.w * iw, 0)}
height={Math.max(region.h * ih, 0)}
stroke={colorAlpha(region.color, 0.75)}
fill={colorAlpha(region.color, 0.25)}
/>
Expand Down Expand Up @@ -80,6 +80,7 @@ const RegionComponents = {
/>
{points.map(({ x, y, angle }, i) => (
<g
key={i}
transform={`translate(${x * iw} ${y * ih}) rotate(${
(-(angle || 0) * 180) / Math.PI
})`}
Expand Down Expand Up @@ -156,6 +157,7 @@ export const RegionShapes = ({
}}
>
<WrappedRegionList
key="wrapped-region-list"
regions={regions}
iw={iw}
ih={ih}
Expand Down
21 changes: 10 additions & 11 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8419,7 +8419,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=

fscreen@^1.0.1:
fscreen@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/fscreen/-/fscreen-1.0.2.tgz#c4c51d96d819d75a19d728e0df445f9be9bb984f"
integrity sha1-xMUdltgZ11oZ1yjg30Rfm+m7mE8=
Expand Down Expand Up @@ -14459,13 +14459,12 @@ react-focus-lock@^2.1.0:
use-callback-ref "^1.2.1"
use-sidecar "^1.0.1"

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

react-github-btn@^1.1.1:
version "1.1.1"
Expand Down Expand Up @@ -14547,10 +14546,10 @@ react-markdown@^4.0.6:
unist-util-visit "^1.3.0"
xtend "^4.0.1"

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