Files
dsProject/dsLightRag/static/JiMeng/image_preview.html
2025-08-21 10:21:28 +08:00

394 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二、分镜头脚本生成</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
body {
background-color: #f5f7fa;
color: #333;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
padding: 30px;
}
h1 {
text-align: center;
margin-bottom: 20px;
color: #2c3e50;
}
.image-container {
display: flex;
justify-content: center;
margin: 30px 0;
min-height: 400px;
align-items: center;
background-color: #f8f9fa;
border-radius: 6px;
padding: 20px;
}
#previewImage {
max-width: 100%;
max-height: 600px;
border-radius: 6px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.loading {
text-align: center;
font-size: 18px;
color: #666;
}
.btn-group {
display: flex;
justify-content: center;
margin-top: 30px;
gap: 20px;
}
.btn {
padding: 12px 25px;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
transition: background 0.3s;
}
.btn-primary {
background-color: #3498db;
color: white;
}
.btn-primary:hover {
background-color: #2980b9;
}
.btn-secondary {
background-color: #95a5a6;
color: white;
}
.btn-secondary:hover {
background-color: #7f8c8d;
}
.btn-danger {
background-color: #e74c3c;
color: white;
}
.btn-danger:hover {
background-color: #c0392b;
}
/* 添加遮罩动画样式 */
.mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
}
.mask.active {
opacity: 1;
visibility: visible;
}
.loader {
width: 50px;
height: 50px;
border: 5px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top-color: #3498db;
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.mask-text {
color: white;
margin-top: 20px;
text-align: center;
font-size: 18px;
}
.mask-content {
display: flex;
flex-direction: column;
align-items: center;
}
/* 新增样式 */
.section {
border-radius: 8px;
padding: 25px;
margin-bottom: 30px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.image-section {
background-color: #f8f9fa;
}
.prompt-section {
background-color: #ffffff;
border: 1px solid #e9ecef;
}
.section-title {
font-size: 20px;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 1px solid #e9ecef;
color: #2c3e50;
}
.btn-group-image {
display: flex;
justify-content: center;
margin-top: 20px;
gap: 15px;
}
.btn-group-fen {
display: flex;
justify-content: flex-end;
margin-top: 15px;
}
</style>
</head>
<body>
<div class="container">
<h1>二、分镜头脚本生成</h1>
<!-- 图片预览区域 -->
<div class="section image-section">
<h2 class="section-title">图片预览</h2>
<div class="image-container">
<div class="loading" id="loading">加载中...</div>
<img id="previewImage" style="display: none;">
</div>
<div class="btn-group-image">
<button class="btn btn-danger" id="backBtn">返回修改</button>
<button class="btn btn-secondary" id="regenerateBtn">重新生成</button>
</div>
</div>
<!-- 分镜头生成区域 -->
<div class="section prompt-section">
<h2 class="section-title">分镜头脚本生成</h2>
<p style="margin-bottom: 15px; color: #666;">请调整提示词,然后点击"生成分镜头"按钮:</p>
<textarea id="fenjingtouPrompt" rows="4" style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; resize: vertical;">以这张图片为首帧帮我生成一个5秒的视频提示词。提示词包括镜号、运镜、画面内容</textarea>
<div class="btn-group-fen">
<button class="btn btn-success" id="generateFenBtn">生成分镜头</button>
</div>
</div>
<!-- 分镜头结果区域 -->
<div id="fenjingtouResult" class="section" style="margin-top: 30px; display: none; background-color: #f8f9fa;">
<h2 class="section-title">分镜头脚本</h2>
<pre style="background-color: #ffffff; padding: 15px; border-radius: 6px; border: 1px solid #ddd; white-space: pre-wrap; word-wrap: break-word;"></pre>
<button class="btn btn-success" id="createVideoBtn" style="margin-top: 15px;">制作视频</button>
</div>
</div>
<!-- 添加遮罩层 -->
<div class="mask" id="mask">
<div class="mask-content">
<div class="loader"></div>
<div class="mask-text" id="maskText">正在生成图片,请稍候...</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const imageUrl = sessionStorage.getItem('generatedImageUrl');
const prompt = sessionStorage.getItem('lastPrompt');
const previewImage = document.getElementById('previewImage');
const loading = document.getElementById('loading');
const backBtn = document.getElementById('backBtn');
const regenerateBtn = document.getElementById('regenerateBtn');
const generateFenBtn = document.getElementById('generateFenBtn'); // 获取新按钮
const fenjingtouResult = document.getElementById('fenjingtouResult');
const fenjingtouPrompt = document.getElementById('fenjingtouPrompt');
const mask = document.getElementById('mask');
const maskText = document.getElementById('maskText');
if (!imageUrl) {
alert('没有找到生成的图片,请返回重新生成');
window.location.href = 'prompt_input.html';
return;
}
// 加载图片
previewImage.onload = function() {
loading.style.display = 'none';
previewImage.style.display = 'block';
};
previewImage.onerror = function() {
loading.textContent = '图片加载失败';
};
previewImage.src = imageUrl;
// 返回修改按钮
backBtn.addEventListener('click', function() {
window.location.href = 'prompt_input.html';
});
// 重新生成按钮
regenerateBtn.addEventListener('click', function() {
// 显示遮罩动画
mask.classList.add('active');
maskText.textContent = '正在重新生成图片,请稍候...';
// 调用 API 重新生成图片
fetch('/api/jimeng/prompt_input', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ prompt: prompt })
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
// 隐藏遮罩动画
mask.classList.remove('active');
if (data.code === 200) {
// 更新图片 URL
const newImageUrl = data.data.image_url;
sessionStorage.setItem('generatedImageUrl', newImageUrl);
previewImage.src = newImageUrl;
} else {
alert('图片生成失败: ' + data.message);
loading.style.display = 'none';
previewImage.style.display = 'block';
}
})
.catch(error => {
// 隐藏遮罩动画
mask.classList.remove('active');
console.error('生成图片时出错:', error);
alert('生成图片时出错: ' + error.message);
loading.style.display = 'none';
previewImage.style.display = 'block';
});
});
// 生成分镜头按钮
generateFenBtn.addEventListener('click', function() {
const promptText = fenjingtouPrompt.value.trim();
if (!promptText) {
alert('请输入分镜头提示词');
return;
}
// 显示遮罩动画
mask.classList.add('active');
maskText.textContent = '正在生成分镜头脚本,请稍候...';
// 调用分镜头API
fetch('/api/jimeng/generate_fenjingtou', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
image_url: imageUrl,
prompt_text: promptText
})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
// 隐藏遮罩动画
mask.classList.remove('active');
if (data.code === 200) {
// 显示分镜头结果
fenjingtouResult.style.display = 'block';
fenjingtouResult.querySelector('pre').textContent = data.data.fenjingtou_content;
} else {
alert('分镜头生成失败: ' + data.message);
}
})
.catch(error => {
// 隐藏遮罩动画
mask.classList.remove('active');
console.error('生成分镜头时出错:', error);
alert('生成分镜头时出错: ' + error.message);
});
});
// 制作视频按钮
const createVideoBtn = document.getElementById('createVideoBtn');
createVideoBtn.addEventListener('click', function() {
const fenjingtouContent = fenjingtouResult.querySelector('pre').textContent.trim();
if (!fenjingtouContent) {
alert('请先生成分镜头脚本');
return;
}
// 显示遮罩动画
mask.classList.add('active');
maskText.textContent = '正在创建视频任务,请稍候...';
// 调用创建视频任务API
fetch('/api/jimeng/create_video_task', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
image_url: imageUrl,
prompt: fenjingtouContent
})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应异常');
}
return response.json();
})
.then(data => {
// 隐藏遮罩动画
mask.classList.remove('active');
if (data.code === 200) {
// 获取任务ID并跳转到视频预览页面
const taskId = data.data.task_id;
sessionStorage.setItem('videoTaskId', taskId);
window.location.href = 'video_preview.html';
} else {
alert('创建视频任务失败: ' + data.message);
}
})
.catch(error => {
// 隐藏遮罩动画
mask.classList.remove('active');
console.error('创建视频任务时出错:', error);
alert('创建视频任务时出错: ' + error.message);
});
});
});
</script>
</body>
</html>