fix: scale canvas image controls with zoom
This commit is contained in:
parent
0d3d5a9507
commit
6cdf3d013e
@ -7792,7 +7792,7 @@ export default function CanvasEditorPage({ params }: PageProps) {
|
|||||||
const brandEntry = (
|
const brandEntry = (
|
||||||
<div className="absolute top-4 left-4 z-20">
|
<div className="absolute top-4 left-4 z-20">
|
||||||
<Button
|
<Button
|
||||||
className="h-10 gap-2 rounded-none border-0 bg-transparent px-0 shadow-none hover:bg-transparent"
|
className="h-10 gap-2 rounded-full border-0 bg-background px-3 shadow-none hover:bg-background hover:text-foreground"
|
||||||
onClick={goHome}
|
onClick={goHome}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1048,42 +1048,45 @@ export function CanvasWorkspace({
|
|||||||
}
|
}
|
||||||
: isSelected && tool === "select";
|
: isSelected && tool === "select";
|
||||||
|
|
||||||
|
const imageHandleSize = IMAGE_HANDLE_SIZE * viewport.zoom;
|
||||||
|
const imageHandleOffset = imageHandleSize / 2;
|
||||||
|
const imageSelectionStrokeWidth = SELECTION_STROKE_WIDTH * viewport.zoom;
|
||||||
const imageResizeHandleStyles = isImageNode
|
const imageResizeHandleStyles = isImageNode
|
||||||
? {
|
? {
|
||||||
topRight: {
|
topRight: {
|
||||||
width: IMAGE_HANDLE_SIZE,
|
width: imageHandleSize,
|
||||||
height: IMAGE_HANDLE_SIZE,
|
height: imageHandleSize,
|
||||||
right: -IMAGE_HANDLE_OFFSET,
|
right: -imageHandleOffset,
|
||||||
top: -IMAGE_HANDLE_OFFSET,
|
top: -imageHandleOffset,
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
},
|
},
|
||||||
bottomRight: {
|
bottomRight: {
|
||||||
width: IMAGE_HANDLE_SIZE,
|
width: imageHandleSize,
|
||||||
height: IMAGE_HANDLE_SIZE,
|
height: imageHandleSize,
|
||||||
right: -IMAGE_HANDLE_OFFSET,
|
right: -imageHandleOffset,
|
||||||
bottom: -IMAGE_HANDLE_OFFSET,
|
bottom: -imageHandleOffset,
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
},
|
},
|
||||||
bottomLeft: {
|
bottomLeft: {
|
||||||
width: IMAGE_HANDLE_SIZE,
|
width: imageHandleSize,
|
||||||
height: IMAGE_HANDLE_SIZE,
|
height: imageHandleSize,
|
||||||
left: -IMAGE_HANDLE_OFFSET,
|
left: -imageHandleOffset,
|
||||||
bottom: -IMAGE_HANDLE_OFFSET,
|
bottom: -imageHandleOffset,
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
},
|
},
|
||||||
topLeft: {
|
topLeft: {
|
||||||
width: IMAGE_HANDLE_SIZE,
|
width: imageHandleSize,
|
||||||
height: IMAGE_HANDLE_SIZE,
|
height: imageHandleSize,
|
||||||
left: -IMAGE_HANDLE_OFFSET,
|
left: -imageHandleOffset,
|
||||||
top: -IMAGE_HANDLE_OFFSET,
|
top: -imageHandleOffset,
|
||||||
borderRadius: 0,
|
borderRadius: 0,
|
||||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||||
backgroundColor: "#ffffff",
|
backgroundColor: "#ffffff",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -362,9 +362,20 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
|||||||
}),
|
}),
|
||||||
[node.size.height, node.size.width]
|
[node.size.height, node.size.width]
|
||||||
);
|
);
|
||||||
|
const viewportZoom = useCanvasStore((state) => state.viewport.zoom);
|
||||||
|
const nodeContentScale = contentScale * viewportZoom;
|
||||||
const scaledContentStyle = useMemo(
|
const scaledContentStyle = useMemo(
|
||||||
() => getScaledNodeContentStyle(contentScale),
|
() => getScaledNodeContentStyle(nodeContentScale, { allowUpscale: true }),
|
||||||
[contentScale]
|
[nodeContentScale]
|
||||||
|
);
|
||||||
|
const selectedTitleStyle = useMemo<React.CSSProperties>(
|
||||||
|
() => ({
|
||||||
|
top: `${-28 * nodeContentScale}px`,
|
||||||
|
transform: `scale(${nodeContentScale})`,
|
||||||
|
transformOrigin: "bottom left",
|
||||||
|
width: `${100 / nodeContentScale}%`,
|
||||||
|
}),
|
||||||
|
[nodeContentScale]
|
||||||
);
|
);
|
||||||
const detailProgressLabel =
|
const detailProgressLabel =
|
||||||
typeof data.metadata?.detailProgressLabel === "string"
|
typeof data.metadata?.detailProgressLabel === "string"
|
||||||
@ -2825,7 +2836,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
|||||||
<>
|
<>
|
||||||
{/* 选中时在图片上方显示标题 */}
|
{/* 选中时在图片上方显示标题 */}
|
||||||
{isSelected && !isMultiSelected && data.src && !sceneFusionDialogOpen && (
|
{isSelected && !isMultiSelected && data.src && !sceneFusionDialogOpen && (
|
||||||
<div className="-top-7 absolute right-0 left-0 z-10 flex items-center justify-between px-1 text-[#2f7df6] text-xs">
|
<div
|
||||||
|
className="-top-7 absolute right-0 left-0 z-10 flex items-center justify-between px-1 text-[#2f7df6] text-xs"
|
||||||
|
style={selectedTitleStyle}
|
||||||
|
>
|
||||||
<div className="flex min-w-0 items-center gap-1">
|
<div className="flex min-w-0 items-center gap-1">
|
||||||
<ImagePlus className="h-3 w-3" />
|
<ImagePlus className="h-3 w-3" />
|
||||||
{isEditingTitle ? (
|
{isEditingTitle ? (
|
||||||
|
|||||||
@ -18,9 +18,14 @@ export function getNodeContentScale(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getScaledNodeContentStyle(
|
export function getScaledNodeContentStyle(
|
||||||
scale: number
|
scale: number,
|
||||||
|
options: { allowUpscale?: boolean } = {}
|
||||||
): CSSProperties | undefined {
|
): CSSProperties | undefined {
|
||||||
if (scale >= 0.999) {
|
const shouldKeepDefault = options.allowUpscale
|
||||||
|
? Math.abs(scale - 1) < 0.001
|
||||||
|
: scale >= 0.999;
|
||||||
|
|
||||||
|
if (shouldKeepDefault) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user