show prev mask when dream again

This commit is contained in:
Qing 2023-05-03 10:01:33 +08:00
parent f4eedbe3b1
commit f5247c89b2
4 changed files with 103 additions and 9 deletions

View File

@ -62,6 +62,8 @@ import emitter, {
EVENT_CUSTOM_MASK,
EVENT_PAINT_BY_EXAMPLE,
RERUN_LAST_MASK,
DREAM_BUTTON_MOUSE_ENTER,
DREAM_BUTTON_MOUSE_LEAVE,
} from '../../event'
import FileSelect from '../FileSelect/FileSelect'
import InteractiveSeg from '../InteractiveSeg/InteractiveSeg'
@ -130,15 +132,24 @@ export default function Editor() {
)
const [showInteractiveSegModal, setShowInteractiveSegModal] = useState(false)
const [interactiveSegMask, setInteractiveSegMask] =
useState<HTMLImageElement | null>(null)
const [interactiveSegMask, setInteractiveSegMask] = useState<
HTMLImageElement | null | undefined
>(null)
// only used while interactive segmentation is on
const [tmpInteractiveSegMask, setTmpInteractiveSegMask] =
useState<HTMLImageElement | null>(null)
const [tmpInteractiveSegMask, setTmpInteractiveSegMask] = useState<
HTMLImageElement | null | undefined
>(null)
const [prevInteractiveSegMask, setPrevInteractiveSegMask] = useState<
HTMLImageElement | null | undefined
>(null)
// 仅用于在 dream button hover 时显示提示
const [dreamButtonHoverSegMask, setDreamButtonHoverSegMask] = useState<
HTMLImageElement | null | undefined
>(null)
const [dreamButtonHoverLineGroup, setDreamButtonHoverLineGroup] =
useState<LineGroup>([])
const [clicks, setClicks] = useRecoilState(interactiveSegClicksState)
const [brushSize, setBrushSize] = useRecoilState(brushSizeState)
@ -202,21 +213,33 @@ export default function Editor() {
context.clearRect(0, 0, context.canvas.width, context.canvas.height)
context.drawImage(render, 0, 0, imageWidth, imageHeight)
if (isInteractiveSeg && tmpInteractiveSegMask !== null) {
if (isInteractiveSeg && tmpInteractiveSegMask) {
context.drawImage(tmpInteractiveSegMask, 0, 0, imageWidth, imageHeight)
}
if (!isInteractiveSeg && interactiveSegMask !== null) {
if (!isInteractiveSeg && interactiveSegMask) {
context.drawImage(interactiveSegMask, 0, 0, imageWidth, imageHeight)
}
if (dreamButtonHoverSegMask) {
context.drawImage(
dreamButtonHoverSegMask,
0,
0,
imageWidth,
imageHeight
)
}
drawLines(context, lineGroup)
drawLines(context, dreamButtonHoverLineGroup)
},
[
context,
isInteractiveSeg,
tmpInteractiveSegMask,
dreamButtonHoverSegMask,
interactiveSegMask,
imageHeight,
imageWidth,
dreamButtonHoverLineGroup,
]
)
@ -277,6 +300,7 @@ export default function Editor() {
const drawOnCurrentRender = useCallback(
(lineGroup: LineGroup) => {
console.log('[drawOnCurrentRender] draw on current render')
if (renders.length === 0) {
draw(original, lineGroup)
} else {
@ -459,6 +483,53 @@ export default function Editor() {
prevInteractiveSegMask,
])
useEffect(() => {
emitter.on(DREAM_BUTTON_MOUSE_ENTER, () => {
// 当前 canvas 上没有手绘 mask 或者 interactiveSegMask 时,显示上一次的 mask
if (!hadDrawSomething() && !interactiveSegMask) {
if (prevInteractiveSegMask) {
setDreamButtonHoverSegMask(prevInteractiveSegMask)
}
let lineGroup2Show: LineGroup = []
if (redoLineGroups.length !== 0) {
lineGroup2Show = redoLineGroups[redoLineGroups.length - 1]
} else if (lineGroups.length !== 0) {
lineGroup2Show = lineGroups[lineGroups.length - 1]
}
console.log(
`[DREAM_BUTTON_MOUSE_ENTER], prevInteractiveSegMask: ${prevInteractiveSegMask} lineGroup2Show: ${lineGroup2Show.length}`
)
if (lineGroup2Show) {
setDreamButtonHoverLineGroup(lineGroup2Show)
}
}
})
return () => {
emitter.off(DREAM_BUTTON_MOUSE_ENTER)
}
}, [
hadDrawSomething,
interactiveSegMask,
prevInteractiveSegMask,
drawOnCurrentRender,
lineGroups,
redoLineGroups,
])
useEffect(() => {
emitter.on(DREAM_BUTTON_MOUSE_LEAVE, () => {
// 当前 canvas 上没有手绘 mask 或者 interactiveSegMask 时,显示上一次的 mask
if (!hadDrawSomething() && !interactiveSegMask) {
setDreamButtonHoverSegMask(null)
setDreamButtonHoverLineGroup([])
drawOnCurrentRender([])
}
})
return () => {
emitter.off(DREAM_BUTTON_MOUSE_LEAVE)
}
}, [hadDrawSomething, interactiveSegMask, drawOnCurrentRender])
useEffect(() => {
emitter.on(EVENT_CUSTOM_MASK, (data: any) => {
// TODO: not work with paint by example
@ -743,7 +814,7 @@ export default function Editor() {
setInitialCentered(true)
}
}, [
context?.canvas,
// context?.canvas,
viewportRef,
original,
isOriginalLoaded,

View File

@ -1,14 +1,18 @@
import React, { FormEvent, useRef, useState } from 'react'
import { useClickAway } from 'react-use'
import { useRecoilState, useRecoilValue } from 'recoil'
import emitter, { EVENT_PROMPT } from '../../event'
import emitter, {
DREAM_BUTTON_MOUSE_ENTER,
DREAM_BUTTON_MOUSE_LEAVE,
EVENT_PROMPT,
} from '../../event'
import { appState, isInpaintingState, propmtState } from '../../store/Atoms'
import Button from '../shared/Button'
import TextInput from '../shared/Input'
// TODO: show progress in input
const PromptInput = () => {
const [app, setAppState] = useRecoilState(appState)
const app = useRecoilValue(appState)
const [prompt, setPrompt] = useRecoilState(propmtState)
const isInpainting = useRecoilValue(isInpaintingState)
const ref = useRef(null)
@ -39,6 +43,14 @@ const PromptInput = () => {
}
}
const onMouseEnter = () => {
emitter.emit(DREAM_BUTTON_MOUSE_ENTER)
}
const onMouseLeave = () => {
emitter.emit(DREAM_BUTTON_MOUSE_LEAVE)
}
return (
<div className="prompt-wrapper">
<TextInput
@ -52,6 +64,8 @@ const PromptInput = () => {
border
onClick={handleRepaintClick}
disabled={prompt.length === 0 || app.isInpainting}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
Dream
</Button>

View File

@ -12,6 +12,8 @@ interface ButtonProps {
onClick?: () => void
onDown?: (ev: PointerEvent) => void
onUp?: (ev: PointerEvent) => void
onMouseEnter?: () => void
onMouseLeave?: () => void
style?: React.CSSProperties
}
@ -27,6 +29,8 @@ const Button: React.FC<ButtonProps> = props => {
onClick,
onDown,
onUp,
onMouseEnter,
onMouseLeave,
style,
} = props
@ -42,6 +46,8 @@ const Button: React.FC<ButtonProps> = props => {
style={style}
onKeyDown={onKeyDown}
onClick={blurOnClick}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onPointerDown={(ev: React.PointerEvent<HTMLDivElement>) => {
onDown?.(ev.nativeEvent)
}}

View File

@ -14,6 +14,9 @@ export interface PaintByExampleEventData {
export const RERUN_LAST_MASK = 'rerun_last_mask'
export const DREAM_BUTTON_MOUSE_ENTER = 'dream_button_mouse_enter'
export const DREAM_BUTTON_MOUSE_LEAVE = 'dream_btoon_mouse_leave'
const emitter = mitt()
export default emitter