// 全局变量 let currentTheme = 'pastel'; let currentStyle = 'cartoon'; let currentCanvasSize = 128; let currentPixelSize = 8; let currentSocialMediaFormat = 'custom'; let favorites = JSON.parse(localStorage.getItem('favorites')) || []; let avatarHistory = JSON.parse(localStorage.getItem('avatarHistory')) || []; let currentSeed = null; let useSeed = false; const maxHistoryItems = 50; // 社交媒体格式尺寸映射 const socialMediaFormats = { facebook: 180, twitter: 400, instagram: 320, linkedin: 400, youtube: 800 }; // 编辑相关变量 let isDrawing = false; let currentTool = 'brush'; let currentColor = '#000000'; let currentBrushSize = 1; let history = []; let historyIndex = -1; // 颜色主题 const colorThemes = { pastel: ['#FFB6C1', '#FFD700', '#98FB98', '#87CEEB', '#DDA0DD', '#FFA07A'], vibrant: ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F'], dark: ['#2C3E50', '#34495E', '#7F8C8D', '#95A5A6', '#BDC3C7', '#ECF0F1'], monochrome: ['#000000', '#333333', '#666666', '#999999', '#CCCCCC', '#FFFFFF'] }; // 初始化 window.addEventListener('DOMContentLoaded', () => { initializeApp(); generateAvatar(); loadHistory(); // 加载历史记录 }); function initializeApp() { // 界面切换 setupNavigation(); // 按钮事件 setupButtons(); // 设置 setupSettings(); // 加载收藏 loadFavorites(); } // 设置导航 function setupNavigation() { const navBtns = document.querySelectorAll('.nav-btn'); navBtns.forEach(btn => { btn.addEventListener('click', () => { const screen = btn.dataset.screen; showScreen(screen); // 更新导航按钮状态 navBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); }); }); // 返回按钮 document.getElementById('backToGenerate').addEventListener('click', () => { showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); document.getElementById('nav-favorites').classList.remove('active'); }); document.getElementById('backToGenerate2').addEventListener('click', () => { showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); document.getElementById('nav-settings').classList.remove('active'); }); document.getElementById('backToGenerate3').addEventListener('click', () => { showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); }); document.getElementById('backToGenerate4').addEventListener('click', () => { showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); document.getElementById('nav-history').classList.remove('active'); }); } // 显示指定界面 function showScreen(screenId) { const screens = document.querySelectorAll('.screen'); screens.forEach(screen => screen.classList.remove('active')); document.getElementById(screenId).classList.add('active'); } // 设置按钮事件 function setupButtons() { // 重新生成按钮 document.getElementById('regenerateBtn').addEventListener('click', generateAvatar); // 保存按钮 document.getElementById('saveBtn').addEventListener('click', saveAvatar); // 编辑按钮 document.getElementById('editBtn').addEventListener('click', openEditScreen); // 收藏按钮 document.getElementById('favoriteBtn').addEventListener('click', addToFavorites); // 下载按钮 document.getElementById('downloadBtn').addEventListener('click', downloadAvatar); // 主题按钮 const themeBtns = document.querySelectorAll('.theme-btn'); themeBtns.forEach(btn => { btn.addEventListener('click', () => { currentTheme = btn.dataset.theme; themeBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); generateAvatar(); }); }); // 风格按钮 const styleBtns = document.querySelectorAll('.style-btn'); styleBtns.forEach(btn => { btn.addEventListener('click', () => { currentStyle = btn.dataset.style; styleBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); generateAvatar(); }); }); // 细节按钮 const detailBtns = document.querySelectorAll('.detail-btn'); detailBtns.forEach(btn => { btn.addEventListener('click', () => { // 随机化特定细节 generateAvatarWithFocus(btn.dataset.detail); }); }); // 社交媒体格式按钮 const socialBtns = document.querySelectorAll('.social-options .theme-btn'); socialBtns.forEach(btn => { btn.addEventListener('click', () => { const format = btn.dataset.format; setSocialMediaFormat(format); }); }); // 种子相关按钮 setupSeedButtons(); // 编辑界面按钮 setupEditButtons(); // 历史记录按钮 const clearHistoryBtn = document.getElementById('clearHistoryBtn'); if (clearHistoryBtn) { clearHistoryBtn.addEventListener('click', clearHistory); } } // 设置设置选项 function setupSettings() { // 画布大小 const canvasSizeSelect = document.getElementById('canvasSize'); canvasSizeSelect.addEventListener('change', (e) => { currentCanvasSize = parseInt(e.target.value); currentSocialMediaFormat = 'custom'; updateCanvasSize(); generateAvatar(); }); // 社交媒体格式 const socialMediaFormatSelect = document.getElementById('socialMediaFormat'); socialMediaFormatSelect.addEventListener('change', (e) => { currentSocialMediaFormat = e.target.value; if (currentSocialMediaFormat !== 'custom') { // 设置为对应社交媒体格式的尺寸 currentCanvasSize = socialMediaFormats[currentSocialMediaFormat]; canvasSizeSelect.value = currentCanvasSize; updateCanvasSize(); generateAvatar(); } }); // 像素大小 const pixelSizeSelect = document.getElementById('pixelSize'); pixelSizeSelect.addEventListener('change', (e) => { currentPixelSize = parseInt(e.target.value); generateAvatar(); }); // 界面主题 const appThemeSelect = document.getElementById('appTheme'); appThemeSelect.addEventListener('change', (e) => { const theme = e.target.value; document.body.className = theme === 'dark' ? 'dark-theme' : ''; localStorage.setItem('appTheme', theme); }); // 加载保存的主题 const savedTheme = localStorage.getItem('appTheme') || 'light'; appThemeSelect.value = savedTheme; document.body.className = savedTheme === 'dark' ? 'dark-theme' : ''; // 清空收藏 document.getElementById('clearFavorites').addEventListener('click', () => { if (confirm('确定要清空所有收藏吗?')) { favorites = []; localStorage.setItem('favorites', JSON.stringify(favorites)); loadFavorites(); } }); } // 设置编辑界面按钮 function setupEditButtons() { // 返回按钮 document.getElementById('backToGenerate3').addEventListener('click', () => { showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); }); // 颜色选择器 document.getElementById('colorPicker').addEventListener('input', (e) => { currentColor = e.target.value; }); // 画笔大小 document.getElementById('brushSize').addEventListener('change', (e) => { currentBrushSize = parseInt(e.target.value); }); // 工具按钮 const toolBtns = document.querySelectorAll('.tool-btn'); toolBtns.forEach(btn => { btn.addEventListener('click', () => { currentTool = btn.dataset.tool; toolBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); }); }); // 撤销/重做按钮 document.getElementById('undoBtn').addEventListener('click', undo); document.getElementById('redoBtn').addEventListener('click', redo); // 保存编辑 document.getElementById('saveEditBtn').addEventListener('click', saveEdit); } // 打开编辑界面 function openEditScreen() { const avatarCanvas = document.getElementById('avatarCanvas'); const editCanvas = document.getElementById('editCanvas'); const ctx = editCanvas.getContext('2d'); // 设置编辑画布大小与生成画布一致 editCanvas.width = avatarCanvas.width; editCanvas.height = avatarCanvas.height; // 复制当前头像到编辑画布 ctx.drawImage(avatarCanvas, 0, 0); // 初始化编辑工具 currentTool = 'brush'; currentColor = '#000000'; currentBrushSize = 1; // 重置历史记录 history = []; historyIndex = -1; saveToHistory(); // 设置画布事件监听 setupCanvasEventListeners(); // 显示编辑界面 showScreen('edit-screen'); } // 设置画布事件监听 function setupCanvasEventListeners() { const canvas = document.getElementById('editCanvas'); // 移除旧的事件监听 canvas.removeEventListener('mousedown', startDrawing); canvas.removeEventListener('mousemove', draw); canvas.removeEventListener('mouseup', stopDrawing); canvas.removeEventListener('mouseout', stopDrawing); canvas.removeEventListener('touchstart', startDrawing); canvas.removeEventListener('touchmove', draw); canvas.removeEventListener('touchend', stopDrawing); // 添加新的事件监听 canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('mousemove', draw); canvas.addEventListener('mouseup', stopDrawing); canvas.addEventListener('mouseout', stopDrawing); canvas.addEventListener('touchstart', startDrawing); canvas.addEventListener('touchmove', draw); canvas.addEventListener('touchend', stopDrawing); } // 开始绘制 function startDrawing(e) { isDrawing = true; draw(e); } // 绘制 function draw(e) { if (!isDrawing) return; const canvas = document.getElementById('editCanvas'); const ctx = canvas.getContext('2d'); // 获取鼠标/触摸位置 let rect = canvas.getBoundingClientRect(); let x, y; if (e.type.startsWith('mouse')) { x = e.clientX - rect.left; y = e.clientY - rect.top; } else { e.preventDefault(); x = e.touches[0].clientX - rect.left; y = e.touches[0].clientY - rect.top; } // 转换为像素坐标(对齐到像素网格) x = Math.floor(x / currentPixelSize) * currentPixelSize; y = Math.floor(y / currentPixelSize) * currentPixelSize; // 根据工具执行不同操作 switch (currentTool) { case 'brush': drawBrush(ctx, x, y); break; case 'eraser': drawEraser(ctx, x, y); break; case 'fill': fillBucket(ctx, x, y); isDrawing = false; break; } } // 停止绘制 function stopDrawing() { if (isDrawing) { isDrawing = false; saveToHistory(); } } // 画笔绘制 function drawBrush(ctx, x, y) { ctx.fillStyle = currentColor; ctx.fillRect(x, y, currentBrushSize * currentPixelSize, currentBrushSize * currentPixelSize); } // 橡皮擦绘制 function drawEraser(ctx, x, y) { ctx.clearRect(x, y, currentBrushSize * currentPixelSize, currentBrushSize * currentPixelSize); } // 填充工具 function fillBucket(ctx, x, y) { const canvas = ctx.canvas; const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; const targetColor = getPixelColor(data, x, y, canvas.width); const fillColor = hexToRgb(currentColor); if (colorsMatch(targetColor, fillColor)) return; const stack = [{x, y}]; while (stack.length > 0) { const pixel = stack.pop(); const currentPixelColor = getPixelColor(data, pixel.x, pixel.y, canvas.width); if (colorsMatch(currentPixelColor, targetColor)) { setPixelColor(data, pixel.x, pixel.y, fillColor, canvas.width); // 检查相邻像素 if (pixel.x > 0) stack.push({x: pixel.x - currentPixelSize, y: pixel.y}); if (pixel.x < canvas.width - currentPixelSize) stack.push({x: pixel.x + currentPixelSize, y: pixel.y}); if (pixel.y > 0) stack.push({x: pixel.x, y: pixel.y - currentPixelSize}); if (pixel.y < canvas.height - currentPixelSize) stack.push({x: pixel.x, y: pixel.y + currentPixelSize}); } } ctx.putImageData(imageData, 0, 0); } // 获取像素颜色 function getPixelColor(data, x, y, width) { const index = (y * width + x) * 4; return { r: data[index], g: data[index + 1], b: data[index + 2], a: data[index + 3] }; } // 设置像素颜色 function setPixelColor(data, x, y, color, width) { const index = (y * width + x) * 4; data[index] = color.r; data[index + 1] = color.g; data[index + 2] = color.b; data[index + 3] = 255; // 不透明 } // 颜色匹配 function colorsMatch(color1, color2) { return color1.r === color2.r && color1.g === color2.g && color1.b === color2.b; } // 十六进制转RGB function hexToRgb(hex) { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } // 保存到历史记录 function saveToHistory() { const canvas = document.getElementById('editCanvas'); const dataURL = canvas.toDataURL(); // 移除当前索引之后的历史记录 if (historyIndex < history.length - 1) { history = history.slice(0, historyIndex + 1); } history.push(dataURL); historyIndex = history.length - 1; } // 撤销 function undo() { if (historyIndex > 0) { historyIndex--; loadFromHistory(); } } // 重做 function redo() { if (historyIndex < history.length - 1) { historyIndex++; loadFromHistory(); } } // 从历史记录加载 function loadFromHistory() { const canvas = document.getElementById('editCanvas'); const ctx = canvas.getContext('2d'); const img = new Image(); img.onload = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0); }; img.src = history[historyIndex]; } // 保存编辑 function saveEdit() { const editCanvas = document.getElementById('editCanvas'); const avatarCanvas = document.getElementById('avatarCanvas'); const ctx = avatarCanvas.getContext('2d'); // 设置生成画布大小与编辑画布一致 avatarCanvas.width = editCanvas.width; avatarCanvas.height = editCanvas.height; // 复制编辑后的头像回生成画布 ctx.drawImage(editCanvas, 0, 0); // 返回生成界面 showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); alert('编辑已保存!'); } // 设置种子相关按钮 function setupSeedButtons() { const seedInput = document.getElementById('seedInput'); const copySeedBtn = document.getElementById('copySeedBtn'); const randomSeedBtn = document.getElementById('randomSeedBtn'); // 种子输入事件 seedInput.addEventListener('input', (e) => { setSeed(e.target.value); }); // 复制种子按钮 copySeedBtn.addEventListener('click', () => { const seedText = seedInput.value; if (seedText) { navigator.clipboard.writeText(seedText).then(() => { alert('种子已复制到剪贴板!'); }).catch(err => { console.error('复制失败:', err); alert('复制失败,请手动复制'); }); } else { alert('没有可复制的种子'); } }); // 生成随机种子按钮 randomSeedBtn.addEventListener('click', () => { const randomSeed = generateRandomSeed(); seedInput.value = randomSeed; setSeed(randomSeed); generateAvatar(); }); // 当重新生成头像时,如果没有种子则生成一个 document.getElementById('regenerateBtn').addEventListener('click', () => { if (!seedInput.value.trim()) { const randomSeed = generateRandomSeed(); seedInput.value = randomSeed; setSeed(randomSeed); } }); } // 设置社交媒体格式 function setSocialMediaFormat(format) { currentSocialMediaFormat = format; // 设置为对应社交媒体格式的尺寸 currentCanvasSize = socialMediaFormats[currentSocialMediaFormat]; // 更新设置界面中的选择器 const canvasSizeSelect = document.getElementById('canvasSize'); const socialMediaFormatSelect = document.getElementById('socialMediaFormat'); canvasSizeSelect.value = currentCanvasSize; socialMediaFormatSelect.value = currentSocialMediaFormat; // 更新画布大小 updateCanvasSize(); // 重新生成头像 generateAvatar(); // 更新社交媒体格式按钮的激活状态 const socialBtns = document.querySelectorAll('.social-options .theme-btn'); socialBtns.forEach(btn => { btn.classList.remove('active'); if (btn.dataset.format === format) { btn.classList.add('active'); } }); } // 更新画布大小 function updateCanvasSize() { const canvas = document.getElementById('avatarCanvas'); canvas.width = currentCanvasSize; canvas.height = currentCanvasSize; } // 生成头像 function generateAvatar() { const canvas = document.getElementById('avatarCanvas'); const ctx = canvas.getContext('2d'); // 如果有种子输入但未设置,先设置种子 const seedInput = document.getElementById('seedInput'); if (seedInput && seedInput.value && seedInput.value.trim() !== '') { setSeed(seedInput.value); } // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 绘制背景 ctx.fillStyle = getRandomColor(); ctx.fillRect(0, 0, canvas.width, canvas.height); // 根据风格生成头像 switch(currentStyle) { case 'cartoon': drawCartoonStyle(ctx); break; case 'pixelart': drawPixelArtStyle(ctx); break; case 'minimal': drawMinimalStyle(ctx); break; } // 保存到历史记录 saveAvatarToHistory(); } // 生成特定细节的头像 function generateAvatarWithFocus(focus) { const canvas = document.getElementById('avatarCanvas'); const ctx = canvas.getContext('2d'); // 保存当前头像 const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); // 重新生成 generateAvatar(); // 根据焦点重新绘制特定部分 switch(focus) { case 'eyes': drawEyes(ctx); break; case 'nose': drawNose(ctx); break; case 'mouth': drawMouth(ctx); break; case 'accessories': drawAccessories(ctx); break; } } // 基于种子的随机数生成器 function seededRandom(seed) { let x = Math.sin(seed) * 10000; return x - Math.floor(x); } // 获取当前随机数生成器 function getRandom() { if (useSeed && currentSeed !== null) { currentSeed = (currentSeed + 0.123456789) % 1; return seededRandom(currentSeed); } return Math.random(); } // 设置随机种子 function setSeed(seed) { if (seed && seed.trim() !== '') { // 将字符串种子转换为数字 let numSeed = 0; for (let i = 0; i < seed.length; i++) { numSeed += seed.charCodeAt(i) * Math.pow(31, i); } currentSeed = numSeed % 1; useSeed = true; } else { useSeed = false; currentSeed = null; } } // 生成随机种子字符串 function generateRandomSeed() { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = ''; for (let i = 0; i < 10; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } // 获取随机颜色 function getRandomColor() { const colors = colorThemes[currentTheme]; return colors[Math.floor(getRandom() * colors.length)]; } // 卡通风格 function drawCartoonStyle(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const size = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.8; // 头部 ctx.fillStyle = getRandomColor(); ctx.beginPath(); ctx.arc(centerX, centerY, size / 2, 0, Math.PI * 2); ctx.fill(); drawEyes(ctx); drawNose(ctx); drawMouth(ctx); drawAccessories(ctx); } // 像素艺术风格 function drawPixelArtStyle(ctx) { const gridSize = currentPixelSize; const cols = Math.floor(ctx.canvas.width / gridSize); const rows = Math.floor(ctx.canvas.height / gridSize); // 头部轮廓 for (let y = 2; y < rows - 2; y++) { for (let x = 2; x < cols - 2; x++) { if ((x === 2 || x === cols - 3) && (y > 4 && y < rows - 5)) continue; if (Math.abs(x - cols/2) + Math.abs(y - rows/2) < rows/2 - 1) { ctx.fillStyle = getRandomColor(); ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize); } } } // 眼睛 drawPixelEyes(ctx, gridSize, cols, rows); // 嘴巴 drawPixelMouth(ctx, gridSize, cols, rows); } // 简约风格 function drawMinimalStyle(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const size = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.6; // 头部 ctx.fillStyle = getRandomColor(); ctx.fillRect(centerX - size/2, centerY - size/2, size, size); // 眼睛 const eyeSize = size * 0.1; ctx.fillStyle = '#000000'; ctx.fillRect(centerX - size/4 - eyeSize/2, centerY - size/6, eyeSize, eyeSize); ctx.fillRect(centerX + size/4 - eyeSize/2, centerY - size/6, eyeSize, eyeSize); // 嘴巴 ctx.fillRect(centerX - size/6, centerY + size/6, size/3, eyeSize/2); } // 绘制眼睛 function drawEyes(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const eyeSize = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.15; ctx.fillStyle = '#FFFFFF'; ctx.beginPath(); ctx.arc(centerX - eyeSize * 1.5, centerY - eyeSize/2, eyeSize, 0, Math.PI * 2); ctx.arc(centerX + eyeSize * 1.5, centerY - eyeSize/2, eyeSize, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#000000'; ctx.beginPath(); ctx.arc(centerX - eyeSize * 1.5, centerY - eyeSize/2, eyeSize * 0.4, 0, Math.PI * 2); ctx.arc(centerX + eyeSize * 1.5, centerY - eyeSize/2, eyeSize * 0.4, 0, Math.PI * 2); ctx.fill(); } // 绘制鼻子 function drawNose(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const noseSize = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.08; ctx.fillStyle = getRandomColor(); ctx.beginPath(); ctx.arc(centerX, centerY, noseSize, 0, Math.PI * 2); ctx.fill(); } // 绘制嘴巴 function drawMouth(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const mouthSize = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.25; ctx.fillStyle = '#FF0000'; ctx.beginPath(); ctx.arc(centerX, centerY + mouthSize/3, mouthSize/2, 0, Math.PI); ctx.fill(); } // 绘制装饰 function drawAccessories(ctx) { const centerX = ctx.canvas.width / 2; const centerY = ctx.canvas.height / 2; const size = Math.min(ctx.canvas.width, ctx.canvas.height) * 0.8; // 随机添加装饰 const accessoryType = Math.floor(getRandom() * 3); switch(accessoryType) { case 0: // 帽子 ctx.fillStyle = getRandomColor(); ctx.fillRect(centerX - size/3, centerY - size/2 - size/6, size * 2/3, size/6); ctx.fillRect(centerX - size/2.5, centerY - size/2, size * 2/5, size/10); break; case 1: // 眼镜 ctx.strokeStyle = getRandomColor(); ctx.lineWidth = 3; ctx.beginPath(); ctx.arc(centerX - size/4, centerY - size/6, size/8, 0, Math.PI * 2); ctx.arc(centerX + size/4, centerY - size/6, size/8, 0, Math.PI * 2); ctx.stroke(); ctx.beginPath(); ctx.moveTo(centerX - size/8, centerY - size/6); ctx.lineTo(centerX + size/8, centerY - size/6); ctx.stroke(); break; case 2: // 耳朵 ctx.fillStyle = getRandomColor(); ctx.beginPath(); ctx.arc(centerX - size/2, centerY, size/6, 0, Math.PI * 2); ctx.arc(centerX + size/2, centerY, size/6, 0, Math.PI * 2); ctx.fill(); break; } } // 绘制像素风格眼睛 function drawPixelEyes(ctx, gridSize, cols, rows) { const centerX = cols / 2; const centerY = rows / 2; ctx.fillStyle = '#FFFFFF'; // 左眼 for (let y = centerY - 2; y <= centerY + 1; y++) { for (let x = centerX - 4; x <= centerX - 2; x++) { ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize); } } // 右眼 for (let y = centerY - 2; y <= centerY + 1; y++) { for (let x = centerX + 2; x <= centerX + 4; x++) { ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize); } } ctx.fillStyle = '#000000'; // 左瞳孔 ctx.fillRect((centerX - 3) * gridSize, centerY * gridSize, gridSize, gridSize); // 右瞳孔 ctx.fillRect((centerX + 3) * gridSize, centerY * gridSize, gridSize, gridSize); } // 绘制像素风格嘴巴 function drawPixelMouth(ctx, gridSize, cols, rows) { const centerX = cols / 2; const centerY = rows / 2; ctx.fillStyle = '#FF0000'; for (let x = centerX - 3; x <= centerX + 3; x++) { ctx.fillRect(x * gridSize, (centerY + 3) * gridSize, gridSize, gridSize); } for (let x = centerX - 2; x <= centerX + 2; x++) { ctx.fillRect(x * gridSize, (centerY + 4) * gridSize, gridSize, gridSize); } } // 保存头像 function saveAvatar() { const canvas = document.getElementById('avatarCanvas'); const dataURL = canvas.toDataURL('image/png'); // 如果自动保存开启,则保存到本地 if (document.getElementById('autoSave').checked) { localStorage.setItem('lastAvatar', dataURL); alert('头像已保存!'); } } // 添加到收藏 function addToFavorites() { const canvas = document.getElementById('avatarCanvas'); const dataURL = canvas.toDataURL('image/png'); // 检查是否已存在 const exists = favorites.some(fav => fav.dataURL === dataURL); if (exists) { alert('该头像已在收藏中!'); return; } favorites.push({ id: Date.now(), dataURL: dataURL, timestamp: new Date().toISOString() }); localStorage.setItem('favorites', JSON.stringify(favorites)); loadFavorites(); alert('头像已添加到收藏!'); } // 下载头像 function downloadAvatar() { const canvas = document.getElementById('avatarCanvas'); const link = document.createElement('a'); link.download = `pixel-avatar-${Date.now()}.png`; link.href = canvas.toDataURL('image/png'); link.click(); } // 加载收藏 function loadFavorites() { const grid = document.getElementById('favorites-grid'); grid.innerHTML = ''; if (favorites.length === 0) { grid.innerHTML = '
暂无收藏
'; return; } favorites.forEach(fav => { const item = document.createElement('div'); item.className = 'favorite-item'; const img = document.createElement('img'); img.src = fav.dataURL; img.alt = '收藏的头像'; const removeBtn = document.createElement('button'); removeBtn.className = 'remove-favorite'; removeBtn.textContent = '×'; removeBtn.addEventListener('click', () => removeFavorite(fav.id)); item.appendChild(img); item.appendChild(removeBtn); grid.appendChild(item); }); } // 移除收藏 function removeFavorite(id) { favorites = favorites.filter(fav => fav.id !== id); localStorage.setItem('favorites', JSON.stringify(favorites)); loadFavorites(); } // 自动保存 window.addEventListener('beforeunload', () => { if (document.getElementById('autoSave').checked) { saveAvatar(); } }); // 保存头像到历史记录 function saveAvatarToHistory() { const canvas = document.getElementById('avatarCanvas'); const dataURL = canvas.toDataURL('image/png'); const seedInput = document.getElementById('seedInput'); const seed = seedInput.value || 'random'; // 检查是否与最近的历史记录相同 if (avatarHistory.length > 0 && avatarHistory[0].dataURL === dataURL) { return; } // 添加新记录到历史 avatarHistory.unshift({ id: Date.now(), dataURL: dataURL, seed: seed, timestamp: new Date().toISOString() }); // 限制历史记录数量 if (avatarHistory.length > maxHistoryItems) { avatarHistory = avatarHistory.slice(0, maxHistoryItems); } localStorage.setItem('avatarHistory', JSON.stringify(avatarHistory)); // 如果当前在历史记录界面,更新显示 if (document.getElementById('history-screen').classList.contains('active')) { loadHistory(); } } // 加载历史记录 function loadHistory() { const grid = document.getElementById('history-grid'); grid.innerHTML = ''; if (avatarHistory.length === 0) { grid.innerHTML = '暂无历史记录
'; return; } avatarHistory.forEach(item => { const historyItem = document.createElement('div'); historyItem.className = 'favorite-item'; const img = document.createElement('img'); img.src = item.dataURL; img.alt = `历史头像 ${new Date(item.timestamp).toLocaleString()}`; // 添加点击事件,可查看详细信息 img.addEventListener('click', () => { // 将历史记录中的头像恢复到生成界面 const avatarCanvas = document.getElementById('avatarCanvas'); const ctx = avatarCanvas.getContext('2d'); const historyImg = new Image(); historyImg.onload = function() { avatarCanvas.width = historyImg.width; avatarCanvas.height = historyImg.height; ctx.drawImage(historyImg, 0, 0); // 设置种子 const seedInput = document.getElementById('seedInput'); seedInput.value = item.seed; if (item.seed !== 'random') { setSeed(item.seed); } // 切换到生成界面 showScreen('generate-screen'); document.getElementById('nav-generate').classList.add('active'); document.getElementById('nav-history').classList.remove('active'); }; historyImg.src = item.dataURL; }); historyItem.appendChild(img); grid.appendChild(historyItem); }); } // 清空历史记录 function clearHistory() { if (confirm('确定要清空所有历史记录吗?')) { avatarHistory = []; localStorage.removeItem('avatarHistory'); loadHistory(); alert('历史记录已清空!'); } }