diff --git a/web/script.js b/web/script.js
index 0fd250b..4164247 100644
--- a/web/script.js
+++ b/web/script.js
@@ -3,6 +3,12 @@
// 添加全局变量
let currentTab = 'search'; // 默认标签页
+// 添加视频URL状态管理
+let currentVideoUrl = ''; // 存储当前视频URL
+
+// 添加全局变量来跟踪视频播放状态
+let wasPlaying = false; // 记录切换标签页前的播放状态
+
function switchTab(tabName) {
// 更新当前标签页
currentTab = tabName;
@@ -10,6 +16,7 @@ function switchTab(tabName) {
// 获取所有标签页内容和按钮
const tabs = document.querySelectorAll('.tab-content');
const buttons = document.querySelectorAll('.tab-button');
+ const videoPlayer = document.getElementById('videoPlayer');
// 隐藏所有标签页内容
tabs.forEach(tab => {
@@ -27,9 +34,25 @@ function switchTab(tabName) {
// 激活对应的按钮
document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
- // 如果切换到播放器标签页,加载视频
+ // 处理视频播放状态
if (tabName === 'player') {
- loadVideo();
+ // 切换到播放器标签页
+ if (!currentVideoUrl) {
+ loadVideo();
+ } else if (wasPlaying && videoPlayer) {
+ // 如果之前是播放状态,恢复播放
+ videoPlayer.play().catch(e => console.error('Resume play failed:', e));
+ }
+ } else {
+ // 切换到其他标签页
+ if (videoPlayer) {
+ // 保存当前播放状态
+ wasPlaying = !videoPlayer.paused;
+ // 暂停视频
+ if (!videoPlayer.paused) {
+ videoPlayer.pause();
+ }
+ }
}
}
@@ -193,7 +216,7 @@ function showCoverImage(searchTerm) {
if (!coverImageContainer) {
coverImageContainer = document.createElement('div');
coverImageContainer.id = 'coverImageContainer';
- coverImageContainer.className = 'cover-image-container hidden';
+ coverImageContainer.className = 'cover-image-container hidden card-3d';
// 创建图片元素
image = document.createElement('img');
@@ -206,6 +229,11 @@ function showCoverImage(searchTerm) {
// 将容器添加到搜索结果之前
document.getElementById('searchResults').insertAdjacentElement('beforebegin', coverImageContainer);
+ } else {
+ // 确保容器有3D卡片类
+ if (!coverImageContainer.classList.contains('card-3d')) {
+ coverImageContainer.classList.add('card-3d');
+ }
}
const modal = document.getElementById('imageModal');
@@ -245,6 +273,9 @@ function showCoverImage(searchTerm) {
coverImageContainer.style.transition = 'opacity 0.3s ease';
coverImageContainer.style.opacity = '1';
image.classList.add('loaded');
+
+ // 添加3D效果初始化
+ initCard3DEffect(coverImageContainer);
});
};
@@ -254,12 +285,80 @@ function showCoverImage(searchTerm) {
};
// 点击图片显示大图
- coverImageContainer.onclick = () => {
- modalImage.src = imageUrl;
+ coverImageContainer.onclick = (e) => {
+ // 获取点击位置相对于容器的坐标
+ const rect = coverImageContainer.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+
+ // 将容器分为3x3的网格,根据点击位置选择不同的图片
+ const width = rect.width;
+ const height = rect.height;
+
+ // 水平分为左、中、右三部分
+ const xSection = Math.floor(x / (width / 3));
+ // 垂直分为上、中、下三部分
+ const ySection = Math.floor(y / (height / 3));
+
+ // 根据9宫格位置选择不同的图片
+ const position = ySection * 3 + xSection;
+
+ // 预加载图片,确保图片存在再显示
+ const preloadImage = new Image();
+
+ // 所有位置都使用相同的图片URL
+ const newImageUrl = imageUrl;
+
+ // 显示加载指示器
+ const loadingIndicator = document.createElement('div');
+ loadingIndicator.className = 'modal-loading';
+ modal.querySelector('.modal-content').appendChild(loadingIndicator);
+
+ // 预加载图片
+ preloadImage.onload = () => {
+ // 图片加载成功,设置src并显示模态框
+ modalImage.src = newImageUrl;
+ modalImage.classList.add('fullwidth-preview');
+ modal.classList.remove('hidden');
+
+ // 移除加载指示器
+ if (loadingIndicator.parentNode) {
+ loadingIndicator.parentNode.removeChild(loadingIndicator);
+ }
+
+ setTimeout(() => {
+ modal.classList.add('active');
+ }, 10);
+ };
+
+ preloadImage.onerror = () => {
+ console.log(`预览图 ${newImageUrl} 加载失败`);
+
+ // 移除加载指示器
+ if (loadingIndicator.parentNode) {
+ loadingIndicator.parentNode.removeChild(loadingIndicator);
+ }
+
+ // 显示错误提示
+ modalImage.classList.add('error');
+ modal.classList.remove('hidden');
+
+ setTimeout(() => {
+ modal.classList.add('active');
+ }, 10);
+ };
+
+ // 开始加载图片
+ preloadImage.src = newImageUrl;
+
+ // 先显示模态框,但图片为空
+ modalImage.src = '';
+ modalImage.classList.remove('error');
+ modalImage.classList.remove('fullwidth-preview');
modal.classList.remove('hidden');
- setTimeout(() => {
- modal.classList.add('active');
- }, 10);
+
+ // 显示模态框时初始化事件
+ initializeModalEvents();
};
} else {
// 如果不是番号格式,隐藏图片容器
@@ -267,39 +366,114 @@ function showCoverImage(searchTerm) {
}
}
+// 初始化3D卡片效果
+function initCard3DEffect(card) {
+ if (!card) return;
+
+ // 移除之前可能添加的事件监听器
+ card.removeEventListener('mousemove', handleMouseMove);
+ card.removeEventListener('mouseleave', handleMouseLeave);
+ card.removeEventListener('mouseenter', handleMouseEnter);
+
+ // 添加事件监听器
+ card.addEventListener('mousemove', handleMouseMove);
+ card.addEventListener('mouseleave', handleMouseLeave);
+ card.addEventListener('mouseenter', handleMouseEnter);
+}
+
+// 处理鼠标移动事件
+function handleMouseMove(e) {
+ const card = this;
+ const rect = card.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+
+ // 计算鼠标位置相对于卡片中心的偏移
+ const centerX = rect.width / 2;
+ const centerY = rect.height / 2;
+ const deltaX = (x - centerX) / centerX;
+ const deltaY = (y - centerY) / centerY;
+
+ // 减小旋转角度,从15度减小到8度
+ const rotateX = deltaY * -8;
+ const rotateY = deltaX * 8;
+
+ // 应用3D变换,减小缩放比例
+ card.style.transform = `perspective(1500px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.02, 1.02, 1.02)`;
+
+ // 减小光影效果的强度
+ card.style.boxShadow = `
+ 0 5px 15px rgba(0,0,0,0.2),
+ ${deltaX * 5}px ${deltaY * 5}px 15px rgba(0,0,0,0.1)
+ `;
+
+ // 减小图片内部的视差效果
+ const image = card.querySelector('img');
+ if (image) {
+ image.style.transform = `translateX(${deltaX * -5}px) translateY(${deltaY * -5}px)`;
+
+ // 添加亮度调整,使图片在不同角度下亮度均匀
+ const brightness = 1 + (deltaX * 0.05);
+ image.style.filter = `brightness(${brightness})`;
+ }
+}
+
+// 处理鼠标离开事件
+function handleMouseLeave() {
+ const card = this;
+
+ // 重置变换
+ card.style.transform = 'perspective(1500px) rotateX(0) rotateY(0) scale3d(1, 1, 1)';
+ card.style.boxShadow = '0 4px 10px rgba(0, 0, 0, 0.2)';
+
+ // 重置图片位置和滤镜
+ const image = card.querySelector('img');
+ if (image) {
+ image.style.transform = 'translateX(0) translateY(0)';
+ image.style.filter = 'brightness(1)';
+ }
+}
+
+// 处理鼠标进入事件
+function handleMouseEnter() {
+ const card = this;
+
+ // 添加初始变换效果,减小缩放比例
+ card.style.transition = 'transform 0.3s ease, box-shadow 0.3s ease';
+ card.style.transform = 'perspective(1500px) scale3d(1.01, 1.01, 1.01)';
+ card.style.boxShadow = '0 5px 15px rgba(0,0,0,0.2)';
+
+ // 短暂延迟后移除过渡效果,使鼠标移动时的变换更加流畅
+ setTimeout(() => {
+ card.style.transition = 'none';
+ }, 300); // 增加延迟时间,使过渡更平滑
+}
+
// 视频播放功能
let hls = null;
-let autoplayEnabled = false;
-let autoNextEnabled = false;
+let autoplayEnabled = localStorage.getItem('autoplay') === 'true'; // 从localStorage读取初始值
+let autoNextEnabled = localStorage.getItem('autoNext') === 'true'; // 从localStorage读取初始值
// 初始化自动播放设置
function initializeAutoplaySettings() {
const autoplayToggle = document.getElementById('autoplayToggle');
- if (autoplayToggle) {
- // 从localStorage读取自动播放设置
- autoplayEnabled = localStorage.getItem('autoplayEnabled') === 'true';
- autoplayToggle.checked = autoplayEnabled;
-
- // 监听自动播放设置变化
- autoplayToggle.addEventListener('change', (e) => {
- autoplayEnabled = e.target.checked;
- localStorage.setItem('autoplayEnabled', autoplayEnabled);
- });
- }
-}
-
-function initializeAutoNextToggle() {
const autoNextToggle = document.getElementById('autoNextToggle');
- if (autoNextToggle) {
- // 从localStorage读取状态
- autoNextEnabled = localStorage.getItem('autoNextEnabled') === 'true';
- autoNextToggle.checked = autoNextEnabled;
- // 绑定change事件
- autoNextToggle.addEventListener('change', (e) => {
- autoNextEnabled = e.target.checked;
- localStorage.setItem('autoNextEnabled', autoNextEnabled);
- });
- }
+
+ // 从localStorage读取设置
+ autoplayToggle.checked = autoplayEnabled;
+ autoNextToggle.checked = autoNextEnabled;
+
+ // 监听自动播放开关变化
+ autoplayToggle.addEventListener('change', function() {
+ autoplayEnabled = this.checked;
+ localStorage.setItem('autoplay', this.checked);
+ });
+
+ // 监听自动下一个开关变化
+ autoNextToggle.addEventListener('change', function() {
+ autoNextEnabled = this.checked;
+ localStorage.setItem('autoNext', this.checked);
+ });
}
// 初始化封面图开关设置
@@ -334,130 +508,136 @@ function initializeCoverToggle() {
});
}
-async function loadVideo() {
+// 修改 loadVideo 函数
+function loadVideo() {
const videoPlayer = document.getElementById('videoPlayer');
+ const videoSourceUrl = document.getElementById('videoSourceUrl');
const notification = document.getElementById('notification');
- const sourceUrlElement = document.getElementById('videoSourceUrl');
const showCover = document.getElementById('coverToggle').checked;
-
- try {
- // 添加加载中状态
- videoPlayer.classList.add('loading');
-
- // 显示加载中通知
- notification.innerHTML = `
-
- ${translations[currentLang].loadingVideo}
- `;
- notification.classList.add('show');
-
- // 预加载封面图
- const response = await fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.VIDEO}`);
- const data = await response.json();
-
- // 创建一个Image对象来预加载封面图
- const img = new Image();
- img.src = data.img_url;
-
- // 等待封面图加载完成
- await new Promise((resolve) => {
- img.onload = resolve;
- img.onerror = resolve; // 如果加载失败也继续
- });
-
- // 销毁之前的HLS实例
- if (hls) {
- hls.destroy();
- hls = null;
+
+ // 如果已经有视频URL,则不重新请求
+ if (currentVideoUrl) {
+ if (videoSourceUrl) {
+ videoSourceUrl.textContent = currentVideoUrl;
}
-
- // 设置视频封面(如果开启了封面图显示)
- if (showCover && data.img_url) {
- videoPlayer.poster = data.img_url;
- } else {
- videoPlayer.poster = ''; // 清除封面图
- }
-
- // 更新视频源地址显示
- sourceUrlElement.textContent = data.url;
-
- // 根据视频URL类型选择播放方式
- if (data.url.endsWith('.m3u8')) {
- if (Hls.isSupported()) {
- hls = new Hls();
- hls.loadSource(data.url);
- hls.attachMedia(videoPlayer);
- hls.on(Hls.Events.MANIFEST_PARSED, () => {
- if (autoplayEnabled) {
- videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
- }
- });
- } else if (videoPlayer.canPlayType('application/vnd.apple.mpegurl')) {
- videoPlayer.src = data.url;
- if (autoplayEnabled) {
- videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
- }
- }
- } else {
- videoPlayer.src = data.url;
+ if (videoPlayer && videoPlayer.src !== currentVideoUrl) {
+ videoPlayer.src = currentVideoUrl;
+ // 根据自动播放设置决定是否播放
if (autoplayEnabled) {
videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
}
}
-
- // 确保播放器控件可见
- videoPlayer.addEventListener('webkitfullscreenchange', () => {
- if (document.webkitFullscreenElement) {
- videoPlayer.style.display = 'block';
- videoPlayer.controls = true;
- }
- });
-
- videoPlayer.addEventListener('fullscreenchange', () => {
- if (document.fullscreenElement) {
- videoPlayer.style.display = 'block';
- videoPlayer.controls = true;
- }
- });
- videoPlayer.addEventListener('ended', ()=> {
- if (autoNextEnabled) {
- loadVideo()}
- ;
- });
-
- videoPlayer.classList.remove('loading');
- notification.classList.remove('show');
- } catch (error) {
- console.error('加载视频出错:', error);
- videoPlayer.classList.remove('loading');
- sourceUrlElement.textContent = '';
-
- notification.innerHTML = `
-
- ${translations[currentLang].videoError}
- `;
- notification.style.background = '#dc2626';
- notification.classList.add('show');
- setTimeout(() => {
- notification.classList.remove('show');
- notification.style.background = '';
- }, 3000);
+ return;
}
+
+ // 显示加载中通知
+ notification.innerHTML = `
+
+ ${translations[currentLang].loadingVideo}
+ `;
+ notification.classList.add('show');
+
+ // 如果没有视频URL,则请求新的
+ fetch(`${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.VIDEO}`)
+ .then(response => response.json())
+ .then(data => {
+ if (data && data.url) {
+ currentVideoUrl = data.url; // 保存视频URL
+ if (videoSourceUrl) {
+ videoSourceUrl.textContent = data.url;
+ }
+ if (videoPlayer) {
+ // 设置视频封面(如果开启了封面图显示)
+ if (showCover && data.img_url) {
+ videoPlayer.poster = data.img_url;
+ } else {
+ videoPlayer.poster = ''; // 清除封面图
+ }
+
+ videoPlayer.src = data.url;
+
+ // 根据自动播放设置决定是否播放
+ if (autoplayEnabled) {
+ videoPlayer.play().catch(e => console.error('Auto-play failed:', e));
+ }
+
+ // 添加视频结束事件监听
+ videoPlayer.onended = () => {
+ if (autoNextEnabled) {
+ clearVideoUrl(); // 清除当前URL
+ loadVideo(); // 加载下一个视频
+ }
+ };
+ }
+
+ // 隐藏加载通知
+ notification.classList.remove('show');
+ }
+ })
+ .catch(error => {
+ console.error('加载视频失败:', error);
+ notification.innerHTML = `
+
+ ${translations[currentLang].videoError}
+ `;
+ notification.style.background = '#dc2626';
+ setTimeout(() => {
+ notification.classList.remove('show');
+ notification.style.background = '';
+ }, 3000);
+ });
}
// 初始化视频播放器
document.addEventListener('DOMContentLoaded', () => {
- initializeAutoplaySettings();
+ initializeAutoplaySettings(); // 这个函数现在已经包含了自动播放和自动下一个的初始化
initializeCopyButton();
initializeCoverToggle();
- initializeAutoNextToggle(); // 新增初始化
+
+ // 修改下一个按钮的事件监听
const nextVideoButton = document.getElementById('nextVideo');
if (nextVideoButton) {
- nextVideoButton.addEventListener('click', loadVideo);
+ nextVideoButton.addEventListener('click', () => {
+ clearVideoUrl(); // 使用clearVideoUrl函数来处理
+ });
+ }
+
+ // 初始化模态框关闭功能
+ const imageModal = document.getElementById('imageModal');
+ const closeModal = document.getElementById('closeModal');
+
+ if (imageModal && closeModal) {
+ // 点击关闭按钮关闭模态框
+ closeModal.addEventListener('click', () => {
+ imageModal.classList.remove('active');
+ setTimeout(() => {
+ imageModal.classList.add('hidden');
+ }, 300);
+ });
+
+ // 点击模态框背景关闭模态框
+ imageModal.addEventListener('click', (e) => {
+ if (e.target === imageModal) {
+ imageModal.classList.remove('active');
+ setTimeout(() => {
+ imageModal.classList.add('hidden');
+ }, 300);
+ }
+ });
+
+ // ESC键关闭模态框
+ document.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape' && !imageModal.classList.contains('hidden')) {
+ imageModal.classList.remove('active');
+ setTimeout(() => {
+ imageModal.classList.add('hidden');
+ }, 300);
+ }
+ });
}
});
@@ -802,7 +982,9 @@ document.addEventListener('DOMContentLoaded', () => {
// 下一个视频按钮
const nextVideoButton = document.getElementById('nextVideo');
if (nextVideoButton) {
- nextVideoButton.addEventListener('click', loadVideo);
+ nextVideoButton.addEventListener('click', () => {
+ clearVideoUrl(); // 使用clearVideoUrl函数来处理
+ });
}
});
@@ -1067,6 +1249,14 @@ function setLanguage(lang) {
el.textContent = translations[lang][messageKey];
}
});
+
+ // 更新模态框关闭提示文本
+ const modal = document.getElementById('imageModal');
+ if (modal) {
+ modal.setAttribute('data-close-text',
+ lang === 'en' ? 'Click anywhere to close' : '点击任意位置关闭'
+ );
+ }
}
// 更新分页控件文本
@@ -1538,15 +1728,52 @@ function showThemeMenu(button) {
document.addEventListener('keydown', handleEscape);
}
-// 注册 Service Worker
-if ('serviceWorker' in navigator) {
+// 修改 Service Worker 注册代码
+if ('serviceWorker' in navigator && window.location.protocol === 'https:') {
window.addEventListener('load', () => {
- navigator.serviceWorker.register('/sw.js')
+ navigator.serviceWorker.register('./sw.js') // 使用相对路径
.then(registration => {
console.log('ServiceWorker registration successful');
})
.catch(err => {
- console.log('ServiceWorker registration failed: ', err);
+ console.error('ServiceWorker registration failed: ', err);
});
});
+} else {
+ console.log('ServiceWorker is not supported or requires HTTPS');
+}
+
+// 修改模态框点击事件处理
+function initializeModalEvents() {
+ const modal = document.getElementById('imageModal');
+ const modalImage = document.getElementById('modalImage');
+
+ // 设置关闭提示文本
+ modal.setAttribute('data-close-text',
+ currentLang === 'en' ? 'Click anywhere to close' : '点击任意位置关闭'
+ );
+
+ // 点击模态框任意位置关闭
+ modal.addEventListener('click', (e) => {
+ // 添加关闭动画
+ modal.classList.remove('active');
+ modalImage.style.transform = 'scale(0.9)';
+ modalImage.style.opacity = '0';
+
+ // 延迟隐藏模态框,等待动画完成
+ setTimeout(() => {
+ modal.classList.add('hidden');
+ // 重置图片样式
+ modalImage.style.transform = '';
+ modalImage.style.opacity = '';
+ }, 300);
+ });
+}
+
+// 添加清除视频URL的函数(可以在需要重新加载视频时调用)
+function clearVideoUrl() {
+ if (currentVideoUrl) { // 只有在有当前URL时才清除并重新加载
+ currentVideoUrl = '';
+ loadVideo();
+ }
}
diff --git a/web/style.css b/web/style.css
index 7a34d39..8921e0f 100644
--- a/web/style.css
+++ b/web/style.css
@@ -835,53 +835,66 @@ body.light-theme select option {
display: flex;
flex-direction: column;
align-items: center;
+ justify-content: center;
gap: 16px;
padding: 32px;
+ width: 100%;
+ position: static;
+ background: var(--background-dark);
+ border-radius: 8px;
+ margin: 20px auto;
+ max-width: 400px;
}
-/* 加载动画 */
+/* 加载动画圆圈 */
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid var(--border-color);
border-top-color: var(--primary-color);
border-radius: 50%;
- animation: spin 1s linear infinite;
- transform-origin: center center;
+ animation: loading-spin 1s linear infinite;
+ margin: 0 auto;
+ display: block;
}
+/* 加载动画旋转效果 */
+@keyframes loading-spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+/* 加载文本样式 */
.loading-text {
color: var(--text-secondary);
font-size: 14px;
- position: relative;
- display: inline-block;
+ text-align: center;
+ margin: 0 auto;
}
+/* 加载文本点动画 */
.loading-text::after {
content: '';
- animation: dots 1.5s steps(4, end) infinite;
+ animation: loading-dots 1.5s steps(4, end) infinite;
}
-@keyframes dots {
+/* 点动画关键帧 */
+@keyframes loading-dots {
0%, 20% { content: ''; }
40% { content: '.'; }
60% { content: '..'; }
80%, 100% { content: '...'; }
}
-@keyframes spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
+/* 搜索结果容器 */
+#searchResults {
+ position: relative;
+ z-index: 1;
}
-/* 亮色主题下的标签页容器样式 */
-[data-theme="light"] .tab-container {
- background: #ffffff;
- border-color: #e5e7eb;
+/* 搜索结果中的加载容器 */
+#searchResults .loading-container {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
/* Logo 样式 */
@@ -995,31 +1008,37 @@ body.light-theme select option {
height: 20px;
}
-/* 视频源地址样式 */
+/* 视频源地址容器样式 */
.video-source {
background: var(--bg-color);
border: 1px solid var(--border-color);
margin-bottom: 1rem;
+ display: flex;
+ align-items: center;
+ flex-wrap: nowrap; /* 防止换行 */
+ gap: 0.5rem;
+ padding: 0.75rem 1rem;
}
-.source-url {
- color: var(--text-color);
- padding: 0.25rem 0;
- word-break: break-all;
+/* 视频源URL容器 */
+.video-source .flex-grow {
+ min-width: 0; /* 允许容器缩小 */
+ flex-shrink: 1; /* 允许收缩 */
}
+/* 复制按钮样式 */
.copy-button {
- background: var(--primary-color);
- color: var(--bg-color);
- transition: all 0.2s;
+ flex-shrink: 0; /* 防止按钮缩小 */
+ white-space: nowrap; /* 防止文字换行 */
+ padding: 0.5rem 1rem;
+ min-width: fit-content; /* 确保按钮宽度适应内容 */
}
-.copy-button:hover {
- opacity: 0.9;
-}
-
-.copy-button.copied {
- background: var(--success-color);
+/* 源地址URL样式 */
+.source-url {
+ text-overflow: ellipsis; /* 超出显示省略号 */
+ overflow: hidden;
+ white-space: nowrap;
}
/* 深色主题适配 */
@@ -1039,38 +1058,114 @@ body.light-theme select option {
margin: 20px auto;
text-align: center;
transition: all 0.3s ease;
- border-radius: 8px;
+ border-radius: 12px;
overflow: hidden;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
cursor: pointer;
- min-height: 300px; /* 添加最小高度 */
+ min-height: 300px;
+ background-color: rgba(0, 0, 0, 0.05);
}
-.cover-image-container::before {
+/* 添加提示文本,告诉用户可以点击不同区域 */
+.cover-image-container::after {
+ content: '点击不同区域查看更多图片';
+ position: absolute;
+ bottom: 10px;
+ left: 50%;
+ transform: translateX(-50%);
+ background-color: rgba(0, 0, 0, 0.7);
+ color: white;
+ padding: 5px 10px;
+ border-radius: 4px;
+ font-size: 12px;
+ opacity: 0;
+ transition: opacity 0.3s ease;
+ z-index: 4;
+ pointer-events: none;
+}
+
+.cover-image-container:hover::after {
+ opacity: 1;
+}
+
+/* 增强模态框中的图片效果 */
+.modal-image {
+ max-width: 100%;
+ max-height: 90vh;
+ object-fit: contain;
+ border-radius: 8px;
+ box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
+ transition: opacity 0.3s ease, transform 0.3s ease;
+ opacity: 0;
+}
+
+.image-modal.active .modal-image {
+ opacity: 1;
+ animation: zoomIn 0.3s forwards;
+}
+
+@keyframes zoomIn {
+ from {
+ transform: scale(0.9);
+ opacity: 0;
+ }
+ to {
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+
+/* 修改3D卡片效果样式,减小抖动幅度 */
+.card-3d {
+ transform-style: preserve-3d;
+ transform: perspective(1500px); /* 增加透视距离,减小变形效果 */
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+ will-change: transform, box-shadow;
+ border-radius: 12px;
+ overflow: hidden;
+ position: relative;
+ cursor: pointer;
+}
+
+/* 修改光影效果,使光线更均匀 */
+.card-3d::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
- background: linear-gradient(90deg,
- rgba(255,255,255,0.1) 25%,
- rgba(255,255,255,0.2) 50%,
- rgba(255,255,255,0.1) 75%
+ background: linear-gradient(
+ 135deg,
+ rgba(255, 255, 255, 0.1) 0%,
+ rgba(255, 255, 255, 0.05) 50%,
+ rgba(255, 255, 255, 0.1) 100%
);
- animation: shimmer 1.5s infinite;
- z-index: 1;
+ z-index: 3;
+ pointer-events: none;
+ transition: opacity 0.3s ease;
}
-@keyframes shimmer {
- 0% {
- transform: translateX(-100%);
- }
- 100% {
- transform: translateX(100%);
- }
+.card-3d:hover::before {
+ opacity: 0.6;
}
+/* 移除辅助线 */
+.card-3d:hover::after {
+ display: none;
+}
+
+/* 修改图片过渡效果,使其更平滑 */
+.card-3d img {
+ transition: transform 0.3s ease;
+ transform-origin: center center;
+ backface-visibility: hidden;
+ position: relative;
+ z-index: 2;
+ filter: brightness(1.02); /* 轻微提高亮度 */
+}
+
+/* 确保图片加载后显示正常 */
.cover-image {
opacity: 0;
transition: opacity 0.3s ease, transform 0.3s ease;
@@ -1089,7 +1184,7 @@ body.light-theme select option {
left: 0;
width: 100%;
height: 100%;
- background-color: rgba(0, 0, 0, 0.9);
+ background-color: rgba(0, 0, 0, 0.95);
display: flex;
justify-content: center;
align-items: center;
@@ -1097,6 +1192,7 @@ body.light-theme select option {
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
+ cursor: pointer;
}
.image-modal.active {
@@ -1110,26 +1206,16 @@ body.light-theme select option {
.modal-content {
position: relative;
- max-width: 90%;
+ max-width: 96vw;
max-height: 90vh;
-}
-
-.modal-image {
- max-width: 100%;
- max-height: 90vh;
- object-fit: contain;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transition: transform 0.3s ease;
}
.modal-close {
- position: absolute;
- top: -40px;
- right: 0;
- background: none;
- border: none;
- color: white;
- cursor: pointer;
- padding: 8px;
- transition: transform 0.2s ease;
+ display: none;
}
.modal-close:hover {
@@ -1141,15 +1227,19 @@ body.light-theme select option {
height: 24px;
}
-/* 添加键盘操作提示 */
-.modal-content::after {
- content: 'ESC 关闭';
- position: absolute;
- bottom: -30px;
+/* 修改点击关闭提示,支持中英文 */
+.image-modal::after {
+ content: attr(data-close-text);
+ position: fixed;
+ bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.6);
font-size: 14px;
+ padding: 8px 16px;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 4px;
+ pointer-events: none;
}
/* 下一个按钮样式 */
@@ -1157,8 +1247,11 @@ body.light-theme select option {
background-color: var(--primary-color);
color: var(--text-color);
border-radius: 0.375rem;
- font-weight: 500;
+ font-weight: 700; /* 加粗文字 */
transition: all 0.2s;
+ padding: 0.5rem 1rem;
+ white-space: nowrap; /* 防止文字换行 */
+ flex-shrink: 0; /* 防止缩小 */
}
.next-button:hover {
@@ -1244,6 +1337,46 @@ body.light-theme select option {
background: rgba(0, 0, 0, 0.05);
padding: 0.75rem 1rem;
border-radius: 0.5rem;
+ display: flex;
+ align-items: center;
+ flex-wrap: nowrap; /* 防止换行 */
+ gap: 1rem; /* 添加间距 */
+}
+
+/* 自动播放开关容器 */
+.autoplay-toggle {
+ display: flex;
+ align-items: center;
+ white-space: nowrap; /* 防止文字换行 */
+ flex-shrink: 0; /* 防止缩小 */
+}
+
+/* 确保开关文字不换行 */
+.autoplay-toggle label {
+ white-space: nowrap;
+}
+
+/* 调整开关间距 */
+.video-controls .autoplay-toggle + .autoplay-toggle {
+ margin-left: 1rem;
+}
+
+/* 确保移动端布局正确 */
+@media (max-width: 640px) {
+ .video-controls {
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 0.5rem;
+ gap: 0.5rem;
+ }
+
+ .autoplay-toggle label {
+ font-size: 0.875rem; /* 稍微减小字体大小 */
+ }
+
+ .next-button {
+ padding: 0.5rem 0.75rem;
+ }
}
/* 自动播放开关样式 */
@@ -1498,3 +1631,152 @@ main {
z-index: 50;
margin-bottom: 60px;
}
+
+/* 添加模态框加载指示器 */
+.modal-loading {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 50px;
+ height: 50px;
+ border: 5px solid rgba(255, 255, 255, 0.3);
+ border-radius: 50%;
+ border-top-color: var(--primary-color);
+ animation: spin 1s ease-in-out infinite;
+ z-index: 10;
+}
+
+@keyframes spin {
+ to { transform: translate(-50%, -50%) rotate(360deg); }
+}
+
+/* 确保模态框内容区域有相对定位 */
+.modal-content {
+ position: relative;
+ max-width: 90%;
+ max-height: 90vh;
+ min-height: 200px;
+ min-width: 200px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* 改进模态框图片加载过程 */
+.modal-image {
+ max-width: 100%;
+ max-height: 90vh;
+ object-fit: contain;
+ border-radius: 8px;
+ box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
+ transition: opacity 0.3s ease, transform 0.3s ease;
+ opacity: 0;
+}
+
+.image-modal.active .modal-image {
+ opacity: 1;
+ animation: zoomIn 0.3s forwards;
+}
+
+/* 添加键盘事件处理,支持ESC关闭和方向键切换图片 */
+.image-modal.active {
+ opacity: 1;
+ visibility: visible;
+}
+
+/* 添加图片加载失败时的提示 */
+.modal-image.error::before {
+ content: '图片加载失败';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: white;
+ background: rgba(0, 0, 0, 0.7);
+ padding: 10px 20px;
+ border-radius: 4px;
+ font-size: 14px;
+}
+
+/* 全宽预览图样式 */
+.fullwidth-preview {
+ width: 96vw !important;
+ max-width: 96vw !important;
+ height: auto !important;
+ max-height: 90vh !important;
+ object-fit: contain !important;
+}
+
+/* 改进模态框样式以适应全宽图片 */
+.modal-content {
+ position: relative;
+ max-width: 96vw;
+ max-height: 90vh;
+ min-height: 200px;
+ min-width: 200px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+/* 确保模态框内容居中 */
+.image-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: rgba(0, 0, 0, 0.95);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+ opacity: 0;
+ visibility: hidden;
+ transition: all 0.3s ease;
+}
+
+/* 改进模态框图片加载过程 */
+.modal-image {
+ max-width: 100%;
+ max-height: 90vh;
+ object-fit: contain;
+ border-radius: 8px;
+ box-shadow: 0 5px 25px rgba(0, 0, 0, 0.5);
+ transition: opacity 0.3s ease, transform 0.3s ease;
+ opacity: 0;
+}
+
+/* 添加图片加载错误状态 */
+.modal-image.error {
+ min-width: 300px;
+ min-height: 200px;
+ background-color: rgba(0, 0, 0, 0.3);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+}
+
+.modal-image.error::after {
+ content: '图片加载失败';
+ position: absolute;
+ color: white;
+ font-size: 16px;
+}
+
+/* 添加提示文本 */
+.image-modal::after {
+ content: '点击任意位置关闭';
+ position: fixed;
+ bottom: 20px;
+ left: 50%;
+ transform: translateX(-50%);
+ color: rgba(255, 255, 255, 0.6);
+ font-size: 14px;
+ padding: 8px 16px;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 4px;
+ pointer-events: none;
+}