639 lines
27 KiB
HTML
639 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport"
|
||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||
<title>Airhub - 故事详情</title>
|
||
<link rel="stylesheet" href="styles.css?v=6">
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
||
<style>
|
||
html,
|
||
body {
|
||
height: 100%;
|
||
margin: 0;
|
||
overflow: hidden;
|
||
/* Prevent body scroll */
|
||
background: #FDF9F3;
|
||
}
|
||
|
||
.result-container {
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
padding: var(--header-padding-top) 24px 110px;
|
||
/* Space for footer */
|
||
max-width: 600px;
|
||
margin: 0 auto;
|
||
position: relative;
|
||
}
|
||
|
||
.dc-header {
|
||
flex-shrink: 0;
|
||
/* Header stays fixed */
|
||
position: relative;
|
||
margin-bottom: 16px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-height: 44px;
|
||
}
|
||
|
||
.back-btn-custom {
|
||
position: absolute;
|
||
left: 0;
|
||
background: none;
|
||
border: none;
|
||
padding: 8px;
|
||
cursor: pointer;
|
||
color: #4B5563;
|
||
}
|
||
|
||
/* Story Card becomes the Scroll Container */
|
||
.story-paper {
|
||
flex: 1;
|
||
/* Fill remaining space */
|
||
overflow-y: auto;
|
||
/* Internal Scroll */
|
||
margin-bottom: 10px;
|
||
/* Hide Scrollbar for App Feel */
|
||
scrollbar-width: none;
|
||
/* Firefox */
|
||
-ms-overflow-style: none;
|
||
/* IE/Edge */
|
||
}
|
||
|
||
/* Video Mode - Maximize Content */
|
||
.story-paper.video-mode {
|
||
padding: 0 !important;
|
||
background: transparent !important;
|
||
box-shadow: none !important;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
/* Webkit Scrollbar styling (Chrome/Safari) */
|
||
.story-paper::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
/* Typography Polish */
|
||
.story-content {
|
||
font-size: 16px;
|
||
line-height: 2.0;
|
||
color: #374151;
|
||
text-align: justify;
|
||
}
|
||
|
||
.story-content p {
|
||
margin-bottom: 20px;
|
||
text-indent: 2em;
|
||
}
|
||
|
||
/* Fullscreen Button */
|
||
.fullscreen-btn {
|
||
position: absolute;
|
||
bottom: 16px;
|
||
right: 16px;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
border-radius: 8px;
|
||
width: 36px;
|
||
height: 36px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: white;
|
||
cursor: pointer;
|
||
z-index: 20;
|
||
/* Above Click Overlay */
|
||
backdrop-filter: blur(4px);
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.fullscreen-btn:active {
|
||
transform: scale(0.9);
|
||
background: rgba(0, 0, 0, 0.7);
|
||
}
|
||
|
||
/* In-Card Loading State */
|
||
.video-loading-state {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 100%;
|
||
width: 100%;
|
||
color: #4B5563;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
|
||
<!-- Remove separate loading mask, moved inside card -->
|
||
|
||
<!-- Custom Modal Overlay -->
|
||
<div class="modal-overlay" id="custom-modal">
|
||
<div class="glass-modal">
|
||
<div class="modal-title" id="modal-title">提示</div>
|
||
<div class="modal-desc" id="modal-desc">内容文本</div>
|
||
<div class="modal-actions">
|
||
<button class="modal-btn cancel" id="modal-cancel">取消</button>
|
||
<button class="modal-btn confirm" id="modal-confirm">确定</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Custom Toast -->
|
||
<div class="custom-toast" id="custom-toast">
|
||
✨ 操作成功
|
||
</div>
|
||
|
||
<!-- Main Scroll Container -->
|
||
<div class="result-container" id="main-container">
|
||
|
||
<!-- Header -->
|
||
<header class="dc-header" id="page-header">
|
||
<button class="back-btn-custom" onclick="window.location.href='device-control.html?tab=story'">
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
||
<path d="M15 18l-6-6 6-6" stroke-linecap="round" stroke-linejoin="round" />
|
||
</svg>
|
||
</button>
|
||
<div class="header-title" style="font-weight:700; color:#4B2404; font-size: 18px;">星际忍者的茶话会</div>
|
||
</header>
|
||
|
||
<!-- Tab Switcher (Hidden by default) -->
|
||
<div class="tab-switch-container" id="content-tabs" style="display:none;">
|
||
<div class="tab-switch">
|
||
<button class="switch-btn active" id="tab-text" onclick="switchContentTab('text')">📄 故事</button>
|
||
<button class="switch-btn" id="tab-video" onclick="switchContentTab('video')">🎬 绘本</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Story Content Card -->
|
||
<div class="story-paper" id="story-card">
|
||
<!-- Text Content -->
|
||
<div class="story-content" id="view-text">
|
||
<p>
|
||
在遥远的银河系边缘,有一个被星云包裹的神秘茶馆。今天,这里迎来了两位特殊的客人:刚执行完火星探测任务的宇航员波波,和正在追捕暗影怪兽的忍者小次郎。
|
||
</p>
|
||
<p>
|
||
“这儿的重力好像有点不对劲?”波波飘在半空中,试图抓住飞来飞去的茶杯。小次郎则冷静地倒挂在天花板上,手里紧握着一枚手里剑——其实那是用来切月饼的。
|
||
</p>
|
||
<p>
|
||
突然,桌上的魔法茶壶“噗”地一声喷出了七彩烟雾,一只会说话的卡皮巴拉钻了出来:“别打架,别打架,喝了这杯‘银河气泡茶’,我们都是好朋友!”
|
||
</p>
|
||
<p>
|
||
于是,宇宙中最奇怪的组合诞生了。他们决定,下一站,去黑洞边缘钓星星。
|
||
</p>
|
||
</div>
|
||
|
||
<!-- Video Content (Hidden by default) -->
|
||
<div class="video-view-container" id="view-video">
|
||
<!-- Loading Wrapper -->
|
||
<div class="video-loading-state" id="video-loading-state" style="display:none;">
|
||
<div class="loader-spinner"
|
||
style="border-width: 3px; width: 40px; height: 40px; border-top-color: #F43F5E;"></div>
|
||
<div style="font-weight:600; margin-top:16px;">AI 正在绘制动态绘本...</div>
|
||
<div style="font-size:12px; color:#9CA3AF; margin-top:8px;">消耗 10 SP</div>
|
||
</div>
|
||
|
||
<!-- Video Wrapper -->
|
||
<div id="video-content-wrapper">
|
||
<video class="story-video" id="video-player" playsinline loop>
|
||
<source src="动态绘本/失控的魔法扫帚.mp4" type="video/mp4">
|
||
您的浏览器不支持视频标签。
|
||
</video>
|
||
<!-- Click Overlay -->
|
||
<div class="video-overlay" id="video-overlay">
|
||
<div class="play-btn-circle" id="overlay-icon">
|
||
<!-- Play Icon -->
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M8 5v14l11-7z" />
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
<!-- Fullscreen Button -->
|
||
<button class="fullscreen-btn" id="fs-btn">
|
||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||
stroke-width="2.5">
|
||
<path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" stroke-linecap="round"
|
||
stroke-linejoin="round" />
|
||
</svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<!-- Generator Mode Footer (New Story) -->
|
||
<div class="generator-footer" id="footer-gen">
|
||
<div class="btn-group-2col">
|
||
<button class="btn-secondary" onclick="window.location.href='story-loading.html'">
|
||
<span>↻ 重写</span>
|
||
</button>
|
||
<button class="btn-capybara-primary" id="save-btn-magic">
|
||
<span>保存故事</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Read Mode Footer: Text Tab -->
|
||
<div class="generator-footer" id="footer-text-mode" style="display: none;">
|
||
<div class="btn-group-2col">
|
||
<button class="btn-secondary" id="tts-btn"
|
||
style="height: 50px; font-weight: 600; display: flex; align-items: center; justify-content: center; gap: 6px;">
|
||
<span id="tts-icon" style="display: flex;">
|
||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||
<path d="M3 18v-6a9 9 0 0 1 18 0v6"></path>
|
||
<path
|
||
d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z">
|
||
</path>
|
||
</svg>
|
||
</span>
|
||
<span id="tts-text">朗读</span>
|
||
</button>
|
||
<button class="btn-capybara-primary" id="make-book-btn">
|
||
<span id="make-book-text">变绘本</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Read Mode Footer: Video Tab -->
|
||
<div class="generator-footer" id="footer-video-mode" style="display: none;">
|
||
<!-- Single Full Width Button for Regen -->
|
||
<button class="btn-capybara-primary" id="regen-video-btn" style="width:100%; justify-content:center;">
|
||
<span>↻ 重新生成</span>
|
||
</button>
|
||
</div>
|
||
|
||
<script>
|
||
// Mock Stories for Testing
|
||
const mockStories = [
|
||
{
|
||
title: "星际忍者的茶话会",
|
||
content: `
|
||
<p>在遥远的银河系边缘,有一个被星云包裹的神秘茶馆。今天,这里迎来了两位特殊的客人:刚执行完火星探测任务的宇航员波波,和正在追捕暗影怪兽的忍者小次郎。</p>
|
||
<p>“这儿的重力好像有点不对劲?”波波飘在半空中,试图抓住飞来飞去的茶杯。小次郎则冷静地倒挂在天花板上,手里紧握着一枚手里剑——其实那是用来切月饼的。</p>
|
||
<p>突然,桌上的魔法茶壶“噗”地一声喷出了七彩烟雾,一只会说话的卡皮巴拉钻了出来:“别打架,别打架,喝了这杯‘银河气泡茶’,我们都是好朋友!”</p>
|
||
<p>于是,宇宙中最奇怪的组合诞生了。他们决定,下一站,去黑洞边缘钓星星。</p>
|
||
`
|
||
},
|
||
{
|
||
title: "卡皮巴拉的午睡奇遇",
|
||
content: `
|
||
<p>午后的阳光洒在亚马逊河畔,一只名叫卡卡的水豚正躺在巨大的睡莲叶上打盹。它的鼻子上停着一只蓝色的蜻蜓,而它的肚子上,竟然正在举行一场蚂蚁足球赛。</p>
|
||
<p>“嘿!那是犯规!”一只穿着草裙的松鼠裁判吹响了哨子。卡卡迷迷糊糊地睁开眼,发现周围聚集了一圈森林里的小动物,连平时最害羞的树懒都慢慢爬下来围观。</p>
|
||
<p>原来,卡卡睡觉时发出的呼噜声,正好是一首完美的桑巴舞曲。小动物们忍不住跟着节奏扭动起来。卡卡打了个哈欠,心想:“既然大家都这么开心,那我再睡五分钟吧。”</p>
|
||
<p>就这样,森林里最盛大的午后舞会,在一只水豚的梦境中拉开了帷幕。</p>
|
||
`
|
||
},
|
||
{
|
||
title: "失控的魔法扫帚",
|
||
content: `
|
||
<p>魔法学院的期末考试正在进行中,小女巫艾米紧张地握着她的新扫帚“光轮2026”。考试题目是:平稳飞越学校的钟楼并且不撞到任何一只鸽子。</p>
|
||
<p>“起飞!”艾米念出咒语。可是,扫帚似乎有了自己的想法,它没有飞向钟楼,而是像火箭一样冲向了食堂的窗户!</p>
|
||
<p>“糟糕!那是校长的草莓蛋糕!”艾米惊呼。就在千钧一发之际,扫帚突然一个急转弯,稳稳地停在了蛋糕前——原来它只是饿了。</p>
|
||
<p>虽然考试不及格,但艾米发明了全校最快的“外卖配送术”。从此以后,魔法学院的学生们再也不用担心吃不到热乎乎的披萨了。</p>
|
||
`
|
||
}
|
||
];
|
||
|
||
let hasGeneratedVideo = false;
|
||
|
||
// --- Custom Modal Helpers ---
|
||
function showCustomConfirm(message, onConfirm) {
|
||
const modal = document.getElementById('custom-modal');
|
||
const title = document.getElementById('modal-title');
|
||
const desc = document.getElementById('modal-desc');
|
||
const cancelBtn = document.getElementById('modal-cancel');
|
||
const confirmBtn = document.getElementById('modal-confirm');
|
||
|
||
title.innerText = "魔法确认";
|
||
desc.innerHTML = message; // Using innerHTML for <br> support
|
||
|
||
modal.classList.add('active');
|
||
|
||
// Clean up old listeners to avoid multiple triggers
|
||
const newConfirm = confirmBtn.cloneNode(true);
|
||
const newCancel = cancelBtn.cloneNode(true);
|
||
confirmBtn.parentNode.replaceChild(newConfirm, confirmBtn);
|
||
cancelBtn.parentNode.replaceChild(newCancel, cancelBtn);
|
||
|
||
newConfirm.addEventListener('click', () => {
|
||
modal.classList.remove('active');
|
||
if (onConfirm) onConfirm();
|
||
});
|
||
|
||
newCancel.addEventListener('click', () => {
|
||
modal.classList.remove('active');
|
||
});
|
||
}
|
||
|
||
function showCustomToast(message) {
|
||
const toast = document.getElementById('custom-toast');
|
||
toast.innerText = message;
|
||
toast.classList.add('active');
|
||
|
||
setTimeout(() => {
|
||
toast.classList.remove('active');
|
||
}, 2000);
|
||
}
|
||
|
||
|
||
// Global function for tab switching
|
||
window.switchContentTab = function (type) {
|
||
const textView = document.getElementById('view-text');
|
||
const videoView = document.getElementById('view-video');
|
||
const btnText = document.getElementById('tab-text');
|
||
const btnVideo = document.getElementById('tab-video');
|
||
const video = document.getElementById('video-player');
|
||
const card = document.getElementById('story-card');
|
||
|
||
// Footer Elements
|
||
const footerText = document.getElementById('footer-text-mode');
|
||
const footerVideo = document.getElementById('footer-video-mode');
|
||
|
||
if (type === 'text') {
|
||
textView.style.display = 'block';
|
||
videoView.style.display = 'none';
|
||
btnText.classList.add('active');
|
||
btnVideo.classList.remove('active');
|
||
video.pause();
|
||
updateOverlayIcon(false);
|
||
|
||
// RESTORE TEXT STYLE: Remove video-mode class
|
||
card.classList.remove('video-mode');
|
||
|
||
// Update Button Text if video exists
|
||
if (hasGeneratedVideo) {
|
||
const makeBookText = document.getElementById('make-book-text');
|
||
makeBookText.innerText = "重新生成";
|
||
}
|
||
|
||
// Show Text Footer Logic
|
||
footerText.style.display = 'flex';
|
||
footerVideo.style.display = 'none';
|
||
|
||
} else {
|
||
textView.style.display = 'none';
|
||
videoView.style.display = 'block';
|
||
btnText.classList.remove('active');
|
||
btnVideo.classList.add('active');
|
||
|
||
// FIX: Do NOT auto-play on simple switch. Only update icon state.
|
||
updateOverlayIcon(!video.paused);
|
||
|
||
// Show Video Footer & Toggle Maximize Mode
|
||
card.classList.add('video-mode'); // Removes padding/shadow/background
|
||
footerText.style.display = 'none';
|
||
footerVideo.style.display = 'flex';
|
||
}
|
||
};
|
||
|
||
function updateOverlayIcon(isPlaying) {
|
||
const overlay = document.getElementById('video-overlay');
|
||
const icon = document.getElementById('overlay-icon');
|
||
|
||
if (isPlaying) {
|
||
overlay.classList.add('hidden');
|
||
} else {
|
||
overlay.classList.remove('hidden');
|
||
icon.innerHTML = `
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
|
||
<path d="M8 5v14l11-7z" />
|
||
</svg>
|
||
`;
|
||
}
|
||
}
|
||
|
||
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
// Check Current Index from LocalStorage
|
||
let index = parseInt(localStorage.getItem('story_test_index') || '0');
|
||
|
||
// --- Check ID Param Override ---
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
if (urlParams.has('id')) {
|
||
index = parseInt(urlParams.get('id'));
|
||
} else if (document.referrer.includes('story-loading.html')) {
|
||
// Only increment if coming from new generation and NO ID param
|
||
index = (index + 1) % mockStories.length;
|
||
localStorage.setItem('story_test_index', index);
|
||
}
|
||
|
||
// Safety check
|
||
if (index >= mockStories.length) index = 0;
|
||
|
||
const story = mockStories[index];
|
||
|
||
// Render
|
||
document.querySelector('.header-title').innerText = story.title;
|
||
const contentEl = document.querySelector('.story-content');
|
||
contentEl.innerHTML = story.content;
|
||
|
||
// --- Video Logic ---
|
||
const video = document.getElementById('video-player');
|
||
const overlay = document.getElementById('video-overlay');
|
||
|
||
// Video Click Handler
|
||
overlay.addEventListener('click', (e) => {
|
||
const videoEl = document.getElementById('video-player');
|
||
if (videoEl.paused) {
|
||
videoEl.play();
|
||
updateOverlayIcon(true);
|
||
} else {
|
||
videoEl.pause();
|
||
updateOverlayIcon(false);
|
||
}
|
||
});
|
||
video.addEventListener('click', () => {
|
||
const videoEl = document.getElementById('video-player');
|
||
if (!videoEl.paused) {
|
||
videoEl.pause();
|
||
updateOverlayIcon(false);
|
||
}
|
||
});
|
||
|
||
// Fullscreen Handler
|
||
const fsBtn = document.getElementById('fs-btn');
|
||
fsBtn.addEventListener('click', (e) => {
|
||
e.stopPropagation(); // Prevent toggling play/pause
|
||
const videoEl = document.getElementById('video-player');
|
||
|
||
if (videoEl.requestFullscreen) {
|
||
videoEl.requestFullscreen();
|
||
} else if (videoEl.webkitEnterFullscreen) {
|
||
videoEl.webkitEnterFullscreen(); // iOS Safari
|
||
} else if (videoEl.mozRequestFullScreen) {
|
||
videoEl.mozRequestFullScreen();
|
||
} else if (videoEl.msRequestFullscreen) {
|
||
videoEl.msRequestFullscreen();
|
||
}
|
||
});
|
||
|
||
|
||
// --- Mode Handling ---
|
||
const mode = urlParams.get('mode');
|
||
|
||
if (mode === 'read') {
|
||
// Hide Generator Footer
|
||
document.getElementById('footer-gen').style.display = 'none';
|
||
|
||
// Show Initial Text Footer
|
||
document.getElementById('footer-text-mode').style.display = 'flex';
|
||
|
||
// --- TTS Logic ---
|
||
const ttsBtn = document.getElementById('tts-btn');
|
||
const ttsIcon = document.getElementById('tts-icon');
|
||
const ttsText = document.getElementById('tts-text');
|
||
|
||
let utterance = null;
|
||
|
||
// Stop any previous speech
|
||
window.speechSynthesis.cancel();
|
||
|
||
function setPauseUI() {
|
||
// Pause Icon
|
||
ttsIcon.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M6 4h4v16H6V4zm8 0h4v16h-4V4z"/></svg>`;
|
||
ttsText.innerText = '暂停';
|
||
ttsBtn.classList.add('playing');
|
||
}
|
||
|
||
function setPlayUI() {
|
||
// Play Icon
|
||
ttsIcon.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>`;
|
||
ttsText.innerText = '继续';
|
||
ttsBtn.classList.remove('playing');
|
||
}
|
||
|
||
function resetTTSUI() {
|
||
// Headset Icon
|
||
ttsIcon.innerHTML = `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path></svg>`;
|
||
ttsText.innerText = '朗读';
|
||
ttsBtn.classList.remove('playing');
|
||
}
|
||
|
||
ttsBtn.onclick = () => {
|
||
const synth = window.speechSynthesis;
|
||
if (!utterance) {
|
||
const pureText = contentEl.innerText;
|
||
utterance = new SpeechSynthesisUtterance(pureText);
|
||
utterance.lang = 'zh-CN';
|
||
utterance.rate = 1.0;
|
||
utterance.onend = () => {
|
||
utterance = null;
|
||
resetTTSUI();
|
||
};
|
||
synth.speak(utterance);
|
||
setPauseUI();
|
||
} else {
|
||
if (synth.paused) {
|
||
synth.resume();
|
||
setPauseUI();
|
||
} else {
|
||
if (synth.speaking) {
|
||
synth.pause();
|
||
setPlayUI();
|
||
} else {
|
||
utterance = null;
|
||
ttsBtn.click(); // Restart
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// --- Helper: Simulate Generation ---
|
||
function runGenerationProcess() {
|
||
const loader = document.getElementById('video-loading-state');
|
||
const videoWrapper = document.getElementById('video-content-wrapper');
|
||
|
||
// Show Tabs & Switch to Video Mode
|
||
document.getElementById('content-tabs').style.display = 'flex';
|
||
hasGeneratedVideo = true;
|
||
switchContentTab('video');
|
||
|
||
// 1. Show Loading State, Hide Content
|
||
loader.style.display = 'flex';
|
||
videoWrapper.style.display = 'none';
|
||
|
||
// 2. Mock Wait
|
||
setTimeout(() => {
|
||
// 3. Swap to Content
|
||
loader.style.display = 'none';
|
||
videoWrapper.style.display = 'block';
|
||
|
||
// Auto-play ONLY on fresh generation
|
||
const video = document.getElementById('video-player');
|
||
video.play().catch(e => console.log("Autoplay failed", e));
|
||
updateOverlayIcon(true);
|
||
}, 2500);
|
||
}
|
||
|
||
// --- Make Picture Book Logic ---
|
||
const makeBookBtn = document.getElementById('make-book-btn');
|
||
makeBookBtn.onclick = () => {
|
||
// STOP TTS IF PLAYING
|
||
if (window.speechSynthesis.speaking) {
|
||
window.speechSynthesis.cancel();
|
||
resetTTSUI();
|
||
}
|
||
|
||
const actionText = hasGeneratedVideo
|
||
? "重新生成将消耗 10 SP<br>确定要继续吗?"
|
||
: "生成动态绘本将消耗 10 SP<br>确定要继续吗?";
|
||
|
||
showCustomConfirm(actionText, () => {
|
||
runGenerationProcess();
|
||
});
|
||
};
|
||
|
||
// --- Regenerate Video Logic ---
|
||
const regenBtn = document.getElementById('regen-video-btn');
|
||
regenBtn.onclick = () => {
|
||
// Force Video Pause immediately
|
||
const video = document.getElementById('video-player');
|
||
video.pause();
|
||
updateOverlayIcon(false);
|
||
|
||
showCustomConfirm("重新生成将消耗 10 SP<br>确定要继续吗?", () => {
|
||
runGenerationProcess();
|
||
});
|
||
};
|
||
|
||
} else {
|
||
// Default: Generator Mode (Magic Save)
|
||
const saveBtn = document.getElementById('save-btn-magic');
|
||
if (saveBtn) {
|
||
saveBtn.addEventListener('click', (e) => {
|
||
const card = document.querySelector('.story-paper');
|
||
if (!card) return;
|
||
|
||
const btnRect = saveBtn.getBoundingClientRect();
|
||
const cardRect = card.getBoundingClientRect();
|
||
const cardCenterX = cardRect.left + cardRect.width / 2;
|
||
const cardCenterY = cardRect.top + cardRect.height / 2;
|
||
const btnCenterX = btnRect.left + btnRect.width / 2;
|
||
const btnCenterY = btnRect.top + btnRect.height / 2;
|
||
const tx = btnCenterX - cardCenterX;
|
||
const ty = btnCenterY - cardCenterY;
|
||
|
||
card.style.setProperty('--tx', `${tx}px`);
|
||
card.style.setProperty('--ty', `${ty}px`);
|
||
card.classList.add('genie-effect');
|
||
|
||
setTimeout(() => {
|
||
window.location.href = 'device-control.html?tab=story&magic=true';
|
||
}, 800);
|
||
});
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html> |