From eca4ac044e27a51adfa3071bad6de7cf1a8db766 Mon Sep 17 00:00:00 2001 From: Zylan Date: Fri, 25 Apr 2025 16:08:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=8F=E6=98=8E=E8=89=B2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=AE=9A=E4=B9=89=E9=80=8F=E6=98=8E?= =?UTF-8?q?=E9=94=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0=E9=80=8F=E6=98=8E=E8=89=B2?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=8C=E4=BC=98=E5=8C=96=E9=A2=9C=E8=89=B2?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E9=80=BB=E8=BE=91=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=A9=A1=E7=9A=AE=E6=93=A6=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=90=8C?= =?UTF-8?q?=E6=97=B6=E6=9B=B4=E6=96=B0=E8=B0=83=E8=89=B2=E6=9D=BF=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E4=BB=A5=E6=98=BE=E7=A4=BA=E9=80=8F=E6=98=8E=E9=80=89?= =?UTF-8?q?=E9=A1=B9=EF=BC=8C=E6=8F=90=E5=8D=87=E7=94=A8=E6=88=B7=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.tsx | 72 ++++++++++++++++++++++++++++----- src/components/ColorPalette.tsx | 54 ++++++++++++++++--------- 2 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 72320c0..30cf5c3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -80,6 +80,12 @@ const fullBeadPalette: PaletteColor[] = Object.entries(beadPaletteData) }) .filter((color): color is PaletteColor => color !== null); +// ++ 添加透明键定义 ++ +const TRANSPARENT_KEY = 'ERASE'; + +// ++ 添加透明色数据 ++ +const transparentColorData: MappedPixel = { key: TRANSPARENT_KEY, color: '#FFFFFF', isExternal: true }; + // ++ Add definition for background color keys ++ const BACKGROUND_COLOR_KEYS = ['T1', 'H1', 'H2']; // 可以根据需要调整 @@ -1042,17 +1048,65 @@ export default function Home() { const currentCell = newPixelData[j]?.[i]; // Get current cell data safely // Check if the color needs changing OR if it was an external cell being colored - if (!currentCell || currentCell.key !== selectedColor.key || currentCell.isExternal) { - // ++ Apply selected color/key AND ensure isExternal is false ++ - newPixelData[j][i] = { ...selectedColor, isExternal: false }; + if (!currentCell) return; // Prevent invalid cells + + const previousKey = currentCell.key; + const wasExternal = currentCell.isExternal; + + // Determine new cell data + let newCellData: MappedPixel; + + // Check if using eraser + if (selectedColor.key === TRANSPARENT_KEY) { + // Erasing: Mark as external + newCellData = { ...transparentColorData }; + } else { + // Normal coloring: Apply selected color and mark as internal + newCellData = { ...selectedColor, isExternal: false }; + } + + // Only update if state actually changes + if (newCellData.key !== previousKey || newCellData.isExternal !== wasExternal) { + newPixelData[j][i] = newCellData; setMappedPixelData(newPixelData); - // Explicitly redraw canvas immediately after state update + // Update color counts + if (colorCounts) { + const newColorCounts = { ...colorCounts }; + let newTotalCount = totalBeadCount; + + // If previous was internal bead, decrement its count + if (!wasExternal && previousKey !== TRANSPARENT_KEY && newColorCounts[previousKey]) { + newColorCounts[previousKey].count--; + if (newColorCounts[previousKey].count <= 0) { + delete newColorCounts[previousKey]; // Remove if count reaches zero + } + newTotalCount--; + } + + // If new is internal bead, increment its count + if (!newCellData.isExternal && newCellData.key !== TRANSPARENT_KEY) { + if (!newColorCounts[newCellData.key]) { + const colorInfo = fullBeadPalette.find(p => p.key === newCellData.key); + newColorCounts[newCellData.key] = { + count: 0, + color: colorInfo?.hex || '#000000' + }; + } + newColorCounts[newCellData.key].count++; + newTotalCount++; + } + + setColorCounts(newColorCounts); + setTotalBeadCount(newTotalCount); + } + + // Immediately redraw canvas if (pixelatedCanvasRef.current) { drawPixelatedCanvas(newPixelData, pixelatedCanvasRef, gridDimensions); } } - // After a click in manual mode, always clear the tooltip + // Clear tooltip after click setTooltipData(null); } // Tooltip Logic (only show if NOT a manual coloring click) @@ -1197,11 +1251,12 @@ export default function Home() { {/* Color Palette (only in manual mode) */}
-

选择颜色后,点击下方画布格子进行填充:

+

选择颜色或橡皮擦后,点击下方画布格子进行填充或擦除:

@@ -1209,9 +1264,6 @@ export default function Home() { {/* Canvas Preview Container */}
-

- {isManualColoringMode ? "手动上色中... (点击格子填充)" : "图纸预览(悬停或长按查看颜色)"} -

void; + transparentKey?: string; // 添加可选参数,用于识别哪个是透明/橡皮擦 } -const ColorPalette: React.FC = ({ colors, selectedColor, onColorSelect }) => { +const ColorPalette: React.FC = ({ + colors, + selectedColor, + onColorSelect, + transparentKey +}) => { if (!colors || colors.length === 0) { return

当前图纸无可用颜色。

; } return (
- {colors.map((colorData) => ( - - ))} + {colors.map((colorData) => { + // 检查当前颜色是否是透明/橡皮擦 + const isTransparent = transparentKey && colorData.key === transparentKey; + + return ( + + ); + })}
); };