From 3e88cfcd81e53303e2dd184f1fadb51696cbe083 Mon Sep 17 00:00:00 2001 From: zihanjian Date: Wed, 25 Jun 2025 16:24:07 +0800 Subject: [PATCH] =?UTF-8?q?=E8=89=B2=E6=9D=BF=E9=80=89=E6=8B=A9=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/page.old.tsx | 430 ---------------------------- src/app/studio/page.tsx | 122 ++++++-- src/components/ColorSystemPanel.tsx | 239 ++++++++++++++++ 3 files changed, 343 insertions(+), 448 deletions(-) delete mode 100644 src/app/page.old.tsx create mode 100644 src/components/ColorSystemPanel.tsx diff --git a/src/app/page.old.tsx b/src/app/page.old.tsx deleted file mode 100644 index fdf9398..0000000 --- a/src/app/page.old.tsx +++ /dev/null @@ -1,430 +0,0 @@ -'use client'; - -import React, { useState, useRef, ChangeEvent, DragEvent, useMemo, useCallback } from 'react'; -import Script from 'next/script'; -import InstallPWA from '../components/InstallPWA'; -import CanvasContainer from '../components/CanvasContainer'; - -// 导入像素化工具和类型 -import { - PixelationMode, - calculatePixelGrid, - PaletteColor, - MappedPixel, - hexToRgb, -} from '../utils/pixelation'; - -import { - colorSystemOptions, - getColorKeyByHex, - getMardToHexMapping, - sortColorsByHue, - ColorSystem -} from '../utils/colorSystemUtils'; - -// 添加自定义动画样式 -const floatAnimation = ` - @keyframes float { - 0% { transform: translateY(0px); } - 50% { transform: translateY(-5px); } - 100% { transform: translateY(0px); } - } - .animate-float { - animation: float 3s ease-in-out infinite; - } -`; - -// 获取完整色板 -const mardToHexMapping = getMardToHexMapping(); -const fullBeadPalette: PaletteColor[] = Object.entries(mardToHexMapping) - .map(([, hex]) => { - const rgb = hexToRgb(hex); - if (!rgb) return null; - return { key: hex, hex, rgb }; - }) - .filter((item): item is PaletteColor => item !== null); - -export default function Home() { - // 基础状态 - const [originalImageSrc, setOriginalImageSrc] = useState(null); - const [granularity, setGranularity] = useState(50); - const [pixelationMode, setPixelationMode] = useState(PixelationMode.Dominant); - const [selectedColorSystem, setSelectedColorSystem] = useState('MARD'); - - // 色板相关 - const [activeBeadPalette] = useState(fullBeadPalette); - - // 像素数据 - const [mappedPixelData, setMappedPixelData] = useState(null); - const [gridDimensions, setGridDimensions] = useState<{ N: number; M: number } | null>(null); - const [colorCounts, setColorCounts] = useState<{ [key: string]: { count: number; color: string } } | null>(null); - const [totalBeadCount, setTotalBeadCount] = useState(0); - - // UI状态 - const [isDonationModalOpen, setIsDonationModalOpen] = useState(false); - const [isProcessing, setIsProcessing] = useState(false); - const fileInputRef = useRef(null); - const mainRef = useRef(null); - - // 处理文件选择 - const handleFileSelect = (e: ChangeEvent) => { - const file = e.target.files?.[0]; - if (file) { - const reader = new FileReader(); - reader.onload = (e) => { - setOriginalImageSrc(e.target?.result as string); - }; - reader.readAsDataURL(file); - } - }; - - // 处理拖拽 - const handleDragOver = (e: DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - }; - - const handleDrop = (e: DragEvent) => { - e.preventDefault(); - e.stopPropagation(); - - const file = e.dataTransfer.files[0]; - if (file && file.type.startsWith('image/')) { - const reader = new FileReader(); - reader.onload = (e) => { - setOriginalImageSrc(e.target?.result as string); - }; - reader.readAsDataURL(file); - } - }; - - // 生成像素画 - const generatePixelArt = useCallback(() => { - if (!originalImageSrc) return; - - setIsProcessing(true); - - const img = new Image(); - img.onload = () => { - // 创建临时 canvas 获取图像数据 - const canvas = document.createElement('canvas'); - const ctx = canvas.getContext('2d'); - if (!ctx) { - setIsProcessing(false); - return; - } - - canvas.width = img.width; - canvas.height = img.height; - ctx.drawImage(img, 0, 0); - - // 计算网格尺寸 - const N = Math.round(img.height / granularity); - const M = Math.round(img.width / granularity); - - // 获取备用颜色(第一个颜色) - const fallbackColor = activeBeadPalette[0] || { key: '#000000', hex: '#000000', rgb: { r: 0, g: 0, b: 0 } }; - - // 调用新的 API - const mappedPixelData = calculatePixelGrid( - ctx, - img.width, - img.height, - N, - M, - activeBeadPalette, - pixelationMode, - fallbackColor - ); - - // 计算颜色统计 - const colorCounts: { [key: string]: { count: number; color: string } } = {}; - let totalBeadCount = 0; - - mappedPixelData.forEach(row => { - row.forEach(pixel => { - if (pixel.key && pixel.key !== 'transparent' && !pixel.isExternal) { - if (!colorCounts[pixel.key]) { - colorCounts[pixel.key] = { count: 0, color: pixel.color }; - } - colorCounts[pixel.key].count++; - totalBeadCount++; - } - }); - }); - - setMappedPixelData(mappedPixelData); - setGridDimensions({ N, M }); - setColorCounts(colorCounts); - setTotalBeadCount(totalBeadCount); - setIsProcessing(false); - }; - img.src = originalImageSrc; - }, [originalImageSrc, granularity, activeBeadPalette, pixelationMode]); - - // 处理像素网格更新 - const handlePixelGridUpdate = useCallback((newGrid: MappedPixel[][]) => { - setMappedPixelData(newGrid); - - // 重新计算颜色统计 - const counts: { [key: string]: { count: number; color: string } } = {}; - let total = 0; - - newGrid.forEach(row => { - row.forEach(pixel => { - if (pixel.key && pixel.key !== 'transparent' && !pixel.isExternal) { - if (!counts[pixel.key]) { - counts[pixel.key] = { count: 0, color: pixel.color }; - } - counts[pixel.key].count++; - total++; - } - }); - }); - - setColorCounts(counts); - setTotalBeadCount(total); - }, []); - - // 计算当前色板 - const currentColorPalette = useMemo(() => { - if (!mappedPixelData) return []; - - const uniqueColors = new Set(); - mappedPixelData.forEach(row => { - row.forEach(pixel => { - if (pixel.key && pixel.key !== 'transparent' && !pixel.isExternal) { - uniqueColors.add(pixel.key); - } - }); - }); - - const colorArray = Array.from(uniqueColors).map(key => { - const colorInfo = colorCounts?.[key]; - return { - key, - hex: colorInfo?.color || key, - color: colorInfo?.color || key, - name: getColorKeyByHex(key, selectedColorSystem) || key - }; - }); - - return sortColorsByHue(colorArray); - }, [mappedPixelData, colorCounts, selectedColorSystem]); - - return ( - <> -