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 = (
|
||||
<div className="absolute top-4 left-4 z-20">
|
||||
<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}
|
||||
variant="ghost"
|
||||
>
|
||||
|
||||
@ -1048,42 +1048,45 @@ export function CanvasWorkspace({
|
||||
}
|
||||
: isSelected && tool === "select";
|
||||
|
||||
const imageHandleSize = IMAGE_HANDLE_SIZE * viewport.zoom;
|
||||
const imageHandleOffset = imageHandleSize / 2;
|
||||
const imageSelectionStrokeWidth = SELECTION_STROKE_WIDTH * viewport.zoom;
|
||||
const imageResizeHandleStyles = isImageNode
|
||||
? {
|
||||
topRight: {
|
||||
width: IMAGE_HANDLE_SIZE,
|
||||
height: IMAGE_HANDLE_SIZE,
|
||||
right: -IMAGE_HANDLE_OFFSET,
|
||||
top: -IMAGE_HANDLE_OFFSET,
|
||||
width: imageHandleSize,
|
||||
height: imageHandleSize,
|
||||
right: -imageHandleOffset,
|
||||
top: -imageHandleOffset,
|
||||
borderRadius: 0,
|
||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
||||
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
bottomRight: {
|
||||
width: IMAGE_HANDLE_SIZE,
|
||||
height: IMAGE_HANDLE_SIZE,
|
||||
right: -IMAGE_HANDLE_OFFSET,
|
||||
bottom: -IMAGE_HANDLE_OFFSET,
|
||||
width: imageHandleSize,
|
||||
height: imageHandleSize,
|
||||
right: -imageHandleOffset,
|
||||
bottom: -imageHandleOffset,
|
||||
borderRadius: 0,
|
||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
||||
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
bottomLeft: {
|
||||
width: IMAGE_HANDLE_SIZE,
|
||||
height: IMAGE_HANDLE_SIZE,
|
||||
left: -IMAGE_HANDLE_OFFSET,
|
||||
bottom: -IMAGE_HANDLE_OFFSET,
|
||||
width: imageHandleSize,
|
||||
height: imageHandleSize,
|
||||
left: -imageHandleOffset,
|
||||
bottom: -imageHandleOffset,
|
||||
borderRadius: 0,
|
||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
||||
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
topLeft: {
|
||||
width: IMAGE_HANDLE_SIZE,
|
||||
height: IMAGE_HANDLE_SIZE,
|
||||
left: -IMAGE_HANDLE_OFFSET,
|
||||
top: -IMAGE_HANDLE_OFFSET,
|
||||
width: imageHandleSize,
|
||||
height: imageHandleSize,
|
||||
left: -imageHandleOffset,
|
||||
top: -imageHandleOffset,
|
||||
borderRadius: 0,
|
||||
border: `${SELECTION_STROKE_WIDTH}px solid ${SELECTION_COLOR}`,
|
||||
border: `${imageSelectionStrokeWidth}px solid ${SELECTION_COLOR}`,
|
||||
backgroundColor: "#ffffff",
|
||||
},
|
||||
}
|
||||
|
||||
@ -362,9 +362,20 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
}),
|
||||
[node.size.height, node.size.width]
|
||||
);
|
||||
const viewportZoom = useCanvasStore((state) => state.viewport.zoom);
|
||||
const nodeContentScale = contentScale * viewportZoom;
|
||||
const scaledContentStyle = useMemo(
|
||||
() => getScaledNodeContentStyle(contentScale),
|
||||
[contentScale]
|
||||
() => getScaledNodeContentStyle(nodeContentScale, { allowUpscale: true }),
|
||||
[nodeContentScale]
|
||||
);
|
||||
const selectedTitleStyle = useMemo<React.CSSProperties>(
|
||||
() => ({
|
||||
top: `${-28 * nodeContentScale}px`,
|
||||
transform: `scale(${nodeContentScale})`,
|
||||
transformOrigin: "bottom left",
|
||||
width: `${100 / nodeContentScale}%`,
|
||||
}),
|
||||
[nodeContentScale]
|
||||
);
|
||||
const detailProgressLabel =
|
||||
typeof data.metadata?.detailProgressLabel === "string"
|
||||
@ -2825,7 +2836,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
<>
|
||||
{/* 选中时在图片上方显示标题 */}
|
||||
{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">
|
||||
<ImagePlus className="h-3 w-3" />
|
||||
{isEditingTitle ? (
|
||||
|
||||
@ -18,9 +18,14 @@ export function getNodeContentScale(
|
||||
}
|
||||
|
||||
export function getScaledNodeContentStyle(
|
||||
scale: number
|
||||
scale: number,
|
||||
options: { allowUpscale?: boolean } = {}
|
||||
): CSSProperties | undefined {
|
||||
if (scale >= 0.999) {
|
||||
const shouldKeepDefault = options.allowUpscale
|
||||
? Math.abs(scale - 1) < 0.001
|
||||
: scale >= 0.999;
|
||||
|
||||
if (shouldKeepDefault) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user