fix(canvas): split compare into two panes for transparent outputs
This commit is contained in:
parent
a1035c5dae
commit
7c69ccefc2
@ -287,6 +287,7 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
// 文件输入的 ref
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const compareFrameRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const updateNode = useCanvasStore((state) => state.updateNode);
|
||||
const deleteNode = useCanvasStore((state) => state.deleteNode);
|
||||
@ -387,6 +388,17 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
}
|
||||
}, [hasCompareSource, isThisNodePicking]);
|
||||
|
||||
const updateCompareSplitByClientX = useCallback((clientX: number) => {
|
||||
const frame = compareFrameRef.current;
|
||||
if (!frame) return;
|
||||
|
||||
const rect = frame.getBoundingClientRect();
|
||||
if (rect.width <= 0) return;
|
||||
|
||||
const rawPercent = ((clientX - rect.left) / rect.width) * 100;
|
||||
setCompareSplitPercent(Math.max(0, Math.min(100, rawPercent)));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isCompareMode) return;
|
||||
|
||||
@ -1589,6 +1601,7 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
<div className="relative w-full h-full">
|
||||
{isCompareMode && hasCompareSource ? (
|
||||
<div
|
||||
ref={compareFrameRef}
|
||||
className="relative h-full w-full overflow-hidden bg-muted/30 select-none cursor-col-resize"
|
||||
style={{ touchAction: "none" }}
|
||||
data-canvas-no-drag="true"
|
||||
@ -1600,22 +1613,31 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
updateCompareSplitByClientX(event.clientX);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={compareSource}
|
||||
alt={`${displayTitle}-原图`}
|
||||
className="absolute inset-0 h-full w-full object-contain"
|
||||
draggable={false}
|
||||
/>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0 overflow-hidden"
|
||||
style={{
|
||||
clipPath: `inset(0 ${100 - compareSplitPercent}% 0 0)`,
|
||||
}}
|
||||
>
|
||||
<div className="absolute inset-0 bg-muted/30" />
|
||||
<img
|
||||
src={data.src}
|
||||
alt={displayTitle}
|
||||
className="absolute inset-0 h-full w-full object-contain"
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="pointer-events-none absolute inset-0 overflow-hidden"
|
||||
style={{
|
||||
clipPath: `inset(0 0 0 ${compareSplitPercent}%)`,
|
||||
}}
|
||||
>
|
||||
<div className="absolute inset-0 bg-muted/30" />
|
||||
<img
|
||||
src={data.src}
|
||||
alt={displayTitle}
|
||||
className="h-full w-full object-contain"
|
||||
src={compareSource}
|
||||
alt={`${displayTitle}-原图`}
|
||||
className="absolute inset-0 h-full w-full object-contain"
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
@ -1631,10 +1653,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
<>
|
||||
</div>
|
||||
<div className="pointer-events-none absolute left-2 top-2 rounded bg-black/55 px-1.5 py-0.5 text-[10px] text-white">
|
||||
原图
|
||||
新图
|
||||
</div>
|
||||
<div className="pointer-events-none absolute right-2 top-2 rounded bg-black/55 px-1.5 py-0.5 text-[10px] text-white">
|
||||
新图
|
||||
原图
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user