fix(label): fix bug
This commit is contained in:
@@ -1642,7 +1642,6 @@ const LabelPage = ({
|
|||||||
showGroupList,
|
showGroupList,
|
||||||
showDescList && projectDetail && projectDetail.label_type === 5,
|
showDescList && projectDetail && projectDetail.label_type === 5,
|
||||||
showDescList && projectDetail && projectDetail.label_type === 6,
|
showDescList && projectDetail && projectDetail.label_type === 6,
|
||||||
showDescList && projectDetail && projectDetail.label_type === 7,
|
|
||||||
showObjectList,
|
showObjectList,
|
||||||
]
|
]
|
||||||
let count = 0
|
let count = 0
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import React, {
|
|||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
|
useLayoutEffect,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
@@ -94,6 +95,12 @@ const renderRaster = (paperGroup: paper.Group, option: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type NormalizedPoint = [number, number]
|
type NormalizedPoint = [number, number]
|
||||||
|
type ContextMenuLayout = {
|
||||||
|
top: number
|
||||||
|
left: number
|
||||||
|
maxHeight: number
|
||||||
|
maxWidth: number
|
||||||
|
}
|
||||||
|
|
||||||
const normalizePoint = (value: any): NormalizedPoint | null => {
|
const normalizePoint = (value: any): NormalizedPoint | null => {
|
||||||
if (value instanceof paper.Point) return [value.x, value.y]
|
if (value instanceof paper.Point) return [value.x, value.y]
|
||||||
@@ -133,10 +140,19 @@ const PaperContainer = (
|
|||||||
) => {
|
) => {
|
||||||
const { forceUpdate, projectDetail, labelState, updateLoadingFlag } = props
|
const { forceUpdate, projectDetail, labelState, updateLoadingFlag } = props
|
||||||
const containerRef = useRef<any>(null)
|
const containerRef = useRef<any>(null)
|
||||||
|
const contextMenuRef = useRef<HTMLDivElement>(null)
|
||||||
const [imgSize, setImageSize] = useState<{
|
const [imgSize, setImageSize] = useState<{
|
||||||
clientWidth: number
|
clientWidth: number
|
||||||
clientHeight: number
|
clientHeight: number
|
||||||
}>()
|
}>()
|
||||||
|
const [contextMenuLayout, setContextMenuLayout] = useState<ContextMenuLayout>(
|
||||||
|
{
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
maxHeight: 0,
|
||||||
|
maxWidth: 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const [firstRender, setFirstRender] = useState(false)
|
const [firstRender, setFirstRender] = useState(false)
|
||||||
const [confirmModalOpened, setConfirmModalOpened] = useState(false)
|
const [confirmModalOpened, setConfirmModalOpened] = useState(false)
|
||||||
@@ -1918,6 +1934,61 @@ const PaperContainer = (
|
|||||||
?.find((item) => item[0] === id)
|
?.find((item) => item[0] === id)
|
||||||
}, [activeImage, id, operationId, storeLabel])
|
}, [activeImage, id, operationId, storeLabel])
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (!showContextMenu) return
|
||||||
|
const container = containerRef.current
|
||||||
|
const menu = contextMenuRef.current
|
||||||
|
if (!container || !menu) return
|
||||||
|
|
||||||
|
const safeMargin = 8
|
||||||
|
const updateMenuLayout = () => {
|
||||||
|
const availableWidth = Math.max(container.clientWidth - safeMargin * 2, 0)
|
||||||
|
const availableHeight = Math.max(
|
||||||
|
container.clientHeight - safeMargin * 2,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
const menuWidth = Math.min(menu.offsetWidth, availableWidth)
|
||||||
|
const menuHeight = Math.min(menu.offsetHeight, availableHeight)
|
||||||
|
const nextLeft = Math.min(
|
||||||
|
Math.max(position.left, safeMargin),
|
||||||
|
Math.max(container.clientWidth - menuWidth - safeMargin, safeMargin)
|
||||||
|
)
|
||||||
|
const nextTop = Math.min(
|
||||||
|
Math.max(position.top, safeMargin),
|
||||||
|
Math.max(container.clientHeight - menuHeight - safeMargin, safeMargin)
|
||||||
|
)
|
||||||
|
|
||||||
|
setContextMenuLayout((prev) => {
|
||||||
|
if (
|
||||||
|
prev.left === nextLeft &&
|
||||||
|
prev.top === nextTop &&
|
||||||
|
prev.maxHeight === availableHeight &&
|
||||||
|
prev.maxWidth === availableWidth
|
||||||
|
) {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
left: nextLeft,
|
||||||
|
top: nextTop,
|
||||||
|
maxHeight: availableHeight,
|
||||||
|
maxWidth: availableWidth,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMenuLayout()
|
||||||
|
|
||||||
|
const resizeObserver = new ResizeObserver(() => {
|
||||||
|
updateMenuLayout()
|
||||||
|
})
|
||||||
|
resizeObserver.observe(container)
|
||||||
|
resizeObserver.observe(menu)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
resizeObserver.disconnect()
|
||||||
|
}
|
||||||
|
}, [position.left, position.top, showContextMenu])
|
||||||
|
|
||||||
// 打开弹窗时,初始化form数据
|
// 打开弹窗时,初始化form数据
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (showContextMenu) {
|
if (showContextMenu) {
|
||||||
@@ -2264,6 +2335,7 @@ const PaperContainer = (
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
|
ref={contextMenuRef}
|
||||||
shadow="sm"
|
shadow="sm"
|
||||||
padding="xs"
|
padding="xs"
|
||||||
radius="md"
|
radius="md"
|
||||||
@@ -2272,10 +2344,20 @@ const PaperContainer = (
|
|||||||
position: "absolute",
|
position: "absolute",
|
||||||
zIndex: 1000,
|
zIndex: 1000,
|
||||||
width: 224,
|
width: 224,
|
||||||
|
maxWidth: contextMenuLayout.maxWidth
|
||||||
|
? `${contextMenuLayout.maxWidth}px`
|
||||||
|
: undefined,
|
||||||
|
maxHeight: contextMenuLayout.maxHeight
|
||||||
|
? `${contextMenuLayout.maxHeight}px`
|
||||||
|
: undefined,
|
||||||
height: "fit-content",
|
height: "fit-content",
|
||||||
display: !showContextMenu ? "none" : "block",
|
display: !showContextMenu ? "none" : "block",
|
||||||
top: `${position.top}px`,
|
top: `${contextMenuLayout.top}px`,
|
||||||
left: `${position.left}px`,
|
left: `${contextMenuLayout.left}px`,
|
||||||
|
overflowY: "auto",
|
||||||
|
overflowX: "hidden",
|
||||||
|
overscrollBehavior: "contain",
|
||||||
|
wordBreak: "break-word",
|
||||||
}}>
|
}}>
|
||||||
<Box p="xs">
|
<Box p="xs">
|
||||||
<Stack gap="xs">
|
<Stack gap="xs">
|
||||||
|
|||||||
@@ -628,16 +628,48 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
<Stack gap="xs" pb="md">
|
<Stack gap="xs" pb="md">
|
||||||
{labelState.get(activeImage) &&
|
{labelState.get(activeImage) &&
|
||||||
labelState.get(activeImage)?.map((operationId) => {
|
labelState.get(activeImage)?.map((operationId) => {
|
||||||
|
const operationSchema = getOperationSchema(operationId)
|
||||||
const isCollapsed =
|
const isCollapsed =
|
||||||
operationStatus[activeImage + operationId]?.["COLLAPSE"]
|
operationStatus[activeImage + operationId]?.["COLLAPSE"]
|
||||||
const isHide =
|
const isHide =
|
||||||
operationStatus[activeImage + operationId]?.HIDE
|
operationStatus[activeImage + operationId]?.HIDE
|
||||||
const hasSubAttrError = getOperationSubAttrStatus(operationId)
|
const hasSubAttrError = getOperationSubAttrStatus(operationId)
|
||||||
|
const operationLabel = operationSchema?.label_class
|
||||||
|
const operationChildren =
|
||||||
|
storeLabel.get(activeImage)?.get(operationId) || []
|
||||||
|
const objectCount = operationChildren.length
|
||||||
|
const visibleChildren = operationChildren.filter((child) => {
|
||||||
|
const { comment } = child[2]
|
||||||
|
let visibleFlag = true
|
||||||
|
if (comment && comment.length) {
|
||||||
|
const latest_comment =
|
||||||
|
(taskDetail && taskDetail.label_status === 2) ||
|
||||||
|
comment.length === 1
|
||||||
|
? comment[comment.length - 1]
|
||||||
|
: comment[comment.length - 2]
|
||||||
|
let type = latest_comment.comment_type
|
||||||
|
if (type === 2) {
|
||||||
|
const { last_modified_timestamp } = child[2]
|
||||||
|
if (
|
||||||
|
last_modified_timestamp &&
|
||||||
|
last_modified_timestamp > latest_comment.date
|
||||||
|
)
|
||||||
|
type = 3
|
||||||
|
}
|
||||||
|
visibleFlag = checkBoxsChecked[3 - type]
|
||||||
|
}
|
||||||
|
if (checkBoxsChecked.every((value) => !value))
|
||||||
|
visibleFlag = true
|
||||||
|
return visibleFlag
|
||||||
|
})
|
||||||
return (
|
return (
|
||||||
<Box key={operationId} w="100%">
|
<Box key={operationId} w="100%">
|
||||||
<Paper withBorder p="xs" radius="md" shadow="sm">
|
<Paper withBorder p="xs" radius="md" shadow="sm">
|
||||||
<Flex justify="space-between" align="center">
|
<Flex align="center" gap="xs" style={{ minWidth: 0 }}>
|
||||||
<Group gap="xs">
|
<Flex
|
||||||
|
align="center"
|
||||||
|
gap="xs"
|
||||||
|
style={{ flex: 1, minWidth: 0 }}>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -650,23 +682,62 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
<EyeOff size={16} />
|
<EyeOff size={16} />
|
||||||
)}
|
)}
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
{renderOperationIcon(
|
<Group
|
||||||
getOperationSchema(operationId)
|
gap={8}
|
||||||
)}
|
wrap="nowrap"
|
||||||
<Text
|
style={{ flex: 1, minWidth: 0 }}>
|
||||||
size="sm"
|
<Group
|
||||||
c={hasSubAttrError ? "red" : undefined}>
|
gap={6}
|
||||||
{renderShortcutKey(operationId)}
|
wrap="nowrap"
|
||||||
</Text>
|
px="xs"
|
||||||
</Group>
|
py={4}
|
||||||
<Text
|
style={{
|
||||||
size="sm"
|
flexShrink: 0,
|
||||||
c={hasSubAttrError ? "red" : undefined}>
|
borderRadius: 999,
|
||||||
{getOperationSchema(operationId)?.label_class}
|
border: `1px solid ${
|
||||||
</Text>
|
hasSubAttrError
|
||||||
<Group gap="xs">
|
? "var(--mantine-color-red-2)"
|
||||||
|
: "var(--mantine-color-gray-2)"
|
||||||
|
}`,
|
||||||
|
background: hasSubAttrError
|
||||||
|
? "var(--mantine-color-red-0)"
|
||||||
|
: "var(--mantine-color-gray-0)",
|
||||||
|
}}>
|
||||||
|
{renderOperationIcon(operationSchema)}
|
||||||
|
<Text
|
||||||
|
size="xs"
|
||||||
|
fw={700}
|
||||||
|
c={hasSubAttrError ? "red" : "dimmed"}
|
||||||
|
style={{
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
lineHeight: 1,
|
||||||
|
}}>
|
||||||
|
{renderShortcutKey(operationId)}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Box style={{ flex: 1, minWidth: 0 }}>
|
||||||
|
<Text
|
||||||
|
size="sm"
|
||||||
|
fw={500}
|
||||||
|
c={hasSubAttrError ? "red" : undefined}
|
||||||
|
title={operationLabel || undefined}
|
||||||
|
style={{
|
||||||
|
minWidth: 0,
|
||||||
|
overflow: "hidden",
|
||||||
|
textOverflow: "ellipsis",
|
||||||
|
whiteSpace: "nowrap",
|
||||||
|
}}>
|
||||||
|
{operationLabel}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
</Flex>
|
||||||
|
<Group
|
||||||
|
gap={6}
|
||||||
|
wrap="nowrap"
|
||||||
|
style={{ flexShrink: 0, marginLeft: "auto" }}>
|
||||||
<TextInput
|
<TextInput
|
||||||
w={96}
|
w={88}
|
||||||
size="xs"
|
size="xs"
|
||||||
placeholder="搜索子属性"
|
placeholder="搜索子属性"
|
||||||
value={searchSubAttrs[operationId] || ""}
|
value={searchSubAttrs[operationId] || ""}
|
||||||
@@ -680,10 +751,13 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
handleSelectedBySearchSubAttr(e, operationId)
|
handleSelectedBySearchSubAttr(e, operationId)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Text size="sm">
|
<Badge
|
||||||
{storeLabel.get(activeImage)?.get(operationId)
|
size="sm"
|
||||||
?.length || 0}
|
variant="light"
|
||||||
</Text>
|
radius="xl"
|
||||||
|
color={hasSubAttrError ? "red" : "gray"}>
|
||||||
|
{objectCount}
|
||||||
|
</Badge>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -704,58 +778,93 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Paper>
|
</Paper>
|
||||||
<Collapse in={!isCollapsed}>
|
<Collapse in={!isCollapsed}>
|
||||||
<Stack gap="xs" mt="xs" pl="xs">
|
<Stack gap="xs" mt="xs" ml="xs">
|
||||||
{storeLabel
|
{visibleChildren.map((child, childIndex) => {
|
||||||
.get(activeImage)
|
const { comment } = child[2]
|
||||||
?.get(operationId)
|
const isSelected = selectedPath[
|
||||||
?.map((child) => {
|
activeImage
|
||||||
const { comment } = child[2]
|
]?.includes(child[0])
|
||||||
let visibleFlag = true
|
const isChildHide =
|
||||||
if (comment && comment.length) {
|
pathStatus[activeImage + child[0]]?.["HIDE"]
|
||||||
const latest_comment =
|
const hasChildError = getSubAttrStatus(
|
||||||
(taskDetail &&
|
getOperationSchema(operationId),
|
||||||
taskDetail.label_status === 2) ||
|
child[2]?.sub_attributes
|
||||||
comment.length === 1
|
)
|
||||||
? comment[comment.length - 1]
|
const isLastVisibleChild =
|
||||||
: comment[comment.length - 2]
|
childIndex === visibleChildren.length - 1
|
||||||
let type = latest_comment.comment_type
|
|
||||||
if (type === 2) {
|
|
||||||
const { last_modified_timestamp } = child[2]
|
|
||||||
if (
|
|
||||||
last_modified_timestamp &&
|
|
||||||
last_modified_timestamp >
|
|
||||||
latest_comment.date
|
|
||||||
)
|
|
||||||
type = 3
|
|
||||||
}
|
|
||||||
visibleFlag = checkBoxsChecked[3 - type]
|
|
||||||
}
|
|
||||||
if (checkBoxsChecked.every((value) => !value))
|
|
||||||
visibleFlag = true
|
|
||||||
|
|
||||||
const isSelected = selectedPath[
|
let textColor = undefined
|
||||||
activeImage
|
let connectorColor = "var(--mantine-color-gray-4)"
|
||||||
]?.includes(child[0])
|
|
||||||
const isChildHide =
|
|
||||||
pathStatus[activeImage + child[0]]?.["HIDE"]
|
|
||||||
const hasChildError = getSubAttrStatus(
|
|
||||||
getOperationSchema(operationId),
|
|
||||||
child[2]?.sub_attributes
|
|
||||||
)
|
|
||||||
|
|
||||||
let textColor = undefined
|
if (hasChildError) {
|
||||||
|
textColor = "red"
|
||||||
|
connectorColor = "var(--mantine-color-red-3)"
|
||||||
|
} else if (isSelected) {
|
||||||
|
textColor = "white"
|
||||||
|
connectorColor =
|
||||||
|
"var(--mantine-primary-color-filled)"
|
||||||
|
}
|
||||||
|
|
||||||
if (hasChildError) {
|
return (
|
||||||
textColor = "red"
|
<Box
|
||||||
} else if (isSelected) {
|
key={child[0]}
|
||||||
textColor = "white"
|
pl="lg"
|
||||||
}
|
style={{ position: "relative" }}>
|
||||||
|
<Box
|
||||||
if (!visibleFlag) return null
|
style={{
|
||||||
|
position: "absolute",
|
||||||
return (
|
left: 7,
|
||||||
|
top: 0,
|
||||||
|
bottom: isLastVisibleChild ? "75%" : 0,
|
||||||
|
width: 1.5,
|
||||||
|
borderRadius: 999,
|
||||||
|
background: connectorColor,
|
||||||
|
opacity: isSelected ? 0.9 : 0.35,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
{isLastVisibleChild ? (
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: 7,
|
||||||
|
top: "calc(50% - 10px)",
|
||||||
|
width: 14,
|
||||||
|
height: 10,
|
||||||
|
borderLeft: `1.5px solid ${connectorColor}`,
|
||||||
|
borderBottom: `1.5px solid ${connectorColor}`,
|
||||||
|
borderBottomLeftRadius: 10,
|
||||||
|
opacity: isSelected ? 0.9 : 0.55,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: 7,
|
||||||
|
top: "50%",
|
||||||
|
width: 14,
|
||||||
|
borderTop: `1.5px solid ${connectorColor}`,
|
||||||
|
opacity: isSelected ? 0.9 : 0.45,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
left: 4,
|
||||||
|
top: "calc(50% - 3px)",
|
||||||
|
width: 6,
|
||||||
|
height: 6,
|
||||||
|
borderRadius: 999,
|
||||||
|
background: connectorColor,
|
||||||
|
boxShadow:
|
||||||
|
"0 0 0 2px var(--mantine-color-body)",
|
||||||
|
opacity: isSelected ? 1 : 0.85,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<Paper
|
<Paper
|
||||||
key={child[0]}
|
|
||||||
withBorder
|
withBorder
|
||||||
p="xs"
|
p="xs"
|
||||||
radius="md"
|
radius="md"
|
||||||
@@ -763,7 +872,7 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
bg={
|
bg={
|
||||||
isSelected
|
isSelected
|
||||||
? "var(--mantine-primary-color-filled)"
|
? "var(--mantine-primary-color-filled)"
|
||||||
: undefined
|
: "var(--mantine-color-gray-0)"
|
||||||
}
|
}
|
||||||
c={isSelected ? "white" : undefined}
|
c={isSelected ? "white" : undefined}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@@ -944,8 +1053,9 @@ const RightObjectTools: React.FC<RightObjectToolsComponentProps> = (props) => {
|
|||||||
) : null}
|
) : null}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Paper>
|
</Paper>
|
||||||
)
|
</Box>
|
||||||
})}
|
)
|
||||||
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -290,6 +290,49 @@ const handleMouseMove = (e: paper.MouseEvent) => {
|
|||||||
usePositionStore.getState().setCurrentMousePosition([e.point.x, e.point.y])
|
usePositionStore.getState().setCurrentMousePosition([e.point.x, e.point.y])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hidePaperContextMenu = () => {
|
||||||
|
useOtherToolsStore.getState().setShowContextMenu({
|
||||||
|
showContextMenu: false,
|
||||||
|
position: {
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
},
|
||||||
|
imageId: useOtherToolsStore.getState().imageId,
|
||||||
|
operationId: useOtherToolsStore.getState().operationId,
|
||||||
|
id: useOtherToolsStore.getState().id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let isMiddleMousePanning = false
|
||||||
|
|
||||||
|
const startMiddleMousePan = (event?: MouseEvent) => {
|
||||||
|
if (!event || event.button !== 1) return false
|
||||||
|
|
||||||
|
event.preventDefault()
|
||||||
|
isMiddleMousePanning = true
|
||||||
|
hidePaperContextMenu()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const dragMiddleMousePan = (e: { event: MouseEvent; delta: paper.Point }) => {
|
||||||
|
if (!isMiddleMousePanning) return false
|
||||||
|
|
||||||
|
e.event.preventDefault()
|
||||||
|
usePaperStore.getState().group!.position = usePaperStore
|
||||||
|
.getState()
|
||||||
|
.group!.position.add(e.delta)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopMiddleMousePan = () => {
|
||||||
|
if (!isMiddleMousePanning) return false
|
||||||
|
|
||||||
|
isMiddleMousePanning = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const { user_id } = usePermissionStore.getState()
|
const { user_id } = usePermissionStore.getState()
|
||||||
|
|
||||||
type OrderPoint = [number, number]
|
type OrderPoint = [number, number]
|
||||||
@@ -427,45 +470,23 @@ export const clearSupportAnnotationItem = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 根据点击位置判断弹窗弹出的top、left
|
// 根据点击位置判断弹窗弹出的top、left
|
||||||
const containerWidth = 244
|
|
||||||
const containerHeight = 240
|
|
||||||
export const getShowContextMenuPosition = (
|
export const getShowContextMenuPosition = (
|
||||||
clickPoint: paper.Point,
|
clickPoint: paper.Point,
|
||||||
category: Project.LabelSchemaList,
|
_category: Project.LabelSchemaList,
|
||||||
offsetWidth = 0,
|
offsetWidth = 0,
|
||||||
offsetHeight = 0
|
offsetHeight = 0
|
||||||
) => {
|
) => {
|
||||||
let subAttrHeight = 0
|
|
||||||
if (category) {
|
|
||||||
const { sub_attributes_describe } = category
|
|
||||||
console.log(sub_attributes_describe)
|
|
||||||
|
|
||||||
if (sub_attributes_describe.length) subAttrHeight += 30
|
|
||||||
sub_attributes_describe.forEach((item) => {
|
|
||||||
if (item.chinese_name) subAttrHeight += 32
|
|
||||||
if (item.optional_item && item.optional_item.length)
|
|
||||||
item.optional_item.forEach(() => {
|
|
||||||
subAttrHeight += 22
|
|
||||||
})
|
|
||||||
if (item.select_mode === 0) subAttrHeight += 32
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const finalHeight = containerHeight + subAttrHeight
|
|
||||||
const element = document.getElementById("paper-container")
|
const element = document.getElementById("paper-container")
|
||||||
const rasterPos = [element!.clientWidth, element!.clientHeight]
|
const containerWidth = element?.clientWidth ?? 0
|
||||||
console.log(rasterPos, finalHeight)
|
const containerHeight = element?.clientHeight ?? 0
|
||||||
let left =
|
const left = Math.min(
|
||||||
clickPoint.x + containerWidth > rasterPos[0]
|
Math.max(clickPoint.x + offsetWidth, 0),
|
||||||
? clickPoint.x + offsetWidth - containerWidth
|
containerWidth || clickPoint.x + offsetWidth
|
||||||
: clickPoint.x + offsetWidth
|
)
|
||||||
let top =
|
const top = Math.min(
|
||||||
clickPoint.y + finalHeight > rasterPos[1]
|
Math.max(clickPoint.y + offsetHeight, 0),
|
||||||
? clickPoint.y + offsetHeight - finalHeight < 0
|
containerHeight || clickPoint.y + offsetHeight
|
||||||
? 0
|
)
|
||||||
: clickPoint.y + offsetHeight - finalHeight
|
|
||||||
: clickPoint.y + offsetHeight
|
|
||||||
console.log("转换之后的x、y", left, top)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
top,
|
top,
|
||||||
@@ -722,25 +743,13 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
panTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
panTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
if (pressCtrl) return
|
if (pressCtrl) return
|
||||||
const currentTime = Date.now()
|
const currentTime = Date.now()
|
||||||
const timeDelta = currentTime - lastTime
|
const timeDelta = currentTime - lastTime
|
||||||
|
|
||||||
if (e.event && e.event.button === 0) {
|
if (e.event && e.event.button === 0) {
|
||||||
useOtherToolsStore.getState().setShowContextMenu({
|
hidePaperContextMenu()
|
||||||
showContextMenu: false,
|
|
||||||
position: {
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
},
|
|
||||||
imageId: useOtherToolsStore.getState().imageId,
|
|
||||||
operationId: useOtherToolsStore.getState().operationId,
|
|
||||||
id: useOtherToolsStore.getState().id,
|
|
||||||
})
|
|
||||||
} else if (e.event && e.event.button === 1) {
|
|
||||||
// 鼠标中键操作图片移动
|
|
||||||
panMode = "item"
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if (useTopToolsStore.getState().isView) {
|
if (useTopToolsStore.getState().isView) {
|
||||||
panMode = ""
|
panMode = ""
|
||||||
@@ -1433,12 +1442,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
downPoint: paper.Point
|
downPoint: paper.Point
|
||||||
delta: paper.Point
|
delta: paper.Point
|
||||||
}) => {
|
}) => {
|
||||||
// 优先判断移动图片
|
if (dragMiddleMousePan(e)) return
|
||||||
if (panMode === "item") {
|
|
||||||
usePaperStore.getState().group!.position = usePaperStore
|
|
||||||
.getState()
|
|
||||||
.group?.position.add(e.delta)!
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useTopToolsStore.getState().isView) return
|
if (useTopToolsStore.getState().isView) return
|
||||||
|
|
||||||
@@ -1677,6 +1681,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
|
|
||||||
// 改变对象不能用 activeImage activeOperation (因为图形只在对应图片渲染,所以activeImage是一样的)
|
// 改变对象不能用 activeImage activeOperation (因为图形只在对应图片渲染,所以activeImage是一样的)
|
||||||
panTool.onMouseUp = (_e: paper.ToolEvent) => {
|
panTool.onMouseUp = (_e: paper.ToolEvent) => {
|
||||||
|
if (stopMiddleMousePan()) return
|
||||||
if (useTopToolsStore.getState().isView) return
|
if (useTopToolsStore.getState().isView) return
|
||||||
|
|
||||||
let newDrawPath: paper.Path | paper.CompoundPath | null = null
|
let newDrawPath: paper.Path | paper.CompoundPath | null = null
|
||||||
@@ -2775,6 +2780,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
event: MouseEvent
|
event: MouseEvent
|
||||||
point: paper.Point
|
point: paper.Point
|
||||||
}) => {
|
}) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
if (e.event.button !== 0) return
|
if (e.event.button !== 0) return
|
||||||
isMouseDown = true
|
isMouseDown = true
|
||||||
|
|
||||||
@@ -3067,7 +3073,14 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
lastPoint = checkPoint
|
lastPoint = checkPoint
|
||||||
lastTime = Date.now()
|
lastTime = Date.now()
|
||||||
}
|
}
|
||||||
|
polygonTool.onMouseDrag = (e: {
|
||||||
|
event: MouseEvent
|
||||||
|
delta: paper.Point
|
||||||
|
}) => {
|
||||||
|
if (dragMiddleMousePan(e)) return
|
||||||
|
}
|
||||||
polygonTool.onMouseUp = (_e: paper.ToolEvent) => {
|
polygonTool.onMouseUp = (_e: paper.ToolEvent) => {
|
||||||
|
if (stopMiddleMousePan()) return
|
||||||
isMouseDown = false
|
isMouseDown = false
|
||||||
}
|
}
|
||||||
polygonTool.onMouseMove = (e: paper.MouseEvent) => {
|
polygonTool.onMouseMove = (e: paper.MouseEvent) => {
|
||||||
@@ -3278,6 +3291,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
let rectangleTool = paperRectangleTool
|
let rectangleTool = paperRectangleTool
|
||||||
|
|
||||||
rectangleTool.onMouseDown = (e: { event: MouseEvent }) => {
|
rectangleTool.onMouseDown = (e: { event: MouseEvent }) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
if (e.event && e.event.button !== 2)
|
if (e.event && e.event.button !== 2)
|
||||||
useOtherToolsStore.getState().setShowContextMenu({
|
useOtherToolsStore.getState().setShowContextMenu({
|
||||||
showContextMenu: false,
|
showContextMenu: false,
|
||||||
@@ -3300,7 +3314,9 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
event: MouseEvent
|
event: MouseEvent
|
||||||
point: paper.Point
|
point: paper.Point
|
||||||
downPoint: paper.Point
|
downPoint: paper.Point
|
||||||
|
delta: paper.Point
|
||||||
}) => {
|
}) => {
|
||||||
|
if (dragMiddleMousePan(e)) return
|
||||||
const delta = e.point.subtract(e.downPoint)
|
const delta = e.point.subtract(e.downPoint)
|
||||||
// 阻止右键移动矩形(e.event.button === 0)
|
// 阻止右键移动矩形(e.event.button === 0)
|
||||||
if (delta.length > 10 && e.event.button === 0) {
|
if (delta.length > 10 && e.event.button === 0) {
|
||||||
@@ -3337,6 +3353,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
event: MouseEvent
|
event: MouseEvent
|
||||||
point: paper.Point
|
point: paper.Point
|
||||||
}) => {
|
}) => {
|
||||||
|
if (stopMiddleMousePan()) return
|
||||||
// add segment judgement
|
// add segment judgement
|
||||||
if (rect && rect.segments?.length && rect?.data?.id) {
|
if (rect && rect.segments?.length && rect?.data?.id) {
|
||||||
// 去除超出图片边界的部分
|
// 去除超出图片边界的部分
|
||||||
@@ -3558,6 +3575,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
brushTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
brushTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
if (e.event.button !== 0) return
|
if (e.event.button !== 0) return
|
||||||
|
|
||||||
// 绘制时去除选中辅助
|
// 绘制时去除选中辅助
|
||||||
@@ -3808,6 +3826,10 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
temp.remove()
|
temp.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brushTool.onMouseDrag = (e: { event: MouseEvent; delta: paper.Point }) => {
|
||||||
|
if (dragMiddleMousePan(e)) return
|
||||||
|
}
|
||||||
|
|
||||||
brushTool.onMouseMove = (e: paper.MouseEvent) => {
|
brushTool.onMouseMove = (e: paper.MouseEvent) => {
|
||||||
handleMouseMove(e)
|
handleMouseMove(e)
|
||||||
|
|
||||||
@@ -3829,6 +3851,10 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brushTool.onMouseUp = (_e: paper.ToolEvent) => {
|
||||||
|
stopMiddleMousePan()
|
||||||
|
}
|
||||||
|
|
||||||
brushTool.onKeyDown = (e: paper.KeyEvent) => {
|
brushTool.onKeyDown = (e: paper.KeyEvent) => {
|
||||||
if (e.key === "escape" || e.key === "alt") {
|
if (e.key === "escape" || e.key === "alt") {
|
||||||
if (myPath) {
|
if (myPath) {
|
||||||
@@ -3953,6 +3979,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
let pointTool = paperPointTool
|
let pointTool = paperPointTool
|
||||||
|
|
||||||
pointTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
pointTool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
if (e.event.button !== 0) return
|
if (e.event.button !== 0) return
|
||||||
|
|
||||||
// 绘制时去除选中辅助
|
// 绘制时去除选中辅助
|
||||||
@@ -4162,6 +4189,9 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
// group.current?.addChild(myCircle);
|
// group.current?.addChild(myCircle);
|
||||||
temp.remove()
|
temp.remove()
|
||||||
}
|
}
|
||||||
|
pointTool.onMouseDrag = (e: { event: MouseEvent; delta: paper.Point }) => {
|
||||||
|
if (dragMiddleMousePan(e)) return
|
||||||
|
}
|
||||||
pointTool.onMouseMove = (e: paper.MouseEvent) => {
|
pointTool.onMouseMove = (e: paper.MouseEvent) => {
|
||||||
handleMouseMove(e)
|
handleMouseMove(e)
|
||||||
|
|
||||||
@@ -4182,6 +4212,9 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pointTool.onMouseUp = (_e: paper.ToolEvent) => {
|
||||||
|
stopMiddleMousePan()
|
||||||
|
}
|
||||||
pointTool.onKeyDown = (e: paper.KeyEvent) => {
|
pointTool.onKeyDown = (e: paper.KeyEvent) => {
|
||||||
if (e.key === "escape" || e.key === "alt") {
|
if (e.key === "escape" || e.key === "alt") {
|
||||||
if (myPath) {
|
if (myPath) {
|
||||||
@@ -4294,12 +4327,18 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
let tags: number[] = []
|
let tags: number[] = []
|
||||||
|
|
||||||
tool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
tool.onMouseDown = (e: { event: MouseEvent; point: paper.Point }) => {
|
||||||
|
if (startMiddleMousePan(e.event)) return
|
||||||
let point = usePaperStore.getState().group!.globalToLocal(e.point)
|
let point = usePaperStore.getState().group!.globalToLocal(e.point)
|
||||||
if (e.event.button === 1) return
|
|
||||||
points.push([point.x, point.y])
|
points.push([point.x, point.y])
|
||||||
tags.push(e.event.button === 0 ? 1 : 0)
|
tags.push(e.event.button === 0 ? 1 : 0)
|
||||||
renderPath(points, tags, points.length === 1)
|
renderPath(points, tags, points.length === 1)
|
||||||
}
|
}
|
||||||
|
tool.onMouseDrag = (e: { event: MouseEvent; delta: paper.Point }) => {
|
||||||
|
if (dragMiddleMousePan(e)) return
|
||||||
|
}
|
||||||
|
tool.onMouseUp = (_e: paper.ToolEvent) => {
|
||||||
|
stopMiddleMousePan()
|
||||||
|
}
|
||||||
|
|
||||||
tool.onKeyDown = (e: paper.KeyEvent) => {
|
tool.onKeyDown = (e: paper.KeyEvent) => {
|
||||||
if (e.key === "escape") {
|
if (e.key === "escape") {
|
||||||
@@ -4416,6 +4455,7 @@ export const usePaperStore = create<PaperState>((set) => ({
|
|||||||
return bufferPath
|
return bufferPath
|
||||||
},
|
},
|
||||||
setPaperMode: (modeParam) => {
|
setPaperMode: (modeParam) => {
|
||||||
|
stopMiddleMousePan()
|
||||||
set((state: PaperState) => ({
|
set((state: PaperState) => ({
|
||||||
...state,
|
...state,
|
||||||
mode: modeParam,
|
mode: modeParam,
|
||||||
|
|||||||
Reference in New Issue
Block a user