save code

This commit is contained in:
xsl
2026-01-18 22:39:06 +08:00
parent 11dd30eddf
commit c93d8b7236
6 changed files with 359 additions and 13 deletions
+153 -4
View File
@@ -27,10 +27,32 @@ async function changeHair(imageFile, hairstyleId) {
}
}
async function changeHairColor(imageFile, rgb, ratio) {
try {
const formData = new FormData();
formData.append('image', imageFile);
formData.append('rgb', rgb);
formData.append('ratio', ratio);
const response = await axios.post('/api/change-hair-color', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
return response.data;
} catch (error) {
console.error('更换头发颜色失败:', error);
throw error;
}
}
// 全局变量
let uploadedImage = null;
let selectedHairstyle = null;
let hairstylesData = [];
let selectedColor = null;
let selectedRatio = 0.9;
let currentFunction = null; // 记录当前执行的功能:'hairstyle' 或 'color'
// DOM元素
const elements = {
@@ -39,16 +61,28 @@ const elements = {
imagePreview: document.getElementById('imagePreview'),
imageUpload: document.getElementById('imageUpload'),
nextBtn: document.getElementById('nextBtn'),
changeColorBtn: document.getElementById('changeColorBtn'),
// 发型选择页元素
hairstylePage: document.getElementById('hairstylePage'),
hairstyleGrid: document.getElementById('hairstyleGrid'),
confirmBtn: document.getElementById('confirmBtn'),
// 头发颜色选择页元素
hairColorPage: document.getElementById('hairColorPage'),
colorPicker: document.getElementById('colorPicker'),
colorPreview: document.getElementById('colorPreview'),
rgbValue: document.getElementById('rgbValue'),
ratioSlider: document.getElementById('ratioSlider'),
ratioValue: document.getElementById('ratioValue'),
confirmColorBtn: document.getElementById('confirmColorBtn'),
// 结果预览页元素
resultPage: document.getElementById('resultPage'),
resultTitle: document.getElementById('resultTitle'),
resultPreview: document.getElementById('resultPreview'),
reselectHairstyleBtn: document.getElementById('reselectHairstyleBtn'),
reselectColorBtn: document.getElementById('reselectColorBtn'),
reuploadImageBtn: document.getElementById('reuploadImageBtn'),
saveResultBtn: document.getElementById('saveResultBtn'),
@@ -71,17 +105,24 @@ function bindEventListeners() {
// 图片上传
elements.imageUpload.addEventListener('change', handleImageUpload);
// 下一步按钮
// 功能选择按钮
elements.nextBtn.addEventListener('click', navigateToHairstylePage);
elements.changeColorBtn.addEventListener('click', navigateToHairColorPage);
// 确认按钮
// 发型确认按钮
elements.confirmBtn.addEventListener('click', handleConfirmHairstyle);
// 头发颜色相关事件
elements.colorPicker.addEventListener('input', handleColorChange);
elements.ratioSlider.addEventListener('input', handleRatioChange);
elements.confirmColorBtn.addEventListener('click', handleConfirmColor);
// 返回按钮
elements.backBtn.addEventListener('click', handleBack);
// 结果页操作按钮
elements.reselectHairstyleBtn.addEventListener('click', handleReselectHairstyle);
elements.reselectColorBtn.addEventListener('click', handleReselectColor);
elements.reuploadImageBtn.addEventListener('click', handleReuploadImage);
elements.saveResultBtn.addEventListener('click', handleSaveResult);
}
@@ -127,11 +168,26 @@ function navigateToHairstylePage() {
return;
}
currentFunction = 'hairstyle';
renderHairstyles();
showPage(elements.hairstylePage);
showBackBtn();
}
// 导航到头发颜色选择页
function navigateToHairColorPage() {
if (!uploadedImage) {
alert('请先上传图片');
return;
}
currentFunction = 'color';
// 初始化颜色选择器
handleColorChange({ target: elements.colorPicker });
showPage(elements.hairColorPage);
showBackBtn();
}
// 渲染发型列表
function renderHairstyles() {
elements.hairstyleGrid.innerHTML = '';
@@ -169,6 +225,82 @@ function selectHairstyle(hairstyleId) {
}
}
// 处理颜色变化
function handleColorChange(e) {
const color = e.target.value;
selectedColor = color;
// 更新颜色预览
elements.colorPreview.style.backgroundColor = color;
// 转换为RGB值
const rgb = hexToRgb(color);
elements.rgbValue.textContent = `[${rgb.r}, ${rgb.g}, ${rgb.b}]`;
}
// 处理比例变化
function handleRatioChange(e) {
const ratio = e.target.value;
selectedRatio = parseFloat(ratio);
elements.ratioValue.textContent = ratio;
}
// 处理确认颜色选择
async function handleConfirmColor() {
if (!uploadedImage || !selectedColor) {
alert('请上传图片并选择颜色');
return;
}
try {
// 显示加载状态
elements.loading.innerHTML = `
<div class="loading-spinner"></div>
<p>正在处理头发颜色更换,请稍候...</p>
<p style="font-size: 0.9rem; color: #666;">此过程可能需要10-60秒</p>
`;
showLoading();
// 转换为RGB值
const rgb = hexToRgb(selectedColor);
const rgbString = `[${rgb.r}, ${rgb.g}, ${rgb.b}]`;
// 发起头发颜色更换请求
const response = await changeHairColor(uploadedImage, rgbString, selectedRatio);
if (response.success) {
// 显示结果
elements.resultTitle.textContent = '头发颜色更换效果';
showResult(response.data.result_image);
// 显示/隐藏相应的按钮
elements.reselectHairstyleBtn.style.display = 'none';
elements.reselectColorBtn.style.display = 'block';
} else {
alert(response.message || '处理失败,请重试');
}
} catch (error) {
console.error('处理失败:', error);
alert('处理失败,请重试');
} finally {
hideLoading();
}
}
// 十六进制颜色转换为RGB
function hexToRgb(hex) {
// 移除#号
hex = hex.replace(/^#/, '');
// 解析RGB值
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return { r, g, b };
}
// 处理确认发型选择
async function handleConfirmHairstyle() {
if (!uploadedImage || !selectedHairstyle) {
@@ -190,7 +322,12 @@ async function handleConfirmHairstyle() {
if (response.success) {
// 显示结果
elements.resultTitle.textContent = '发型更换效果';
showResult(response.data.result_image);
// 显示/隐藏相应的按钮
elements.reselectHairstyleBtn.style.display = 'block';
elements.reselectColorBtn.style.display = 'none';
} else {
alert(response.message || '处理失败,请重试');
}
@@ -216,6 +353,11 @@ function handleReselectHairstyle() {
showPage(elements.hairstylePage);
}
// 处理重新选择颜色
function handleReselectColor() {
showPage(elements.hairColorPage);
}
// 处理重新上传图片
function handleReuploadImage() {
// 重置图片上传
@@ -258,17 +400,24 @@ function handleSaveResult() {
// 处理返回按钮
function handleBack() {
if (elements.resultPage.classList.contains('active')) {
showPage(elements.hairstylePage);
if (currentFunction === 'hairstyle') {
showPage(elements.hairstylePage);
} else if (currentFunction === 'color') {
showPage(elements.hairColorPage);
}
} else if (elements.hairstylePage.classList.contains('active')) {
showPage(elements.homePage);
hideBackBtn();
} else if (elements.hairColorPage.classList.contains('active')) {
showPage(elements.homePage);
hideBackBtn();
}
}
// 显示页面
function showPage(page) {
// 隐藏所有页面
[elements.homePage, elements.hairstylePage, elements.resultPage].forEach(p => {
[elements.homePage, elements.hairstylePage, elements.hairColorPage, elements.resultPage].forEach(p => {
p.classList.remove('active');
});