document.addEventListener('DOMContentLoaded', function() { // 添加基础URL配置 const BASE_URL = 'https://jasonnoy-boss-translator.hf.space/'; // 空字符串表示使用相对路径 // 动态文案循环显示 - 打字机效果 const dynamicText = document.getElementById('dynamic-text'); if (dynamicText) { const texts = ['"丑"', '"不高级"', '"再试试"']; let currentIndex = 0; let isDeleting = false; let charIndex = 0; let typingSpeed = 150; // 打字速度 let pauseTime = 2000; // 完成后暂停时间,调整为2秒 function typeEffect() { const currentText = texts[currentIndex]; if (!isDeleting) { // 打字阶段 if (charIndex < currentText.length) { dynamicText.textContent = currentText.substring(0, charIndex + 1); charIndex++; setTimeout(typeEffect, typingSpeed); } else { // 完成打字,等待删除 setTimeout(() => { isDeleting = true; typeEffect(); }, pauseTime); } } else { // 删除阶段 if (charIndex > 0) { dynamicText.textContent = currentText.substring(0, charIndex); charIndex--; setTimeout(typeEffect, typingSpeed / 2); } else { // 完成删除,切换到下一个文案 isDeleting = false; currentIndex = (currentIndex + 1) % texts.length; setTimeout(typeEffect, 500); } } } // 开始打字机效果 typeEffect(); } // 添加花朵的微小浮动动画 const flowerImg = document.querySelector('.flower-img'); if (flowerImg) { flowerImg.style.animation = 'floatFlower 4s ease-in-out infinite alternate'; } // 添加浮动动画的CSS const style = document.createElement('style'); style.textContent = ` @keyframes floatFlower { 0% { transform: translateY(0) rotate(0); } 100% { transform: translateY(-15px) rotate(2deg); } } `; document.head.appendChild(style); // 图片上传处理 const imageUploadArea = document.getElementById('image-upload'); const imageInput = document.getElementById('image-input'); if (imageUploadArea && imageInput) { imageUploadArea.addEventListener('click', function() { imageInput.click(); }); imageInput.addEventListener('change', function() { if (this.files && this.files[0]) { const reader = new FileReader(); reader.onload = function(e) { // 移除上传按钮 while (imageUploadArea.firstChild) { imageUploadArea.removeChild(imageUploadArea.firstChild); } // 添加预览图片 const img = document.createElement('img'); img.src = e.target.result; imageUploadArea.appendChild(img); imageUploadArea.classList.add('with-image'); // 存储图片数据到 sessionStorage 以便在反馈页面使用 sessionStorage.setItem('uploadedImage', e.target.result); }; reader.readAsDataURL(this.files[0]); } }); // 拖放上传功能 ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { imageUploadArea.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { imageUploadArea.addEventListener(eventName, function() { imageUploadArea.classList.add('highlight'); }, false); }); ['dragleave', 'drop'].forEach(eventName => { imageUploadArea.addEventListener(eventName, function() { imageUploadArea.classList.remove('highlight'); }, false); }); imageUploadArea.addEventListener('drop', function(e) { const dt = e.dataTransfer; const files = dt.files; if (files && files[0]) { imageInput.files = files; const reader = new FileReader(); reader.onload = function(e) { // 移除上传按钮 while (imageUploadArea.firstChild) { imageUploadArea.removeChild(imageUploadArea.firstChild); } // 添加预览图片 const img = document.createElement('img'); img.src = e.target.result; imageUploadArea.appendChild(img); imageUploadArea.classList.add('with-image'); sessionStorage.setItem('uploadedImage', e.target.result); console.log("image uploaded") }; reader.readAsDataURL(files[0]); } }, false); } // 解析按钮处理 const resolveButton = document.getElementById('resolve-button'); const textInput = document.getElementById('text-input'); if (resolveButton && textInput) { resolveButton.addEventListener('click', function() { const text = textInput.value.trim(); // 检查是否有文本输入 if (text === '') { alert('请输入需求方反馈内容'); return; } // 显示加载状态 resolveButton.disabled = true; // 有趣的加载文案 const loadingTexts = [ "检测到需求方第8版需求残留怨气...正在召唤阴阳师修改图层结界", "监控到大象对话框散发红光!自动生成24K纯杠精防护罩..." ]; // 随机选择一个文案作为起点 let currentTextIndex = Math.floor(Math.random() * loadingTexts.length); let currentText = loadingTexts[currentTextIndex]; let charIndex = 0; let typingSpeed = 100; // 打字速度,从50ms增加到100ms // 添加弹跳动画的CSS if (!document.getElementById('bounce-animation-style')) { const bounceStyle = document.createElement('style'); bounceStyle.id = 'bounce-animation-style'; bounceStyle.textContent = ` .wave-container { position: relative; white-space: nowrap; } .bounce-text { display: inline-block; position: relative; transition: transform 0.3s ease-out; } `; document.head.appendChild(bounceStyle); } // 创建一个容器来包含所有字符 const waveContainer = document.createElement('div'); waveContainer.className = 'wave-container'; resolveButton.innerHTML = ''; resolveButton.appendChild(waveContainer); // 跟踪波峰位置 let peakPosition = -1; let waveInterval; // 打字机效果函数 function typeLoadingText() { if (charIndex < currentText.length) { // 创建一个span元素包装字符 const charSpan = document.createElement('span'); charSpan.className = 'bounce-text'; charSpan.textContent = currentText.charAt(charIndex); // 添加到容器 waveContainer.appendChild(charSpan); charIndex++; setTimeout(typeLoadingText, typingSpeed); // 如果这是第一个字符,开始波动动画 if (charIndex === 1) { startWaveAnimation(); } } else { // 当前文案打完,等待一段时间后切换到下一个文案 setTimeout(() => { // 清除波动动画 if (waveInterval) { clearInterval(waveInterval); waveInterval = null; } // 切换到下一个文案 charIndex = 0; currentTextIndex = (currentTextIndex + 1) % loadingTexts.length; currentText = loadingTexts[currentTextIndex]; // 清空容器,准备下一个文案 waveContainer.innerHTML = ''; typeLoadingText(); }, 4000); // 完整显示时间 } } // 波动动画函数 function startWaveAnimation() { // 清除之前的间隔 if (waveInterval) clearInterval(waveInterval); // 启动波动动画 waveInterval = setInterval(() => { // 获取所有字符 const chars = waveContainer.querySelectorAll('.bounce-text'); if (chars.length === 0) return; // 移动波峰位置 peakPosition = (peakPosition + 1) % chars.length; // 应用变换 chars.forEach((char, index) => { if (index === peakPosition) { // 波峰位置 char.style.transform = 'translateY(-8px)'; } else if (Math.abs(index - peakPosition) === 1) { // 波峰旁边的字符稍微上移 char.style.transform = 'translateY(-4px)'; } else { // 其他字符回到原位 char.style.transform = 'translateY(0)'; } }); }, 100); // 每100ms更新一次波峰位置 } // 开始打字机效果 typeLoadingText(); // 存储文本到 sessionStorage sessionStorage.setItem('uploadedText', text); console.log(text) // 获取上传的图片数据 const uploadedImage = sessionStorage.getItem('uploadedImage'); // 分析反馈内容,生成解读结果 analyzeUserInput(text, uploadedImage).then(() => { // 解读完成后跳转到反馈页面 window.location.href = 'feedback.html'; }).catch(error => { console.error('解读失败:', error); alert('解读失败,请重试'); resolveButton.disabled = false; resolveButton.textContent = '一键解读'; }); }); } // 分析用户输入和图片的函数 async function analyzeUserInput(text, imageData) { try { const health = await fetch(`${BASE_URL}health`) console.log(health) const response = await fetch(`${BASE_URL}api/analyze`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: text, image_data: imageData, request_model_id: 'gpt-4.1-mini' }) }); console.log(response) const data = await response.json(); console.log(data) const rep = data['output'][0]['content'][0]['text']; sessionStorage.setItem('analysisResult', rep); } catch (error) { console.error('分析失败:', error); // 使用默认的分析结果 const defaultAnalysis = `情绪值:😠😠😠\n\n情绪分析:需求方目前很不满,需要大幅改正。 修改建议: 1. 色彩调整:在保持整体色调的基础上,加入一些明亮的点缀色,如淡黄色、淡紫蓝、淡红蓝微粉等。用于按钮、图标或重要文本,以增加吸引力。 2. 增加层级感:利用饱和度(Glassmorphism)效果,为卡片/重要框添加模糊背景和阴影,营造出浮起感,引入3D元素或深浅变化,增加页面的深度和空间感。 3. 增加互动性:为按钮和图标添加悬停动画或点击动画,提供用户及时反馈。引入微动画(Micro-interactions),如加载动画、切换动画等等,使页面更具活力。`; sessionStorage.setItem('analysisResult', defaultAnalysis); } } // 示例图片添加到参考案例 const exampleCards = document.querySelectorAll('.example-card'); if (exampleCards.length > 0) { // 为示例卡片添加示例图片背景 const exampleBgs = [ 'linear-gradient(45deg, #2d2d4e, #1e1e30)', 'linear-gradient(45deg, #2e2e2e, #1a1a1a)', 'linear-gradient(45deg, #332e42, #1f1b30)' ]; exampleCards.forEach((card, index) => { card.style.background = exampleBgs[index % exampleBgs.length]; }); } // 加载并显示反馈页面的分析结果 function loadAnalysisResult() { const analysisResult = sessionStorage.getItem('analysisResult'); console.log(analysisResult) if (!analysisResult) return; try { // 设置情绪值 if (analysisResult) { const emotionIcons = document.querySelector('.emotion-icons'); const emotionText = document.querySelector('.emotion-text'); if (emotionIcons && emotionText) { // 清空图标区域 emotionIcons.innerHTML = ''; // 提取情绪值部分 const emojiText = analysisResult.split('情绪值:')[1].split('\n')[0]; const emotionAnalyse = analysisResult.split('情绪分析:')[1].split('\n')[0]; // 提取emoji const emojis = [emojiText.codePointAt(0), emojiText.codePointAt(2), emojiText.codePointAt(4)]; console.log(emojis) emojis.forEach(emoji => { console.log(emoji) }) if (emojis) { // 只显示3个emoji,确保一致性 const displayEmojis = emojis.slice(0, 3); displayEmojis.forEach(emoji => { const span = document.createElement('span'); span.className = 'emoji'; span.textContent = String.fromCodePoint(emoji); emotionIcons.appendChild(span); }); } else { // 默认情绪 for (let i = 0; i < 3; i++) { const span = document.createElement('span'); span.className = 'emoji'; span.textContent = '😠'; emotionIcons.appendChild(span); } } // 设置文字描述 // 查找"情绪分析:"部分 let textDescription = ''; if (emotionAnalyse) { textDescription = emotionAnalyse.trim(); } else { // 如果没有情绪分析部分,根据emoji生成默认文本 if (emojis && emojis[0] === '😠') { textDescription = '需求方对设计非常不满意,建议全面改进'; } else if (emojis && emojis[0] === '🙁') { textDescription = '需求方对设计不太满意,需要较多改进'; } else if (emojis && emojis[0] === '😐') { textDescription = '需求方对设计感觉一般,有改进空间'; } else if (emojis && emojis[0] === '🙂') { textDescription = '需求方对设计比较满意,小幅改进即可'; } else if (emojis && emojis[0] === '😊') { textDescription = '需求方对设计非常满意,细节优化即可'; } else { textDescription = '需要基于反馈进行改进'; } } emotionText.textContent = textDescription; } } // 提取修改建议 const suggestionsContainer = document.querySelector('.suggestions-container'); if (suggestionsContainer) { try { // 使用split提取修改建议部分 const suggestionsText = analysisResult.split('修改建议:')[1].split('搜索内容:')[0]; sessionStorage.setItem('suggestionsText', suggestionsText) if (suggestionsText) { // 提取三个建议 const suggestionLines = suggestionsText.trim().split('\n\n'); const suggestions = []; // 处理每一行建议 for (let i = 0; i < suggestionLines.length; i++) { const line = suggestionLines[i].trim(); if (line.match(/^\d+\.\s/)) { // 找到了序号开头的行,这是建议的标题和内容 const suggestionText = line.replace(/^\d+\.\s/, ''); // 拆分标题和内容(假设冒号或:分隔) let title = suggestionText; let content = ''; if (suggestionText.includes(':')) { [title, content] = suggestionText.split(':', 2); } else if (suggestionText.includes(':')) { [title, content] = suggestionText.split(':', 2); } suggestions.push({ title: title.trim(), content: content.trim() }); // 最多收集三个建议 if (suggestions.length >= 3) break; } } // 更新建议卡片 if (suggestions.length > 0) { const cardStyles = ['yellow-top', 'cyan-top', 'purple-top']; suggestionsContainer.innerHTML = ''; suggestions.forEach((suggestion, index) => { const cardStyle = cardStyles[index % cardStyles.length]; const card = document.createElement('div'); card.className = `suggestion-card ${cardStyle}`; const titleElement = document.createElement('h3'); titleElement.className = 'suggestion-title'; titleElement.textContent = suggestion.title; const textElement = document.createElement('p'); textElement.className = 'suggestion-text'; textElement.textContent = suggestion.content; card.appendChild(titleElement); card.appendChild(textElement); suggestionsContainer.appendChild(card); }); // 加载参考案例 loadReferenceExamples(suggestions); } } } catch (error) { console.error('解析建议失败:', error); } } } catch (error) { console.error('解析分析结果失败:', error); } } // 根据建议加载参考案例 async function loadReferenceExamples(suggestions) { const analysisResult = sessionStorage.getItem('analysisResult'); const searchContent = analysisResult.split('搜索内容:')[1].trim(); const examplesContainer = document.querySelector('.examples-container'); if (!examplesContainer) return; // 获取现有的示例卡片元素 const exampleCards = examplesContainer.querySelectorAll('.example-card'); if (exampleCards.length !== 2) { console.error('未找到预期的两个示例卡片元素'); return; } try { // 显示加载状态 exampleCards.forEach(card => { const img = card.querySelector('.example-image'); const desc = card.querySelector('.example-desc'); const sourceLink = card.querySelector('.example-source a'); if (img) { img.style.display = 'none'; } if (desc) { desc.innerHTML = `
生成失败: ${error.message || '请稍后重试'}
生成失败: ${error.message || '请稍后重试'}
生成中,请稍候...