fix(canvas): make compare toggle size adaptive with separate hit area
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-03-01 03:57:13 +08:00
parent 8457cb98f4
commit c4924dbd6b

View File

@ -357,6 +357,22 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
}, [allNodes, data.metadata, data.originalSrc, data.src, node.connections, node.id]);
const hasCompareSource = Boolean(data.src) && Boolean(compareSource);
const compareButtonVisualSize = useMemo(() => {
const minSide = Math.max(1, Math.min(node.size.width || 0, node.size.height || 0));
return Math.round(Math.max(32, Math.min(42, minSide * 0.12)));
}, [node.size.height, node.size.width]);
const compareButtonHitSize = useMemo(
() => Math.max(44, compareButtonVisualSize + 12),
[compareButtonVisualSize]
);
const compareButtonIconSize = useMemo(
() => Math.round(Math.max(14, Math.min(20, compareButtonVisualSize * 0.45))),
[compareButtonVisualSize]
);
const compareButtonInset = useMemo(
() => Math.max(6, Math.min(12, Math.round(compareButtonVisualSize * 0.24))),
[compareButtonVisualSize]
);
// 退出拾取模式时清空状态
useEffect(() => {
@ -1716,13 +1732,18 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
<button
type="button"
className={cn(
"pointer-events-auto absolute right-2 top-1/2 z-[220] inline-flex h-14 w-14 -translate-y-1/2 items-center justify-center rounded-full border text-white transition-all data-[state=on]:scale-100",
"pointer-events-auto absolute top-1/2 z-[220] inline-flex -translate-y-1/2 items-center justify-center rounded-full text-white transition-all data-[state=on]:scale-100",
isCompareMode
? "border-sky-100 bg-sky-500/95 shadow-[0_0_0_3px_rgba(255,255,255,0.55),0_10px_22px_rgba(14,165,233,0.42)]"
: "border-white/80 bg-black/78 shadow-[0_8px_18px_rgba(0,0,0,0.34)] hover:bg-black/88"
? "shadow-[0_0_0_3px_rgba(255,255,255,0.45),0_10px_22px_rgba(14,165,233,0.35)]"
: "shadow-[0_8px_18px_rgba(0,0,0,0.28)]"
)}
data-state={isCompareMode ? "on" : "off"}
data-canvas-no-drag="true"
style={{
width: `${compareButtonHitSize}px`,
height: `${compareButtonHitSize}px`,
right: `${compareButtonInset}px`,
}}
onPointerDown={(event) => {
event.preventDefault();
event.stopPropagation();
@ -1734,19 +1755,32 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
title={isCompareMode ? "对比已开启" : "开启对比"}
aria-label={isCompareMode ? "对比已开启" : "开启对比"}
>
<svg
viewBox="0 0 24 24"
className="h-6 w-6"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
<span
className={cn(
"inline-flex items-center justify-center rounded-full border text-white transition-colors",
isCompareMode
? "border-sky-100 bg-sky-500/95"
: "border-white/80 bg-black/78 hover:bg-black/88"
)}
style={{
width: `${compareButtonVisualSize}px`,
height: `${compareButtonVisualSize}px`,
}}
>
<rect x="3" y="4" width="18" height="16" rx="4.5" />
<path d="M12 4v16" />
<circle cx="12" cy="12" r="2.8" fill="currentColor" stroke="none" />
</svg>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
style={{ width: `${compareButtonIconSize}px`, height: `${compareButtonIconSize}px` }}
>
<rect x="3" y="4" width="18" height="16" rx="4.5" />
<path d="M12 4v16" />
<circle cx="12" cy="12" r="2.8" fill="currentColor" stroke="none" />
</svg>
</span>
</button>
)}
</div>