### Focus Mode Guidance Strategies Source: https://context7.com/zippland/perler-beads/llms.txt Defines different strategies for guiding the user in focus mode. Choose a strategy based on desired user experience, with 'largest' offering the highest efficiency. ```typescript // /focus 页面的引导模式配置 type GuidanceMode = 'nearest' | 'largest' | 'edge-first'; // nearest: 优先选距上一个完成格子最近的连通区域 // largest: 优先选面积最大的连通区域(效率最高) // edge-first: 优先选包含边缘格子的区域(符合从外向内的拼豆习惯) ``` -------------------------------- ### Get All Connected Regions Source: https://context7.com/zippland/perler-beads/llms.txt Scans the entire pixel grid to find all independent connected regions of a specified color. Used for counting color blocks and determining the next recommended creation area. ```typescript import { getAllConnectedRegions, sortRegionsBySize, sortRegionsByDistance } from '@/utils/floodFillUtils'; // 获取所有红色连通区域 const regions = getAllConnectedRegions(mappedPixelData, '#FF0000'); // => [[{row:0,col:0},{row:0,col:1},...], [{row:5,col:8},...], ...] // 按面积排序(最大区域优先) const bySize = sortRegionsBySize(regions); console.log(`最大区域有 ${bySize[0].length} 个格子`); // 按距离排序(距参考点最近的区域优先) const byDistance = sortRegionsByDistance(regions, { row: 10, col: 20 }); ``` -------------------------------- ### floodFillErase Source: https://context7.com/zippland/perler-beads/llms.txt Performs a non-recursive, stack-based flood fill operation starting from a specified cell. It changes all connected cells of the same color to transparent (marked as external), effectively erasing a connected color block. ```APIDOC ## floodFillErase ### Description Performs a non-recursive, stack-based flood fill operation starting from a specified cell. It changes all connected cells of the same color to transparent (marked as external), effectively erasing a connected color block. ### Parameters - **mappedPixelData** (MappedPixel[][]) - The current 2D array of pixel data. - **gridDimensions** (object) - An object containing the grid dimensions, with properties `N` (width) and `M` (height). - **startRow** (number) - The starting row index for the flood fill. - **startCol** (number) - The starting column index for the flood fill. - **targetColorKey** (string) - The exact key of the color to be replaced. ### Returns - **MappedPixel[][]** - A new 2D array of pixel data with the specified area erased. ``` -------------------------------- ### `getConnectedRegion` Source: https://context7.com/zippland/perler-beads/llms.txt Retrieves a list of coordinates for all connected pixels of the same color starting from a specified pixel. Used for region marking and erasing in the 'Focus on Perler Beads' mode. ```APIDOC ## `getConnectedRegion` — 获取连通区域 从指定格子出发,返回所有与其颜色相同且连通的格子坐标列表。用于「专心拼豆」模式的区域标记和擦除功能。 ```typescript import { getConnectedRegion } from '@/utils/floodFillUtils'; const region = getConnectedRegion( mappedPixelData, 5, // 起始行 10, // 起始列 '#FF0000' // 目标颜色(必须精确匹配) ); // => [{ row: 5, col: 10 }, { row: 5, col: 11 }, { row: 6, col: 10 }, ...] console.log(`连通区域共 ${region.length} 个格子`); ``` ``` -------------------------------- ### Get MARD Color Number to Hex Mapping Source: https://context7.com/zippland/perler-beads/llms.txt Extracts the mapping from MARD color numbers to hexadecimal color values from 'colorSystemMapping.json'. Used for initializing a complete color palette. ```typescript import { getMardToHexMapping } from '@/utils/colorSystemUtils'; const mardToHex = getMardToHexMapping(); // => { 'A1': '#FF0000', 'A2': '#FF6600', ... } // 构建完整的 PaletteColor 数组 const fullPalette: PaletteColor[] = Object.entries(mardToHex) .map(([mardKey, hex]) => { const rgb = hexToRgb(hex); if (!rgb) return null; return { key: hex, hex, rgb }; // 使用 hex 作为内部 key }) .filter(Boolean) as PaletteColor[]; console.log(`调色板共 ${fullPalette.length} 种颜色`); ``` -------------------------------- ### Get Connected Region Source: https://context7.com/zippland/perler-beads/llms.txt Retrieves a list of connected pixel coordinates with the same color starting from a specified cell. Used for 'Focus Beading' mode's region marking and erasing. ```typescript import { getConnectedRegion } from '@/utils/floodFillUtils'; const region = getConnectedRegion( mappedPixelData, 5, // 起始行 10, // 起始列 '#FF0000' // 目标颜色(必须精确匹配) ); // => [{ row: 5, col: 10 }, { row: 5, col: 11 }, { row: 6, col: 10 }, ...] console.log(`连通区域共 ${region.length} 个格子`); ``` -------------------------------- ### `downloadImage` Source: https://context7.com/zippland/perler-beads/llms.txt Generates a complete perler bead pattern PNG file and initiates a browser download. The PNG includes a branded header with a QR code, a grid with color number annotations, optional axes, and a bottom purchase statistics table. ```APIDOC ## `downloadImage` — 下载图纸 PNG 生成完整的拼豆图纸 PNG 文件并触发浏览器下载。图纸包含品牌标题栏(含二维码)、带色号标注的格子网格、可选的坐标轴和底部采购统计表。 ```typescript import { downloadImage } from '@/utils/imageDownloader'; import { GridDownloadOptions } from '@/types/downloadTypes'; const options: GridDownloadOptions = { showGrid: true, gridInterval: 10, showCoordinates: true, showCellNumbers: true, gridLineColor: '#555555', includeStats: true, exportCsv: true // 同时导出 CSV 数据文件 }; await downloadImage({ mappedPixelData, // MappedPixel[][] 图纸数据 gridDimensions: { N: 100, M: 80 }, // 网格尺寸 colorCounts, // 颜色统计对象 totalBeadCount: 8000, // 总拼豆数 options, activeBeadPalette, selectedColorSystem: 'MARD' // 色号系统 }); // 浏览器弹出下载:bead-grid-100x80-keys-palette_MARD.png // 若 exportCsv=true,同时下载:bead-pattern-100x80-MARD.csv ``` ``` -------------------------------- ### GridDownloadOptions Type - Download Configuration Source: https://context7.com/zippland/perler-beads/llms.txt Configures visual aspects for exporting the bead pattern as a PNG. Options include grid lines, coordinate axes, cell numbers, line colors, and whether to include purchase statistics or export as CSV. ```typescript import { GridDownloadOptions } from '@/types/downloadTypes'; const options: GridDownloadOptions = { showGrid: true, // 是否显示分区网格线 gridInterval: 10, // 每 N 格画一条分区线 showCoordinates: true, // 是否显示坐标轴(四边数字标注) showCellNumbers: true, // 是否在格子中心标注色号 gridLineColor: '#333333', // 分区线颜色 includeStats: true, // 是否在图纸底部追加采购统计 exportCsv: false // 是否同时导出 CSV 数据文件 }; ``` -------------------------------- ### Download Image as PNG Source: https://context7.com/zippland/perler-beads/llms.txt Generates a complete Perler bead pattern PNG file for download. Includes options for grid lines, coordinates, cell numbers, and a purchase statistics table. Can also export CSV data. ```typescript import { downloadImage } from '@/utils/imageDownloader'; import { GridDownloadOptions } from '@/types/downloadTypes'; const options: GridDownloadOptions = { showGrid: true, gridInterval: 10, showCoordinates: true, showCellNumbers: true, gridLineColor: '#555555', includeStats: true, exportCsv: true // 同时导出 CSV 数据文件 }; await downloadImage({ mappedPixelData, gridDimensions: { N: 100, M: 80 }, // 网格尺寸 colorCounts, totalBeadCount: 8000, // 总拼豆数 options, activeBeadPalette, selectedColorSystem: 'MARD' // 色号系统 }); // 浏览器弹出下载:bead-grid-100x80-keys-palette_MARD.png // 若 exportCsv=true,同时下载:bead-pattern-100x80-MARD.csv ``` -------------------------------- ### Navigate to Focus Mode with Local Storage Source: https://context7.com/zippland/perler-beads/llms.txt Saves necessary data to localStorage before redirecting to the focus mode route. Ensure all required data is stringified before storage. ```typescript const handleProceedToFocusMode = () => { // 1. 将所有必要数据写入 localStorage localStorage.setItem('focusMode_pixelData', JSON.stringify(mappedPixelData)); localStorage.setItem('focusMode_gridDimensions', JSON.stringify(gridDimensions)); localStorage.setItem('focusMode_colorCounts', JSON.stringify(colorCounts)); localStorage.setItem('focusMode_selectedColorSystem', selectedColorSystem); // 2. 跳转至 /focus 路由 window.location.href = '/focus'; }; ``` -------------------------------- ### convertPaletteToColorSystem Source: https://context7.com/zippland/perler-beads/llms.txt Converts the 'key' field of a given set of PaletteColor objects from an internal hex format to a target brand color key. ```APIDOC ## convertPaletteToColorSystem ### Description Converts the 'key' field of a given set of PaletteColor objects from an internal hex format to a target brand color key. This function is useful for batch conversion of color palettes. ### Parameters - **palette** (Array) - An array of PaletteColor objects to convert. - **targetColorSystem** (ColorSystem) - The target color system (e.g., 'MARD', 'COCO') to convert the keys to. ### Returns - **Array** - An array of PaletteColor objects with their keys converted to the target color system. ``` -------------------------------- ### Sort Colors by Hue, Lightness, and Saturation Source: https://context7.com/zippland/perler-beads/llms.txt Sorts an array of colors based on HSL hue, then lightness, then saturation. This creates a visual rainbow gradient effect for color palettes. ```typescript import { sortColorsByHue } from '@/utils/colorSystemUtils'; const colors = [ { key: 'B1', color: '#0000FF' }, // 蓝 { key: 'R1', color: '#FF0000' }, // 红 { key: 'G1', color: '#00FF00' }, // 绿 ]; const sorted = sortColorsByHue(colors); // => [红(0°), 绿(120°), 蓝(240°)] 按色相升序排列 // 色相相近时,浅色在前(高明度优先),鲜艳色在前(高饱和度优先) ``` -------------------------------- ### `getAllConnectedRegions`, `sortRegionsBySize`, `sortRegionsByDistance` Source: https://context7.com/zippland/perler-beads/llms.txt Scans the entire pixel grid to find all independent connected regions of a specified color. The results can be sorted by size or distance from a reference point, useful for counting color blocks and determining the next recommended area to work on. ```APIDOC ## `getAllConnectedRegions` — 获取所有同色连通区域 扫描整个像素网格,返回指定颜色的所有独立连通区域(每个区域为一组格子坐标)。用于统计色块数量和计算推荐下一个制作区域。 ```typescript import { getAllConnectedRegions, sortRegionsBySize, sortRegionsByDistance } from '@/utils/floodFillUtils'; // 获取所有红色连通区域 const regions = getAllConnectedRegions(mappedPixelData, '#FF0000'); // => [[{row:0,col:0},{row:0,col:1},...], [{row:5,col:8},...], ...] // 按面积排序(最大区域优先) const bySize = sortRegionsBySize(regions); console.log(`最大区域有 ${bySize[0].length} 个格子`); // 按距离排序(距参考点最近的区域优先) const byDistance = sortRegionsByDistance(regions, { row: 10, col: 20 }); ``` ``` -------------------------------- ### Recalculate Color Statistics Source: https://context7.com/zippland/perler-beads/llms.txt Recalculates color counts and total bead count from pixel data. Call this after manual edits to update the shopping list. ```typescript import { recalculateColorStats } from '@/utils/pixelEditingUtils'; const { colorCounts, totalCount } = recalculateColorStats(mappedPixelData); // colorCounts 以 hex 为键 // => { '#FF0000': { count: 42, color: '#FF0000' }, '#0000FF': { count: 18, color: '#0000FF' } } // totalCount => 60 // 更新 React 状态 setColorCounts(colorCounts); setTotalBeadCount(totalCount); ``` -------------------------------- ### hexToRgb Utility - Hex to RGB Conversion Source: https://context7.com/zippland/perler-beads/llms.txt Converts a hexadecimal color string into an RGB color object. Returns `null` for invalid input. This is fundamental for building the color palette and performing color calculations. ```typescript import { hexToRgb, RgbColor } from '@/utils/pixelation'; const rgb: RgbColor | null = hexToRgb('#A3C4BC'); // => { r: 163, g: 196, b: 188 } const invalid = hexToRgb('notacolor'); // => null // 在构建调色板时过滤无效颜色 const palette: PaletteColor[] = Object.entries(mardToHexMapping) .map(([mardKey, hex]) => { const rgb = hexToRgb(hex); if (!rgb) return null; return { key: hex, hex, rgb }; }) .filter((c): c is PaletteColor => c !== null); ``` -------------------------------- ### `recalculateColorStats` Source: https://context7.com/zippland/perler-beads/llms.txt Recalculates the color statistics for the pixel grid, counting non-external, non-transparent beads. This function should be called after manual edits to update the purchasing list. ```APIDOC ## `recalculateColorStats` — 重新计算颜色统计 遍历整个像素网格,统计所有非外部、非透明格子的颜色数量,返回颜色统计对象和总格数。手动编辑后需调用此函数更新采购清单。 ```typescript import { recalculateColorStats } from '@/utils/pixelEditingUtils'; const { colorCounts, totalCount } = recalculateColorStats(mappedPixelData); // colorCounts 以 hex 为键 // => { '#FF0000': { count: 42, color: '#FF0000' }, '#0000FF': { count: 18, color: '#0000FF' } } // totalCount => 60 // 更新 React 状态 setColorCounts(colorCounts); setTotalBeadCount(totalCount); ``` ``` -------------------------------- ### colorDistance Utility - Oklab Color Distance Calculation Source: https://context7.com/zippland/perler-beads/llms.txt Calculates the perceptual difference between two colors using the Oklab color space, which better matches human vision than RGB. The returned value is directly comparable to the color merging threshold. ```typescript import { colorDistance, RgbColor } from '@/utils/pixelation'; const redRgb: RgbColor = { r: 255, g: 0, b: 0 }; const orangeRgb: RgbColor = { r: 255, g: 165, b: 0 }; const blueRgb: RgbColor = { r: 0, g: 0, b: 255 }; console.log(colorDistance(redRgb, orangeRgb)); // ~25.3(相近,可能被合并) console.log(colorDistance(redRgb, blueRgb)); // ~75.8(差异大,不合并) // 典型用途:在颜色合并阈值为 30 时,距离 < 30 的低频色会被合并到高频色 const threshold = 30; if (colorDistance(colorA.rgb, colorB.rgb) < threshold) { // 将 colorB(低频)合并到 colorA(高频) } ``` -------------------------------- ### calculatePixelGrid Source: https://context7.com/zippland/perler-beads/llms.txt Converts original image data from a Canvas into an N×M MappedPixel 2D array. This is the initial step for image processing, with subsequent color merging and background removal based on its output. ```APIDOC ## calculatePixelGrid ### Description Converts original image data from a Canvas into an N×M MappedPixel 2D array. This is the initial step for image processing, with subsequent color merging and background removal based on its output. ### Parameters - **originalCtx** (CanvasRenderingContext2D) - The 2D rendering context of the canvas containing the original image. - **imgWidth** (number) - The width of the original image in pixels. - **imgHeight** (number) - The height of the original image in pixels. - **N** (number) - The number of horizontal grid cells (controlled by the granularity parameter). - **M** (number) - The number of vertical grid cells, calculated proportionally. - **palette** (Array) - The currently active color palette. - **pixelationMode** (PixelationMode) - The mode for pixelation, e.g., `Dominant` or `Average`. - **fallbackColor** (PaletteColor) - The fallback color for empty or fully transparent cells. ### Returns - **MappedPixel[][]** - A 2D array of MappedPixel objects, where each cell corresponds to the closest color in the palette. ``` -------------------------------- ### `savePaletteSelections` / `loadPaletteSelections` Source: https://context7.com/zippland/perler-beads/llms.txt Persists user's custom palette selections to `localStorage`. Selections are stored as an object where keys are hexadecimal color values and values are booleans indicating selection status. `loadPaletteSelections` retrieves these saved states. ```APIDOC ## `savePaletteSelections` / `loadPaletteSelections` — 色板持久化 将用户的自定义色板选择状态保存到 `localStorage`,键为十六进制颜色值,值为是否选中的布尔值。 ```typescript import { savePaletteSelections, loadPaletteSelections, presetToSelections, PaletteSelections } from '@/utils/localStorageUtils'; // 保存自定义色板 const selections: PaletteSelections = { '#FF0000': true, '#00FF00': false, '#0000FF': true, }; savePaletteSelections(selections); // 加载已保存的色板(返回 null 表示无缓存或解析失败) const saved = loadPaletteSelections(); if (saved) { console.log(`加载了 ${Object.keys(saved).length} 条色板记录`); } // 将预设颜色数组转换为 PaletteSelections 格式 const allHex = ['#FF0000', '#00FF00', '#0000FF']; const presetHex = ['#FF0000', '#0000FF']; // 预设只选这两个 const initial = presetToSelections(allHex, presetHex); // => { '#FF0000': true, '#00FF00': false, '#0000FF': true } ``` ``` -------------------------------- ### findClosestPaletteColor Utility - Nearest Neighbor Color Matching Source: https://context7.com/zippland/perler-beads/llms.txt Finds the closest color in a given palette to a target RGB color. It optimizes performance by returning immediately if an exact match (distance 0) is found. Handles empty palettes by returning an error placeholder color. ```typescript import { findClosestPaletteColor, PaletteColor, RgbColor } from '@/utils/pixelation'; const targetRgb: RgbColor = { r: 200, g: 100, b: 50 }; const palette: PaletteColor[] = [ { key: '#C86432', hex: '#C86432', rgb: { r: 200, g: 100, b: 50 } }, { key: '#FFFFFF', hex: '#FFFFFF', rgb: { r: 255, g: 255, b: 255 } }, { key: '#000000', hex: '#000000', rgb: { r: 0, g: 0, b: 0 } }, ]; const closest = findClosestPaletteColor(targetRgb, palette); // => { key: '#C86432', hex: '#C86432', rgb: { r: 200, g: 100, b: 50 } } // 调色板为空时返回错误占位色 const empty = findClosestPaletteColor(targetRgb, []); // => { key: 'ERR', hex: '#000000', rgb: { r: 0, g: 0, b: 0 } } ``` -------------------------------- ### Toggle Color Exclusion and Remapping Source: https://context7.com/zippland/perler-beads/llms.txt Dynamically excludes or restores colors. When excluding, it finds the nearest alternative color from available options to maintain visual continuity. Restoring triggers a full re-processing of the image. ```typescript // 排除颜色(hexKey 为大写的十六进制颜色值) handleToggleExcludeColor('#FF0000'); // 内部逻辑: // 1. 计算重映射目标调色板 = 初始出现颜色 - 当前排除颜色 - 本次要排除的颜色 // 2. 若目标调色板为空,阻止排除(避免图纸变空白) // 3. 遍历 mappedPixelData,将所有使用 #FF0000 的非外部格子替换为最近邻颜色 // 4. 更新 excludedColorKeys、mappedPixelData、colorCounts 状态 // 恢复颜色 handleToggleExcludeColor('#FF0000'); // 再次调用同一 hexKey // 内部逻辑: 从 excludedColorKeys 中移除,触发 setRemapTrigger 完整重新处理 ``` -------------------------------- ### getMardToHexMapping Source: https://context7.com/zippland/perler-beads/llms.txt Retrieves the mapping from MARD color keys to their corresponding hexadecimal color values from the color system mapping configuration. ```APIDOC ## getMardToHexMapping ### Description Retrieves the mapping from MARD color keys to their corresponding hexadecimal color values from the color system mapping configuration. This is used to initialize a complete color palette. ### Returns - **object** - An object where keys are MARD color identifiers (e.g., 'A1') and values are their corresponding hex color strings (e.g., '#FF0000'). ``` -------------------------------- ### Convert Palette Color Keys to Target Brand Color System Source: https://context7.com/zippland/perler-beads/llms.txt Converts the 'key' field of a group of PaletteColor objects from an internal hex format to target brand color numbers. Supports multiple color systems like MARD and COCO. ```typescript import { convertPaletteToColorSystem } from '@/utils/colorSystemUtils'; const hexPalette: PaletteColor[] = [ { key: '#FF0000', hex: '#FF0000', rgb: { r: 255, g: 0, b: 0 } } ]; const mardPalette = convertPaletteToColorSystem(hexPalette, 'MARD'); // => [{ key: 'A1', hex: '#FF0000', rgb: { r: 255, g: 0, b: 0 } }] const cocoPalette = convertPaletteToColorSystem(hexPalette, 'COCO'); // => [{ key: '218', hex: '#FF0000', rgb: { r: 255, g: 0, b: 0 } }] ``` -------------------------------- ### Save and Load Palette Selections Source: https://context7.com/zippland/perler-beads/llms.txt Persists custom palette selections to localStorage. Stores selections as hex color values mapped to their selected state (boolean). ```typescript import { savePaletteSelections, loadPaletteSelections, presetToSelections, PaletteSelections } from '@/utils/localStorageUtils'; // 保存自定义色板 const selections: PaletteSelections = { '#FF0000': true, '#00FF00': false, '#0000FF': true, }; savePaletteSelections(selections); // 加载已保存的色板(返回 null 表示无缓存或解析失败) const saved = loadPaletteSelections(); if (saved) { console.log(`加载了 ${Object.keys(saved).length} 条色板记录`); } // 将预设颜色数组转换为 PaletteSelections 格式 const allHex = ['#FF0000', '#0000FF']; // 预设只选这两个 const initial = presetToSelections(allHex, presetHex); // => { '#FF0000': true, '#00FF00': false, '#0000FF': true } ``` -------------------------------- ### `exportCsvData` Source: https://context7.com/zippland/perler-beads/llms.txt Exports the pixel grid into a row-by-row CSV file. Each cell contains its hex color value, with 'TRANSPARENT' for external cells. This facilitates migrating pattern data between different tools. ```APIDOC ## `exportCsvData` — 导出 CSV 数据 将像素网格导出为逐行 CSV 文件,每格为 hex 颜色值(外部格子为 `TRANSPARENT`)。可用于在不同工具之间迁移图纸数据。 ```typescript import { exportCsvData } from '@/utils/imageDownloader'; exportCsvData({ mappedPixelData, gridDimensions: { N: 50, M: 40 }, selectedColorSystem: 'COCO' }); // 下载文件: bead-pattern-50x40-COCO.csv // 文件内容示例: // #FF0000,#FF0000,TRANSPARENT,#0000FF,... // #FF0000,TRANSPARENT,TRANSPARENT,#0000FF,... ``` ``` -------------------------------- ### `importCsvData` Source: https://context7.com/zippland/perler-beads/llms.txt Parses an exported CSV file to restore the `MappedPixel[][]` array and grid dimensions, allowing users to continue editing previously saved patterns. ```APIDOC ## `importCsvData` — 导入 CSV 数据 解析已导出的 CSV 文件,还原为 `MappedPixel[][]` 数组和网格尺寸,支持继续编辑之前保存的图纸。 ```typescript import { importCsvData } from '@/utils/imageDownloader'; const fileInput = document.querySelector('input[type="file"]'); const file = fileInput?.files?.[0]; if (file) { try { const { mappedPixelData, gridDimensions } = await importCsvData(file); console.log(`导入成功: ${gridDimensions.N}x${gridDimensions.M} 格子`); // 更新应用状态 setMappedPixelData(mappedPixelData); setGridDimensions(gridDimensions); } catch (err) { console.error('CSV 导入失败:', err.message); // 可能原因: 格式不合法、列数不一致、包含无效 hex 值 } } ``` ``` -------------------------------- ### Define Canvas State Interface Source: https://github.com/zippland/perler-beads/blob/master/CLAUDE.md Defines the structure for managing the state of the canvas, including mode, viewport, pixel data, current tool, and operation history. ```typescript interface CanvasState { mode: 'preview' | 'edit' | 'create' viewport: { x: number, y: number, scale: number } pixelData: MappedPixel[][] currentTool: ToolType operationHistory: Operation[] } ``` -------------------------------- ### sortColorsByHue Source: https://context7.com/zippland/perler-beads/llms.txt Sorts an array of colors based on their HSL hue, then lightness, then saturation. This creates a visual gradient effect, like a rainbow. ```APIDOC ## sortColorsByHue ### Description Sorts an array of colors based on their HSL hue, then lightness, then saturation. This creates a visual gradient effect, like a rainbow, making the color palette more aesthetically pleasing. ### Parameters - **colors** (Array) - An array of color objects, each expected to have a `color` property (hex string) or similar representation from which HSL can be derived. ### Returns - **Array** - The input array of colors sorted by hue (ascending), then lightness, then saturation. ``` -------------------------------- ### Import CSV Data Source: https://context7.com/zippland/perler-beads/llms.txt Parses an exported CSV file to restore the pixel grid data and dimensions, enabling continuation of previously saved patterns. Handles potential errors during import. ```typescript import { importCsvData } from '@/utils/imageDownloader'; const fileInput = document.querySelector('input[type="file"]'); const file = fileInput?.files?.[0]; if (file) { try { const { mappedPixelData, gridDimensions } = await importCsvData(file); console.log(`导入成功: ${gridDimensions.N}x${gridDimensions.M} 格子`); // 更新应用状态 setMappedPixelData(mappedPixelData); setGridDimensions(gridDimensions); } catch (err) { console.error('CSV 导入失败:', err.message); // 可能原因: 格式不合法、列数不一致、包含无效 hex 值 } } ``` -------------------------------- ### MappedPixel Interface - Mapped Pixel Unit Source: https://context7.com/zippland/perler-beads/llms.txt Represents a single pixel in the bead grid. `key` is the color ID, `color` is the hex value, and `isExternal` distinguishes background pixels not included in bead counts. The grid is a 2D array of these objects. ```typescript import { MappedPixel } from '@/utils/pixelation'; // 一个内部像素(计入拼豆统计) const innerPixel: MappedPixel = { key: '#FF0000', // 内部使用 hex 作为 key color: '#FF0000', // 十六进制颜色 isExternal: false // false = 需要拼豆的区域 }; // 一个外部背景像素(不计入统计,下载时渲染为白色) const bgPixel: MappedPixel = { key: 'ERASE', color: '#FFFFFF', isExternal: true }; // mappedPixelData 是一个 M 行 × N 列的二维数组 const grid: MappedPixel[][] = Array(M).fill(null).map(() => Array(N).fill(innerPixel)); ``` -------------------------------- ### getColorKeyByHex Source: https://context7.com/zippland/perler-beads/llms.txt Converts a hex color value to a brand-specific color key (e.g., 'A1' for MARD, '101' for COCO) based on a specified color system. ```APIDOC ## getColorKeyByHex ### Description Converts a hex color value to a brand-specific color key (e.g., 'A1' for MARD, '101' for COCO) based on a specified color system. Returns '?' if no mapping is found. ### Parameters - **hexValue** (string) - The hex color value to convert (e.g., '#FF0000'). - **colorSystem** (ColorSystem) - The target color system (e.g., 'MARD', 'COCO'). ### Returns - **string** - The brand-specific color key, or '?' if the hex value cannot be mapped. ``` -------------------------------- ### replaceColor Source: https://context7.com/zippland/perler-beads/llms.txt Iterates through the entire pixel grid and replaces all internal cells matching the `sourceColor` with the `targetColor`. It returns the modified pixel data and the count of replaced cells. ```APIDOC ## replaceColor ### Description Iterates through the entire pixel grid and replaces all internal cells matching the `sourceColor` with the `targetColor`. It returns the modified pixel data and the count of replaced cells. ### Parameters - **mappedPixelData** (MappedPixel[][]) - The current 2D array of pixel data. - **gridDimensions** (object) - An object containing the grid dimensions, with properties `N` (width) and `M` (height). - **sourceColor** (object) - The color object to be replaced (e.g., `{ key: '#FF0000', color: '#FF0000' }`). - **targetColor** (object) - The color object to replace with (e.g., `{ key: '#FF6600', color: '#FF6600' }`). ### Returns - **object** - An object containing: - `newPixelData` (MappedPixel[][]): The updated pixel data. - `replaceCount` (number): The number of cells that were replaced. ``` -------------------------------- ### Convert Hex Color to Brand Color Key Source: https://context7.com/zippland/perler-beads/llms.txt Converts a hex color value to a brand-specific color key (e.g., 'A1' for MARD, '101' for COCO) based on a specified color system. Returns '?' for unmappable colors. ```typescript import { getColorKeyByHex, ColorSystem } from '@/utils/colorSystemUtils'; const hexValue = '#FF0000'; console.log(getColorKeyByHex(hexValue, 'MARD')); // 例: 'A1' console.log(getColorKeyByHex(hexValue, 'COCO')); // 例: '218' console.log(getColorKeyByHex(hexValue, '漫漫')); // 例: 'MM-001' console.log(getColorKeyByHex('#INVALID', 'MARD')); // '?'(找不到映射时的回退值) // 批量转换显示列表 const displayList = Object.keys(colorCounts).map(hex => ({ key: getColorKeyByHex(hex, selectedColorSystem), hex, count: colorCounts[hex].count })); ``` -------------------------------- ### Calculate Pixel Grid for Image Pixelation Source: https://context7.com/zippland/perler-beads/llms.txt Converts raw image data from a Canvas context into a 2D array of MappedPixels. This is the first step in image processing, used for subsequent color merging and background removal. ```typescript import { calculatePixelGrid, PixelationMode } from '@/utils/pixelation'; // 假设 originalCtx 是已绘制了原始图像的 Canvas 2D Context const N = 100; // 横向格子数(由 granularity 参数控制) const M = Math.round(N * (imgHeight / imgWidth)); // 纵向按比例计算 const fallbackColor: PaletteColor = palette[0]; // T1 白色通常作为备用 const initialMappedData = calculatePixelGrid( originalCtx, // CanvasRenderingContext2D imgWidth, // 原始图像宽度(像素) imgHeight, // 原始图像高度(像素) N, // 横向格子数 M, // 纵向格子数 palette, // 当前活跃调色板 PixelationMode.Dominant, // 或 Average fallbackColor // 空白/全透明格子的备用色 ); // 返回 MappedPixel[][] 二维数组,每格对应调色板中最近的颜色 console.log(initialMappedData[0][0]); // { key: '#FFFFFF', color: '#FFFFFF', isExternal: false } ``` -------------------------------- ### Export CSV Data Source: https://context7.com/zippland/perler-beads/llms.txt Exports the pixel grid data into a row-by-row CSV file, with each cell represented by its hex color value or 'TRANSPARENT' for external cells. Useful for migrating pattern data between tools. ```typescript import { exportCsvData } from '@/utils/imageDownloader'; exportCsvData({ mappedPixelData, gridDimensions: { N: 50, M: 40 }, selectedColorSystem: 'COCO' }); // 下载文件: bead-pattern-50x40-COCO.csv // 文件内容示例: // #FF0000,#FF0000,TRANSPARENT,#0000FF,... // #FF0000,TRANSPARENT,TRANSPARENT,#0000FF,... ``` -------------------------------- ### PaletteColor Interface - Palette Color Source: https://context7.com/zippland/perler-beads/llms.txt Defines the structure for colors in the palette, including their key, hex value, and RGB components for color distance calculations. The `hexToRgb` function is used to derive the RGB values. ```typescript import { PaletteColor, hexToRgb } from '@/utils/pixelation'; const color: PaletteColor = { key: '#FF0000', // hex 值作为内部键 hex: '#FF0000', rgb: hexToRgb('#FF0000')! // { r: 255, g: 0, b: 0 } }; ``` -------------------------------- ### PixelationMode Enum - Pixelation Modes Source: https://context7.com/zippland/perler-beads/llms.txt Defines strategies for color sampling within each pixel grid. Use `Dominant` for sharp, cartoon-like results and `Average` for softer, realistic color blending. This can be managed in the page's state. ```typescript import { PixelationMode } from '@/utils/pixelation'; // 卡通模式(默认):取主色,保持色块纯净 const mode1 = PixelationMode.Dominant; // 'dominant' // 真实模式:取平均色,保留色彩过渡 const mode2 = PixelationMode.Average; // 'average' // 在页面状态中切换 const [pixelationMode, setPixelationMode] = useState(PixelationMode.Dominant); ``` -------------------------------- ### Replace All Occurrences of a Source Color Source: https://context7.com/zippland/perler-beads/llms.txt Iterates through the entire pixel grid and replaces all cells matching the `sourceColor` with the `targetColor`. Returns the number of replacements made. ```typescript import { replaceColor } from '@/utils/pixelEditingUtils'; const { newPixelData, replaceCount } = replaceColor( mappedPixelData, { N: 100, M: 80 }, { key: '#FF0000', color: '#FF0000' }, // 源颜色(将被替换) { key: '#FF6600', color: '#FF6600' } // 目标颜色 ); console.log(`已将 ${replaceCount} 个格子从红色替换为橙色`); // => 已将 42 个格子从红色替换为橙色 ``` -------------------------------- ### Flood Fill Erase Connected Color Regions Source: https://context7.com/zippland/perler-beads/llms.txt Performs a non-recursive, stack-based flood fill to erase a connected region of a specific color by setting it to transparent. Useful for erasing contiguous color blocks. ```typescript import { floodFillErase, TRANSPARENT_KEY } from '@/utils/pixelEditingUtils'; // 擦除 (5, 3) 格子及其同色连通区域 const newPixelData = floodFillErase( mappedPixelData, // MappedPixel[][] 当前像素数据 { N: 100, M: 80 }, // 网格尺寸 5, // 起始行 3, // 起始列 '#FF0000' // 目标颜色键(必须精确匹配) ); // 验证擦除结果 console.log(newPixelData[5][3].key); // 'ERASE' console.log(newPixelData[5][3].isExternal); // true ``` -------------------------------- ### paintSinglePixel Source: https://context7.com/zippland/perler-beads/llms.txt Changes the color of a single pixel at the specified coordinates. Supports both regular colors and transparent color (eraser). Returns the new pixel data, the previous cell's data, and a flag indicating if a change occurred. ```APIDOC ## paintSinglePixel ### Description Changes the color of a single pixel at the specified coordinates. Supports both regular colors and transparent color (eraser). Returns the new pixel data, the previous cell's data, and a flag indicating if a change occurred. ### Parameters - **mappedPixelData** (MappedPixel[][]) - The current 2D array of pixel data. - **row** (number) - The row index of the pixel to paint. - **col** (number) - The column index of the pixel to paint. - **newColor** (object) - The new color object to apply (e.g., `{ key: '#FF0000', color: '#FF0000', isExternal: false }` or `{ key: TRANSPARENT_KEY, color: '#FFFFFF', isExternal: true }`). ### Returns - **object** - An object containing: - `newPixelData` (MappedPixel[][]): The updated pixel data. - `previousCell` (MappedPixel | null): The data of the cell before the change. - `hasChange` (boolean): True if the pixel's color was changed, false otherwise. ``` -------------------------------- ### Paint a Single Pixel Source: https://context7.com/zippland/perler-beads/llms.txt Changes the color of a single pixel at the specified coordinates. Supports both regular colors and transparent color (eraser). Returns the new pixel data, the previous cell state, and a flag indicating if a change occurred. ```typescript import { paintSinglePixel, TRANSPARENT_KEY } from '@/utils/pixelEditingUtils'; // 将 (10, 20) 格子涂为红色 const { newPixelData, previousCell, hasChange } = paintSinglePixel( mappedPixelData, 10, // 行 20, // 列 { key: '#FF0000', color: '#FF0000', isExternal: false } ); if (hasChange) { console.log(`原色: ${previousCell?.color}, 新色: newPixelData[10][20].color`); } // 使用透明色(橡皮擦)擦除单个格子 const { newPixelData: erased } = paintSinglePixel( mappedPixelData, 10, 20, { key: TRANSPARENT_KEY, color: '#FFFFFF', isExternal: true } ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.