去杂色
This commit is contained in:
@@ -1067,6 +1067,11 @@ export default function FocusMode() {
|
||||
const handleRemoveCanvasColor = useCallback((hexToRemove: string) => {
|
||||
if (!mappedPixelData) return;
|
||||
|
||||
// 检查颜色是否已经被移除
|
||||
if (removedColors.includes(hexToRemove)) {
|
||||
return; // 已经移除过,不重复操作
|
||||
}
|
||||
|
||||
// 更新画布色板
|
||||
const newCanvasPalette = new Set(canvasPalette);
|
||||
newCanvasPalette.delete(hexToRemove);
|
||||
@@ -1145,12 +1150,17 @@ export default function FocusMode() {
|
||||
};
|
||||
|
||||
img.src = imageSrc;
|
||||
}, [mappedPixelData, canvasPalette, saveToHistory, gridDimensions, pixelationMode, colorMergeThreshold, removeBackground]);
|
||||
}, [mappedPixelData, canvasPalette, saveToHistory, gridDimensions, pixelationMode, colorMergeThreshold, removeBackground, removedColors]);
|
||||
|
||||
// 去杂色:恢复颜色
|
||||
const handleRestoreCanvasColor = useCallback((hexToRestore: string) => {
|
||||
if (!mappedPixelData) return;
|
||||
|
||||
// 检查颜色是否在已移除列表中
|
||||
if (!removedColors.includes(hexToRestore)) {
|
||||
return; // 不在已移除列表中,不需要恢复
|
||||
}
|
||||
|
||||
// 从已移除列表中移除
|
||||
setRemovedColors(prev => prev.filter(hex => hex !== hexToRestore));
|
||||
|
||||
@@ -1351,7 +1361,7 @@ export default function FocusMode() {
|
||||
};
|
||||
|
||||
img.src = imageSrc;
|
||||
}, [mappedPixelData, canvasPalette, saveToHistory, gridDimensions, pixelationMode, colorMergeThreshold, removeBackground]);
|
||||
}, [mappedPixelData, canvasPalette, saveToHistory, gridDimensions, pixelationMode, colorMergeThreshold, removeBackground, removedColors]);
|
||||
|
||||
// 处理下载
|
||||
const handleDownload = useCallback(async (options?: GridDownloadOptions) => {
|
||||
|
||||
@@ -28,102 +28,112 @@ const CanvasColorPanel: React.FC<CanvasColorPanelProps> = ({
|
||||
const sortedColors = [...canvasColors].sort((a, b) => a.count - b.count);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-x-0 bottom-0 bg-white/95 backdrop-blur-lg border-t border-gray-200/30 shadow-lg z-40 max-h-96 overflow-hidden flex flex-col">
|
||||
<div className="flex items-center justify-between px-4 py-3 border-b border-gray-200/30 bg-white/50">
|
||||
<h3 className="text-sm font-medium text-gray-700">去杂色模式 - 点击颜色来移除</h3>
|
||||
<div className="fixed inset-x-0 bottom-0 bg-white/98 backdrop-blur-xl border-t border-gray-200/40 shadow-2xl z-40 max-h-80 overflow-hidden flex flex-col">
|
||||
{/* 精简的标题栏 */}
|
||||
<div className="flex items-center justify-between px-4 py-2.5 border-b border-gray-100/60">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 bg-red-400 rounded-full"></div>
|
||||
<h3 className="text-sm font-medium text-gray-800">去杂色</h3>
|
||||
<span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full">
|
||||
{sortedColors.filter(color => !removedColors.includes(color.hex)).length} 色
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={onClose}
|
||||
className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
className="p-1.5 hover:bg-gray-100 rounded-lg transition-colors"
|
||||
>
|
||||
<svg className="w-5 h-5 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<svg className="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto px-4 py-3">
|
||||
<div className="grid grid-cols-1 gap-2">
|
||||
{/* 当前画布颜色 */}
|
||||
{sortedColors.map(color => (
|
||||
{/* 紧凑的颜色网格 */}
|
||||
<div className="flex-1 overflow-y-auto px-3 py-2">
|
||||
<div className="grid grid-cols-2 gap-1.5">
|
||||
{/* 当前画布颜色 - 紧凑布局 */}
|
||||
{sortedColors
|
||||
.filter(color => !removedColors.includes(color.hex)) // 过滤掉已移除的颜色
|
||||
.map(color => (
|
||||
<button
|
||||
key={color.hex}
|
||||
onClick={() => onColorRemove(color.hex)}
|
||||
className="flex items-center gap-3 p-3 hover:bg-red-50/50 rounded-lg transition-all duration-200 active:bg-red-100/60 group border border-transparent hover:border-red-200"
|
||||
className="flex items-center gap-2 p-2 hover:bg-red-50 rounded-md transition-all duration-150 group border border-transparent hover:border-red-200/60 active:scale-95"
|
||||
>
|
||||
{/* 颜色块 */}
|
||||
{/* 颜色块 - 更小 */}
|
||||
<div
|
||||
className="w-8 h-8 rounded-lg border border-gray-200 flex-shrink-0 shadow-sm"
|
||||
className="w-5 h-5 rounded border border-gray-200/60 flex-shrink-0"
|
||||
style={{ backgroundColor: color.hex }}
|
||||
/>
|
||||
|
||||
{/* 色号名称 */}
|
||||
<span className="text-sm font-mono text-gray-700 min-w-[3rem] font-medium">
|
||||
{color.key}
|
||||
</span>
|
||||
{/* 信息区域 */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-xs font-mono text-gray-800 truncate">
|
||||
{color.key}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500">
|
||||
{color.count}粒
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 数量 */}
|
||||
<span className="text-sm text-gray-600 ml-auto">
|
||||
{color.count} 粒
|
||||
</span>
|
||||
|
||||
{/* 删除图标 */}
|
||||
<svg className="w-5 h-5 text-gray-400 group-hover:text-red-500 transition-colors opacity-0 group-hover:opacity-100 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||
{/* 删除图标 - 更小 */}
|
||||
<svg className="w-3.5 h-3.5 text-gray-400 group-hover:text-red-500 transition-colors opacity-0 group-hover:opacity-100 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||
</svg>
|
||||
</button>
|
||||
))}
|
||||
|
||||
{/* 已移除颜色区域 */}
|
||||
{removedColors.length > 0 && (
|
||||
<>
|
||||
<div className="border-t border-gray-300/50 pt-3 mt-3">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<span className="text-xs font-medium text-gray-500 bg-gray-100 px-2 py-1 rounded">已移除颜色</span>
|
||||
<div className="flex-1 h-px bg-gray-200"></div>
|
||||
{/* 已移除颜色 - 更紧凑 */}
|
||||
{[...new Set(removedColors)].map(hex => { // 使用 Set 去重
|
||||
const key = getColorKeyByHex(hex, selectedColorSystem);
|
||||
return (
|
||||
<button
|
||||
key={hex}
|
||||
onClick={() => onColorRestore(hex)}
|
||||
className="flex items-center gap-2 p-2 bg-gray-50/60 hover:bg-green-50 rounded-md transition-all duration-150 group opacity-60 hover:opacity-100 border border-gray-200/40 hover:border-green-200/60 active:scale-95"
|
||||
>
|
||||
{/* 颜色块 - 带删除线 */}
|
||||
<div
|
||||
className="w-5 h-5 rounded border border-gray-300/60 flex-shrink-0 relative"
|
||||
style={{ backgroundColor: hex }}
|
||||
>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="w-full h-0.5 bg-red-400/80"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{removedColors.map(hex => {
|
||||
const key = getColorKeyByHex(hex, selectedColorSystem);
|
||||
return (
|
||||
<button
|
||||
key={hex}
|
||||
onClick={() => onColorRestore(hex)}
|
||||
className="flex items-center gap-3 p-3 bg-gray-50/80 hover:bg-green-50/50 rounded-lg transition-all duration-200 active:bg-green-100/60 group opacity-60 hover:opacity-100 border border-gray-200 hover:border-green-200"
|
||||
>
|
||||
{/* 颜色块 */}
|
||||
<div
|
||||
className="w-8 h-8 rounded-lg border border-gray-300 flex-shrink-0 relative shadow-sm"
|
||||
style={{ backgroundColor: hex }}
|
||||
>
|
||||
{/* 删除线标识 */}
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<div className="w-full h-0.5 bg-red-400 rotate-45"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 色号名称 */}
|
||||
<span className="text-sm font-mono text-gray-500 min-w-[3rem] line-through font-medium">
|
||||
{key}
|
||||
</span>
|
||||
|
||||
{/* 恢复图标 */}
|
||||
<svg className="w-5 h-5 text-gray-400 group-hover:text-green-500 transition-colors opacity-0 group-hover:opacity-100 ml-auto flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* 信息区域 */}
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-xs font-mono text-gray-500 line-through truncate">
|
||||
{key}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">
|
||||
已移除
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 恢复图标 */}
|
||||
<svg className="w-3.5 h-3.5 text-gray-400 group-hover:text-green-500 transition-colors opacity-0 group-hover:opacity-100 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2.5} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
|
||||
</svg>
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{sortedColors.length === 0 && removedColors.length === 0 && (
|
||||
<div className="text-center py-8 text-gray-500 text-sm">
|
||||
<div className="text-center py-6 text-gray-500 text-sm">
|
||||
暂无颜色数据
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* 底部操作提示 */}
|
||||
<div className="px-3 py-2 bg-gray-50/50 border-t border-gray-100/60">
|
||||
<div className="text-xs text-gray-500 text-center">
|
||||
点击颜色移除 · 点击已移除颜色恢复
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user